3 * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
6 * Functions to translate dib pictures into eps
8 *================================================================
9 * This part of the software is based on:
10 * The Windows Bitmap Decoder Class part of paintlib
11 * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow
12 *================================================================
13 * The credit should go to him, but all the bugs are mine.
21 * vDecode1bpp - decode an uncompressed 1 bit per pixel image
24 vDecode1bpp(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
27 int iX
, iY
, iN
, iByte
, iTmp
, iEighthWidth
, iUse
;
29 DBG_MSG("vDecode1bpp");
31 fail(pOutFile
== NULL
);
33 fail(pImg
->iColorsUsed
< 1 || pImg
->iColorsUsed
> 2);
35 DBG_DEC(pImg
->iWidth
);
36 DBG_DEC(pImg
->iHeight
);
38 iEighthWidth
= (pImg
->iWidth
+ 7) / 8;
39 tPadding
= (size_t)(ROUND4(iEighthWidth
) - iEighthWidth
);
41 for (iY
= 0; iY
< pImg
->iHeight
; iY
++) {
42 for (iX
= 0; iX
< iEighthWidth
; iX
++) {
43 iByte
= iNextByte(pInFile
);
45 vASCII85EncodeByte(pOutFile
, EOF
);
48 if (iX
== iEighthWidth
- 1 && pImg
->iWidth
% 8 != 0) {
49 iUse
= pImg
->iWidth
% 8;
53 for (iN
= 0; iN
< iUse
; iN
++) {
55 case 0: iTmp
= (iByte
& 0x80) / 128; break;
56 case 1: iTmp
= (iByte
& 0x40) / 64; break;
57 case 2: iTmp
= (iByte
& 0x20) / 32; break;
58 case 3: iTmp
= (iByte
& 0x10) / 16; break;
59 case 4: iTmp
= (iByte
& 0x08) / 8; break;
60 case 5: iTmp
= (iByte
& 0x04) / 4; break;
61 case 6: iTmp
= (iByte
& 0x02) / 2; break;
62 case 7: iTmp
= (iByte
& 0x01); break;
63 default: iTmp
= 0; break;
65 vASCII85EncodeByte(pOutFile
, iTmp
);
68 (void)tSkipBytes(pInFile
, tPadding
);
70 vASCII85EncodeByte(pOutFile
, EOF
);
71 } /* end of vDecode1bpp */
74 * vDecode4bpp - decode an uncompressed 4 bits per pixel image
77 vDecode4bpp(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
80 int iX
, iY
, iN
, iByte
, iTmp
, iHalfWidth
, iUse
;
82 DBG_MSG("vDecode4bpp");
84 fail(pInFile
== NULL
);
85 fail(pOutFile
== NULL
);
87 fail(pImg
->iColorsUsed
< 1 || pImg
->iColorsUsed
> 16);
89 DBG_DEC(pImg
->iWidth
);
90 DBG_DEC(pImg
->iHeight
);
92 iHalfWidth
= (pImg
->iWidth
+ 1) / 2;
93 tPadding
= (size_t)(ROUND4(iHalfWidth
) - iHalfWidth
);
95 for (iY
= 0; iY
< pImg
->iHeight
; iY
++) {
96 for (iX
= 0; iX
< iHalfWidth
; iX
++) {
97 iByte
= iNextByte(pInFile
);
99 vASCII85EncodeByte(pOutFile
, EOF
);
102 if (iX
== iHalfWidth
- 1 && odd(pImg
->iWidth
)) {
107 for (iN
= 0; iN
< iUse
; iN
++) {
111 iTmp
= (iByte
& 0xf0) / 16;
113 vASCII85EncodeByte(pOutFile
, iTmp
);
116 (void)tSkipBytes(pInFile
, tPadding
);
118 vASCII85EncodeByte(pOutFile
, EOF
);
119 } /* end of vDecode4bpp */
122 * vDecode8bpp - decode an uncompressed 8 bits per pixel image
125 vDecode8bpp(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
130 DBG_MSG("vDecode8bpp");
132 fail(pInFile
== NULL
);
133 fail(pOutFile
== NULL
);
135 fail(pImg
->iColorsUsed
< 1 || pImg
->iColorsUsed
> 256);
137 DBG_DEC(pImg
->iWidth
);
138 DBG_DEC(pImg
->iHeight
);
140 tPadding
= (size_t)(ROUND4(pImg
->iWidth
) - pImg
->iWidth
);
142 for (iY
= 0; iY
< pImg
->iHeight
; iY
++) {
143 for (iX
= 0; iX
< pImg
->iWidth
; iX
++) {
144 iByte
= iNextByte(pInFile
);
146 vASCII85EncodeByte(pOutFile
, EOF
);
149 vASCII85EncodeByte(pOutFile
, iByte
);
151 (void)tSkipBytes(pInFile
, tPadding
);
153 vASCII85EncodeByte(pOutFile
, EOF
);
154 } /* end of vDecode8bpp */
157 * vDecode24bpp - decode an uncompressed 24 bits per pixel image
160 vDecode24bpp(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
163 int iX
, iY
, iBlue
, iGreen
, iRed
, iTripleWidth
;
165 DBG_MSG("vDecode24bpp");
167 fail(pInFile
== NULL
);
168 fail(pOutFile
== NULL
);
170 fail(!pImg
->bColorImage
);
172 DBG_DEC(pImg
->iWidth
);
173 DBG_DEC(pImg
->iHeight
);
175 iTripleWidth
= pImg
->iWidth
* 3;
176 tPadding
= (size_t)(ROUND4(iTripleWidth
) - iTripleWidth
);
178 for (iY
= 0; iY
< pImg
->iHeight
; iY
++) {
179 for (iX
= 0; iX
< pImg
->iWidth
; iX
++) {
180 /* Change from BGR order to RGB order */
181 iBlue
= iNextByte(pInFile
);
183 vASCII85EncodeByte(pOutFile
, EOF
);
186 iGreen
= iNextByte(pInFile
);
188 vASCII85EncodeByte(pOutFile
, EOF
);
191 iRed
= iNextByte(pInFile
);
193 vASCII85EncodeByte(pOutFile
, EOF
);
196 vASCII85EncodeByte(pOutFile
, iRed
);
197 vASCII85EncodeByte(pOutFile
, iGreen
);
198 vASCII85EncodeByte(pOutFile
, iBlue
);
200 (void)tSkipBytes(pInFile
, tPadding
);
202 vASCII85EncodeByte(pOutFile
, EOF
);
203 } /* end of vDecode24bpp */
206 * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
209 vDecodeRle4(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
211 int iX
, iY
, iByte
, iTmp
, iRunLength
, iRun
;
214 DBG_MSG("vDecodeRle4");
216 fail(pInFile
== NULL
);
217 fail(pOutFile
== NULL
);
219 fail(pImg
->iColorsUsed
< 1 || pImg
->iColorsUsed
> 16);
221 DBG_DEC(pImg
->iWidth
);
222 DBG_DEC(pImg
->iHeight
);
226 for (iY
= 0; iY
< pImg
->iHeight
&& !bEOF
; iY
++) {
230 iRunLength
= iNextByte(pInFile
);
231 if (iRunLength
== EOF
) {
232 vASCII85EncodeByte(pOutFile
, EOF
);
235 if (iRunLength
!= 0) {
238 * RunLength pixels, all the "same" value
240 iByte
= iNextByte(pInFile
);
242 vASCII85EncodeByte(pOutFile
, EOF
);
245 for (iRun
= 0; iRun
< iRunLength
; iRun
++) {
249 iTmp
= (iByte
& 0xf0) / 16;
251 if (iX
< pImg
->iWidth
) {
252 vASCII85EncodeByte(pOutFile
, iTmp
);
258 /* Literal or escape */
259 iRunLength
= iNextByte(pInFile
);
260 if (iRunLength
== EOF
) {
261 vASCII85EncodeByte(pOutFile
, EOF
);
264 if (iRunLength
== 0) { /* End of line escape */
266 } else if (iRunLength
== 1) { /* End of file escape */
269 } else if (iRunLength
== 2) { /* Delta escape */
270 DBG_MSG("RLE4: encountered delta escape");
273 } else { /* Literal packet */
275 for (iRun
= 0; iRun
< iRunLength
; iRun
++) {
279 iByte
= iNextByte(pInFile
);
281 vASCII85EncodeByte(pOutFile
, EOF
);
284 iTmp
= (iByte
& 0xf0) / 16;
286 if (iX
< pImg
->iWidth
) {
287 vASCII85EncodeByte(pOutFile
, iTmp
);
291 /* Padding if the number of bytes is odd */
292 if (odd((iRunLength
+ 1) / 2)) {
293 (void)tSkipBytes(pInFile
, 1);
297 DBG_DEC_C(iX
!= pImg
->iWidth
, iX
);
299 vASCII85EncodeByte(pOutFile
, EOF
);
300 } /* end of vDecodeRle4 */
303 * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
306 vDecodeRle8(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
308 int iX
, iY
, iByte
, iRunLength
, iRun
;
311 DBG_MSG("vDecodeRle8");
313 fail(pInFile
== NULL
);
314 fail(pOutFile
== NULL
);
316 fail(pImg
->iColorsUsed
< 1 || pImg
->iColorsUsed
> 256);
318 DBG_DEC(pImg
->iWidth
);
319 DBG_DEC(pImg
->iHeight
);
323 for (iY
= 0; iY
< pImg
->iHeight
&& !bEOF
; iY
++) {
327 iRunLength
= iNextByte(pInFile
);
328 if (iRunLength
== EOF
) {
329 vASCII85EncodeByte(pOutFile
, EOF
);
332 if (iRunLength
!= 0) {
335 * RunLength pixels, all the same value
337 iByte
= iNextByte(pInFile
);
339 vASCII85EncodeByte(pOutFile
, EOF
);
342 for (iRun
= 0; iRun
< iRunLength
; iRun
++) {
343 if (iX
< pImg
->iWidth
) {
344 vASCII85EncodeByte(pOutFile
, iByte
);
350 /* Literal or escape */
351 iRunLength
= iNextByte(pInFile
);
352 if (iRunLength
== EOF
) {
353 vASCII85EncodeByte(pOutFile
, EOF
);
356 if (iRunLength
== 0) { /* End of line escape */
358 } else if (iRunLength
== 1) { /* End of file escape */
361 } else if (iRunLength
== 2) { /* Delta escape */
362 DBG_MSG("RLE8: encountered delta escape");
365 } else { /* Literal packet */
366 for (iRun
= 0; iRun
< iRunLength
; iRun
++) {
367 iByte
= iNextByte(pInFile
);
369 vASCII85EncodeByte(pOutFile
, EOF
);
372 if (iX
< pImg
->iWidth
) {
373 vASCII85EncodeByte(pOutFile
, iByte
);
377 /* Padding if the number of bytes is odd */
378 if (odd(iRunLength
)) {
379 (void)tSkipBytes(pInFile
, 1);
383 DBG_DEC_C(iX
!= pImg
->iWidth
, iX
);
385 vASCII85EncodeByte(pOutFile
, EOF
);
386 } /* end of vDecodeRle8 */
389 * vDecodeDIB - decode a dib picture
392 vDecodeDIB(FILE *pInFile
, FILE *pOutFile
, const imagedata_type
*pImg
)
396 fail(pInFile
== NULL
);
397 fail(pOutFile
== NULL
);
400 /* Skip the bitmap info header */
401 tHeaderSize
= (size_t)ulNextLong(pInFile
);
402 (void)tSkipBytes(pInFile
, tHeaderSize
- 4);
403 /* Skip the colortable */
404 if (pImg
->uiBitsPerComponent
<= 8) {
405 (void)tSkipBytes(pInFile
,
406 (size_t)(pImg
->iColorsUsed
*
407 ((tHeaderSize
> 12) ? 4 : 3)));
410 switch (pImg
->uiBitsPerComponent
) {
412 fail(pImg
->eCompression
!= compression_none
);
413 vDecode1bpp(pInFile
, pOutFile
, pImg
);
416 fail(pImg
->eCompression
!= compression_none
&&
417 pImg
->eCompression
!= compression_rle4
);
418 if (pImg
->eCompression
== compression_rle4
) {
419 vDecodeRle4(pInFile
, pOutFile
, pImg
);
421 vDecode4bpp(pInFile
, pOutFile
, pImg
);
425 fail(pImg
->eCompression
!= compression_none
&&
426 pImg
->eCompression
!= compression_rle8
);
427 if (pImg
->eCompression
== compression_rle8
) {
428 vDecodeRle8(pInFile
, pOutFile
, pImg
);
430 vDecode8bpp(pInFile
, pOutFile
, pImg
);
434 fail(pImg
->eCompression
!= compression_none
);
435 vDecode24bpp(pInFile
, pOutFile
, pImg
);
438 DBG_DEC(pImg
->uiBitsPerComponent
);
441 } /* end of vDecodeDIB */
448 vCopy2File(FILE *pInFile
, ULONG ulFileOffset
, size_t tPictureLen
)
450 static int iPicCounter
= 0;
456 if (!bSetDataOffset(pInFile
, ulFileOffset
)) {
460 sprintf(szFilename
, "/tmp/pic/pic%04d.bmp", ++iPicCounter
);
461 pOutFile
= fopen(szFilename
, "wb");
462 if (pOutFile
== NULL
) {
465 /* Turn a dib into a bmp by adding a fake 14 byte header */
466 (void)putc('B', pOutFile
);
467 (void)putc('M', pOutFile
);
468 for (iTmp
= 0; iTmp
< 12; iTmp
++) {
469 if (putc(0, pOutFile
) == EOF
) {
473 for (tIndex
= 0; tIndex
< tPictureLen
; tIndex
++) {
474 iTmp
= iNextByte(pInFile
);
475 if (putc(iTmp
, pOutFile
) == EOF
) {
479 (void)fclose(pOutFile
);
480 } /* end of vCopy2File */
484 * bTranslateDIB - translate a DIB picture
486 * This function translates a picture from dib to eps
488 * return TRUE when sucessful, otherwise FALSE
491 bTranslateDIB(diagram_type
*pDiag
, FILE *pInFile
,
492 ULONG ulFileOffset
, const imagedata_type
*pImg
)
495 fail(pImg
->tPosition
> pImg
->tLength
);
496 vCopy2File(pInFile
, ulFileOffset
, pImg
->tLength
- pImg
->tPosition
);
499 /* Seek to start position of DIB data */
500 if (!bSetDataOffset(pInFile
, ulFileOffset
)) {
504 vImagePrologue(pDiag
, pImg
);
505 vDecodeDIB(pInFile
, pDiag
->pOutFile
, pImg
);
506 vImageEpilogue(pDiag
);
509 } /* end of bTranslateDIB */