1*f5736e95SDavid du Colombier /*
2*f5736e95SDavid du Colombier * dib2eps.c
3*f5736e95SDavid du Colombier * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
4*f5736e95SDavid du Colombier *
5*f5736e95SDavid du Colombier * Description:
6*f5736e95SDavid du Colombier * Functions to translate dib pictures into eps
7*f5736e95SDavid du Colombier *
8*f5736e95SDavid du Colombier *================================================================
9*f5736e95SDavid du Colombier * This part of the software is based on:
10*f5736e95SDavid du Colombier * The Windows Bitmap Decoder Class part of paintlib
11*f5736e95SDavid du Colombier * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow
12*f5736e95SDavid du Colombier *================================================================
13*f5736e95SDavid du Colombier * The credit should go to him, but all the bugs are mine.
14*f5736e95SDavid du Colombier */
15*f5736e95SDavid du Colombier
16*f5736e95SDavid du Colombier #include <stdio.h>
17*f5736e95SDavid du Colombier #include "antiword.h"
18*f5736e95SDavid du Colombier
19*f5736e95SDavid du Colombier
20*f5736e95SDavid du Colombier /*
21*f5736e95SDavid du Colombier * vDecode1bpp - decode an uncompressed 1 bit per pixel image
22*f5736e95SDavid du Colombier */
23*f5736e95SDavid du Colombier static void
vDecode1bpp(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)24*f5736e95SDavid du Colombier vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
25*f5736e95SDavid du Colombier {
26*f5736e95SDavid du Colombier size_t tPadding;
27*f5736e95SDavid du Colombier int iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
28*f5736e95SDavid du Colombier
29*f5736e95SDavid du Colombier DBG_MSG("vDecode1bpp");
30*f5736e95SDavid du Colombier
31*f5736e95SDavid du Colombier fail(pOutFile == NULL);
32*f5736e95SDavid du Colombier fail(pImg == NULL);
33*f5736e95SDavid du Colombier fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
34*f5736e95SDavid du Colombier
35*f5736e95SDavid du Colombier DBG_DEC(pImg->iWidth);
36*f5736e95SDavid du Colombier DBG_DEC(pImg->iHeight);
37*f5736e95SDavid du Colombier
38*f5736e95SDavid du Colombier iEighthWidth = (pImg->iWidth + 7) / 8;
39*f5736e95SDavid du Colombier tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
40*f5736e95SDavid du Colombier
41*f5736e95SDavid du Colombier for (iY = 0; iY < pImg->iHeight; iY++) {
42*f5736e95SDavid du Colombier for (iX = 0; iX < iEighthWidth; iX++) {
43*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
44*f5736e95SDavid du Colombier if (iByte == EOF) {
45*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
46*f5736e95SDavid du Colombier return;
47*f5736e95SDavid du Colombier }
48*f5736e95SDavid du Colombier if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
49*f5736e95SDavid du Colombier iUse = pImg->iWidth % 8;
50*f5736e95SDavid du Colombier } else {
51*f5736e95SDavid du Colombier iUse = 8;
52*f5736e95SDavid du Colombier }
53*f5736e95SDavid du Colombier for (iN = 0; iN < iUse; iN++) {
54*f5736e95SDavid du Colombier switch (iN) {
55*f5736e95SDavid du Colombier case 0: iTmp = (iByte & 0x80) / 128; break;
56*f5736e95SDavid du Colombier case 1: iTmp = (iByte & 0x40) / 64; break;
57*f5736e95SDavid du Colombier case 2: iTmp = (iByte & 0x20) / 32; break;
58*f5736e95SDavid du Colombier case 3: iTmp = (iByte & 0x10) / 16; break;
59*f5736e95SDavid du Colombier case 4: iTmp = (iByte & 0x08) / 8; break;
60*f5736e95SDavid du Colombier case 5: iTmp = (iByte & 0x04) / 4; break;
61*f5736e95SDavid du Colombier case 6: iTmp = (iByte & 0x02) / 2; break;
62*f5736e95SDavid du Colombier case 7: iTmp = (iByte & 0x01); break;
63*f5736e95SDavid du Colombier default: iTmp = 0; break;
64*f5736e95SDavid du Colombier }
65*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iTmp);
66*f5736e95SDavid du Colombier }
67*f5736e95SDavid du Colombier }
68*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, tPadding);
69*f5736e95SDavid du Colombier }
70*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
71*f5736e95SDavid du Colombier } /* end of vDecode1bpp */
72*f5736e95SDavid du Colombier
73*f5736e95SDavid du Colombier /*
74*f5736e95SDavid du Colombier * vDecode4bpp - decode an uncompressed 4 bits per pixel image
75*f5736e95SDavid du Colombier */
76*f5736e95SDavid du Colombier static void
vDecode4bpp(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)77*f5736e95SDavid du Colombier vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
78*f5736e95SDavid du Colombier {
79*f5736e95SDavid du Colombier size_t tPadding;
80*f5736e95SDavid du Colombier int iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
81*f5736e95SDavid du Colombier
82*f5736e95SDavid du Colombier DBG_MSG("vDecode4bpp");
83*f5736e95SDavid du Colombier
84*f5736e95SDavid du Colombier fail(pInFile == NULL);
85*f5736e95SDavid du Colombier fail(pOutFile == NULL);
86*f5736e95SDavid du Colombier fail(pImg == NULL);
87*f5736e95SDavid du Colombier fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
88*f5736e95SDavid du Colombier
89*f5736e95SDavid du Colombier DBG_DEC(pImg->iWidth);
90*f5736e95SDavid du Colombier DBG_DEC(pImg->iHeight);
91*f5736e95SDavid du Colombier
92*f5736e95SDavid du Colombier iHalfWidth = (pImg->iWidth + 1) / 2;
93*f5736e95SDavid du Colombier tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
94*f5736e95SDavid du Colombier
95*f5736e95SDavid du Colombier for (iY = 0; iY < pImg->iHeight; iY++) {
96*f5736e95SDavid du Colombier for (iX = 0; iX < iHalfWidth; iX++) {
97*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
98*f5736e95SDavid du Colombier if (iByte == EOF) {
99*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
100*f5736e95SDavid du Colombier return;
101*f5736e95SDavid du Colombier }
102*f5736e95SDavid du Colombier if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
103*f5736e95SDavid du Colombier iUse = 1;
104*f5736e95SDavid du Colombier } else {
105*f5736e95SDavid du Colombier iUse = 2;
106*f5736e95SDavid du Colombier }
107*f5736e95SDavid du Colombier for (iN = 0; iN < iUse; iN++) {
108*f5736e95SDavid du Colombier if (odd(iN)) {
109*f5736e95SDavid du Colombier iTmp = iByte & 0x0f;
110*f5736e95SDavid du Colombier } else {
111*f5736e95SDavid du Colombier iTmp = (iByte & 0xf0) / 16;
112*f5736e95SDavid du Colombier }
113*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iTmp);
114*f5736e95SDavid du Colombier }
115*f5736e95SDavid du Colombier }
116*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, tPadding);
117*f5736e95SDavid du Colombier }
118*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
119*f5736e95SDavid du Colombier } /* end of vDecode4bpp */
120*f5736e95SDavid du Colombier
121*f5736e95SDavid du Colombier /*
122*f5736e95SDavid du Colombier * vDecode8bpp - decode an uncompressed 8 bits per pixel image
123*f5736e95SDavid du Colombier */
124*f5736e95SDavid du Colombier static void
vDecode8bpp(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)125*f5736e95SDavid du Colombier vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
126*f5736e95SDavid du Colombier {
127*f5736e95SDavid du Colombier size_t tPadding;
128*f5736e95SDavid du Colombier int iX, iY, iByte;
129*f5736e95SDavid du Colombier
130*f5736e95SDavid du Colombier DBG_MSG("vDecode8bpp");
131*f5736e95SDavid du Colombier
132*f5736e95SDavid du Colombier fail(pInFile == NULL);
133*f5736e95SDavid du Colombier fail(pOutFile == NULL);
134*f5736e95SDavid du Colombier fail(pImg == NULL);
135*f5736e95SDavid du Colombier fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
136*f5736e95SDavid du Colombier
137*f5736e95SDavid du Colombier DBG_DEC(pImg->iWidth);
138*f5736e95SDavid du Colombier DBG_DEC(pImg->iHeight);
139*f5736e95SDavid du Colombier
140*f5736e95SDavid du Colombier tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
141*f5736e95SDavid du Colombier
142*f5736e95SDavid du Colombier for (iY = 0; iY < pImg->iHeight; iY++) {
143*f5736e95SDavid du Colombier for (iX = 0; iX < pImg->iWidth; iX++) {
144*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
145*f5736e95SDavid du Colombier if (iByte == EOF) {
146*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
147*f5736e95SDavid du Colombier return;
148*f5736e95SDavid du Colombier }
149*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iByte);
150*f5736e95SDavid du Colombier }
151*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, tPadding);
152*f5736e95SDavid du Colombier }
153*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
154*f5736e95SDavid du Colombier } /* end of vDecode8bpp */
155*f5736e95SDavid du Colombier
156*f5736e95SDavid du Colombier /*
157*f5736e95SDavid du Colombier * vDecode24bpp - decode an uncompressed 24 bits per pixel image
158*f5736e95SDavid du Colombier */
159*f5736e95SDavid du Colombier static void
vDecode24bpp(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)160*f5736e95SDavid du Colombier vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
161*f5736e95SDavid du Colombier {
162*f5736e95SDavid du Colombier size_t tPadding;
163*f5736e95SDavid du Colombier int iX, iY, iBlue, iGreen, iRed, iTripleWidth;
164*f5736e95SDavid du Colombier
165*f5736e95SDavid du Colombier DBG_MSG("vDecode24bpp");
166*f5736e95SDavid du Colombier
167*f5736e95SDavid du Colombier fail(pInFile == NULL);
168*f5736e95SDavid du Colombier fail(pOutFile == NULL);
169*f5736e95SDavid du Colombier fail(pImg == NULL);
170*f5736e95SDavid du Colombier fail(!pImg->bColorImage);
171*f5736e95SDavid du Colombier
172*f5736e95SDavid du Colombier DBG_DEC(pImg->iWidth);
173*f5736e95SDavid du Colombier DBG_DEC(pImg->iHeight);
174*f5736e95SDavid du Colombier
175*f5736e95SDavid du Colombier iTripleWidth = pImg->iWidth * 3;
176*f5736e95SDavid du Colombier tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
177*f5736e95SDavid du Colombier
178*f5736e95SDavid du Colombier for (iY = 0; iY < pImg->iHeight; iY++) {
179*f5736e95SDavid du Colombier for (iX = 0; iX < pImg->iWidth; iX++) {
180*f5736e95SDavid du Colombier /* Change from BGR order to RGB order */
181*f5736e95SDavid du Colombier iBlue = iNextByte(pInFile);
182*f5736e95SDavid du Colombier if (iBlue == EOF) {
183*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
184*f5736e95SDavid du Colombier return;
185*f5736e95SDavid du Colombier }
186*f5736e95SDavid du Colombier iGreen = iNextByte(pInFile);
187*f5736e95SDavid du Colombier if (iGreen == EOF) {
188*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
189*f5736e95SDavid du Colombier return;
190*f5736e95SDavid du Colombier }
191*f5736e95SDavid du Colombier iRed = iNextByte(pInFile);
192*f5736e95SDavid du Colombier if (iRed == EOF) {
193*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
194*f5736e95SDavid du Colombier return;
195*f5736e95SDavid du Colombier }
196*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iRed);
197*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iGreen);
198*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iBlue);
199*f5736e95SDavid du Colombier }
200*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, tPadding);
201*f5736e95SDavid du Colombier }
202*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
203*f5736e95SDavid du Colombier } /* end of vDecode24bpp */
204*f5736e95SDavid du Colombier
205*f5736e95SDavid du Colombier /*
206*f5736e95SDavid du Colombier * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
207*f5736e95SDavid du Colombier */
208*f5736e95SDavid du Colombier static void
vDecodeRle4(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)209*f5736e95SDavid du Colombier vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
210*f5736e95SDavid du Colombier {
211*f5736e95SDavid du Colombier int iX, iY, iByte, iTmp, iRunLength, iRun;
212*f5736e95SDavid du Colombier BOOL bEOF, bEOL;
213*f5736e95SDavid du Colombier
214*f5736e95SDavid du Colombier DBG_MSG("vDecodeRle4");
215*f5736e95SDavid du Colombier
216*f5736e95SDavid du Colombier fail(pInFile == NULL);
217*f5736e95SDavid du Colombier fail(pOutFile == NULL);
218*f5736e95SDavid du Colombier fail(pImg == NULL);
219*f5736e95SDavid du Colombier fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
220*f5736e95SDavid du Colombier
221*f5736e95SDavid du Colombier DBG_DEC(pImg->iWidth);
222*f5736e95SDavid du Colombier DBG_DEC(pImg->iHeight);
223*f5736e95SDavid du Colombier
224*f5736e95SDavid du Colombier bEOF = FALSE;
225*f5736e95SDavid du Colombier
226*f5736e95SDavid du Colombier for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
227*f5736e95SDavid du Colombier bEOL = FALSE;
228*f5736e95SDavid du Colombier iX = 0;
229*f5736e95SDavid du Colombier while (!bEOL) {
230*f5736e95SDavid du Colombier iRunLength = iNextByte(pInFile);
231*f5736e95SDavid du Colombier if (iRunLength == EOF) {
232*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
233*f5736e95SDavid du Colombier return;
234*f5736e95SDavid du Colombier }
235*f5736e95SDavid du Colombier if (iRunLength != 0) {
236*f5736e95SDavid du Colombier /*
237*f5736e95SDavid du Colombier * Encoded packet:
238*f5736e95SDavid du Colombier * RunLength pixels, all the "same" value
239*f5736e95SDavid du Colombier */
240*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
241*f5736e95SDavid du Colombier if (iByte == EOF) {
242*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
243*f5736e95SDavid du Colombier return;
244*f5736e95SDavid du Colombier }
245*f5736e95SDavid du Colombier for (iRun = 0; iRun < iRunLength; iRun++) {
246*f5736e95SDavid du Colombier if (odd(iRun)) {
247*f5736e95SDavid du Colombier iTmp = iByte & 0x0f;
248*f5736e95SDavid du Colombier } else {
249*f5736e95SDavid du Colombier iTmp = (iByte & 0xf0) / 16;
250*f5736e95SDavid du Colombier }
251*f5736e95SDavid du Colombier if (iX < pImg->iWidth) {
252*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iTmp);
253*f5736e95SDavid du Colombier }
254*f5736e95SDavid du Colombier iX++;
255*f5736e95SDavid du Colombier }
256*f5736e95SDavid du Colombier continue;
257*f5736e95SDavid du Colombier }
258*f5736e95SDavid du Colombier /* Literal or escape */
259*f5736e95SDavid du Colombier iRunLength = iNextByte(pInFile);
260*f5736e95SDavid du Colombier if (iRunLength == EOF) {
261*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
262*f5736e95SDavid du Colombier return;
263*f5736e95SDavid du Colombier }
264*f5736e95SDavid du Colombier if (iRunLength == 0) { /* End of line escape */
265*f5736e95SDavid du Colombier bEOL = TRUE;
266*f5736e95SDavid du Colombier } else if (iRunLength == 1) { /* End of file escape */
267*f5736e95SDavid du Colombier bEOF = TRUE;
268*f5736e95SDavid du Colombier bEOL = TRUE;
269*f5736e95SDavid du Colombier } else if (iRunLength == 2) { /* Delta escape */
270*f5736e95SDavid du Colombier DBG_MSG("RLE4: encountered delta escape");
271*f5736e95SDavid du Colombier bEOF = TRUE;
272*f5736e95SDavid du Colombier bEOL = TRUE;
273*f5736e95SDavid du Colombier } else { /* Literal packet */
274*f5736e95SDavid du Colombier iByte = 0;
275*f5736e95SDavid du Colombier for (iRun = 0; iRun < iRunLength; iRun++) {
276*f5736e95SDavid du Colombier if (odd(iRun)) {
277*f5736e95SDavid du Colombier iTmp = iByte & 0x0f;
278*f5736e95SDavid du Colombier } else {
279*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
280*f5736e95SDavid du Colombier if (iByte == EOF) {
281*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
282*f5736e95SDavid du Colombier return;
283*f5736e95SDavid du Colombier }
284*f5736e95SDavid du Colombier iTmp = (iByte & 0xf0) / 16;
285*f5736e95SDavid du Colombier }
286*f5736e95SDavid du Colombier if (iX < pImg->iWidth) {
287*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iTmp);
288*f5736e95SDavid du Colombier }
289*f5736e95SDavid du Colombier iX++;
290*f5736e95SDavid du Colombier }
291*f5736e95SDavid du Colombier /* Padding if the number of bytes is odd */
292*f5736e95SDavid du Colombier if (odd((iRunLength + 1) / 2)) {
293*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, 1);
294*f5736e95SDavid du Colombier }
295*f5736e95SDavid du Colombier }
296*f5736e95SDavid du Colombier }
297*f5736e95SDavid du Colombier DBG_DEC_C(iX != pImg->iWidth, iX);
298*f5736e95SDavid du Colombier }
299*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
300*f5736e95SDavid du Colombier } /* end of vDecodeRle4 */
301*f5736e95SDavid du Colombier
302*f5736e95SDavid du Colombier /*
303*f5736e95SDavid du Colombier * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
304*f5736e95SDavid du Colombier */
305*f5736e95SDavid du Colombier static void
vDecodeRle8(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)306*f5736e95SDavid du Colombier vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
307*f5736e95SDavid du Colombier {
308*f5736e95SDavid du Colombier int iX, iY, iByte, iRunLength, iRun;
309*f5736e95SDavid du Colombier BOOL bEOF, bEOL;
310*f5736e95SDavid du Colombier
311*f5736e95SDavid du Colombier DBG_MSG("vDecodeRle8");
312*f5736e95SDavid du Colombier
313*f5736e95SDavid du Colombier fail(pInFile == NULL);
314*f5736e95SDavid du Colombier fail(pOutFile == NULL);
315*f5736e95SDavid du Colombier fail(pImg == NULL);
316*f5736e95SDavid du Colombier fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
317*f5736e95SDavid du Colombier
318*f5736e95SDavid du Colombier DBG_DEC(pImg->iWidth);
319*f5736e95SDavid du Colombier DBG_DEC(pImg->iHeight);
320*f5736e95SDavid du Colombier
321*f5736e95SDavid du Colombier bEOF = FALSE;
322*f5736e95SDavid du Colombier
323*f5736e95SDavid du Colombier for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
324*f5736e95SDavid du Colombier bEOL = FALSE;
325*f5736e95SDavid du Colombier iX = 0;
326*f5736e95SDavid du Colombier while (!bEOL) {
327*f5736e95SDavid du Colombier iRunLength = iNextByte(pInFile);
328*f5736e95SDavid du Colombier if (iRunLength == EOF) {
329*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
330*f5736e95SDavid du Colombier return;
331*f5736e95SDavid du Colombier }
332*f5736e95SDavid du Colombier if (iRunLength != 0) {
333*f5736e95SDavid du Colombier /*
334*f5736e95SDavid du Colombier * Encoded packet:
335*f5736e95SDavid du Colombier * RunLength pixels, all the same value
336*f5736e95SDavid du Colombier */
337*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
338*f5736e95SDavid du Colombier if (iByte == EOF) {
339*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
340*f5736e95SDavid du Colombier return;
341*f5736e95SDavid du Colombier }
342*f5736e95SDavid du Colombier for (iRun = 0; iRun < iRunLength; iRun++) {
343*f5736e95SDavid du Colombier if (iX < pImg->iWidth) {
344*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iByte);
345*f5736e95SDavid du Colombier }
346*f5736e95SDavid du Colombier iX++;
347*f5736e95SDavid du Colombier }
348*f5736e95SDavid du Colombier continue;
349*f5736e95SDavid du Colombier }
350*f5736e95SDavid du Colombier /* Literal or escape */
351*f5736e95SDavid du Colombier iRunLength = iNextByte(pInFile);
352*f5736e95SDavid du Colombier if (iRunLength == EOF) {
353*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
354*f5736e95SDavid du Colombier return;
355*f5736e95SDavid du Colombier }
356*f5736e95SDavid du Colombier if (iRunLength == 0) { /* End of line escape */
357*f5736e95SDavid du Colombier bEOL = TRUE;
358*f5736e95SDavid du Colombier } else if (iRunLength == 1) { /* End of file escape */
359*f5736e95SDavid du Colombier bEOF = TRUE;
360*f5736e95SDavid du Colombier bEOL = TRUE;
361*f5736e95SDavid du Colombier } else if (iRunLength == 2) { /* Delta escape */
362*f5736e95SDavid du Colombier DBG_MSG("RLE8: encountered delta escape");
363*f5736e95SDavid du Colombier bEOF = TRUE;
364*f5736e95SDavid du Colombier bEOL = TRUE;
365*f5736e95SDavid du Colombier } else { /* Literal packet */
366*f5736e95SDavid du Colombier for (iRun = 0; iRun < iRunLength; iRun++) {
367*f5736e95SDavid du Colombier iByte = iNextByte(pInFile);
368*f5736e95SDavid du Colombier if (iByte == EOF) {
369*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
370*f5736e95SDavid du Colombier return;
371*f5736e95SDavid du Colombier }
372*f5736e95SDavid du Colombier if (iX < pImg->iWidth) {
373*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, iByte);
374*f5736e95SDavid du Colombier }
375*f5736e95SDavid du Colombier iX++;
376*f5736e95SDavid du Colombier }
377*f5736e95SDavid du Colombier /* Padding if the number of bytes is odd */
378*f5736e95SDavid du Colombier if (odd(iRunLength)) {
379*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, 1);
380*f5736e95SDavid du Colombier }
381*f5736e95SDavid du Colombier }
382*f5736e95SDavid du Colombier }
383*f5736e95SDavid du Colombier DBG_DEC_C(iX != pImg->iWidth, iX);
384*f5736e95SDavid du Colombier }
385*f5736e95SDavid du Colombier vASCII85EncodeByte(pOutFile, EOF);
386*f5736e95SDavid du Colombier } /* end of vDecodeRle8 */
387*f5736e95SDavid du Colombier
388*f5736e95SDavid du Colombier /*
389*f5736e95SDavid du Colombier * vDecodeDIB - decode a dib picture
390*f5736e95SDavid du Colombier */
391*f5736e95SDavid du Colombier static void
vDecodeDIB(FILE * pInFile,FILE * pOutFile,const imagedata_type * pImg)392*f5736e95SDavid du Colombier vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
393*f5736e95SDavid du Colombier {
394*f5736e95SDavid du Colombier size_t tHeaderSize;
395*f5736e95SDavid du Colombier
396*f5736e95SDavid du Colombier fail(pInFile == NULL);
397*f5736e95SDavid du Colombier fail(pOutFile == NULL);
398*f5736e95SDavid du Colombier fail(pImg == NULL);
399*f5736e95SDavid du Colombier
400*f5736e95SDavid du Colombier /* Skip the bitmap info header */
401*f5736e95SDavid du Colombier tHeaderSize = (size_t)ulNextLong(pInFile);
402*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile, tHeaderSize - 4);
403*f5736e95SDavid du Colombier /* Skip the colortable */
404*f5736e95SDavid du Colombier if (pImg->uiBitsPerComponent <= 8) {
405*f5736e95SDavid du Colombier (void)tSkipBytes(pInFile,
406*f5736e95SDavid du Colombier (size_t)(pImg->iColorsUsed *
407*f5736e95SDavid du Colombier ((tHeaderSize > 12) ? 4 : 3)));
408*f5736e95SDavid du Colombier }
409*f5736e95SDavid du Colombier
410*f5736e95SDavid du Colombier switch (pImg->uiBitsPerComponent) {
411*f5736e95SDavid du Colombier case 1:
412*f5736e95SDavid du Colombier fail(pImg->eCompression != compression_none);
413*f5736e95SDavid du Colombier vDecode1bpp(pInFile, pOutFile, pImg);
414*f5736e95SDavid du Colombier break;
415*f5736e95SDavid du Colombier case 4:
416*f5736e95SDavid du Colombier fail(pImg->eCompression != compression_none &&
417*f5736e95SDavid du Colombier pImg->eCompression != compression_rle4);
418*f5736e95SDavid du Colombier if (pImg->eCompression == compression_rle4) {
419*f5736e95SDavid du Colombier vDecodeRle4(pInFile, pOutFile, pImg);
420*f5736e95SDavid du Colombier } else {
421*f5736e95SDavid du Colombier vDecode4bpp(pInFile, pOutFile, pImg);
422*f5736e95SDavid du Colombier }
423*f5736e95SDavid du Colombier break;
424*f5736e95SDavid du Colombier case 8:
425*f5736e95SDavid du Colombier fail(pImg->eCompression != compression_none &&
426*f5736e95SDavid du Colombier pImg->eCompression != compression_rle8);
427*f5736e95SDavid du Colombier if (pImg->eCompression == compression_rle8) {
428*f5736e95SDavid du Colombier vDecodeRle8(pInFile, pOutFile, pImg);
429*f5736e95SDavid du Colombier } else {
430*f5736e95SDavid du Colombier vDecode8bpp(pInFile, pOutFile, pImg);
431*f5736e95SDavid du Colombier }
432*f5736e95SDavid du Colombier break;
433*f5736e95SDavid du Colombier case 24:
434*f5736e95SDavid du Colombier fail(pImg->eCompression != compression_none);
435*f5736e95SDavid du Colombier vDecode24bpp(pInFile, pOutFile, pImg);
436*f5736e95SDavid du Colombier break;
437*f5736e95SDavid du Colombier default:
438*f5736e95SDavid du Colombier DBG_DEC(pImg->uiBitsPerComponent);
439*f5736e95SDavid du Colombier break;
440*f5736e95SDavid du Colombier }
441*f5736e95SDavid du Colombier } /* end of vDecodeDIB */
442*f5736e95SDavid du Colombier
443*f5736e95SDavid du Colombier #if defined(DEBUG)
444*f5736e95SDavid du Colombier /*
445*f5736e95SDavid du Colombier * vCopy2File
446*f5736e95SDavid du Colombier */
447*f5736e95SDavid du Colombier static void
vCopy2File(FILE * pInFile,ULONG ulFileOffset,size_t tPictureLen)448*f5736e95SDavid du Colombier vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
449*f5736e95SDavid du Colombier {
450*f5736e95SDavid du Colombier static int iPicCounter = 0;
451*f5736e95SDavid du Colombier FILE *pOutFile;
452*f5736e95SDavid du Colombier size_t tIndex;
453*f5736e95SDavid du Colombier int iTmp;
454*f5736e95SDavid du Colombier char szFilename[30];
455*f5736e95SDavid du Colombier
456*f5736e95SDavid du Colombier if (!bSetDataOffset(pInFile, ulFileOffset)) {
457*f5736e95SDavid du Colombier return;
458*f5736e95SDavid du Colombier }
459*f5736e95SDavid du Colombier
460*f5736e95SDavid du Colombier sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
461*f5736e95SDavid du Colombier pOutFile = fopen(szFilename, "wb");
462*f5736e95SDavid du Colombier if (pOutFile == NULL) {
463*f5736e95SDavid du Colombier return;
464*f5736e95SDavid du Colombier }
465*f5736e95SDavid du Colombier /* Turn a dib into a bmp by adding a fake 14 byte header */
466*f5736e95SDavid du Colombier (void)putc('B', pOutFile);
467*f5736e95SDavid du Colombier (void)putc('M', pOutFile);
468*f5736e95SDavid du Colombier for (iTmp = 0; iTmp < 12; iTmp++) {
469*f5736e95SDavid du Colombier if (putc(0, pOutFile) == EOF) {
470*f5736e95SDavid du Colombier break;
471*f5736e95SDavid du Colombier }
472*f5736e95SDavid du Colombier }
473*f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
474*f5736e95SDavid du Colombier iTmp = iNextByte(pInFile);
475*f5736e95SDavid du Colombier if (putc(iTmp, pOutFile) == EOF) {
476*f5736e95SDavid du Colombier break;
477*f5736e95SDavid du Colombier }
478*f5736e95SDavid du Colombier }
479*f5736e95SDavid du Colombier (void)fclose(pOutFile);
480*f5736e95SDavid du Colombier } /* end of vCopy2File */
481*f5736e95SDavid du Colombier #endif /* DEBUG */
482*f5736e95SDavid du Colombier
483*f5736e95SDavid du Colombier /*
484*f5736e95SDavid du Colombier * bTranslateDIB - translate a DIB picture
485*f5736e95SDavid du Colombier *
486*f5736e95SDavid du Colombier * This function translates a picture from dib to eps
487*f5736e95SDavid du Colombier *
488*f5736e95SDavid du Colombier * return TRUE when sucessful, otherwise FALSE
489*f5736e95SDavid du Colombier */
490*f5736e95SDavid du Colombier BOOL
bTranslateDIB(diagram_type * pDiag,FILE * pInFile,ULONG ulFileOffset,const imagedata_type * pImg)491*f5736e95SDavid du Colombier bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
492*f5736e95SDavid du Colombier ULONG ulFileOffset, const imagedata_type *pImg)
493*f5736e95SDavid du Colombier {
494*f5736e95SDavid du Colombier #if defined(DEBUG)
495*f5736e95SDavid du Colombier fail(pImg->tPosition > pImg->tLength);
496*f5736e95SDavid du Colombier vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
497*f5736e95SDavid du Colombier #endif /* DEBUG */
498*f5736e95SDavid du Colombier
499*f5736e95SDavid du Colombier /* Seek to start position of DIB data */
500*f5736e95SDavid du Colombier if (!bSetDataOffset(pInFile, ulFileOffset)) {
501*f5736e95SDavid du Colombier return FALSE;
502*f5736e95SDavid du Colombier }
503*f5736e95SDavid du Colombier
504*f5736e95SDavid du Colombier vImagePrologue(pDiag, pImg);
505*f5736e95SDavid du Colombier vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
506*f5736e95SDavid du Colombier vImageEpilogue(pDiag);
507*f5736e95SDavid du Colombier
508*f5736e95SDavid du Colombier return TRUE;
509*f5736e95SDavid du Colombier } /* end of bTranslateDIB */
510