| 1 | /* $Id: icon.cpp,v 1.15 2003-02-24 17:02:43 sandervl Exp $ */ | 
|---|
| 2 |  | 
|---|
| 3 | /* | 
|---|
| 4 | * Win32 icon conversion functions for OS/2 | 
|---|
| 5 | * | 
|---|
| 6 | * Copyright 1998 Sander van Leeuwen | 
|---|
| 7 | * | 
|---|
| 8 | * | 
|---|
| 9 | * Project Odin Software License can be found in LICENSE.TXT | 
|---|
| 10 | * | 
|---|
| 11 | */ | 
|---|
| 12 | #define INCL_GPIBITMAPS | 
|---|
| 13 | #define INCL_BITMAPFILEFORMAT | 
|---|
| 14 | #define INCL_DOSFILEMGR          /* File Manager values      */ | 
|---|
| 15 | #define INCL_DOSERRORS           /* DOS Error values         */ | 
|---|
| 16 | #define INCL_DOSPROCESS          /* DOS Process values       */ | 
|---|
| 17 | #define INCL_DOSMISC             /* DOS Miscellanous values  */ | 
|---|
| 18 | #define INCL_WIN | 
|---|
| 19 | #include <os2wrap.h>    //Odin32 OS/2 api wrappers | 
|---|
| 20 | #include <stdio.h> | 
|---|
| 21 | #include <string.h> | 
|---|
| 22 | #include <stdlib.h> | 
|---|
| 23 | #include <string.h> | 
|---|
| 24 | #ifndef __EMX__ | 
|---|
| 25 | #include <iostream.h> | 
|---|
| 26 | #endif | 
|---|
| 27 |  | 
|---|
| 28 | #include <win32api.h> | 
|---|
| 29 | #include <win32type.h> | 
|---|
| 30 | #include "dib.h" | 
|---|
| 31 | #include <winicon.h> | 
|---|
| 32 | #include <misc.h> | 
|---|
| 33 |  | 
|---|
| 34 | #define DBG_LOCALLOG    DBG_icon | 
|---|
| 35 | #include "dbglocal.h" | 
|---|
| 36 |  | 
|---|
| 37 | #define DIB_RGB_COLORS_W   0 | 
|---|
| 38 | #define DIB_PAL_COLORS_W   1 | 
|---|
| 39 | #define CBM_INIT_W         4 | 
|---|
| 40 |  | 
|---|
| 41 |  | 
|---|
| 42 | //****************************************************************************** | 
|---|
| 43 | //****************************************************************************** | 
|---|
| 44 | ULONG QueryConvertedIconSize(WINBITMAPINFOHEADER *bmpHdr, int size, BOOL fResizeTo40x40 = FALSE) | 
|---|
| 45 | { | 
|---|
| 46 | int bwsize, colorsize, rgbsize, iconsize; | 
|---|
| 47 |  | 
|---|
| 48 | if(fResizeTo40x40) { | 
|---|
| 49 | bwsize    = DIB_GetDIBImageBytes(40, 40, 1); | 
|---|
| 50 | colorsize = DIB_GetDIBImageBytes(40, 40, bmpHdr->biBitCount); | 
|---|
| 51 | } | 
|---|
| 52 | else { | 
|---|
| 53 | bwsize    = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1); | 
|---|
| 54 | colorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount); | 
|---|
| 55 | } | 
|---|
| 56 |  | 
|---|
| 57 | if(bmpHdr->biBitCount <= 8) | 
|---|
| 58 | rgbsize = (1<<bmpHdr->biBitCount)*sizeof(RGB2); | 
|---|
| 59 | else  rgbsize = 0; | 
|---|
| 60 |  | 
|---|
| 61 | if(bmpHdr->biSizeImage == 0 && bmpHdr->biCompression == 0) { | 
|---|
| 62 | bmpHdr->biSizeImage = bwsize + colorsize; | 
|---|
| 63 | } | 
|---|
| 64 |  | 
|---|
| 65 | //SvL: 28-09-'98: cllngenu.dll has an incorrect size in the header | 
|---|
| 66 | if(bmpHdr->biSizeImage < colorsize) { | 
|---|
| 67 | bmpHdr->biSizeImage = colorsize; | 
|---|
| 68 | } | 
|---|
| 69 | //bitmapfileheader for AndXor mask + 2 RGB structs + bitmapfileheader | 
|---|
| 70 | //for color bitmap + RGB structs for all the colors | 
|---|
| 71 | //SvL, 3-3-98: 2*bwsize | 
|---|
| 72 | iconsize = 2*sizeof(BITMAPFILEHEADER2) + 2*sizeof(RGB2) + | 
|---|
| 73 | rgbsize + 2*bwsize + colorsize; | 
|---|
| 74 |  | 
|---|
| 75 | return iconsize; | 
|---|
| 76 | } | 
|---|
| 77 | //****************************************************************************** | 
|---|
| 78 | //NOTE: offsetBits is the value added to the offBits bitmap structure members | 
|---|
| 79 | //      (handy for converting icon groups) | 
|---|
| 80 | //****************************************************************************** | 
|---|
| 81 | void *ConvertIcon(WINBITMAPINFOHEADER *bmpHdr, int size, int *os2size, int offsetBits, | 
|---|
| 82 | BOOL fResizeTo40x40 = FALSE) | 
|---|
| 83 | { | 
|---|
| 84 | RGBQUAD *rgb; | 
|---|
| 85 | RGB2    *os2rgb; | 
|---|
| 86 | int bwsize, i, colorsize, rgbsize, iconsize, orgbwsize, orgcolorsize; | 
|---|
| 87 | BITMAPFILEHEADER2 *iconhdr; | 
|---|
| 88 | BITMAPFILEHEADER2 *iconhdr2; | 
|---|
| 89 | char *pAnd, *pXor; | 
|---|
| 90 |  | 
|---|
| 91 | if(fResizeTo40x40) { | 
|---|
| 92 | orgbwsize    = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1); | 
|---|
| 93 | orgcolorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount); | 
|---|
| 94 | bwsize       = DIB_GetDIBImageBytes(40, 40, 1); | 
|---|
| 95 | colorsize    = DIB_GetDIBImageBytes(40, 40, bmpHdr->biBitCount); | 
|---|
| 96 | } | 
|---|
| 97 | else { | 
|---|
| 98 | bwsize    = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1); | 
|---|
| 99 | colorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount); | 
|---|
| 100 | } | 
|---|
| 101 | //SvL: 28-09-'98: only for <= 8 | 
|---|
| 102 | if(bmpHdr->biBitCount <= 8) | 
|---|
| 103 | rgbsize = (1<<bmpHdr->biBitCount)*sizeof(RGB2); | 
|---|
| 104 | else  rgbsize = 0; | 
|---|
| 105 |  | 
|---|
| 106 | if(bmpHdr->biSizeImage == 0 && bmpHdr->biCompression == 0) { | 
|---|
| 107 | bmpHdr->biSizeImage = bwsize + colorsize; | 
|---|
| 108 | } | 
|---|
| 109 | dprintf(("Icon size    : %d", bmpHdr->biSizeImage)); | 
|---|
| 110 | dprintf(("Icon Width   : %d", bmpHdr->biWidth)); | 
|---|
| 111 | //height for both the XOR and AND bitmap (color & BW) | 
|---|
| 112 | dprintf(("Height       : %d", bmpHdr->biHeight)); | 
|---|
| 113 | dprintf(("Icon Bitcount: %d", bmpHdr->biBitCount)); | 
|---|
| 114 | dprintf(("Icon Compress: %d", bmpHdr->biCompression)); | 
|---|
| 115 |  | 
|---|
| 116 | //SvL: 28-09-'98: cllngenu.dll has an incorrect size in the header | 
|---|
| 117 | if(bmpHdr->biSizeImage < colorsize) { | 
|---|
| 118 | bmpHdr->biSizeImage = colorsize; | 
|---|
| 119 | } | 
|---|
| 120 | //bitmapfileheader for AndXor mask + 2 RGB structs + bitmapfileheader | 
|---|
| 121 | //for color bitmap + RGB structs for all the colors | 
|---|
| 122 | //SvL, 3-3-98: 2*bwsize | 
|---|
| 123 | iconsize = 2*sizeof(BITMAPFILEHEADER2) + 2*sizeof(RGB2) + | 
|---|
| 124 | rgbsize + 2*bwsize + colorsize; | 
|---|
| 125 |  | 
|---|
| 126 | iconhdr  = (BITMAPFILEHEADER2 *)malloc(iconsize); | 
|---|
| 127 | memset(iconhdr, 0, iconsize); | 
|---|
| 128 | iconhdr->usType        = BFT_COLORICON; | 
|---|
| 129 | iconhdr->cbSize        = sizeof(BITMAPFILEHEADER2); | 
|---|
| 130 | iconhdr->xHotspot      = 0; | 
|---|
| 131 | iconhdr->yHotspot      = 0; | 
|---|
| 132 | iconhdr->offBits       = 2*sizeof(BITMAPFILEHEADER2) + | 
|---|
| 133 | 2*sizeof(RGB2) + rgbsize + offsetBits; | 
|---|
| 134 | iconhdr->bmp2.cbFix    = sizeof(BITMAPINFOHEADER2); | 
|---|
| 135 | if(fResizeTo40x40) { | 
|---|
| 136 | iconhdr->bmp2.cx   = (USHORT)40; | 
|---|
| 137 | iconhdr->bmp2.cy   = (USHORT)80; | 
|---|
| 138 | } | 
|---|
| 139 | else { | 
|---|
| 140 | iconhdr->bmp2.cx   = (USHORT)bmpHdr->biWidth; | 
|---|
| 141 | iconhdr->bmp2.cy   = (USHORT)bmpHdr->biHeight; | 
|---|
| 142 | } | 
|---|
| 143 | iconhdr->bmp2.cPlanes  = 1; | 
|---|
| 144 | iconhdr->bmp2.cBitCount= 1; | 
|---|
| 145 | iconhdr->bmp2.cbImage  = 2*bwsize; | 
|---|
| 146 | iconhdr->bmp2.cclrUsed = 2; | 
|---|
| 147 | iconhdr->bmp2.cclrImportant = 2; | 
|---|
| 148 | iconhdr->bmp2.ulCompression   = BCA_UNCOMP; | 
|---|
| 149 | iconhdr->bmp2.ulColorEncoding = BCE_RGB; | 
|---|
| 150 | os2rgb                 = (RGB2 *)(iconhdr+1); | 
|---|
| 151 | memset(os2rgb, 0, sizeof(RGB2)); | 
|---|
| 152 | memset(os2rgb+1, 0xff, sizeof(RGB)); //not reserved byte! | 
|---|
| 153 | iconhdr2               = (BITMAPFILEHEADER2 *)(os2rgb+2); | 
|---|
| 154 | iconhdr2->usType       = BFT_COLORICON; | 
|---|
| 155 | iconhdr2->cbSize       = sizeof(BITMAPFILEHEADER2); | 
|---|
| 156 | iconhdr2->xHotspot     = 0; | 
|---|
| 157 | iconhdr2->yHotspot     = 0; | 
|---|
| 158 | iconhdr2->offBits      = 2*sizeof(BITMAPFILEHEADER2) + | 
|---|
| 159 | 2*sizeof(RGB2) + rgbsize + 2*bwsize + offsetBits; | 
|---|
| 160 | iconhdr2->bmp2.cbFix   = sizeof(BITMAPINFOHEADER2); | 
|---|
| 161 | if(fResizeTo40x40) { | 
|---|
| 162 | iconhdr2->bmp2.cx  = (USHORT)40; | 
|---|
| 163 | iconhdr2->bmp2.cy  = (USHORT)40; | 
|---|
| 164 | } | 
|---|
| 165 | else { | 
|---|
| 166 | iconhdr2->bmp2.cx  = (USHORT)bmpHdr->biWidth; | 
|---|
| 167 | iconhdr2->bmp2.cy  = (USHORT)(bmpHdr->biHeight/2); | 
|---|
| 168 | } | 
|---|
| 169 | iconhdr2->bmp2.cPlanes = bmpHdr->biPlanes; | 
|---|
| 170 | iconhdr2->bmp2.cBitCount= bmpHdr->biBitCount; | 
|---|
| 171 | iconhdr2->bmp2.cbImage  = colorsize; | 
|---|
| 172 | iconhdr2->bmp2.cclrUsed = bmpHdr->biClrUsed; | 
|---|
| 173 | iconhdr2->bmp2.cclrImportant = bmpHdr->biClrImportant; | 
|---|
| 174 | iconhdr2->bmp2.ulCompression   = BCA_UNCOMP; | 
|---|
| 175 | iconhdr2->bmp2.ulColorEncoding = BCE_RGB; | 
|---|
| 176 | os2rgb                 = (RGB2 *)(iconhdr2+1); | 
|---|
| 177 | rgb                    = (RGBQUAD *)(bmpHdr+1); | 
|---|
| 178 | if(bmpHdr->biBitCount <= 8) { | 
|---|
| 179 | for(i=0;i<(1<<bmpHdr->biBitCount);i++) { | 
|---|
| 180 | os2rgb->bRed   = rgb->red; | 
|---|
| 181 | os2rgb->bBlue  = rgb->blue; | 
|---|
| 182 | os2rgb->bGreen = rgb->green; | 
|---|
| 183 | os2rgb++; | 
|---|
| 184 | rgb++; | 
|---|
| 185 | } | 
|---|
| 186 | } | 
|---|
| 187 |  | 
|---|
| 188 | if(fResizeTo40x40) | 
|---|
| 189 | { | 
|---|
| 190 | BYTE *src, *dest; | 
|---|
| 191 | int linesizesrc, linesizedest; | 
|---|
| 192 |  | 
|---|
| 193 | pXor = (char *)os2rgb; | 
|---|
| 194 | pAnd = (char *)os2rgb + bwsize; | 
|---|
| 195 |  | 
|---|
| 196 | if ((size - (bmpHdr->biSize + rgbsize + orgcolorsize + orgbwsize)) == orgbwsize) | 
|---|
| 197 | {//this means an AND and XOR mask is present (interleaved; and/xor) | 
|---|
| 198 | char *q; | 
|---|
| 199 | int i, linesize; | 
|---|
| 200 |  | 
|---|
| 201 | //TODO: | 
|---|
| 202 | dprintf(("TODO: icon conversion not correct")); | 
|---|
| 203 | linesize = DIB_GetDIBWidthBytes(bmpHdr->biWidth, 1); | 
|---|
| 204 | q = (char *)rgb + orgcolorsize; | 
|---|
| 205 | for (i = 0; i < bmpHdr->biHeight/2; i++) { | 
|---|
| 206 | memcpy (pAnd, q, linesize); | 
|---|
| 207 | pAnd += linesize; | 
|---|
| 208 | q += linesize; | 
|---|
| 209 |  | 
|---|
| 210 | memcpy (pXor, q, linesize); | 
|---|
| 211 | pXor += linesize; | 
|---|
| 212 | q += linesize; | 
|---|
| 213 | } | 
|---|
| 214 | } | 
|---|
| 215 | else { | 
|---|
| 216 | linesizesrc  = DIB_GetDIBWidthBytes(bmpHdr->biWidth, 1); | 
|---|
| 217 | linesizedest = DIB_GetDIBWidthBytes(40, 1); | 
|---|
| 218 |  | 
|---|
| 219 | src  = (BYTE *)rgb + orgcolorsize; | 
|---|
| 220 | dest = (BYTE *)pAnd + 4*linesizedest; //skip 4 lines | 
|---|
| 221 | memset((char *)pAnd, 0xFF, bwsize); | 
|---|
| 222 | for (i = 0; i < bmpHdr->biHeight/2; i++) { | 
|---|
| 223 | for(int j=0;j<linesizesrc;j++) { | 
|---|
| 224 | //must skip 4 pixels (4 bits) | 
|---|
| 225 | dest[j]   = (dest[j] & 0xF0) | ((src[j] >> 4)); | 
|---|
| 226 | dest[j+1] = (dest[j+1] & 0x0F) | ((src[j] & 0xF) << 4); | 
|---|
| 227 | } | 
|---|
| 228 | dest += linesizedest; | 
|---|
| 229 | src  += linesizesrc; | 
|---|
| 230 | } | 
|---|
| 231 | memset (pXor, 0, bwsize); | 
|---|
| 232 | } | 
|---|
| 233 | linesizesrc  = DIB_GetDIBWidthBytes(32, bmpHdr->biBitCount); | 
|---|
| 234 | linesizedest = DIB_GetDIBWidthBytes(40, bmpHdr->biBitCount); | 
|---|
| 235 | int skipsize = (4*bmpHdr->biBitCount)/8; //must skip 4 pixels | 
|---|
| 236 | src  = (BYTE *)rgb; | 
|---|
| 237 | dest = (BYTE *)os2rgb+2*bwsize + 4*linesizedest; //skip 4 rows | 
|---|
| 238 |  | 
|---|
| 239 | for (i = 0; i < 32; i++) { | 
|---|
| 240 | memcpy(dest+skipsize, src, linesizesrc); | 
|---|
| 241 | dest += linesizedest; | 
|---|
| 242 | src  += linesizesrc; | 
|---|
| 243 | } | 
|---|
| 244 | } | 
|---|
| 245 | else { | 
|---|
| 246 | pXor = (char *)os2rgb; | 
|---|
| 247 | pAnd = (char *)os2rgb + bwsize; | 
|---|
| 248 |  | 
|---|
| 249 | if ((size - (bmpHdr->biSize + rgbsize + colorsize + bwsize)) == bwsize) | 
|---|
| 250 | {//this means an AND and XOR mask is present (interleaved; and/xor) | 
|---|
| 251 | char *q; | 
|---|
| 252 | int i, linesize; | 
|---|
| 253 |  | 
|---|
| 254 | linesize = DIB_GetDIBWidthBytes(bmpHdr->biWidth, 1); | 
|---|
| 255 | q = (char *)rgb + orgcolorsize; | 
|---|
| 256 | for (i = 0; i < bmpHdr->biHeight/2; i++) { | 
|---|
| 257 | memcpy (pAnd, q, linesize); | 
|---|
| 258 | pAnd += linesize; | 
|---|
| 259 | q += linesize; | 
|---|
| 260 |  | 
|---|
| 261 | memcpy (pXor, q, linesize); | 
|---|
| 262 | pXor += linesize; | 
|---|
| 263 | q += linesize; | 
|---|
| 264 | } | 
|---|
| 265 | } | 
|---|
| 266 | else { | 
|---|
| 267 | memcpy (pAnd, (char *)rgb + colorsize, bwsize); | 
|---|
| 268 | memset (pXor, 0, bwsize); | 
|---|
| 269 | } | 
|---|
| 270 | memcpy((char *)os2rgb+2*bwsize, (char *)rgb, colorsize); | 
|---|
| 271 | } | 
|---|
| 272 | *os2size = iconsize; | 
|---|
| 273 | return (void *)iconhdr; | 
|---|
| 274 | } | 
|---|
| 275 |  | 
|---|
| 276 | extern "C" { | 
|---|
| 277 |  | 
|---|
| 278 | //****************************************************************************** | 
|---|
| 279 | //****************************************************************************** | 
|---|
| 280 | void * WIN32API ConvertIconGroup(void *hdr, HINSTANCE hInstance, DWORD *ressize) | 
|---|
| 281 | { | 
|---|
| 282 | IconHeader *ihdr = (IconHeader *)hdr; | 
|---|
| 283 | ResourceDirectory *rdir = (ResourceDirectory *)(ihdr + 1); | 
|---|
| 284 | int i, groupsize = 0, os2iconsize; | 
|---|
| 285 | BITMAPARRAYFILEHEADER2 *bafh, *orgbafh; | 
|---|
| 286 | WINBITMAPINFOHEADER    *iconhdr; | 
|---|
| 287 | void                   *os2icon; | 
|---|
| 288 | HRSRC                   hRes; | 
|---|
| 289 | int                     nricons = 0; | 
|---|
| 290 |  | 
|---|
| 291 | dprintf(("Icon Group type :%d", ihdr->wType)); | 
|---|
| 292 | dprintf(("Icon Group count:%d", ihdr->wCount)); | 
|---|
| 293 | for(i=0;i<ihdr->wCount;i++) { | 
|---|
| 294 | dprintf2(("Icon    : %d", rdir->wNameOrdinal)); | 
|---|
| 295 | dprintf2(("Width   : %d", (int)rdir->bWidth)); | 
|---|
| 296 | dprintf2(("Height  : %d", (int)rdir->bHeight)); | 
|---|
| 297 | dprintf2(("Colors  : %d", (int)rdir->bColorCount)); | 
|---|
| 298 | dprintf2(("Bits    : %d", rdir->wBitCount)); | 
|---|
| 299 | dprintf2(("ResBytes: %d", rdir->lBytesInRes)); | 
|---|
| 300 | hRes = FindResourceA(hInstance, | 
|---|
| 301 | (LPCSTR)rdir->wNameOrdinal, (LPSTR)NTRT_ICON); | 
|---|
| 302 |  | 
|---|
| 303 | groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)), | 
|---|
| 304 | SizeofResource(hInstance, hRes)); | 
|---|
| 305 | //add centered icon if size is 32x32 | 
|---|
| 306 | if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4) | 
|---|
| 307 | { | 
|---|
| 308 | groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)), | 
|---|
| 309 | SizeofResource(hInstance, hRes), TRUE); | 
|---|
| 310 | //extra pixels | 
|---|
| 311 | groupsize += (40*8 + 8*32)*rdir->wBitCount/8; | 
|---|
| 312 | nricons++; | 
|---|
| 313 | } | 
|---|
| 314 | nricons++; | 
|---|
| 315 | rdir++; | 
|---|
| 316 | } | 
|---|
| 317 | groupsize = groupsize+nricons*(sizeof(BITMAPARRAYFILEHEADER2) - sizeof(BITMAPFILEHEADER2)); | 
|---|
| 318 | bafh    = (BITMAPARRAYFILEHEADER2 *)malloc(groupsize); | 
|---|
| 319 | memset(bafh, 0, groupsize); | 
|---|
| 320 | orgbafh = bafh; | 
|---|
| 321 |  | 
|---|
| 322 | rdir = (ResourceDirectory *)(ihdr + 1); | 
|---|
| 323 | for(i=0;i<ihdr->wCount;i++) { | 
|---|
| 324 | bafh->usType    = BFT_BITMAPARRAY; | 
|---|
| 325 | bafh->cbSize    = sizeof(BITMAPARRAYFILEHEADER2); | 
|---|
| 326 | bafh->cxDisplay = 0; | 
|---|
| 327 | bafh->cyDisplay = 0; | 
|---|
| 328 | hRes = FindResourceA(hInstance, | 
|---|
| 329 | (LPCSTR)rdir->wNameOrdinal, (LPSTR)NTRT_ICON); | 
|---|
| 330 | if(hRes == NULL) { | 
|---|
| 331 | dprintf(("Can't find icon!")); | 
|---|
| 332 | rdir++; | 
|---|
| 333 | continue; | 
|---|
| 334 | } | 
|---|
| 335 | iconhdr = (WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)); | 
|---|
| 336 | os2icon = ConvertIcon(iconhdr, SizeofResource(hInstance, hRes), &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2)); | 
|---|
| 337 | if(os2icon == NULL) { | 
|---|
| 338 | dprintf(("Can't convert icon!")); | 
|---|
| 339 | rdir++; | 
|---|
| 340 | continue; | 
|---|
| 341 | } | 
|---|
| 342 |  | 
|---|
| 343 | if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4) | 
|---|
| 344 | { | 
|---|
| 345 | //add 40x40 icon by centering 32x32 icon in 40x40 grid | 
|---|
| 346 | //(resize is really ugly) | 
|---|
| 347 | bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize; | 
|---|
| 348 | memcpy((char *)&bafh->bfh2, os2icon, os2iconsize); | 
|---|
| 349 | free(os2icon); | 
|---|
| 350 |  | 
|---|
| 351 | bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize); | 
|---|
| 352 |  | 
|---|
| 353 | os2icon = ConvertIcon(iconhdr, SizeofResource(hInstance, hRes), &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2), TRUE); | 
|---|
| 354 | if(os2icon == NULL) { | 
|---|
| 355 | dprintf(("Can't convert icon!")); | 
|---|
| 356 | rdir++; | 
|---|
| 357 | continue; | 
|---|
| 358 | } | 
|---|
| 359 | } | 
|---|
| 360 |  | 
|---|
| 361 | if(i != ihdr->wCount -1) { | 
|---|
| 362 | bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize; | 
|---|
| 363 | } | 
|---|
| 364 | else    bafh->offNext = 0; | 
|---|
| 365 |  | 
|---|
| 366 | memcpy((char *)&bafh->bfh2, os2icon, os2iconsize); | 
|---|
| 367 | free(os2icon); | 
|---|
| 368 |  | 
|---|
| 369 | bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize); | 
|---|
| 370 |  | 
|---|
| 371 | rdir++; | 
|---|
| 372 | } | 
|---|
| 373 | *ressize = groupsize; | 
|---|
| 374 | return (void *)orgbafh; | 
|---|
| 375 | } | 
|---|
| 376 | //****************************************************************************** | 
|---|
| 377 | //****************************************************************************** | 
|---|
| 378 | void *WIN32API ConvertIconGroupIndirect(void *lpIconData, DWORD iconsize, | 
|---|
| 379 | DWORD *ressize) | 
|---|
| 380 | { | 
|---|
| 381 | ICONDIR *ihdr = (ICONDIR *)lpIconData; | 
|---|
| 382 | ICONDIRENTRY *rdir = (ICONDIRENTRY *)(ihdr + 1); | 
|---|
| 383 | int i, groupsize = 0, os2iconsize; | 
|---|
| 384 | BITMAPARRAYFILEHEADER2 *bafh, *orgbafh; | 
|---|
| 385 | WINBITMAPINFOHEADER    *iconhdr; | 
|---|
| 386 | void                   *os2icon; | 
|---|
| 387 | int                     nricons = 0; | 
|---|
| 388 | void                   *winicon; | 
|---|
| 389 |  | 
|---|
| 390 | dprintf(("Icon Group type :%d", ihdr->idType)); | 
|---|
| 391 | dprintf(("Icon Group count:%d", ihdr->idCount)); | 
|---|
| 392 | for(i=0;i<ihdr->idCount;i++) { | 
|---|
| 393 | dprintf2(("Icon    : %x", rdir->dwImageOffset)); | 
|---|
| 394 | dprintf2(("Width   : %d", (int)rdir->bWidth)); | 
|---|
| 395 | dprintf2(("Height  : %d", (int)rdir->bHeight)); | 
|---|
| 396 | dprintf2(("Colors  : %d", (int)rdir->bColorCount)); | 
|---|
| 397 | dprintf2(("Bits    : %d", rdir->wBitCount)); | 
|---|
| 398 | dprintf2(("ResBytes: %d", rdir->dwBytesInRes)); | 
|---|
| 399 |  | 
|---|
| 400 | winicon = (char *)lpIconData + rdir->dwImageOffset; | 
|---|
| 401 | groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)winicon, | 
|---|
| 402 | rdir->dwBytesInRes); | 
|---|
| 403 | //add centered icon if size is 32x32 | 
|---|
| 404 | if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4) | 
|---|
| 405 | { | 
|---|
| 406 | groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)winicon, | 
|---|
| 407 | rdir->dwBytesInRes, TRUE); | 
|---|
| 408 | //extra pixels | 
|---|
| 409 | groupsize += (40*8 + 8*32)*rdir->wBitCount/8; | 
|---|
| 410 | nricons++; | 
|---|
| 411 | } | 
|---|
| 412 | nricons++; | 
|---|
| 413 | rdir++; | 
|---|
| 414 | } | 
|---|
| 415 | groupsize = groupsize+nricons*(sizeof(BITMAPARRAYFILEHEADER2) - sizeof(BITMAPFILEHEADER2)); | 
|---|
| 416 | bafh    = (BITMAPARRAYFILEHEADER2 *)malloc(groupsize); | 
|---|
| 417 | memset(bafh, 0, groupsize); | 
|---|
| 418 | orgbafh = bafh; | 
|---|
| 419 |  | 
|---|
| 420 | rdir = (ICONDIRENTRY *)(ihdr + 1); | 
|---|
| 421 | for(i=0;i<ihdr->idCount;i++) { | 
|---|
| 422 | bafh->usType    = BFT_BITMAPARRAY; | 
|---|
| 423 | bafh->cbSize    = sizeof(BITMAPARRAYFILEHEADER2); | 
|---|
| 424 | bafh->cxDisplay = 0; | 
|---|
| 425 | bafh->cyDisplay = 0; | 
|---|
| 426 |  | 
|---|
| 427 | winicon = (char *)lpIconData + rdir->dwImageOffset; | 
|---|
| 428 | iconhdr = (WINBITMAPINFOHEADER *)winicon; | 
|---|
| 429 |  | 
|---|
| 430 | os2icon = ConvertIcon(iconhdr, rdir->dwBytesInRes, &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2)); | 
|---|
| 431 | if(os2icon == NULL) { | 
|---|
| 432 | dprintf(("Can't convert icon!")); | 
|---|
| 433 | rdir++; | 
|---|
| 434 | continue; | 
|---|
| 435 | } | 
|---|
| 436 |  | 
|---|
| 437 | if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4) | 
|---|
| 438 | { | 
|---|
| 439 | //add 40x40 icon by centering 32x32 icon in 40x40 grid | 
|---|
| 440 | //(resize is really ugly) | 
|---|
| 441 | bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize; | 
|---|
| 442 | memcpy((char *)&bafh->bfh2, os2icon, os2iconsize); | 
|---|
| 443 | free(os2icon); | 
|---|
| 444 |  | 
|---|
| 445 | bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize); | 
|---|
| 446 |  | 
|---|
| 447 | os2icon = ConvertIcon(iconhdr, rdir->dwBytesInRes, &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2), TRUE); | 
|---|
| 448 | if(os2icon == NULL) { | 
|---|
| 449 | dprintf(("Can't convert icon!")); | 
|---|
| 450 | rdir++; | 
|---|
| 451 | continue; | 
|---|
| 452 | } | 
|---|
| 453 | } | 
|---|
| 454 |  | 
|---|
| 455 | if(i != ihdr->idCount -1) { | 
|---|
| 456 | bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize; | 
|---|
| 457 | } | 
|---|
| 458 | else    bafh->offNext = 0; | 
|---|
| 459 |  | 
|---|
| 460 | memcpy((char *)&bafh->bfh2, os2icon, os2iconsize); | 
|---|
| 461 | free(os2icon); | 
|---|
| 462 |  | 
|---|
| 463 | bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize); | 
|---|
| 464 |  | 
|---|
| 465 | rdir++; | 
|---|
| 466 | } | 
|---|
| 467 | *ressize = groupsize; | 
|---|
| 468 | return (void *)orgbafh; | 
|---|
| 469 | } | 
|---|
| 470 | //****************************************************************************** | 
|---|
| 471 | //****************************************************************************** | 
|---|
| 472 |  | 
|---|
| 473 | } // extern "C" | 
|---|