source: trunk/src/pe2lx/bitmap.cpp@ 46

Last change on this file since 46 was 46, checked in by sandervl, 26 years ago

* empty log message *

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