123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509 |
- /*
- * dib2eps.c
- * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
- *
- * Description:
- * Functions to translate dib pictures into eps
- *
- *================================================================
- * This part of the software is based on:
- * The Windows Bitmap Decoder Class part of paintlib
- * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow
- *================================================================
- * The credit should go to him, but all the bugs are mine.
- */
- #include <stdio.h>
- #include "antiword.h"
- /*
- * vDecode1bpp - decode an uncompressed 1 bit per pixel image
- */
- static void
- vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- size_t tPadding;
- int iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
- DBG_MSG("vDecode1bpp");
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
- DBG_DEC(pImg->iWidth);
- DBG_DEC(pImg->iHeight);
- iEighthWidth = (pImg->iWidth + 7) / 8;
- tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
- for (iY = 0; iY < pImg->iHeight; iY++) {
- for (iX = 0; iX < iEighthWidth; iX++) {
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
- iUse = pImg->iWidth % 8;
- } else {
- iUse = 8;
- }
- for (iN = 0; iN < iUse; iN++) {
- switch (iN) {
- case 0: iTmp = (iByte & 0x80) / 128; break;
- case 1: iTmp = (iByte & 0x40) / 64; break;
- case 2: iTmp = (iByte & 0x20) / 32; break;
- case 3: iTmp = (iByte & 0x10) / 16; break;
- case 4: iTmp = (iByte & 0x08) / 8; break;
- case 5: iTmp = (iByte & 0x04) / 4; break;
- case 6: iTmp = (iByte & 0x02) / 2; break;
- case 7: iTmp = (iByte & 0x01); break;
- default: iTmp = 0; break;
- }
- vASCII85EncodeByte(pOutFile, iTmp);
- }
- }
- (void)tSkipBytes(pInFile, tPadding);
- }
- vASCII85EncodeByte(pOutFile, EOF);
- } /* end of vDecode1bpp */
- /*
- * vDecode4bpp - decode an uncompressed 4 bits per pixel image
- */
- static void
- vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- size_t tPadding;
- int iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
- DBG_MSG("vDecode4bpp");
- fail(pInFile == NULL);
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
- DBG_DEC(pImg->iWidth);
- DBG_DEC(pImg->iHeight);
- iHalfWidth = (pImg->iWidth + 1) / 2;
- tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
- for (iY = 0; iY < pImg->iHeight; iY++) {
- for (iX = 0; iX < iHalfWidth; iX++) {
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
- iUse = 1;
- } else {
- iUse = 2;
- }
- for (iN = 0; iN < iUse; iN++) {
- if (odd(iN)) {
- iTmp = iByte & 0x0f;
- } else {
- iTmp = (iByte & 0xf0) / 16;
- }
- vASCII85EncodeByte(pOutFile, iTmp);
- }
- }
- (void)tSkipBytes(pInFile, tPadding);
- }
- vASCII85EncodeByte(pOutFile, EOF);
- } /* end of vDecode4bpp */
- /*
- * vDecode8bpp - decode an uncompressed 8 bits per pixel image
- */
- static void
- vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- size_t tPadding;
- int iX, iY, iByte;
- DBG_MSG("vDecode8bpp");
- fail(pInFile == NULL);
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
- DBG_DEC(pImg->iWidth);
- DBG_DEC(pImg->iHeight);
- tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
- for (iY = 0; iY < pImg->iHeight; iY++) {
- for (iX = 0; iX < pImg->iWidth; iX++) {
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- vASCII85EncodeByte(pOutFile, iByte);
- }
- (void)tSkipBytes(pInFile, tPadding);
- }
- vASCII85EncodeByte(pOutFile, EOF);
- } /* end of vDecode8bpp */
- /*
- * vDecode24bpp - decode an uncompressed 24 bits per pixel image
- */
- static void
- vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- size_t tPadding;
- int iX, iY, iBlue, iGreen, iRed, iTripleWidth;
- DBG_MSG("vDecode24bpp");
- fail(pInFile == NULL);
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- fail(!pImg->bColorImage);
- DBG_DEC(pImg->iWidth);
- DBG_DEC(pImg->iHeight);
- iTripleWidth = pImg->iWidth * 3;
- tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
- for (iY = 0; iY < pImg->iHeight; iY++) {
- for (iX = 0; iX < pImg->iWidth; iX++) {
- /* Change from BGR order to RGB order */
- iBlue = iNextByte(pInFile);
- if (iBlue == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- iGreen = iNextByte(pInFile);
- if (iGreen == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- iRed = iNextByte(pInFile);
- if (iRed == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- vASCII85EncodeByte(pOutFile, iRed);
- vASCII85EncodeByte(pOutFile, iGreen);
- vASCII85EncodeByte(pOutFile, iBlue);
- }
- (void)tSkipBytes(pInFile, tPadding);
- }
- vASCII85EncodeByte(pOutFile, EOF);
- } /* end of vDecode24bpp */
- /*
- * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
- */
- static void
- vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- int iX, iY, iByte, iTmp, iRunLength, iRun;
- BOOL bEOF, bEOL;
- DBG_MSG("vDecodeRle4");
- fail(pInFile == NULL);
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
- DBG_DEC(pImg->iWidth);
- DBG_DEC(pImg->iHeight);
- bEOF = FALSE;
- for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
- bEOL = FALSE;
- iX = 0;
- while (!bEOL) {
- iRunLength = iNextByte(pInFile);
- if (iRunLength == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iRunLength != 0) {
- /*
- * Encoded packet:
- * RunLength pixels, all the "same" value
- */
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- for (iRun = 0; iRun < iRunLength; iRun++) {
- if (odd(iRun)) {
- iTmp = iByte & 0x0f;
- } else {
- iTmp = (iByte & 0xf0) / 16;
- }
- if (iX < pImg->iWidth) {
- vASCII85EncodeByte(pOutFile, iTmp);
- }
- iX++;
- }
- continue;
- }
- /* Literal or escape */
- iRunLength = iNextByte(pInFile);
- if (iRunLength == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iRunLength == 0) { /* End of line escape */
- bEOL = TRUE;
- } else if (iRunLength == 1) { /* End of file escape */
- bEOF = TRUE;
- bEOL = TRUE;
- } else if (iRunLength == 2) { /* Delta escape */
- DBG_MSG("RLE4: encountered delta escape");
- bEOF = TRUE;
- bEOL = TRUE;
- } else { /* Literal packet */
- iByte = 0;
- for (iRun = 0; iRun < iRunLength; iRun++) {
- if (odd(iRun)) {
- iTmp = iByte & 0x0f;
- } else {
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- iTmp = (iByte & 0xf0) / 16;
- }
- if (iX < pImg->iWidth) {
- vASCII85EncodeByte(pOutFile, iTmp);
- }
- iX++;
- }
- /* Padding if the number of bytes is odd */
- if (odd((iRunLength + 1) / 2)) {
- (void)tSkipBytes(pInFile, 1);
- }
- }
- }
- DBG_DEC_C(iX != pImg->iWidth, iX);
- }
- vASCII85EncodeByte(pOutFile, EOF);
- } /* end of vDecodeRle4 */
- /*
- * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
- */
- static void
- vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- int iX, iY, iByte, iRunLength, iRun;
- BOOL bEOF, bEOL;
- DBG_MSG("vDecodeRle8");
- fail(pInFile == NULL);
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
- DBG_DEC(pImg->iWidth);
- DBG_DEC(pImg->iHeight);
- bEOF = FALSE;
- for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
- bEOL = FALSE;
- iX = 0;
- while (!bEOL) {
- iRunLength = iNextByte(pInFile);
- if (iRunLength == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iRunLength != 0) {
- /*
- * Encoded packet:
- * RunLength pixels, all the same value
- */
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- for (iRun = 0; iRun < iRunLength; iRun++) {
- if (iX < pImg->iWidth) {
- vASCII85EncodeByte(pOutFile, iByte);
- }
- iX++;
- }
- continue;
- }
- /* Literal or escape */
- iRunLength = iNextByte(pInFile);
- if (iRunLength == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iRunLength == 0) { /* End of line escape */
- bEOL = TRUE;
- } else if (iRunLength == 1) { /* End of file escape */
- bEOF = TRUE;
- bEOL = TRUE;
- } else if (iRunLength == 2) { /* Delta escape */
- DBG_MSG("RLE8: encountered delta escape");
- bEOF = TRUE;
- bEOL = TRUE;
- } else { /* Literal packet */
- for (iRun = 0; iRun < iRunLength; iRun++) {
- iByte = iNextByte(pInFile);
- if (iByte == EOF) {
- vASCII85EncodeByte(pOutFile, EOF);
- return;
- }
- if (iX < pImg->iWidth) {
- vASCII85EncodeByte(pOutFile, iByte);
- }
- iX++;
- }
- /* Padding if the number of bytes is odd */
- if (odd(iRunLength)) {
- (void)tSkipBytes(pInFile, 1);
- }
- }
- }
- DBG_DEC_C(iX != pImg->iWidth, iX);
- }
- vASCII85EncodeByte(pOutFile, EOF);
- } /* end of vDecodeRle8 */
- /*
- * vDecodeDIB - decode a dib picture
- */
- static void
- vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
- {
- size_t tHeaderSize;
- fail(pInFile == NULL);
- fail(pOutFile == NULL);
- fail(pImg == NULL);
- /* Skip the bitmap info header */
- tHeaderSize = (size_t)ulNextLong(pInFile);
- (void)tSkipBytes(pInFile, tHeaderSize - 4);
- /* Skip the colortable */
- if (pImg->uiBitsPerComponent <= 8) {
- (void)tSkipBytes(pInFile,
- (size_t)(pImg->iColorsUsed *
- ((tHeaderSize > 12) ? 4 : 3)));
- }
- switch (pImg->uiBitsPerComponent) {
- case 1:
- fail(pImg->eCompression != compression_none);
- vDecode1bpp(pInFile, pOutFile, pImg);
- break;
- case 4:
- fail(pImg->eCompression != compression_none &&
- pImg->eCompression != compression_rle4);
- if (pImg->eCompression == compression_rle4) {
- vDecodeRle4(pInFile, pOutFile, pImg);
- } else {
- vDecode4bpp(pInFile, pOutFile, pImg);
- }
- break;
- case 8:
- fail(pImg->eCompression != compression_none &&
- pImg->eCompression != compression_rle8);
- if (pImg->eCompression == compression_rle8) {
- vDecodeRle8(pInFile, pOutFile, pImg);
- } else {
- vDecode8bpp(pInFile, pOutFile, pImg);
- }
- break;
- case 24:
- fail(pImg->eCompression != compression_none);
- vDecode24bpp(pInFile, pOutFile, pImg);
- break;
- default:
- DBG_DEC(pImg->uiBitsPerComponent);
- break;
- }
- } /* end of vDecodeDIB */
- #if defined(DEBUG)
- /*
- * vCopy2File
- */
- static void
- vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
- {
- static int iPicCounter = 0;
- FILE *pOutFile;
- size_t tIndex;
- int iTmp;
- char szFilename[30];
- if (!bSetDataOffset(pInFile, ulFileOffset)) {
- return;
- }
- sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
- pOutFile = fopen(szFilename, "wb");
- if (pOutFile == NULL) {
- return;
- }
- /* Turn a dib into a bmp by adding a fake 14 byte header */
- (void)putc('B', pOutFile);
- (void)putc('M', pOutFile);
- for (iTmp = 0; iTmp < 12; iTmp++) {
- if (putc(0, pOutFile) == EOF) {
- break;
- }
- }
- for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
- iTmp = iNextByte(pInFile);
- if (putc(iTmp, pOutFile) == EOF) {
- break;
- }
- }
- (void)fclose(pOutFile);
- } /* end of vCopy2File */
- #endif /* DEBUG */
- /*
- * bTranslateDIB - translate a DIB picture
- *
- * This function translates a picture from dib to eps
- *
- * return TRUE when sucessful, otherwise FALSE
- */
- BOOL
- bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
- ULONG ulFileOffset, const imagedata_type *pImg)
- {
- #if defined(DEBUG)
- fail(pImg->tPosition > pImg->tLength);
- vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
- #endif /* DEBUG */
- /* Seek to start position of DIB data */
- if (!bSetDataOffset(pInFile, ulFileOffset)) {
- return FALSE;
- }
- vImagePrologue(pDiag, pImg);
- vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
- vImageEpilogue(pDiag);
- return TRUE;
- } /* end of bTranslateDIB */
|