[9851] | 1 | /* $Id: icon.cpp,v 1.15 2003-02-24 17:02:43 sandervl Exp $ */
|
---|
[2469] | 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>
|
---|
[21916] | 23 | #include <string.h>
|
---|
| 24 | #ifndef __EMX__
|
---|
[2469] | 25 | #include <iostream.h>
|
---|
[21916] | 26 | #endif
|
---|
[2469] | 27 |
|
---|
[6487] | 28 | #include <win32api.h>
|
---|
[2469] | 29 | #include <win32type.h>
|
---|
[6487] | 30 | #include "dib.h"
|
---|
[2469] | 31 | #include <winicon.h>
|
---|
| 32 | #include <misc.h>
|
---|
| 33 |
|
---|
[2804] | 34 | #define DBG_LOCALLOG DBG_icon
|
---|
| 35 | #include "dbglocal.h"
|
---|
| 36 |
|
---|
[6487] | 37 | #define DIB_RGB_COLORS_W 0
|
---|
| 38 | #define DIB_PAL_COLORS_W 1
|
---|
| 39 | #define CBM_INIT_W 4
|
---|
| 40 |
|
---|
[2469] | 41 |
|
---|
| 42 | //******************************************************************************
|
---|
| 43 | //******************************************************************************
|
---|
[6503] | 44 | ULONG QueryConvertedIconSize(WINBITMAPINFOHEADER *bmpHdr, int size, BOOL fResizeTo40x40 = FALSE)
|
---|
[6487] | 45 | {
|
---|
| 46 | int bwsize, colorsize, rgbsize, iconsize;
|
---|
| 47 |
|
---|
[6503] | 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 | }
|
---|
[6487] | 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) +
|
---|
[6490] | 73 | rgbsize + 2*bwsize + colorsize;
|
---|
[6487] | 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 | //******************************************************************************
|
---|
[6503] | 81 | void *ConvertIcon(WINBITMAPINFOHEADER *bmpHdr, int size, int *os2size, int offsetBits,
|
---|
| 82 | BOOL fResizeTo40x40 = FALSE)
|
---|
[6487] | 83 | {
|
---|
| 84 | RGBQUAD *rgb;
|
---|
| 85 | RGB2 *os2rgb;
|
---|
[6503] | 86 | int bwsize, i, colorsize, rgbsize, iconsize, orgbwsize, orgcolorsize;
|
---|
[6487] | 87 | BITMAPFILEHEADER2 *iconhdr;
|
---|
| 88 | BITMAPFILEHEADER2 *iconhdr2;
|
---|
| 89 | char *pAnd, *pXor;
|
---|
| 90 |
|
---|
[6503] | 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 | }
|
---|
[6487] | 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) +
|
---|
[6490] | 124 | rgbsize + 2*bwsize + colorsize;
|
---|
[6487] | 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);
|
---|
[6503] | 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 | }
|
---|
[6487] | 143 | iconhdr->bmp2.cPlanes = 1;
|
---|
| 144 | iconhdr->bmp2.cBitCount= 1;
|
---|
[6490] | 145 | iconhdr->bmp2.cbImage = 2*bwsize;
|
---|
| 146 | iconhdr->bmp2.cclrUsed = 2;
|
---|
| 147 | iconhdr->bmp2.cclrImportant = 2;
|
---|
[6487] | 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);
|
---|
[6503] | 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 | }
|
---|
[6487] | 169 | iconhdr2->bmp2.cPlanes = bmpHdr->biPlanes;
|
---|
| 170 | iconhdr2->bmp2.cBitCount= bmpHdr->biBitCount;
|
---|
[6490] | 171 | iconhdr2->bmp2.cbImage = colorsize;
|
---|
| 172 | iconhdr2->bmp2.cclrUsed = bmpHdr->biClrUsed;
|
---|
| 173 | iconhdr2->bmp2.cclrImportant = bmpHdr->biClrImportant;
|
---|
[6487] | 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 |
|
---|
[6503] | 188 | if(fResizeTo40x40)
|
---|
| 189 | {
|
---|
| 190 | BYTE *src, *dest;
|
---|
| 191 | int linesizesrc, linesizedest;
|
---|
[6487] | 192 |
|
---|
[6503] | 193 | pXor = (char *)os2rgb;
|
---|
| 194 | pAnd = (char *)os2rgb + bwsize;
|
---|
[6487] | 195 |
|
---|
[6503] | 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;
|
---|
[6487] | 200 |
|
---|
[7733] | 201 | //TODO:
|
---|
| 202 | dprintf(("TODO: icon conversion not correct"));
|
---|
[6503] | 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 | }
|
---|
[6487] | 244 | }
|
---|
[6503] | 245 | else {
|
---|
| 246 | pXor = (char *)os2rgb;
|
---|
| 247 | pAnd = (char *)os2rgb + bwsize;
|
---|
[6487] | 248 |
|
---|
[6503] | 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 | }
|
---|
[6487] | 272 | *os2size = iconsize;
|
---|
| 273 | return (void *)iconhdr;
|
---|
| 274 | }
|
---|
[21916] | 275 |
|
---|
| 276 | extern "C" {
|
---|
| 277 |
|
---|
[6487] | 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;
|
---|
[6503] | 289 | int nricons = 0;
|
---|
[6487] | 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));
|
---|
[7733] | 305 | //add centered icon if size is 32x32
|
---|
| 306 | if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4)
|
---|
| 307 | {
|
---|
[6503] | 308 | groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)),
|
---|
| 309 | SizeofResource(hInstance, hRes), TRUE);
|
---|
[7733] | 310 | //extra pixels
|
---|
| 311 | groupsize += (40*8 + 8*32)*rdir->wBitCount/8;
|
---|
[6503] | 312 | nricons++;
|
---|
| 313 | }
|
---|
| 314 | nricons++;
|
---|
[6487] | 315 | rdir++;
|
---|
| 316 | }
|
---|
[6503] | 317 | groupsize = groupsize+nricons*(sizeof(BITMAPARRAYFILEHEADER2) - sizeof(BITMAPFILEHEADER2));
|
---|
[6487] | 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 |
|
---|
[6503] | 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 |
|
---|
[6487] | 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 | //******************************************************************************
|
---|
[9851] | 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 | //******************************************************************************
|
---|
[21916] | 472 |
|
---|
| 473 | } // extern "C"
|
---|