Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * dib2eps.c
3
 * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
4
 *
5
 * Description:
6
 * Functions to translate dib pictures into eps
7
 *
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.
14
 */
15
 
16
#include <stdio.h>
17
#include "antiword.h"
18
 
19
 
20
/*
21
 * vDecode1bpp - decode an uncompressed 1 bit per pixel image
22
 */
23
static void
24
vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
25
{
26
	size_t	tPadding;
27
	int	iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
28
 
29
	DBG_MSG("vDecode1bpp");
30
 
31
	fail(pOutFile == NULL);
32
	fail(pImg == NULL);
33
	fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
34
 
35
	DBG_DEC(pImg->iWidth);
36
	DBG_DEC(pImg->iHeight);
37
 
38
	iEighthWidth = (pImg->iWidth + 7) / 8;
39
	tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
40
 
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;
47
			}
48
			if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
49
				iUse = pImg->iWidth % 8;
50
			} else {
51
				iUse = 8;
52
			}
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;
64
				}
65
				vASCII85EncodeByte(pOutFile, iTmp);
66
			}
67
		}
68
		(void)tSkipBytes(pInFile, tPadding);
69
	}
70
	vASCII85EncodeByte(pOutFile, EOF);
71
} /* end of vDecode1bpp */
72
 
73
/*
74
 * vDecode4bpp - decode an uncompressed 4 bits per pixel image
75
 */
76
static void
77
vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
78
{
79
	size_t	tPadding;
80
	int	iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
81
 
82
	DBG_MSG("vDecode4bpp");
83
 
84
	fail(pInFile == NULL);
85
	fail(pOutFile == NULL);
86
	fail(pImg == NULL);
87
	fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
88
 
89
	DBG_DEC(pImg->iWidth);
90
	DBG_DEC(pImg->iHeight);
91
 
92
	iHalfWidth = (pImg->iWidth + 1) / 2;
93
	tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
94
 
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;
101
			}
102
			if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
103
				iUse = 1;
104
			} else {
105
				iUse = 2;
106
			}
107
			for (iN = 0; iN < iUse; iN++) {
108
				if (odd(iN)) {
109
					iTmp = iByte & 0x0f;
110
				} else {
111
					iTmp = (iByte & 0xf0) / 16;
112
				}
113
				vASCII85EncodeByte(pOutFile, iTmp);
114
			}
115
		}
116
		(void)tSkipBytes(pInFile, tPadding);
117
	}
118
	vASCII85EncodeByte(pOutFile, EOF);
119
} /* end of vDecode4bpp */
120
 
121
/*
122
 * vDecode8bpp - decode an uncompressed 8 bits per pixel image
123
 */
124
static void
125
vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
126
{
127
	size_t	tPadding;
128
	int	iX, iY, iByte;
129
 
130
	DBG_MSG("vDecode8bpp");
131
 
132
	fail(pInFile == NULL);
133
	fail(pOutFile == NULL);
134
	fail(pImg == NULL);
135
	fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
136
 
137
	DBG_DEC(pImg->iWidth);
138
	DBG_DEC(pImg->iHeight);
139
 
140
	tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
141
 
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;
148
			}
149
			vASCII85EncodeByte(pOutFile, iByte);
150
		}
151
		(void)tSkipBytes(pInFile, tPadding);
152
	}
153
	vASCII85EncodeByte(pOutFile, EOF);
154
} /* end of vDecode8bpp */
155
 
156
/*
157
 * vDecode24bpp - decode an uncompressed 24 bits per pixel image
158
 */
159
static void
160
vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
161
{
162
	size_t	tPadding;
163
	int	iX, iY, iBlue, iGreen, iRed, iTripleWidth;
164
 
165
	DBG_MSG("vDecode24bpp");
166
 
167
	fail(pInFile == NULL);
168
	fail(pOutFile == NULL);
169
	fail(pImg == NULL);
170
	fail(!pImg->bColorImage);
171
 
172
	DBG_DEC(pImg->iWidth);
173
	DBG_DEC(pImg->iHeight);
174
 
175
	iTripleWidth = pImg->iWidth * 3;
176
	tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
177
 
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;
185
			}
186
			iGreen = iNextByte(pInFile);
187
			if (iGreen == EOF) {
188
				vASCII85EncodeByte(pOutFile, EOF);
189
				return;
190
			}
191
			iRed = iNextByte(pInFile);
192
			if (iRed == EOF) {
193
				vASCII85EncodeByte(pOutFile, EOF);
194
				return;
195
			}
196
			vASCII85EncodeByte(pOutFile, iRed);
197
			vASCII85EncodeByte(pOutFile, iGreen);
198
			vASCII85EncodeByte(pOutFile, iBlue);
199
		}
200
		(void)tSkipBytes(pInFile, tPadding);
201
	}
202
	vASCII85EncodeByte(pOutFile, EOF);
203
} /* end of vDecode24bpp */
204
 
205
/*
206
 * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
207
 */
208
static void
209
vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
210
{
211
	int	iX, iY, iByte, iTmp, iRunLength, iRun;
212
	BOOL	bEOF, bEOL;
213
 
214
	DBG_MSG("vDecodeRle4");
215
 
216
	fail(pInFile == NULL);
217
	fail(pOutFile == NULL);
218
	fail(pImg == NULL);
219
	fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
220
 
221
	DBG_DEC(pImg->iWidth);
222
	DBG_DEC(pImg->iHeight);
223
 
224
	bEOF = FALSE;
225
 
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;
234
			}
235
			if (iRunLength != 0) {
236
				/*
237
				 * Encoded packet:
238
				 * RunLength pixels, all the "same" value
239
				 */
240
				iByte = iNextByte(pInFile);
241
				if (iByte == EOF) {
242
					vASCII85EncodeByte(pOutFile, EOF);
243
					return;
244
				}
245
				for (iRun = 0; iRun < iRunLength; iRun++) {
246
					if (odd(iRun)) {
247
						iTmp = iByte & 0x0f;
248
					} else {
249
						iTmp = (iByte & 0xf0) / 16;
250
					}
251
					if (iX < pImg->iWidth) {
252
						vASCII85EncodeByte(pOutFile, iTmp);
253
					}
254
					iX++;
255
				}
256
				continue;
257
			}
258
			/* Literal or escape */
259
			iRunLength = iNextByte(pInFile);
260
			if (iRunLength == EOF) {
261
				vASCII85EncodeByte(pOutFile, EOF);
262
				return;
263
			}
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;
283
						}
284
						iTmp = (iByte & 0xf0) / 16;
285
					}
286
					if (iX < pImg->iWidth) {
287
						vASCII85EncodeByte(pOutFile, iTmp);
288
					}
289
					iX++;
290
				}
291
				/* Padding if the number of bytes is odd */
292
				if (odd((iRunLength + 1) / 2)) {
293
					(void)tSkipBytes(pInFile, 1);
294
				}
295
			}
296
		}
297
		DBG_DEC_C(iX != pImg->iWidth, iX);
298
	}
299
	vASCII85EncodeByte(pOutFile, EOF);
300
} /* end of vDecodeRle4 */
301
 
302
/*
303
 * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
304
 */
305
static void
306
vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
307
{
308
	int	iX, iY, iByte, iRunLength, iRun;
309
	BOOL	bEOF, bEOL;
310
 
311
	DBG_MSG("vDecodeRle8");
312
 
313
	fail(pInFile == NULL);
314
	fail(pOutFile == NULL);
315
	fail(pImg == NULL);
316
	fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
317
 
318
	DBG_DEC(pImg->iWidth);
319
	DBG_DEC(pImg->iHeight);
320
 
321
	bEOF = FALSE;
322
 
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;
331
			}
332
			if (iRunLength != 0) {
333
				/*
334
				 * Encoded packet:
335
				 * RunLength pixels, all the same value
336
				 */
337
				iByte = iNextByte(pInFile);
338
				if (iByte == EOF) {
339
					vASCII85EncodeByte(pOutFile, EOF);
340
					return;
341
				}
342
				for (iRun = 0; iRun < iRunLength; iRun++) {
343
					if (iX < pImg->iWidth) {
344
						vASCII85EncodeByte(pOutFile, iByte);
345
					}
346
					iX++;
347
				}
348
				continue;
349
			}
350
			/* Literal or escape */
351
			iRunLength = iNextByte(pInFile);
352
			if (iRunLength == EOF) {
353
				vASCII85EncodeByte(pOutFile, EOF);
354
				return;
355
			}
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;
371
					}
372
					if (iX < pImg->iWidth) {
373
						vASCII85EncodeByte(pOutFile, iByte);
374
					}
375
					iX++;
376
				}
377
				/* Padding if the number of bytes is odd */
378
				if (odd(iRunLength)) {
379
					(void)tSkipBytes(pInFile, 1);
380
				}
381
			}
382
		}
383
		DBG_DEC_C(iX != pImg->iWidth, iX);
384
	}
385
	vASCII85EncodeByte(pOutFile, EOF);
386
} /* end of vDecodeRle8 */
387
 
388
/*
389
 * vDecodeDIB - decode a dib picture
390
 */
391
static void
392
vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
393
{
394
	size_t	tHeaderSize;
395
 
396
	fail(pInFile == NULL);
397
	fail(pOutFile == NULL);
398
	fail(pImg == NULL);
399
 
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)));
408
	}
409
 
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);
422
		}
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);
431
		}
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;
440
	}
441
} /* end of vDecodeDIB */
442
 
443
#if defined(DEBUG)
444
/*
445
 * vCopy2File
446
 */
447
static void
448
vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
449
{
450
	static int	iPicCounter = 0;
451
	FILE	*pOutFile;
452
	size_t	tIndex;
453
	int	iTmp;
454
	char	szFilename[30];
455
 
456
	if (!bSetDataOffset(pInFile, ulFileOffset)) {
457
		return;
458
	}
459
 
460
	sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
461
	pOutFile = fopen(szFilename, "wb");
462
	if (pOutFile == NULL) {
463
		return;
464
	}
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;
471
		}
472
	}
473
	for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
474
		iTmp = iNextByte(pInFile);
475
		if (putc(iTmp, pOutFile) == EOF) {
476
			break;
477
		}
478
	}
479
	(void)fclose(pOutFile);
480
} /* end of vCopy2File */
481
#endif /* DEBUG */
482
 
483
/*
484
 * bTranslateDIB - translate a DIB picture
485
 *
486
 * This function translates a picture from dib to eps
487
 *
488
 * return TRUE when sucessful, otherwise FALSE
489
 */
490
BOOL
491
bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
492
		ULONG ulFileOffset, const imagedata_type *pImg)
493
{
494
#if defined(DEBUG)
495
	fail(pImg->tPosition > pImg->tLength);
496
	vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
497
#endif /* DEBUG */
498
 
499
	/* Seek to start position of DIB data */
500
	if (!bSetDataOffset(pInFile, ulFileOffset)) {
501
		return FALSE;
502
	}
503
 
504
	vImagePrologue(pDiag, pImg);
505
	vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
506
	vImageEpilogue(pDiag);
507
 
508
	return TRUE;
509
} /* end of bTranslateDIB */