Imported from antiword-0.37.tar.gz.
[antiword.git] / dib2eps.c
blob2673d38e0e4235d6b828ad4f3226bc9ce145971b
1 /*
2 * dib2eps.c
3 * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
5 * Description:
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.
16 #include <stdio.h>
17 #include "antiword.h"
21 * vDecode1bpp - decode an uncompressed 1 bit per pixel image
23 static void
24 vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
26 size_t tPadding;
27 int iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
29 DBG_MSG("vDecode1bpp");
31 fail(pOutFile == NULL);
32 fail(pImg == 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);
44 if (iByte == EOF) {
45 vASCII85EncodeByte(pOutFile, EOF);
46 return;
48 if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
49 iUse = pImg->iWidth % 8;
50 } else {
51 iUse = 8;
53 for (iN = 0; iN < iUse; iN++) {
54 switch (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
76 static void
77 vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
79 size_t tPadding;
80 int iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
82 DBG_MSG("vDecode4bpp");
84 fail(pInFile == NULL);
85 fail(pOutFile == NULL);
86 fail(pImg == 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);
98 if (iByte == EOF) {
99 vASCII85EncodeByte(pOutFile, EOF);
100 return;
102 if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
103 iUse = 1;
104 } else {
105 iUse = 2;
107 for (iN = 0; iN < iUse; iN++) {
108 if (odd(iN)) {
109 iTmp = iByte & 0x0f;
110 } else {
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
124 static void
125 vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
127 size_t tPadding;
128 int iX, iY, iByte;
130 DBG_MSG("vDecode8bpp");
132 fail(pInFile == NULL);
133 fail(pOutFile == NULL);
134 fail(pImg == 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);
145 if (iByte == EOF) {
146 vASCII85EncodeByte(pOutFile, EOF);
147 return;
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
159 static void
160 vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
162 size_t tPadding;
163 int iX, iY, iBlue, iGreen, iRed, iTripleWidth;
165 DBG_MSG("vDecode24bpp");
167 fail(pInFile == NULL);
168 fail(pOutFile == NULL);
169 fail(pImg == 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);
182 if (iBlue == EOF) {
183 vASCII85EncodeByte(pOutFile, EOF);
184 return;
186 iGreen = iNextByte(pInFile);
187 if (iGreen == EOF) {
188 vASCII85EncodeByte(pOutFile, EOF);
189 return;
191 iRed = iNextByte(pInFile);
192 if (iRed == EOF) {
193 vASCII85EncodeByte(pOutFile, EOF);
194 return;
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
208 static void
209 vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
211 int iX, iY, iByte, iTmp, iRunLength, iRun;
212 BOOL bEOF, bEOL;
214 DBG_MSG("vDecodeRle4");
216 fail(pInFile == NULL);
217 fail(pOutFile == NULL);
218 fail(pImg == NULL);
219 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
221 DBG_DEC(pImg->iWidth);
222 DBG_DEC(pImg->iHeight);
224 bEOF = FALSE;
226 for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
227 bEOL = FALSE;
228 iX = 0;
229 while (!bEOL) {
230 iRunLength = iNextByte(pInFile);
231 if (iRunLength == EOF) {
232 vASCII85EncodeByte(pOutFile, EOF);
233 return;
235 if (iRunLength != 0) {
237 * Encoded packet:
238 * RunLength pixels, all the "same" value
240 iByte = iNextByte(pInFile);
241 if (iByte == EOF) {
242 vASCII85EncodeByte(pOutFile, EOF);
243 return;
245 for (iRun = 0; iRun < iRunLength; iRun++) {
246 if (odd(iRun)) {
247 iTmp = iByte & 0x0f;
248 } else {
249 iTmp = (iByte & 0xf0) / 16;
251 if (iX < pImg->iWidth) {
252 vASCII85EncodeByte(pOutFile, iTmp);
254 iX++;
256 continue;
258 /* Literal or escape */
259 iRunLength = iNextByte(pInFile);
260 if (iRunLength == EOF) {
261 vASCII85EncodeByte(pOutFile, EOF);
262 return;
264 if (iRunLength == 0) { /* End of line escape */
265 bEOL = TRUE;
266 } else if (iRunLength == 1) { /* End of file escape */
267 bEOF = TRUE;
268 bEOL = TRUE;
269 } else if (iRunLength == 2) { /* Delta escape */
270 DBG_MSG("RLE4: encountered delta escape");
271 bEOF = TRUE;
272 bEOL = TRUE;
273 } else { /* Literal packet */
274 iByte = 0;
275 for (iRun = 0; iRun < iRunLength; iRun++) {
276 if (odd(iRun)) {
277 iTmp = iByte & 0x0f;
278 } else {
279 iByte = iNextByte(pInFile);
280 if (iByte == EOF) {
281 vASCII85EncodeByte(pOutFile, EOF);
282 return;
284 iTmp = (iByte & 0xf0) / 16;
286 if (iX < pImg->iWidth) {
287 vASCII85EncodeByte(pOutFile, iTmp);
289 iX++;
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
305 static void
306 vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
308 int iX, iY, iByte, iRunLength, iRun;
309 BOOL bEOF, bEOL;
311 DBG_MSG("vDecodeRle8");
313 fail(pInFile == NULL);
314 fail(pOutFile == NULL);
315 fail(pImg == NULL);
316 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
318 DBG_DEC(pImg->iWidth);
319 DBG_DEC(pImg->iHeight);
321 bEOF = FALSE;
323 for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
324 bEOL = FALSE;
325 iX = 0;
326 while (!bEOL) {
327 iRunLength = iNextByte(pInFile);
328 if (iRunLength == EOF) {
329 vASCII85EncodeByte(pOutFile, EOF);
330 return;
332 if (iRunLength != 0) {
334 * Encoded packet:
335 * RunLength pixels, all the same value
337 iByte = iNextByte(pInFile);
338 if (iByte == EOF) {
339 vASCII85EncodeByte(pOutFile, EOF);
340 return;
342 for (iRun = 0; iRun < iRunLength; iRun++) {
343 if (iX < pImg->iWidth) {
344 vASCII85EncodeByte(pOutFile, iByte);
346 iX++;
348 continue;
350 /* Literal or escape */
351 iRunLength = iNextByte(pInFile);
352 if (iRunLength == EOF) {
353 vASCII85EncodeByte(pOutFile, EOF);
354 return;
356 if (iRunLength == 0) { /* End of line escape */
357 bEOL = TRUE;
358 } else if (iRunLength == 1) { /* End of file escape */
359 bEOF = TRUE;
360 bEOL = TRUE;
361 } else if (iRunLength == 2) { /* Delta escape */
362 DBG_MSG("RLE8: encountered delta escape");
363 bEOF = TRUE;
364 bEOL = TRUE;
365 } else { /* Literal packet */
366 for (iRun = 0; iRun < iRunLength; iRun++) {
367 iByte = iNextByte(pInFile);
368 if (iByte == EOF) {
369 vASCII85EncodeByte(pOutFile, EOF);
370 return;
372 if (iX < pImg->iWidth) {
373 vASCII85EncodeByte(pOutFile, iByte);
375 iX++;
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
391 static void
392 vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
394 size_t tHeaderSize;
396 fail(pInFile == NULL);
397 fail(pOutFile == NULL);
398 fail(pImg == 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) {
411 case 1:
412 fail(pImg->eCompression != compression_none);
413 vDecode1bpp(pInFile, pOutFile, pImg);
414 break;
415 case 4:
416 fail(pImg->eCompression != compression_none &&
417 pImg->eCompression != compression_rle4);
418 if (pImg->eCompression == compression_rle4) {
419 vDecodeRle4(pInFile, pOutFile, pImg);
420 } else {
421 vDecode4bpp(pInFile, pOutFile, pImg);
423 break;
424 case 8:
425 fail(pImg->eCompression != compression_none &&
426 pImg->eCompression != compression_rle8);
427 if (pImg->eCompression == compression_rle8) {
428 vDecodeRle8(pInFile, pOutFile, pImg);
429 } else {
430 vDecode8bpp(pInFile, pOutFile, pImg);
432 break;
433 case 24:
434 fail(pImg->eCompression != compression_none);
435 vDecode24bpp(pInFile, pOutFile, pImg);
436 break;
437 default:
438 DBG_DEC(pImg->uiBitsPerComponent);
439 break;
441 } /* end of vDecodeDIB */
443 #if defined(DEBUG)
445 * vCopy2File
447 static void
448 vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
450 static int iPicCounter = 0;
451 FILE *pOutFile;
452 size_t tIndex;
453 int iTmp;
454 char szFilename[30];
456 if (!bSetDataOffset(pInFile, ulFileOffset)) {
457 return;
460 sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
461 pOutFile = fopen(szFilename, "wb");
462 if (pOutFile == NULL) {
463 return;
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) {
470 break;
473 for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
474 iTmp = iNextByte(pInFile);
475 if (putc(iTmp, pOutFile) == EOF) {
476 break;
479 (void)fclose(pOutFile);
480 } /* end of vCopy2File */
481 #endif /* DEBUG */
484 * bTranslateDIB - translate a DIB picture
486 * This function translates a picture from dib to eps
488 * return TRUE when sucessful, otherwise FALSE
490 BOOL
491 bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
492 ULONG ulFileOffset, const imagedata_type *pImg)
494 #if defined(DEBUG)
495 fail(pImg->tPosition > pImg->tLength);
496 vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
497 #endif /* DEBUG */
499 /* Seek to start position of DIB data */
500 if (!bSetDataOffset(pInFile, ulFileOffset)) {
501 return FALSE;
504 vImagePrologue(pDiag, pImg);
505 vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
506 vImageEpilogue(pDiag);
508 return TRUE;
509 } /* end of bTranslateDIB */