00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #define INCL_GPIBITMAPS
00013 #define INCL_BITMAPFILEFORMAT
00014 #define INCL_DOSFILEMGR
00015 #define INCL_DOSERRORS
00016 #define INCL_DOSPROCESS
00017 #define INCL_DOSMISC
00018 #define INCL_WIN
00019 #include <os2wrap.h>
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <stdlib.h>
00023 #include <iostream.h>
00024 #include <string.h>
00025
00026 #include <win32api.h>
00027 #include <win32type.h>
00028 #include "dib.h"
00029 #include <winicon.h>
00030 #include <misc.h>
00031
00032 #define DBG_LOCALLOG DBG_icon
00033 #include "dbglocal.h"
00034
00035 #define DIB_RGB_COLORS_W 0
00036 #define DIB_PAL_COLORS_W 1
00037 #define CBM_INIT_W 4
00038
00039
00040
00041
00042 ULONG QueryConvertedIconSize(WINBITMAPINFOHEADER *bmpHdr, int size, BOOL fResizeTo40x40 = FALSE)
00043 {
00044 int bwsize, colorsize, rgbsize, iconsize;
00045
00046 if(fResizeTo40x40) {
00047 bwsize = DIB_GetDIBImageBytes(40, 40, 1);
00048 colorsize = DIB_GetDIBImageBytes(40, 40, bmpHdr->biBitCount);
00049 }
00050 else {
00051 bwsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1);
00052 colorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount);
00053 }
00054
00055 if(bmpHdr->biBitCount <= 8)
00056 rgbsize = (1<<bmpHdr->biBitCount)*sizeof(RGB2);
00057 else rgbsize = 0;
00058
00059 if(bmpHdr->biSizeImage == 0 && bmpHdr->biCompression == 0) {
00060 bmpHdr->biSizeImage = bwsize + colorsize;
00061 }
00062
00063
00064 if(bmpHdr->biSizeImage < colorsize) {
00065 bmpHdr->biSizeImage = colorsize;
00066 }
00067
00068
00069
00070 iconsize = 2*sizeof(BITMAPFILEHEADER2) + 2*sizeof(RGB2) +
00071 rgbsize + 2*bwsize + colorsize;
00072
00073 return iconsize;
00074 }
00075
00076
00077
00078
00079 void *ConvertIcon(WINBITMAPINFOHEADER *bmpHdr, int size, int *os2size, int offsetBits,
00080 BOOL fResizeTo40x40 = FALSE)
00081 {
00082 RGBQUAD *rgb;
00083 RGB2 *os2rgb;
00084 int bwsize, i, colorsize, rgbsize, iconsize, orgbwsize, orgcolorsize;
00085 BITMAPFILEHEADER2 *iconhdr;
00086 BITMAPFILEHEADER2 *iconhdr2;
00087 char *pAnd, *pXor;
00088
00089 if(fResizeTo40x40) {
00090 orgbwsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1);
00091 orgcolorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount);
00092 bwsize = DIB_GetDIBImageBytes(40, 40, 1);
00093 colorsize = DIB_GetDIBImageBytes(40, 40, bmpHdr->biBitCount);
00094 }
00095 else {
00096 bwsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1);
00097 colorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount);
00098 }
00099
00100 if(bmpHdr->biBitCount <= 8)
00101 rgbsize = (1<<bmpHdr->biBitCount)*sizeof(RGB2);
00102 else rgbsize = 0;
00103
00104 if(bmpHdr->biSizeImage == 0 && bmpHdr->biCompression == 0) {
00105 bmpHdr->biSizeImage = bwsize + colorsize;
00106 }
00107 dprintf(("Icon size : %d", bmpHdr->biSizeImage));
00108 dprintf(("Icon Width : %d", bmpHdr->biWidth));
00109
00110 dprintf(("Height : %d", bmpHdr->biHeight));
00111 dprintf(("Icon Bitcount: %d", bmpHdr->biBitCount));
00112 dprintf(("Icon Compress: %d", bmpHdr->biCompression));
00113
00114
00115 if(bmpHdr->biSizeImage < colorsize) {
00116 bmpHdr->biSizeImage = colorsize;
00117 }
00118
00119
00120
00121 iconsize = 2*sizeof(BITMAPFILEHEADER2) + 2*sizeof(RGB2) +
00122 rgbsize + 2*bwsize + colorsize;
00123
00124 iconhdr = (BITMAPFILEHEADER2 *)malloc(iconsize);
00125 memset(iconhdr, 0, iconsize);
00126 iconhdr->usType = BFT_COLORICON;
00127 iconhdr->cbSize = sizeof(BITMAPFILEHEADER2);
00128 iconhdr->xHotspot = 0;
00129 iconhdr->yHotspot = 0;
00130 iconhdr->offBits = 2*sizeof(BITMAPFILEHEADER2) +
00131 2*sizeof(RGB2) + rgbsize + offsetBits;
00132 iconhdr->bmp2.cbFix = sizeof(BITMAPINFOHEADER2);
00133 if(fResizeTo40x40) {
00134 iconhdr->bmp2.cx = (USHORT)40;
00135 iconhdr->bmp2.cy = (USHORT)80;
00136 }
00137 else {
00138 iconhdr->bmp2.cx = (USHORT)bmpHdr->biWidth;
00139 iconhdr->bmp2.cy = (USHORT)bmpHdr->biHeight;
00140 }
00141 iconhdr->bmp2.cPlanes = 1;
00142 iconhdr->bmp2.cBitCount= 1;
00143 iconhdr->bmp2.cbImage = 2*bwsize;
00144 iconhdr->bmp2.cclrUsed = 2;
00145 iconhdr->bmp2.cclrImportant = 2;
00146 iconhdr->bmp2.ulCompression = BCA_UNCOMP;
00147 iconhdr->bmp2.ulColorEncoding = BCE_RGB;
00148 os2rgb = (RGB2 *)(iconhdr+1);
00149 memset(os2rgb, 0, sizeof(RGB2));
00150 memset(os2rgb+1, 0xff, sizeof(RGB));
00151 iconhdr2 = (BITMAPFILEHEADER2 *)(os2rgb+2);
00152 iconhdr2->usType = BFT_COLORICON;
00153 iconhdr2->cbSize = sizeof(BITMAPFILEHEADER2);
00154 iconhdr2->xHotspot = 0;
00155 iconhdr2->yHotspot = 0;
00156 iconhdr2->offBits = 2*sizeof(BITMAPFILEHEADER2) +
00157 2*sizeof(RGB2) + rgbsize + 2*bwsize + offsetBits;
00158 iconhdr2->bmp2.cbFix = sizeof(BITMAPINFOHEADER2);
00159 if(fResizeTo40x40) {
00160 iconhdr2->bmp2.cx = (USHORT)40;
00161 iconhdr2->bmp2.cy = (USHORT)40;
00162 }
00163 else {
00164 iconhdr2->bmp2.cx = (USHORT)bmpHdr->biWidth;
00165 iconhdr2->bmp2.cy = (USHORT)(bmpHdr->biHeight/2);
00166 }
00167 iconhdr2->bmp2.cPlanes = bmpHdr->biPlanes;
00168 iconhdr2->bmp2.cBitCount= bmpHdr->biBitCount;
00169 iconhdr2->bmp2.cbImage = colorsize;
00170 iconhdr2->bmp2.cclrUsed = bmpHdr->biClrUsed;
00171 iconhdr2->bmp2.cclrImportant = bmpHdr->biClrImportant;
00172 iconhdr2->bmp2.ulCompression = BCA_UNCOMP;
00173 iconhdr2->bmp2.ulColorEncoding = BCE_RGB;
00174 os2rgb = (RGB2 *)(iconhdr2+1);
00175 rgb = (RGBQUAD *)(bmpHdr+1);
00176 if(bmpHdr->biBitCount <= 8) {
00177 for(i=0;i<(1<<bmpHdr->biBitCount);i++) {
00178 os2rgb->bRed = rgb->red;
00179 os2rgb->bBlue = rgb->blue;
00180 os2rgb->bGreen = rgb->green;
00181 os2rgb++;
00182 rgb++;
00183 }
00184 }
00185
00186 if(fResizeTo40x40)
00187 {
00188 BYTE *src, *dest;
00189 int linesizesrc, linesizedest;
00190
00191 pXor = (char *)os2rgb;
00192 pAnd = (char *)os2rgb + bwsize;
00193
00194 if ((size - (bmpHdr->biSize + rgbsize + orgcolorsize + orgbwsize)) == orgbwsize)
00195 {
00196 char *q;
00197 int i, linesize;
00198
00199
00200 dprintf(("TODO: icon conversion not correct"));
00201 linesize = DIB_GetDIBWidthBytes(bmpHdr->biWidth, 1);
00202 q = (char *)rgb + orgcolorsize;
00203 for (i = 0; i < bmpHdr->biHeight/2; i++) {
00204 memcpy (pAnd, q, linesize);
00205 pAnd += linesize;
00206 q += linesize;
00207
00208 memcpy (pXor, q, linesize);
00209 pXor += linesize;
00210 q += linesize;
00211 }
00212 }
00213 else {
00214 linesizesrc = DIB_GetDIBWidthBytes(bmpHdr->biWidth, 1);
00215 linesizedest = DIB_GetDIBWidthBytes(40, 1);
00216
00217 src = (BYTE *)rgb + orgcolorsize;
00218 dest = (BYTE *)pAnd + 4*linesizedest;
00219 memset((char *)pAnd, 0xFF, bwsize);
00220 for (i = 0; i < bmpHdr->biHeight/2; i++) {
00221 for(int j=0;j<linesizesrc;j++) {
00222
00223 dest[j] = (dest[j] & 0xF0) | ((src[j] >> 4));
00224 dest[j+1] = (dest[j+1] & 0x0F) | ((src[j] & 0xF) << 4);
00225 }
00226 dest += linesizedest;
00227 src += linesizesrc;
00228 }
00229 memset (pXor, 0, bwsize);
00230 }
00231 linesizesrc = DIB_GetDIBWidthBytes(32, bmpHdr->biBitCount);
00232 linesizedest = DIB_GetDIBWidthBytes(40, bmpHdr->biBitCount);
00233 int skipsize = (4*bmpHdr->biBitCount)/8;
00234 src = (BYTE *)rgb;
00235 dest = (BYTE *)os2rgb+2*bwsize + 4*linesizedest;
00236
00237 for (i = 0; i < 32; i++) {
00238 memcpy(dest+skipsize, src, linesizesrc);
00239 dest += linesizedest;
00240 src += linesizesrc;
00241 }
00242 }
00243 else {
00244 pXor = (char *)os2rgb;
00245 pAnd = (char *)os2rgb + bwsize;
00246
00247 if ((size - (bmpHdr->biSize + rgbsize + colorsize + bwsize)) == bwsize)
00248 {
00249 char *q;
00250 int i, linesize;
00251
00252 linesize = DIB_GetDIBWidthBytes(bmpHdr->biWidth, 1);
00253 q = (char *)rgb + orgcolorsize;
00254 for (i = 0; i < bmpHdr->biHeight/2; i++) {
00255 memcpy (pAnd, q, linesize);
00256 pAnd += linesize;
00257 q += linesize;
00258
00259 memcpy (pXor, q, linesize);
00260 pXor += linesize;
00261 q += linesize;
00262 }
00263 }
00264 else {
00265 memcpy (pAnd, (char *)rgb + colorsize, bwsize);
00266 memset (pXor, 0, bwsize);
00267 }
00268 memcpy((char *)os2rgb+2*bwsize, (char *)rgb, colorsize);
00269 }
00270 *os2size = iconsize;
00271 return (void *)iconhdr;
00272 }
00273
00274
00275 void * WIN32API ConvertIconGroup(void *hdr, HINSTANCE hInstance, DWORD *ressize)
00276 {
00277 IconHeader *ihdr = (IconHeader *)hdr;
00278 ResourceDirectory *rdir = (ResourceDirectory *)(ihdr + 1);
00279 int i, groupsize = 0, os2iconsize;
00280 BITMAPARRAYFILEHEADER2 *bafh, *orgbafh;
00281 WINBITMAPINFOHEADER *iconhdr;
00282 void *os2icon;
00283 HRSRC hRes;
00284 int nricons = 0;
00285
00286 dprintf(("Icon Group type :%d", ihdr->wType));
00287 dprintf(("Icon Group count:%d", ihdr->wCount));
00288 for(i=0;i<ihdr->wCount;i++) {
00289 dprintf2(("Icon : %d", rdir->wNameOrdinal));
00290 dprintf2(("Width : %d", (int)rdir->bWidth));
00291 dprintf2(("Height : %d", (int)rdir->bHeight));
00292 dprintf2(("Colors : %d", (int)rdir->bColorCount));
00293 dprintf2(("Bits : %d", rdir->wBitCount));
00294 dprintf2(("ResBytes: %d", rdir->lBytesInRes));
00295 hRes = FindResourceA(hInstance,
00296 (LPCSTR)rdir->wNameOrdinal, (LPSTR)NTRT_ICON);
00297
00298 groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)),
00299 SizeofResource(hInstance, hRes));
00300
00301 if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4)
00302 {
00303 groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)),
00304 SizeofResource(hInstance, hRes), TRUE);
00305
00306 groupsize += (40*8 + 8*32)*rdir->wBitCount/8;
00307 nricons++;
00308 }
00309 nricons++;
00310 rdir++;
00311 }
00312 groupsize = groupsize+nricons*(sizeof(BITMAPARRAYFILEHEADER2) - sizeof(BITMAPFILEHEADER2));
00313 bafh = (BITMAPARRAYFILEHEADER2 *)malloc(groupsize);
00314 memset(bafh, 0, groupsize);
00315 orgbafh = bafh;
00316
00317 rdir = (ResourceDirectory *)(ihdr + 1);
00318 for(i=0;i<ihdr->wCount;i++) {
00319 bafh->usType = BFT_BITMAPARRAY;
00320 bafh->cbSize = sizeof(BITMAPARRAYFILEHEADER2);
00321 bafh->cxDisplay = 0;
00322 bafh->cyDisplay = 0;
00323 hRes = FindResourceA(hInstance,
00324 (LPCSTR)rdir->wNameOrdinal, (LPSTR)NTRT_ICON);
00325 if(hRes == NULL) {
00326 dprintf(("Can't find icon!"));
00327 rdir++;
00328 continue;
00329 }
00330 iconhdr = (WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes));
00331 os2icon = ConvertIcon(iconhdr, SizeofResource(hInstance, hRes), &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2));
00332 if(os2icon == NULL) {
00333 dprintf(("Can't convert icon!"));
00334 rdir++;
00335 continue;
00336 }
00337
00338 if(rdir->bWidth == 32 && rdir->bHeight == 32 && rdir->wBitCount >= 4)
00339 {
00340
00341
00342 bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize;
00343 memcpy((char *)&bafh->bfh2, os2icon, os2iconsize);
00344 free(os2icon);
00345
00346 bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize);
00347
00348 os2icon = ConvertIcon(iconhdr, SizeofResource(hInstance, hRes), &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2), TRUE);
00349 if(os2icon == NULL) {
00350 dprintf(("Can't convert icon!"));
00351 rdir++;
00352 continue;
00353 }
00354 }
00355
00356 if(i != ihdr->wCount -1) {
00357 bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize;
00358 }
00359 else bafh->offNext = 0;
00360
00361 memcpy((char *)&bafh->bfh2, os2icon, os2iconsize);
00362 free(os2icon);
00363
00364 bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize);
00365
00366 rdir++;
00367 }
00368 *ressize = groupsize;
00369 return (void *)orgbafh;
00370 }
00371
00372