Subversion Repositories planix.SVN

Rev

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

/*
 * 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 */