mirror of
https://github.com/simon987/antiword.git
synced 2025-04-10 13:06:41 +00:00
192 lines
3.9 KiB
C
192 lines
3.9 KiB
C
/*
|
|
* png2eps.c
|
|
* Copyright (C) 2000-2002 A.J. van Os; Released under GPL
|
|
*
|
|
* Description:
|
|
* Functions to translate png images into eps
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#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 */
|