/* * png2eps.c * Copyright (C) 2000-2002 A.J. van Os; Released under GPL * * Description: * Functions to translate png images into eps * */ #include #include #include "antiword.h" #if defined(DEBUG) static int iPicCounter = 0; #endif /* DEBUG */ /* * tSkipToData - skip until a IDAT chunk is found * * returns the length of the pixeldata or -1 in case of error */ static size_t tSkipToData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped) { ULONG ulName, ulTmp; size_t tDataLength, tToSkip; int iCounter; fail(pFile == NULL); fail(ptSkipped == NULL); /* Examine chunks */ while (*ptSkipped + 8 < tMaxBytes) { tDataLength = (size_t)ulNextLongBE(pFile); DBG_DEC(tDataLength); *ptSkipped += 4; ulName = 0x00; for (iCounter = 0; iCounter < 4; iCounter++) { ulTmp = (ULONG)iNextByte(pFile); if (!isalpha((int)ulTmp)) { DBG_HEX(ulTmp); return (size_t)-1; } ulName <<= 8; ulName |= ulTmp; } DBG_HEX(ulName); *ptSkipped += 4; if (ulName == PNG_CN_IEND) { break; } if (ulName == PNG_CN_IDAT) { return tDataLength; } tToSkip = tDataLength + 4; if (tToSkip >= tMaxBytes - *ptSkipped) { DBG_DEC(tToSkip); DBG_DEC(tMaxBytes - *ptSkipped); return (size_t)-1; } (void)tSkipBytes(pFile, tToSkip); *ptSkipped += tToSkip; } return (size_t)-1; } /* end of iSkipToData */ /* * iFindFirstPixelData - find the first pixeldata if a PNG image * * returns the length of the pixeldata or -1 in case of error */ static size_t tFindFirstPixelData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped) { fail(pFile == NULL); fail(tMaxBytes == 0); fail(ptSkipped == NULL); if (tMaxBytes < 8) { DBG_DEC(tMaxBytes); return (size_t)-1; } /* Skip over the PNG signature */ (void)tSkipBytes(pFile, 8); *ptSkipped = 8; return tSkipToData(pFile, tMaxBytes, ptSkipped); } /* end of iFindFirstPixelData */ /* * tFindNextPixelData - find the next pixeldata if a PNG image * * returns the length of the pixeldata or -1 in case of error */ static size_t tFindNextPixelData(FILE *pFile, size_t tMaxBytes, size_t *ptSkipped) { fail(pFile == NULL); fail(tMaxBytes == 0); fail(ptSkipped == NULL); if (tMaxBytes < 4) { DBG_DEC(tMaxBytes); return (size_t)-1; } /* Skip over the crc */ (void)tSkipBytes(pFile, 4); *ptSkipped = 4; return tSkipToData(pFile, tMaxBytes, ptSkipped); } /* end of tFindNextPixelData */ #if defined(DEBUG) /* * vCopy2File */ static void vCopy2File(FILE *pFile, ULONG ulFileOffset, size_t tPictureLen) { FILE *pOutFile; size_t tIndex; int iTmp; char szFilename[30]; if (!bSetDataOffset(pFile, ulFileOffset)) { return; } sprintf(szFilename, "/tmp/pic/pic%04d.png", ++iPicCounter); pOutFile = fopen(szFilename, "wb"); if (pOutFile == NULL) { return; } for (tIndex = 0; tIndex < tPictureLen; tIndex++) { iTmp = iNextByte(pFile); if (putc(iTmp, pOutFile) == EOF) { break; } } (void)fclose(pOutFile); } /* end of vCopy2File */ #endif /* DEBUG */ /* * bTranslatePNG - translate a PNG image * * This function translates an image from png to eps * * return TRUE when sucessful, otherwise FALSE */ BOOL bTranslatePNG(diagram_type *pDiag, FILE *pFile, ULONG ulFileOffset, size_t tPictureLen, const imagedata_type *pImg) { size_t tMaxBytes, tDataLength, tSkipped; #if defined(DEBUG) vCopy2File(pFile, ulFileOffset, tPictureLen); #endif /* DEBUG */ /* Seek to start position of PNG data */ if (!bSetDataOffset(pFile, ulFileOffset)) { return FALSE; } tMaxBytes = tPictureLen; tDataLength = tFindFirstPixelData(pFile, tMaxBytes, &tSkipped); if (tDataLength == (size_t)-1) { return FALSE; } vImagePrologue(pDiag, pImg); do { tMaxBytes -= tSkipped; vASCII85EncodeArray(pFile, pDiag->pOutFile, tDataLength); tMaxBytes -= tDataLength; tDataLength = tFindNextPixelData(pFile, tMaxBytes, &tSkipped); } while (tDataLength != (size_t)-1); vASCII85EncodeByte(pDiag->pOutFile, EOF); vImageEpilogue(pDiag); return TRUE; } /* end of bTranslatePNG */