1 /*
2 * png2eps.c
3 * Copyright (C) 2000-2002 A.J. van Os; Released under GPL
4 *
5 * Description:
6 * Functions to translate png images into eps
7 *
8 */
9
10 #include <stdio.h>
11 #include <ctype.h>
12 #include "antiword.h"
13
14 #if defined(DEBUG)
15 static int iPicCounter = 0;
16 #endif /* DEBUG */
17
18
19 /*
20 * tSkipToData - skip until a IDAT chunk is found
21 *
22 * returns the length of the pixeldata or -1 in case of error
23 */
24 static size_t
tSkipToData(FILE * pFile,size_t tMaxBytes,size_t * ptSkipped)25 tSkipToData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped)
26 {
27 ULONG ulName, ulTmp;
28 size_t tDataLength, tToSkip;
29 int iCounter;
30
31 fail(pFile == NULL);
32 fail(ptSkipped == NULL);
33
34 /* Examine chunks */
35 while (*ptSkipped + 8 < tMaxBytes) {
36 tDataLength = (size_t)ulNextLongBE(pFile);
37 DBG_DEC(tDataLength);
38 *ptSkipped += 4;
39
40 ulName = 0x00;
41 for (iCounter = 0; iCounter < 4; iCounter++) {
42 ulTmp = (ULONG)iNextByte(pFile);
43 if (!isalpha((int)ulTmp)) {
44 DBG_HEX(ulTmp);
45 return (size_t)-1;
46 }
47 ulName <<= 8;
48 ulName |= ulTmp;
49 }
50 DBG_HEX(ulName);
51 *ptSkipped += 4;
52
53 if (ulName == PNG_CN_IEND) {
54 break;
55 }
56 if (ulName == PNG_CN_IDAT) {
57 return tDataLength;
58 }
59
60 tToSkip = tDataLength + 4;
61 if (tToSkip >= tMaxBytes - *ptSkipped) {
62 DBG_DEC(tToSkip);
63 DBG_DEC(tMaxBytes - *ptSkipped);
64 return (size_t)-1;
65 }
66 (void)tSkipBytes(pFile, tToSkip);
67 *ptSkipped += tToSkip;
68 }
69
70 return (size_t)-1;
71 } /* end of iSkipToData */
72
73 /*
74 * iFindFirstPixelData - find the first pixeldata if a PNG image
75 *
76 * returns the length of the pixeldata or -1 in case of error
77 */
78 static size_t
tFindFirstPixelData(FILE * pFile,size_t tMaxBytes,size_t * ptSkipped)79 tFindFirstPixelData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped)
80 {
81 fail(pFile == NULL);
82 fail(tMaxBytes == 0);
83 fail(ptSkipped == NULL);
84
85 if (tMaxBytes < 8) {
86 DBG_DEC(tMaxBytes);
87 return (size_t)-1;
88 }
89
90 /* Skip over the PNG signature */
91 (void)tSkipBytes(pFile, 8);
92 *ptSkipped = 8;
93
94 return tSkipToData(pFile, tMaxBytes, ptSkipped);
95 } /* end of iFindFirstPixelData */
96
97 /*
98 * tFindNextPixelData - find the next pixeldata if a PNG image
99 *
100 * returns the length of the pixeldata or -1 in case of error
101 */
102 static size_t
tFindNextPixelData(FILE * pFile,size_t tMaxBytes,size_t * ptSkipped)103 tFindNextPixelData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped)
104 {
105 fail(pFile == NULL);
106 fail(tMaxBytes == 0);
107 fail(ptSkipped == NULL);
108
109 if (tMaxBytes < 4) {
110 DBG_DEC(tMaxBytes);
111 return (size_t)-1;
112 }
113
114 /* Skip over the crc */
115 (void)tSkipBytes(pFile, 4);
116 *ptSkipped = 4;
117
118 return tSkipToData(pFile, tMaxBytes, ptSkipped);
119 } /* end of tFindNextPixelData */
120
121 #if defined(DEBUG)
122 /*
123 * vCopy2File
124 */
125 static void
vCopy2File(FILE * pFile,ULONG ulFileOffset,size_t tPictureLen)126 vCopy2File(FILE *pFile, ULONG ulFileOffset, size_t tPictureLen)
127 {
128 FILE *pOutFile;
129 size_t tIndex;
130 int iTmp;
131 char szFilename[30];
132
133 if (!bSetDataOffset(pFile, ulFileOffset)) {
134 return;
135 }
136
137 sprintf(szFilename, "/tmp/pic/pic%04d.png", ++iPicCounter);
138 pOutFile = fopen(szFilename, "wb");
139 if (pOutFile == NULL) {
140 return;
141 }
142 for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
143 iTmp = iNextByte(pFile);
144 if (putc(iTmp, pOutFile) == EOF) {
145 break;
146 }
147 }
148 (void)fclose(pOutFile);
149 } /* end of vCopy2File */
150 #endif /* DEBUG */
151
152 /*
153 * bTranslatePNG - translate a PNG image
154 *
155 * This function translates an image from png to eps
156 *
157 * return TRUE when sucessful, otherwise FALSE
158 */
159 BOOL
bTranslatePNG(diagram_type * pDiag,FILE * pFile,ULONG ulFileOffset,size_t tPictureLen,const imagedata_type * pImg)160 bTranslatePNG(diagram_type *pDiag, FILE *pFile,
161 ULONG ulFileOffset, size_t tPictureLen, const imagedata_type *pImg)
162 {
163 size_t tMaxBytes, tDataLength, tSkipped;
164
165 #if defined(DEBUG)
166 vCopy2File(pFile, ulFileOffset, tPictureLen);
167 #endif /* DEBUG */
168
169 /* Seek to start position of PNG data */
170 if (!bSetDataOffset(pFile, ulFileOffset)) {
171 return FALSE;
172 }
173
174 tMaxBytes = tPictureLen;
175 tDataLength = tFindFirstPixelData(pFile, tMaxBytes, &tSkipped);
176 if (tDataLength == (size_t)-1) {
177 return FALSE;
178 }
179
180 vImagePrologue(pDiag, pImg);
181 do {
182 tMaxBytes -= tSkipped;
183 vASCII85EncodeArray(pFile, pDiag->pOutFile, tDataLength);
184 tMaxBytes -= tDataLength;
185 tDataLength = tFindNextPixelData(pFile, tMaxBytes, &tSkipped);
186 } while (tDataLength != (size_t)-1);
187 vASCII85EncodeByte(pDiag->pOutFile, EOF);
188 vImageEpilogue(pDiag);
189
190 return TRUE;
191 } /* end of bTranslatePNG */
192