xref: /plan9/sys/src/cmd/aux/antiword/dib2eps.c (revision f5736e95f14e1485b3a0291fa82d86cca323ab61)
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