source: trunk/src/user32/icon.cpp@ 6490

Last change on this file since 6490 was 6490, checked in by sandervl, 24 years ago

minor icon conversion fixes

File size: 9.3 KB
Line 
1/* $Id: icon.cpp,v 1.12 2001-08-08 12:06:29 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 <iostream.h>
24#include <string.h>
25
26#include <win32api.h>
27#include <win32type.h>
28#include "dib.h"
29#include <winicon.h>
30#include <misc.h>
31
32#define DBG_LOCALLOG DBG_icon
33#include "dbglocal.h"
34
35#define DIB_RGB_COLORS_W 0
36#define DIB_PAL_COLORS_W 1
37#define CBM_INIT_W 4
38
39
40//******************************************************************************
41//******************************************************************************
42ULONG QueryConvertedIconSize(WINBITMAPINFOHEADER *bmpHdr, int size)
43{
44 int bwsize, colorsize, rgbsize, iconsize;
45
46 bwsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1);
47 colorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount);
48
49 if(bmpHdr->biBitCount <= 8)
50 rgbsize = (1<<bmpHdr->biBitCount)*sizeof(RGB2);
51 else rgbsize = 0;
52
53 if(bmpHdr->biSizeImage == 0 && bmpHdr->biCompression == 0) {
54 bmpHdr->biSizeImage = bwsize + colorsize;
55 }
56
57 //SvL: 28-09-'98: cllngenu.dll has an incorrect size in the header
58 if(bmpHdr->biSizeImage < colorsize) {
59 bmpHdr->biSizeImage = colorsize;
60 }
61 //bitmapfileheader for AndXor mask + 2 RGB structs + bitmapfileheader
62 //for color bitmap + RGB structs for all the colors
63 //SvL, 3-3-98: 2*bwsize
64 iconsize = 2*sizeof(BITMAPFILEHEADER2) + 2*sizeof(RGB2) +
65 rgbsize + 2*bwsize + colorsize;
66
67 return iconsize;
68}
69//******************************************************************************
70//NOTE: offsetBits is the value added to the offBits bitmap structure members
71// (handy for converting icon groups)
72//******************************************************************************
73void *ConvertIcon(WINBITMAPINFOHEADER *bmpHdr, int size, int *os2size, int offsetBits)
74{
75 RGBQUAD *rgb;
76 RGB2 *os2rgb;
77 int bwsize, i, colorsize, rgbsize, iconsize;
78 BITMAPFILEHEADER2 *iconhdr;
79 BITMAPFILEHEADER2 *iconhdr2;
80 char *pAnd, *pXor;
81
82 bwsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), 1);
83 colorsize = DIB_GetDIBImageBytes(bmpHdr->biWidth, (bmpHdr->biHeight/2), bmpHdr->biBitCount);
84 //SvL: 28-09-'98: only for <= 8
85 if(bmpHdr->biBitCount <= 8)
86 rgbsize = (1<<bmpHdr->biBitCount)*sizeof(RGB2);
87 else rgbsize = 0;
88
89 if(bmpHdr->biSizeImage == 0 && bmpHdr->biCompression == 0) {
90 bmpHdr->biSizeImage = bwsize + colorsize;
91 }
92 dprintf(("Icon size : %d", bmpHdr->biSizeImage));
93 dprintf(("Icon Width : %d", bmpHdr->biWidth));
94 //height for both the XOR and AND bitmap (color & BW)
95 dprintf(("Height : %d", bmpHdr->biHeight));
96 dprintf(("Icon Bitcount: %d", bmpHdr->biBitCount));
97 dprintf(("Icon Compress: %d", bmpHdr->biCompression));
98
99 //SvL: 28-09-'98: cllngenu.dll has an incorrect size in the header
100 if(bmpHdr->biSizeImage < colorsize) {
101 bmpHdr->biSizeImage = colorsize;
102 }
103 //bitmapfileheader for AndXor mask + 2 RGB structs + bitmapfileheader
104 //for color bitmap + RGB structs for all the colors
105 //SvL, 3-3-98: 2*bwsize
106 iconsize = 2*sizeof(BITMAPFILEHEADER2) + 2*sizeof(RGB2) +
107 rgbsize + 2*bwsize + colorsize;
108
109 iconhdr = (BITMAPFILEHEADER2 *)malloc(iconsize);
110 memset(iconhdr, 0, iconsize);
111 iconhdr->usType = BFT_COLORICON;
112 iconhdr->cbSize = sizeof(BITMAPFILEHEADER2);
113 iconhdr->xHotspot = 0;
114 iconhdr->yHotspot = 0;
115 iconhdr->offBits = 2*sizeof(BITMAPFILEHEADER2) +
116 2*sizeof(RGB2) + rgbsize + offsetBits;
117 iconhdr->bmp2.cbFix = sizeof(BITMAPINFOHEADER2);
118 iconhdr->bmp2.cx = (USHORT)bmpHdr->biWidth;
119 iconhdr->bmp2.cy = (USHORT)bmpHdr->biHeight;
120 iconhdr->bmp2.cPlanes = 1;
121 iconhdr->bmp2.cBitCount= 1;
122 iconhdr->bmp2.cbImage = 2*bwsize;
123 iconhdr->bmp2.cclrUsed = 2;
124 iconhdr->bmp2.cclrImportant = 2;
125 iconhdr->bmp2.ulCompression = BCA_UNCOMP;
126 iconhdr->bmp2.ulColorEncoding = BCE_RGB;
127 os2rgb = (RGB2 *)(iconhdr+1);
128 memset(os2rgb, 0, sizeof(RGB2));
129 memset(os2rgb+1, 0xff, sizeof(RGB)); //not reserved byte!
130 iconhdr2 = (BITMAPFILEHEADER2 *)(os2rgb+2);
131 iconhdr2->usType = BFT_COLORICON;
132 iconhdr2->cbSize = sizeof(BITMAPFILEHEADER2);
133 iconhdr2->xHotspot = 0;
134 iconhdr2->yHotspot = 0;
135 iconhdr2->offBits = 2*sizeof(BITMAPFILEHEADER2) +
136 2*sizeof(RGB2) + rgbsize + 2*bwsize + offsetBits;
137 iconhdr2->bmp2.cbFix = sizeof(BITMAPINFOHEADER2);
138 iconhdr2->bmp2.cx = (USHORT)bmpHdr->biWidth;
139 iconhdr2->bmp2.cy = (USHORT)(bmpHdr->biHeight/2);
140 iconhdr2->bmp2.cPlanes = bmpHdr->biPlanes;
141 iconhdr2->bmp2.cBitCount= bmpHdr->biBitCount;
142 iconhdr2->bmp2.cbImage = colorsize;
143 iconhdr2->bmp2.cclrUsed = bmpHdr->biClrUsed;
144 iconhdr2->bmp2.cclrImportant = bmpHdr->biClrImportant;
145 iconhdr2->bmp2.ulCompression = BCA_UNCOMP;
146 iconhdr2->bmp2.ulColorEncoding = BCE_RGB;
147 os2rgb = (RGB2 *)(iconhdr2+1);
148 rgb = (RGBQUAD *)(bmpHdr+1);
149 if(bmpHdr->biBitCount <= 8) {
150 for(i=0;i<(1<<bmpHdr->biBitCount);i++) {
151 os2rgb->bRed = rgb->red;
152 os2rgb->bBlue = rgb->blue;
153 os2rgb->bGreen = rgb->green;
154 os2rgb++;
155 rgb++;
156 }
157 }
158
159 pXor = (char *)os2rgb;
160 pAnd = (char *)os2rgb + bwsize;
161
162 if ((size - (bmpHdr->biSize + rgbsize + colorsize + bwsize)) == bwsize)
163 {//this means an AND and XOR mask is present (interleaved; and/xor)
164 char *q;
165 int i, linesize;
166
167 linesize = bmpHdr->biWidth / 8;
168 q = (char *)rgb + colorsize;
169 for (i = 0; i < (bmpHdr->biHeight/2); i++) {
170 memcpy (pAnd, q, linesize);
171 pAnd += linesize;
172 q += linesize;
173
174 memcpy (pXor, q, linesize);
175 pXor += linesize;
176 q += linesize;
177 }
178 } else {
179 memcpy (pAnd, (char *)rgb + colorsize, bwsize);
180 memset (pXor, 0, bwsize);
181 }
182 memcpy((char *)os2rgb+2*bwsize, (char *)rgb, colorsize);
183
184 *os2size = iconsize;
185 return (void *)iconhdr;
186}
187//******************************************************************************
188//******************************************************************************
189void * WIN32API ConvertIconGroup(void *hdr, HINSTANCE hInstance, DWORD *ressize)
190{
191 IconHeader *ihdr = (IconHeader *)hdr;
192 ResourceDirectory *rdir = (ResourceDirectory *)(ihdr + 1);
193 int i, groupsize = 0, os2iconsize;
194 BITMAPARRAYFILEHEADER2 *bafh, *orgbafh;
195 WINBITMAPINFOHEADER *iconhdr;
196 void *os2icon;
197 HRSRC hRes;
198
199 dprintf(("Icon Group type :%d", ihdr->wType));
200 dprintf(("Icon Group count:%d", ihdr->wCount));
201 for(i=0;i<ihdr->wCount;i++) {
202 dprintf2(("Icon : %d", rdir->wNameOrdinal));
203 dprintf2(("Width : %d", (int)rdir->bWidth));
204 dprintf2(("Height : %d", (int)rdir->bHeight));
205 dprintf2(("Colors : %d", (int)rdir->bColorCount));
206 dprintf2(("Bits : %d", rdir->wBitCount));
207 dprintf2(("ResBytes: %d", rdir->lBytesInRes));
208 hRes = FindResourceA(hInstance,
209 (LPCSTR)rdir->wNameOrdinal, (LPSTR)NTRT_ICON);
210
211 groupsize += QueryConvertedIconSize((WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes)),
212 SizeofResource(hInstance, hRes));
213 rdir++;
214 }
215 groupsize = groupsize+ihdr->wCount*(sizeof(BITMAPARRAYFILEHEADER2) - sizeof(BITMAPFILEHEADER2));
216 bafh = (BITMAPARRAYFILEHEADER2 *)malloc(groupsize);
217 memset(bafh, 0, groupsize);
218 orgbafh = bafh;
219
220 rdir = (ResourceDirectory *)(ihdr + 1);
221 for(i=0;i<ihdr->wCount;i++) {
222 bafh->usType = BFT_BITMAPARRAY;
223 bafh->cbSize = sizeof(BITMAPARRAYFILEHEADER2);
224 bafh->cxDisplay = 0;
225 bafh->cyDisplay = 0;
226 hRes = FindResourceA(hInstance,
227 (LPCSTR)rdir->wNameOrdinal, (LPSTR)NTRT_ICON);
228 if(hRes == NULL) {
229 dprintf(("Can't find icon!"));
230 rdir++;
231 continue;
232 }
233 iconhdr = (WINBITMAPINFOHEADER *)LockResource(LoadResource(hInstance, hRes));
234 os2icon = ConvertIcon(iconhdr, SizeofResource(hInstance, hRes), &os2iconsize, (ULONG)bafh - (ULONG)orgbafh + sizeof(BITMAPARRAYFILEHEADER2)-sizeof(BITMAPFILEHEADER2));
235 if(os2icon == NULL) {
236 dprintf(("Can't convert icon!"));
237 rdir++;
238 continue;
239 }
240
241 if(i != ihdr->wCount -1) {
242 bafh->offNext = (ULONG)&bafh->bfh2 - (ULONG)orgbafh + os2iconsize;
243 }
244 else bafh->offNext = 0;
245
246 memcpy((char *)&bafh->bfh2, os2icon, os2iconsize);
247 free(os2icon);
248
249 bafh = (BITMAPARRAYFILEHEADER2 *)((ULONG)&bafh->bfh2 + os2iconsize);
250
251 rdir++;
252 }
253 *ressize = groupsize;
254 return (void *)orgbafh;
255}
256//******************************************************************************
257//******************************************************************************
Note: See TracBrowser for help on using the repository browser.