source: trunk/src/win32k/pe2lx/bitmap.cpp@ 847

Last change on this file since 847 was 847, checked in by bird, 26 years ago

Initial checkin of Win32k. (not tested & pe2lx not up-to-date!)

File size: 24.2 KB
Line 
1/* $Id: bitmap.cpp,v 1.1 1999-09-06 02:20:03 bird Exp $ */
2
3/*
4 * PE2LX bitmap conversion code
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Knut St. Osmundsen
8 *
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14/*******************************************************************************
15* Header Files *
16*******************************************************************************/
17#include <pe2lx.h>
18#include "icon.h"
19#include "bitmap.h"
20
21
22
23/*
24 * HISTORY
25 * * * * * *
26 * KSO - Aug 3 1998 6:30pm:
27 * -Fixed some bugs.
28 * -Standalone bitmap converter.
29 * -Need a 16 and/or 32bit bitmaps to test these and to implement bitfields
30 *
31 * KSO - Aug 1 1998 6:22pm:
32 * -Rewrote everything.
33 * -New bitmaps from nt/win9x are not supported but detected. Need docs!!!
34 * -2 COLOR (not BW) bitmaps are now converted to 16 color bitmaps.
35 * Converting of OS/2 v1.x bitmaps (2 color -> 16 color) are not tested
36 * -All Resources should have 3 operation: Show<rsrc>, Convert<rsrc> and QuerySize<rsrc>
37 */
38
39
40/* COMPILETIME CONVERSION OPTIONS */
41//#define NO_1BIT_TO_4BIT_CONVERSION
42//#define DUMP_BMPS_TO_FILES
43
44#ifdef DUMP_BMPS_TO_FILES
45 #include <stdio.h>
46#endif
47
48static ULONG Convert1BitTo4Bit(void *pNewData, PBYTE pbOldData, LONG cx, LONG cy);
49static ULONG QueryPaletteSize(WINBITMAPINFOHEADER *pBHdr);
50static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr);
51static ULONG QueryPaletteSize(BITMAPINFOHEADER2 *pBHdr);
52static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy);
53
54
55
56/**********/
57/* Macros */
58/**********/
59#define Need1BitTo4BitConvertWIN(pBHdr) \
60 ( \
61 pBHdr->biBitCount == 1 \
62 && !( \
63 (((PULONG)pBHdr)[10] == 0x00000000 && (pBHdr->biClrUsed == 1 || ((PULONG)pBHdr)[11] == 0x00ffffff)) /*black and white*/ \
64 || (((PULONG)pBHdr)[10] == 0x00ffffff && (pBHdr->biClrUsed == 1 || ((PULONG)pBHdr)[11] == 0x00000000)) /*white and black*/ \
65 ) \
66 )
67
68#define Need1BitTo4BitConvertOS2(pBIH) \
69 ( \
70 pBIH->cBitCount == 1 \
71 && !( \
72 (((PULONG)pBIH)[3] == 0x0ff00000 && ((PUSHORT)pBIH)[8] == 0xffff) /*black and white*/ \
73 || (((PULONG)pBIH)[3] == 0x00ffffff && ((PUSHORT)pBIH)[8] == 0x0000) /*white and black*/ \
74 ) \
75 )
76
77
78
79/*************/
80/* Functions */
81/*************/
82#ifndef BITMAPCONVERTER
83
84BOOL ShowBitmap(LXHeaderSuper &OS2Exe, int id, WINBITMAPINFOHEADER *bhdr, int size)
85{
86#if 1
87 void *pConvertedBitmap;
88 ULONG ulSize;
89 BOOL rc;
90
91 pConvertedBitmap = ConvertBitmap(bhdr, size, (PULONG)SSToDS(&ulSize));
92 if (pConvertedBitmap != NULL)
93 {
94 rc = OS2Exe.StoreResource(id, RT_BITMAP, ulSize, (char *)pConvertedBitmap);
95
96 #ifdef DUMP_BMPS_TO_FILES
97 /* debug option to dump bitmaps to file(s). */
98 char szFilename[CCHMAXPATH];
99 sprintf(SSToDS(szFilename), "%d.bmp", id);
100 FILE *pFile = fopen(szFilename, "wb");
101 if (pFile != NULL)
102 {
103 fwrite(pConvertedBitmap, 1, ulSize, pFile);
104 fclose(pFile);
105 }
106 else
107 cout << "warning: could not open " << szFilename << endl;
108
109 sprintf(SSToDS(szFilename), "w%d.bmp", id);
110 pFile = fopen(szFilename, "wb");
111 if (pFile != NULL)
112 {
113 PBITMAPFILEHEADER pBFHConv = (PBITMAPFILEHEADER)pConvertedBitmap;
114 BITMAPFILEHEADER BFHWin;
115 memcpy( (void*)&BFHWin, (void*)pConvertedBitmap, sizeof(BFHWin));
116 BFHWin.cbSize -= pBFHConv->bmp.cbFix - bhdr->biSize;
117 BFHWin.offBits -= pBFHConv->bmp.cbFix - bhdr->biSize;
118
119 fwrite(&BFHWin, 1, 14, pFile);
120 fwrite(bhdr, 1, size, pFile);
121 fclose(pFile);
122 }
123 else
124 cout << "warning: could not open " << szFilename << endl;
125
126 #endif //DUMP_BMPS_TO_FILES
127 free(pConvertedBitmap);
128 }
129 else
130 rc = FALSE;
131
132 return rc;
133#else
134 return OS2Exe.StoreResource(id, RT_BITMAP, size, (char*) bhdr);
135#endif
136}
137
138#endif //#ifndef BITMAPCONVERTER
139
140
141void *ConvertBitmap(WINBITMAPINFOHEADER *pBHdr, ULONG ulSize, PULONG pulSize)
142{
143 ltassert((ULONG)pBHdr > MINPTR && (ULONG)pBHdr+ulSize < MAXPTR);
144
145 switch (pBHdr->biSize)
146 {
147 /**************************************/
148 /* Windows v3.0 bitmap */
149 /**************************************/
150 case sizeof(WINBITMAPINFOHEADER):
151 {//convert to OS/2 v2.0 bitmap
152 PBITMAPFILEHEADER2 pBFH;
153 ULONG cbPalette;
154 ULONG cbImage;
155 BOOL fConvert1Bit = FALSE;
156
157 cout << "Windows v3.0 bitmap" << endl;
158 cout << " Size: " << pBHdr->biSizeImage << endl;
159 cout << " Width: " << pBHdr->biWidth << endl;
160 cout << " Height: " << pBHdr->biHeight << endl;
161 cout << " Bitcount: " << pBHdr->biBitCount << endl;
162 cout << " Compress: " << pBHdr->biCompression << endl;
163
164 #ifndef NO_1BIT_TO_4BIT_CONVERSION
165 fConvert1Bit = Need1BitTo4BitConvertWIN(pBHdr);
166 #endif
167
168 cbPalette = QueryPaletteSize(pBHdr);
169 ltassert(cbPalette != -1);
170 cout << " PaletteSize: " << cbPalette << endl;
171
172
173 /* calc bitmap size and allocate */
174 #ifdef BITFIELDS
175 if (pBHdr->biCompression == BI_RGB || pBHdr->biCompression == BI_BITFIELDS)
176 #else
177 if (pBHdr->biCompression == BI_RGB)
178 #endif
179 {
180 /* recalc for non-compressed images */
181 if (fConvert1Bit)
182 cbImage = CalcBitmapSize(4, pBHdr->biWidth, pBHdr->biHeight);
183 else
184 cbImage = CalcBitmapSize(pBHdr->biBitCount, pBHdr->biWidth, pBHdr->biHeight);
185 }
186 else
187 {
188 ltassert(!fConvert1Bit);
189 cbImage = pBHdr->biSizeImage;
190 if (cbImage == 0)
191 cbImage = ulSize - sizeof(WINBITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER2);
192 }
193 ltassert(cbImage != 0);
194
195 //bounds checking
196 if (!fConvert1Bit)
197 { /* brackets must not be removed! */
198 ltassert(cbImage <= ulSize - sizeof(WINBITMAPINFOHEADER) - cbPalette);
199 }
200 else
201 {
202 ltassert(CalcBitmapSize(pBHdr->biBitCount, pBHdr->biWidth, pBHdr->biHeight) <= ulSize - sizeof(WINBITMAPINFOHEADER) - cbPalette);
203 }
204
205 *pulSize = sizeof(BITMAPFILEHEADER2) + cbPalette + cbImage;
206
207 cout << " Debug: Size(recalced): " << cbImage << endl;
208 cout << " Debug: Size in : " << ulSize << endl;
209 cout << " Debug: Size out : " << *pulSize << endl;
210
211 pBFH = (PBITMAPFILEHEADER2)malloc(*pulSize + 0x10);//allocate more than we need!
212 ltassert(pBFH);
213
214
215 /* file header */
216 pBFH->usType = BFT_BMAP;
217 pBFH->cbSize = sizeof(BITMAPFILEHEADER2);
218 pBFH->xHotspot = 0;
219 pBFH->yHotspot = 0;
220 pBFH->offBits = sizeof(BITMAPFILEHEADER2) + cbPalette;
221
222
223 /* info header*/
224 memset((void*)&pBFH->bmp2, 0, sizeof(BITMAPINFOHEADER2));
225 memcpy((void*)&pBFH->bmp2, (void*)pBHdr, sizeof(WINBITMAPINFOHEADER));
226 pBFH->bmp2.cbFix = sizeof(BITMAPINFOHEADER2);
227
228 /* bitfields */
229 if (pBFH->bmp2.ulCompression == BI_BITFIELDS)
230 {//TODO: Identical except for BI_BITFIELDS (3L) type! - cast a warning note
231 /* KSO: I need files to test it on */
232 #ifndef BITFIELDS
233 cout << "Warning: ulCompression = BI_BITFIELDS" << endl;
234 pBFH->bmp2.ulCompression = BCA_UNCOMP; //since BI_BITFIELDS == BCA_RLE24
235 #else
236 #error("Sorry, BITFIELDS are not implmented yet.")
237 /* generate new palette */
238 /* convert bitmap data */
239 /* update fileheader */
240 #endif //#ifdef BITFIELDS
241 #ifdef RING0
242 ltassert(FALSE && "bitfields are fatal\n");
243 #endif
244 }
245
246
247 /* palette */
248 if (cbPalette > 0)
249 memcpy((void*)((ULONG)pBFH + sizeof(BITMAPFILEHEADER2)), (void*)((ULONG)pBHdr + sizeof(WINBITMAPINFOHEADER)), cbPalette);
250
251
252 /* bitmap data */
253 if (fConvert1Bit)
254 {
255 /* convert */
256 Convert1BitTo4Bit(
257 (PVOID)((ULONG)pBFH + sizeof(BITMAPFILEHEADER2) + cbPalette),
258 (PBYTE)((ULONG)pBHdr + sizeof(WINBITMAPINFOHEADER)+ cbPalette),
259 pBFH->bmp2.cx,
260 pBFH->bmp2.cy
261 );
262
263 /* update some infoheader fields */
264 pBFH->bmp2.cBitCount = 4;
265 if (pBFH->bmp2.cclrUsed == 0)
266 pBFH->bmp2.cclrUsed = 2;
267 if (pBFH->bmp2.cbImage != 0)
268 pBFH->bmp2.cbImage = cbImage;
269 }
270 else
271 memcpy((void*)((ULONG)pBFH + sizeof(BITMAPFILEHEADER2) + cbPalette), (void*)((ULONG)pBHdr + sizeof(WINBITMAPINFOHEADER) + cbPalette), cbImage);
272
273 return pBFH;
274 }
275
276
277
278 /**************************************/
279 /* Windows v4.0 bitmap */
280 /**************************************/
281 case sizeof(BITMAPV4HEADER):
282 {//convert to OS/2 v2.0 bitmap - some other day when I find the specs.
283 cout << "Windows v4.0 bitmap" << endl;
284 cout << " Not supported yet!" << endl;
285 ltassert(FALSE && "Windows v4.0 bitmap");
286 }
287 break;
288
289
290 /**************************************/
291 /* OS/2 v1.x bitmap */
292 /**************************************/
293 case sizeof(BITMAPINFOHEADER):
294 {//no conversion needed - only build fileheader
295 PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER)pBHdr;
296 PBITMAPFILEHEADER pBFH ;
297 BOOL fConvert1Bit;
298 ULONG cbPalette;
299
300 cbPalette = QueryPaletteSize(pBIH);
301 ltassert(cbPalette != -1);
302 *pulSize = ulSize + sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER);
303
304 fConvert1Bit = Need1BitTo4BitConvertOS2(pBIH);
305 #ifdef NO_1BIT_TO_4BIT_CONVERSION
306 fConvert1Bit = FALSE;
307 #endif
308
309 if (fConvert1Bit)
310 *pulSize += (ulSize - cbPalette - sizeof(BITMAPINFOHEADER))*3 + 14 * sizeof(RGB);
311
312 pBFH = (PBITMAPFILEHEADER)malloc(*pulSize);
313 ltassert(pBFH != NULL);
314
315 if (fConvert1Bit)
316 {
317 /* copy infoheader */
318 memcpy(&pBFH->bmp, pBIH, sizeof(pBFH->bmp));
319 memset((void*)((ULONG)pBFH + sizeof(*pBFH)), 0, 16*sizeof(RGB));
320 memcpy((void*)((ULONG)pBFH + sizeof(*pBFH)), (void*)((ULONG)pBIH + sizeof(*pBIH)), 2*sizeof(RGB));
321 *pulSize = Convert1BitTo4Bit(
322 (PVOID)((ULONG)pBFH + sizeof(BITMAPFILEHEADER) + 16 * sizeof(RGB)),
323 (PBYTE)((ULONG)pBHdr + sizeof(BITMAPINFOHEADER) + cbPalette),
324 pBFH->bmp.cx,
325 pBFH->bmp.cy
326 );
327
328 /* update infoheader */
329 pBFH->bmp.cBitCount = 4;
330 cbPalette = 16 * sizeof(RGB); //used in fileheader
331 }
332 else
333 {
334 /* copy entire bitmap from infoheader */
335 memcpy(&pBFH->bmp, pBIH, ulSize);
336 *pulSize = CalcBitmapSize(pBIH->cBitCount, pBIH->cx, pBIH->cy);
337 ltassert(*pulSize != 0);
338 }
339 *pulSize += sizeof(BITMAPFILEHEADER) + cbPalette;
340
341 /* fileheader */
342 pBFH->usType = BFT_BMAP;
343 pBFH->cbSize = sizeof(BITMAPFILEHEADER);
344 pBFH->xHotspot = 0;
345 pBFH->yHotspot = 0;
346 pBFH->offBits = sizeof(BITMAPFILEHEADER) + cbPalette;
347
348 /* log info */
349 cout << "OS/2 v1.x bitmap" << endl;
350 cout << " Width: " << pBFH->bmp.cx << endl;
351 cout << " Height: " << pBFH->bmp.cy << endl;
352 cout << " Bitcount: " << pBFH->bmp.cBitCount << endl;
353 cout << " PaletteSize: " << cbPalette << endl;
354 cout << "debug 1" << endl;
355
356 return (void*)pBFH;
357 }
358
359
360
361 /**************************************/
362 /* OS/2 v2.0 bitmap - highly unlikely!*/
363 /**************************************/
364 case sizeof(BITMAPINFOHEADER2):
365 {//no conversion needed - only build fileheader
366 PBITMAPFILEHEADER2 pBFH;
367 pBFH = (PBITMAPFILEHEADER2)malloc(ulSize + sizeof(BITMAPFILEHEADER2) - sizeof(BITMAPINFOHEADER2));
368 ltassert(pBFH != NULL);
369
370 memcpy(&pBFH->bmp2, pBHdr, ulSize);
371
372 pBFH->usType = BFT_BMAP;
373 pBFH->cbSize = sizeof(BITMAPFILEHEADER2);
374 pBFH->xHotspot = 0;
375 pBFH->yHotspot = 0;
376 pBFH->offBits = sizeof(BITMAPFILEHEADER2);
377
378 cout << "OS/2 v2.0 bitmap" << endl;
379 cout << " Width: " << pBFH->bmp2.cx << endl;
380 cout << " Height: " << pBFH->bmp2.cy << endl;
381 cout << " Bitcount: " << pBFH->bmp2.cBitCount << endl;
382
383 if (pBFH->bmp2.cBitCount < 24)
384 pBFH->offBits += ( 1 << pBFH->bmp2.cBitCount ) * sizeof(RGB2);
385 else
386 pBFH->offBits += pBFH->bmp2.cclrUsed;
387
388 return pBFH;
389 }
390
391
392 /**************************************/
393 /* Unknown */
394 /**************************************/
395 default: //fail
396 cout << "ConvertBitmap - default - fail!" << endl;
397 return NULL;
398 }
399
400 return NULL;
401}
402
403
404
405
406/* Converting 1 bit bitmaps to 4 bit bitmaps
407 */
408static ULONG Convert1BitTo4Bit(void *pNewData, PBYTE pbOldData, LONG cx, LONG cy)
409{
410 PBYTE pbNewData = (PBYTE)pNewData;
411
412 cout << " 1->4 convert" << endl;
413
414 //negative height
415 cy = cy < 0 ? -cy : cy;
416
417 *pbNewData = 0;
418 for (int y = 0; y < cy; y++)
419 {//outer loop: lines
420 int x;
421
422 for (x = 0; x < cx; x++)
423 {//inner loop: scanline
424 int iBit = 7-(x%8);
425 *pbNewData |= (((0x1 << iBit) & *pbOldData) >> iBit) << (iBit%2)*4;
426
427 if (x % 2)
428 {
429 pbNewData++;
430 *pbNewData = 0;
431 }
432
433 if ((x+1) % 8 == 0)
434 pbOldData++;
435 }
436
437 //next byte
438 if (x % 2)
439 {
440 pbNewData++;
441 *pbNewData = 0;
442 }
443 if ((x+1) % 8 == 0)
444 pbOldData++;
445
446 //aligning
447 for (int a = ((x+1)/2)%4; a < 4 && a != 0; a++)
448 {
449 pbNewData++;
450 *pbNewData = 0;
451 }
452 for (int b = ((x+7)/8)%4; b < 4 && b != 0; b++)
453 pbOldData++;
454 }
455
456 return (int)pbNewData - (int)pNewData;
457}
458
459
460
461static ULONG QueryPaletteSize(WINBITMAPINFOHEADER *pBHdr)
462{
463 ULONG cbPalette;
464
465 switch (pBHdr->biBitCount)
466 {
467 case 1:
468 case 4:
469 case 8:
470 /* Windows Bitmaps seems to have a full palette even when it don't use all of it - OS/2 does not...
471 Good for us, the fileheader holds the offset to the bitmap data - which means that this not should be a problem, luckily. */
472 //cbPalette = ((pBHdr->biClrUsed != 0) ? pBHdr->biClrUsed : 1 << pBHdr->biBitCount) * sizeof(RGB2);
473 cbPalette = (1 << pBHdr->biBitCount) * sizeof(RGB2);
474 break;
475
476 case 16:
477 case 32:
478 #ifdef BITFIELDS
479 if (pBHdr->biCompression == BI_BITFIELDS)
480 {
481 cbPalette = 3* sizeof(DWORD);
482 break;
483 }
484 #endif
485 case 24:
486 /* docs have it that there may be a palette used for optmizing processing of 16, 24 and 32 bits bitmaps */
487 /* the size of the palette is contained in biClrUsed - don't know if it stored as number of colors or as bytes... */
488 cbPalette = pBHdr->biClrUsed; //size in bytes or in (*sizeof(RGB2))?
489 break;
490
491 default:
492 cout << "QueryPaletteSize: error pBHdr->biBitCount = " << pBHdr->biBitCount << endl;
493 cbPalette = -1;
494 }
495
496 return cbPalette;
497}
498
499
500static ULONG QueryPaletteSize(BITMAPINFOHEADER *pBHdr)
501{
502 ULONG cbPalette;
503
504 switch (pBHdr->cBitCount)
505 {
506 case 1:
507 case 4:
508 case 8:
509 cbPalette = (1 << pBHdr->cBitCount) * sizeof(RGB);
510 break;
511
512 case 16:
513 case 24:
514 case 32:
515 cbPalette = 0;
516 break;
517
518 default:
519 cout << "QueryPaletteSize: error pBHdr->biBitCount = " << pBHdr->cBitCount << endl;
520 cbPalette = -1;
521 }
522
523 return cbPalette;
524}
525
526
527static ULONG QueryPaletteSize(BITMAPINFOHEADER2 *pBHdr)
528{
529 ULONG cbPalette;
530
531 switch (pBHdr->cBitCount)
532 {
533 case 1:
534 case 4:
535 case 8:
536 cbPalette = ((pBHdr->cclrUsed != 0) ? pBHdr->cclrUsed : 1 << pBHdr->cBitCount) * sizeof(RGB2);
537 //cbPalette = (1 << pBHdr->cBitCount) * sizeof(RGB2);
538 break;
539
540 case 16:
541 case 32:
542 case 24:
543 /* docs have it that there may be a palette used for optmizing processing of 16, 24 and 32 bits bitmaps */
544 /* the size of the palette is contained in biClrUsed - don't know if it stored as number of colors or as bytes... */
545 cbPalette = pBHdr->cclrUsed; //size in bytes or in (*sizeof(RGB2))?
546 break;
547
548 default:
549 cout << "QueryPaletteSize: error pBHdr->biBitCount = " << pBHdr->cBitCount << endl;
550 cbPalette = -1;
551 }
552
553 return cbPalette;
554}
555
556
557
558
559static ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy)
560{
561 ULONG alignment;
562 ULONG factor;
563 BOOL flag = TRUE; //true: '*' false: '/'
564
565 cy = cy < 0 ? -cy : cy;
566
567 switch(cBits)
568 {
569 case 1:
570 factor = 8;
571 flag = FALSE;
572 break;
573
574 case 4:
575 factor = 2;
576 flag = FALSE;
577 break;
578
579 case 8:
580 factor = 1;
581 break;
582
583 case 16:
584 factor = 2;
585 break;
586
587 case 24:
588 factor = 3;
589 break;
590
591 case 32:
592 return cx*cy;
593
594 default:
595 return 0;
596 }
597
598 if (flag)
599 alignment = (cx = (cx*factor)) % 4;
600 else
601 alignment = (cx = ((cx+factor-1)/factor)) % 4;
602
603 if (alignment != 0)
604 cx += 4 - alignment;
605
606 return cx*cy;
607}
608
609
610ULONG QuerySizeBitmap(WINBITMAPINFOHEADER *pBHdr, ULONG ulSize)
611{
612 ULONG retSize;
613 ltassert((ULONG)pBHdr > MINPTR && (ULONG)pBHdr+ulSize < MAXPTR);
614
615 switch (pBHdr->biSize)
616 {
617 /**************************************/
618 /* Windows v3.0 bitmap */
619 /**************************************/
620 case sizeof(WINBITMAPINFOHEADER):
621 {//convert to OS/2 v2.0 bitmap
622 #ifdef BITFIELDS
623 if (pBHdr->biCompression == BI_RGB || pBHdr->biCompression == BI_BITFIELDS)
624 #else
625 if (pBHdr->biCompression == BI_RGB)
626 #endif
627 {
628 if (Need1BitTo4BitConvertWIN(pBHdr))
629 retSize = CalcBitmapSize(4, pBHdr->biWidth, pBHdr->biHeight);
630 else
631 retSize = CalcBitmapSize(pBHdr->biBitCount, pBHdr->biWidth, pBHdr->biHeight);
632 }
633 else
634 {
635 retSize = pBHdr->biSizeImage;
636 if (retSize == 0)
637 retSize = ulSize - sizeof(WINBITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER2);
638 }
639 ltassert(retSize != 0);
640
641 ULONG a = QueryPaletteSize(pBHdr);
642 ltassert(a != -1);
643 retSize += sizeof(BITMAPFILEHEADER2) + a;
644 }
645 break;
646
647 /**************************************/
648 /* Windows v4.0 bitmap */
649 /**************************************/
650 case sizeof(BITMAPV4HEADER):
651 {//convert to OS/2 v2.0 bitmap - some other day when I find the specs.
652 ltassert(FALSE && "Windows v4.0 bitmap");
653 }
654 break;
655
656 /**************************************/
657 /* OS/2 v1.x bitmap */
658 /**************************************/
659 case sizeof(BITMAPINFOHEADER):
660 {//no conversion needed - only build fileheader
661 PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER)pBHdr;
662
663 if (Need1BitTo4BitConvertOS2(pBIH))
664 {
665 retSize = CalcBitmapSize(4, pBIH->cx, pBIH->cy);
666 ltassert(retSize != 0);
667
668 retSize += sizeof(RGB)*16; //palette
669 }
670 else
671 {
672 retSize = CalcBitmapSize(pBIH->cBitCount, pBIH->cx, pBIH->cy);
673 ltassert(retSize != 0);
674
675 ULONG a = QueryPaletteSize(pBIH);
676 ltassert(a != -1);
677 retSize += a;
678 }
679
680 retSize += sizeof(BITMAPFILEHEADER);
681 }
682
683 /**************************************/
684 /* OS/2 v2.0 bitmap - highly unlikely!*/
685 /**************************************/
686 case sizeof(BITMAPINFOHEADER2):
687 {//no conversion needed - only build fileheader
688 return ulSize + sizeof(BITMAPFILEHEADER2) - sizeof(BITMAPINFOHEADER2);
689 }
690
691 /**************************************/
692 /* Unknown */
693 /**************************************/
694 default: //fail
695 cout << "QuerySizeBitmap - default - fail!" << endl;
696 return 0;
697 }
698
699 return retSize;
700}
701
702
703#ifdef BITMAPCONVERTER
704
705ULONG fsize(FILE *ph)
706{
707 LONG lPos;
708 ULONG ulSize;
709
710 lPos = ftell(ph);
711 fseek(ph, 0, SEEK_END);
712 ulSize = ftell(ph);
713 fseek(ph, lPos, SEEK_SET);
714
715 return ulSize;
716}
717
718
719void main(int argi, char **argc)
720{
721 char *pF1Buf;
722 char *pF2Buf;
723 char *pszF1;
724 char *pszF2;
725 FILE *phF1;
726 FILE *phF2;
727 ULONG cbF1;
728 ULONG cbF2;
729
730 /* tittle */
731 cout << "PE2LX Resources: Bitmap Convert v0.0.2alpha" << endl;
732
733 /* quick test of arguments */
734 if (argi < 3)
735 {
736 cout << "error: incorrect number of parameters" << endl;
737 return;
738 }
739 pszF1 = argc[1];
740 pszF2 = argc[2];
741
742 /* open files */
743 phF1 = fopen(pszF1, "rb");
744 phF2 = fopen(pszF2, "wb");
745 if (phF1 == NULL || phF2 == NULL)
746 {
747 cout << "error: could not open file ";
748 if (phF1 == NULL)
749 cout << pszF1 << endl;
750 else
751 cout << pszF2 << endl;
752 }
753
754
755 /* read infile */
756 cbF1 = fsize(phF1);
757 if (cbF1 > sizeof(BITMAPFILEHEADER))
758 {
759 pF1Buf = (char*)malloc(cbF1);
760 assert(pF1Buf != NULL);
761
762 if (fread(pF1Buf, 1, cbF1, phF1))
763 {
764 ULONG ulOffset;
765 if (pF1Buf[0]=='B' && pF1Buf[1]=='M')
766 ulOffset = sizeof(BITMAPFILEHEADER) - sizeof(BITMAPINFOHEADER);
767 else
768 ulOffset = 0;
769 pF2Buf = (char*)ConvertBitmap((WINBITMAPINFOHEADER*)&pF1Buf[ulOffset], cbF1-ulOffset, &cbF2);
770 if (pF2Buf != NULL)
771 {
772 cout << "filesize: " << cbF2 << endl;
773 if (fwrite (pF2Buf, 1, cbF2, phF2))
774 cout << "Converted bitmap is successfully written to disk." << endl;
775 else
776 cout << "error: error occured while writing converted bitmap to disk." << endl;
777 free(pF2Buf);
778 }
779 else
780 cout << "error: failed!" << endl;
781 }
782 else
783 cout << "error: error while reading infile" << endl;
784
785 free(pF1Buf);
786 }
787 else
788 cout << "error: invalid infile" << endl;
789
790 /* finished */
791 fclose(phF1);
792 fclose(phF2);
793}
794
795#endif
Note: See TracBrowser for help on using the repository browser.