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