diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/antiword/dib2eps.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/antiword/dib2eps.c')
-rwxr-xr-x | sys/src/cmd/aux/antiword/dib2eps.c | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/antiword/dib2eps.c b/sys/src/cmd/aux/antiword/dib2eps.c new file mode 100755 index 000000000..2673d38e0 --- /dev/null +++ b/sys/src/cmd/aux/antiword/dib2eps.c @@ -0,0 +1,509 @@ +/* + * 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 */ |