home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / dib2eps.c < prev    next >
C/C++ Source or Header  |  2001-02-05  |  12KB  |  508 lines

  1. /*
  2.  * dib2eps.c
  3.  * Copyright (C) 2000,2001 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Functions to translate dib pictures into eps
  7.  *
  8.  *================================================================
  9.  * This part of the software is based on:
  10.  * The Windows Bitmap Decoder Class part of paintlib
  11.  * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow
  12.  *================================================================
  13.  * The credit should go to him, but all the bugs are mine.
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include "antiword.h"
  18.  
  19.  
  20. /*
  21.  * vDecode1bpp - decode an uncompressed 1 bit per pixel image
  22.  */
  23. static void
  24. vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  25. {
  26.     size_t    tPadding;
  27.     int    iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
  28.  
  29.     DBG_MSG("vDecode1bpp");
  30.  
  31.     fail(pOutFile == NULL);
  32.     fail(pImg == NULL);
  33.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
  34.  
  35.     DBG_DEC(pImg->iWidth);
  36.     DBG_DEC(pImg->iHeight);
  37.  
  38.     iEighthWidth = (pImg->iWidth + 7) / 8;
  39.     tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
  40.  
  41.     for (iY = 0; iY < pImg->iHeight; iY++) {
  42.         for (iX = 0; iX < iEighthWidth; iX++) {
  43.             iByte = iNextByte(pInFile);
  44.             if (iByte == EOF) {
  45.                 vASCII85EncodeByte(pOutFile, EOF);
  46.                 return;
  47.             }
  48.             if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
  49.                 iUse = pImg->iWidth % 8;
  50.             } else {
  51.                 iUse = 8;
  52.             }
  53.             for (iN = 0; iN < iUse; iN++) {
  54.                 switch (iN) {
  55.                 case 0: iTmp = (iByte & 0x80) / 128; break;
  56.                 case 1: iTmp = (iByte & 0x40) / 64; break;
  57.                 case 2: iTmp = (iByte & 0x20) / 32; break;
  58.                 case 3: iTmp = (iByte & 0x10) / 16; break;
  59.                 case 4: iTmp = (iByte & 0x08) / 8; break;
  60.                 case 5: iTmp = (iByte & 0x04) / 4; break;
  61.                 case 6: iTmp = (iByte & 0x02) / 2; break;
  62.                 case 7: iTmp = (iByte & 0x01); break;
  63.                 default: iTmp = 0; break;
  64.                 }
  65.                 vASCII85EncodeByte(pOutFile, iTmp);
  66.             }
  67.         }
  68.         (void)iSkipBytes(pInFile, tPadding);
  69.     }
  70.     vASCII85EncodeByte(pOutFile, EOF);
  71. } /* end of vDecode1bpp */
  72.  
  73. /*
  74.  * vDecode4bpp - decode an uncompressed 4 bits per pixel image
  75.  */
  76. static void
  77. vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  78. {
  79.     size_t    tPadding;
  80.     int    iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
  81.  
  82.     DBG_MSG("vDecode4bpp");
  83.  
  84.     fail(pInFile == NULL);
  85.     fail(pOutFile == NULL);
  86.     fail(pImg == NULL);
  87.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
  88.  
  89.     DBG_DEC(pImg->iWidth);
  90.     DBG_DEC(pImg->iHeight);
  91.  
  92.     iHalfWidth = (pImg->iWidth + 1) / 2;
  93.     tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
  94.  
  95.     for (iY = 0; iY < pImg->iHeight; iY++) {
  96.         for (iX = 0; iX < iHalfWidth; iX++) {
  97.             iByte = iNextByte(pInFile);
  98.             if (iByte == EOF) {
  99.                 vASCII85EncodeByte(pOutFile, EOF);
  100.                 return;
  101.             }
  102.             if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
  103.                 iUse = 1;
  104.             } else {
  105.                 iUse = 2;
  106.             }
  107.             for (iN = 0; iN < iUse; iN++) {
  108.                 if (odd(iN)) {
  109.                     iTmp = iByte & 0x0f;
  110.                 } else {
  111.                     iTmp = (iByte & 0xf0) / 16;
  112.                 }
  113.                 vASCII85EncodeByte(pOutFile, iTmp);
  114.             }
  115.         }
  116.         (void)iSkipBytes(pInFile, tPadding);
  117.     }
  118.     vASCII85EncodeByte(pOutFile, EOF);
  119. } /* end of vDecode4bpp */
  120.  
  121. /*
  122.  * vDecode8bpp - decode an uncompressed 8 bits per pixel image
  123.  */
  124. static void
  125. vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  126. {
  127.     size_t    tPadding;
  128.     int    iX, iY, iByte;
  129.  
  130.     DBG_MSG("vDecode8bpp");
  131.  
  132.     fail(pInFile == NULL);
  133.     fail(pOutFile == NULL);
  134.     fail(pImg == NULL);
  135.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
  136.  
  137.     DBG_DEC(pImg->iWidth);
  138.     DBG_DEC(pImg->iHeight);
  139.  
  140.     tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
  141.  
  142.     for (iY = 0; iY < pImg->iHeight; iY++) {
  143.         for (iX = 0; iX < pImg->iWidth; iX++) {
  144.             iByte = iNextByte(pInFile);
  145.             if (iByte == EOF) {
  146.                 vASCII85EncodeByte(pOutFile, EOF);
  147.                 return;
  148.             }
  149.             vASCII85EncodeByte(pOutFile, iByte);
  150.         }
  151.         (void)iSkipBytes(pInFile, tPadding);
  152.     }
  153.     vASCII85EncodeByte(pOutFile, EOF);
  154. } /* end of vDecode8bpp */
  155.  
  156. /*
  157.  * vDecode24bpp - decode an uncompressed 24 bits per pixel image
  158.  */
  159. static void
  160. vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  161. {
  162.     size_t    tPadding;
  163.     int    iX, iY, iBlue, iGreen, iRed, iTripleWidth;
  164.  
  165.     DBG_MSG("vDecode24bpp");
  166.  
  167.     fail(pInFile == NULL);
  168.     fail(pOutFile == NULL);
  169.     fail(pImg == NULL);
  170.     fail(!pImg->bColorImage);
  171.  
  172.     DBG_DEC(pImg->iWidth);
  173.     DBG_DEC(pImg->iHeight);
  174.  
  175.     iTripleWidth = pImg->iWidth * 3;
  176.     tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
  177.  
  178.     for (iY = 0; iY < pImg->iHeight; iY++) {
  179.         for (iX = 0; iX < pImg->iWidth; iX++) {
  180.             /* Change from BGR order to RGB order */
  181.             iBlue = iNextByte(pInFile);
  182.             if (iBlue == EOF) {
  183.                 vASCII85EncodeByte(pOutFile, EOF);
  184.                 return;
  185.             }
  186.             iGreen = iNextByte(pInFile);
  187.             if (iGreen == EOF) {
  188.                 vASCII85EncodeByte(pOutFile, EOF);
  189.                 return;
  190.             }
  191.             iRed = iNextByte(pInFile);
  192.             if (iRed == EOF) {
  193.                 vASCII85EncodeByte(pOutFile, EOF);
  194.                 return;
  195.             }
  196.             vASCII85EncodeByte(pOutFile, iRed);
  197.             vASCII85EncodeByte(pOutFile, iGreen);
  198.             vASCII85EncodeByte(pOutFile, iBlue);
  199.         }
  200.         (void)iSkipBytes(pInFile, tPadding);
  201.     }
  202.     vASCII85EncodeByte(pOutFile, EOF);
  203. } /* end of vDecode24bpp */
  204.  
  205. /*
  206.  * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
  207.  */
  208. static void
  209. vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  210. {
  211.     int    iX, iY, iByte, iTmp, iRunLength, iRun;
  212.     BOOL    bEOF, bEOL;
  213.  
  214.     DBG_MSG("vDecodeRle4");
  215.  
  216.     fail(pInFile == NULL);
  217.     fail(pOutFile == NULL);
  218.     fail(pImg == NULL);
  219.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
  220.  
  221.     DBG_DEC(pImg->iWidth);
  222.     DBG_DEC(pImg->iHeight);
  223.  
  224.     bEOF = FALSE;
  225.  
  226.     for (iY =  0; iY < pImg->iHeight && !bEOF; iY++) {
  227.         bEOL = FALSE;
  228.         iX = 0;
  229.         while (!bEOL) {
  230.             iRunLength = iNextByte(pInFile);
  231.             if (iRunLength == EOF) {
  232.                 vASCII85EncodeByte(pOutFile, EOF);
  233.                 return;
  234.             }
  235.             if (iRunLength != 0) {
  236.                 /*
  237.                  * Encoded packet:
  238.                  * RunLength pixels, all the "same" value
  239.                  */
  240.                 iByte = iNextByte(pInFile);
  241.                 if (iByte == EOF) {
  242.                     vASCII85EncodeByte(pOutFile, EOF);
  243.                     return;
  244.                 }
  245.                 for (iRun = 0; iRun < iRunLength; iRun++) {
  246.                     if (odd(iRun)) {
  247.                         iTmp = iByte & 0x0f;
  248.                     } else {
  249.                         iTmp = (iByte & 0xf0) / 16;
  250.                     }
  251.                     if (iX < pImg->iWidth) {
  252.                         vASCII85EncodeByte(pOutFile, iTmp);
  253.                     }
  254.                     iX++;
  255.                 }
  256.                 continue;
  257.             }
  258.             /* Literal or escape */
  259.             iRunLength = iNextByte(pInFile);
  260.             if (iRunLength == EOF) {
  261.                 vASCII85EncodeByte(pOutFile, EOF);
  262.                 return;
  263.             }
  264.             if (iRunLength == 0) {        /* End of line escape */
  265.                 bEOL = TRUE;
  266.             } else if (iRunLength == 1) {    /* End of file escape */
  267.                 bEOF = TRUE;
  268.                 bEOL = TRUE;
  269.             } else if (iRunLength == 2) {    /* Delta escape */
  270.                 DBG_MSG("RLE4: encountered delta escape");
  271.                 bEOF = TRUE;
  272.                 bEOL = TRUE;
  273.             } else {            /* Literal packet */
  274.                 iByte = 0;
  275.                 for (iRun = 0; iRun < iRunLength; iRun++) {
  276.                     if (odd(iRun)) {
  277.                         iTmp = iByte & 0x0f;
  278.                     } else {
  279.                         iByte = iNextByte(pInFile);
  280.                         if (iByte == EOF) {
  281.                             vASCII85EncodeByte(pOutFile, EOF);
  282.                             return;
  283.                         }
  284.                         iTmp = (iByte & 0xf0) / 16;
  285.                     }
  286.                     if (iX < pImg->iWidth) {
  287.                         vASCII85EncodeByte(pOutFile, iTmp);
  288.                     }
  289.                     iX++;
  290.                 }
  291.                 /* Padding if the number of bytes is odd */
  292.                 if (odd((iRunLength + 1) / 2)) {
  293.                     (void)iSkipBytes(pInFile, 1);
  294.                 }
  295.             }
  296.         }
  297.         DBG_DEC_C(iX != pImg->iWidth, iX);
  298.     }
  299.     vASCII85EncodeByte(pOutFile, EOF);
  300. } /* end of vDecodeRle4 */
  301.  
  302. /*
  303.  * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
  304.  */
  305. static void
  306. vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  307. {
  308.     int    iX, iY, iByte, iRunLength, iRun;
  309.     BOOL    bEOF, bEOL;
  310.  
  311.     DBG_MSG("vDecodeRle8");
  312.  
  313.     fail(pInFile == NULL);
  314.     fail(pOutFile == NULL);
  315.     fail(pImg == NULL);
  316.     fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
  317.  
  318.     DBG_DEC(pImg->iWidth);
  319.     DBG_DEC(pImg->iHeight);
  320.  
  321.     bEOF = FALSE;
  322.  
  323.     for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
  324.         bEOL = FALSE;
  325.         iX = 0;
  326.         while (!bEOL) {
  327.             iRunLength = iNextByte(pInFile);
  328.             if (iRunLength == EOF) {
  329.                 vASCII85EncodeByte(pOutFile, EOF);
  330.                 return;
  331.             }
  332.             if (iRunLength != 0) {
  333.                 /*
  334.                  * Encoded packet:
  335.                  * RunLength pixels, all the same value
  336.                  */
  337.                 iByte = iNextByte(pInFile);
  338.                 if (iByte == EOF) {
  339.                     vASCII85EncodeByte(pOutFile, EOF);
  340.                     return;
  341.                 }
  342.                 for (iRun = 0; iRun < iRunLength; iRun++) {
  343.                     if (iX < pImg->iWidth) {
  344.                         vASCII85EncodeByte(pOutFile, iByte);
  345.                     }
  346.                     iX++;
  347.                 }
  348.                 continue;
  349.             }
  350.             /* Literal or escape */
  351.             iRunLength = iNextByte(pInFile);
  352.             if (iRunLength == EOF) {
  353.                 vASCII85EncodeByte(pOutFile, EOF);
  354.                 return;
  355.             }
  356.             if (iRunLength == 0) {        /* End of line escape */
  357.                 bEOL = TRUE;
  358.             } else if (iRunLength == 1) {    /* End of file escape */
  359.                 bEOF = TRUE;
  360.                 bEOL = TRUE;
  361.             } else if (iRunLength == 2) {    /* Delta escape */
  362.                 DBG_MSG("RLE8: encountered delta escape");
  363.                 bEOF = TRUE;
  364.                 bEOL = TRUE;
  365.             } else {            /* Literal packet */
  366.                 for (iRun = 0; iRun < iRunLength; iRun++) {
  367.                     iByte = iNextByte(pInFile);
  368.                     if (iByte == EOF) {
  369.                         vASCII85EncodeByte(pOutFile, EOF);
  370.                         return;
  371.                     }
  372.                     if (iX < pImg->iWidth) {
  373.                         vASCII85EncodeByte(pOutFile, iByte);
  374.                     }
  375.                     iX++;
  376.                 }
  377.                 /* Padding if the number of bytes is odd */
  378.                 if (odd(iRunLength)) {
  379.                     (void)iSkipBytes(pInFile, 1);
  380.                 }
  381.             }
  382.         }
  383.         DBG_DEC_C(iX != pImg->iWidth, iX);
  384.     }
  385.     vASCII85EncodeByte(pOutFile, EOF);
  386. } /* end of vDecodeRle8 */
  387.  
  388. /*
  389.  * vDecodeDIB - decode a dib picture
  390.  */
  391. static void
  392. vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
  393. {
  394.     size_t    tHeaderSize;
  395.  
  396.     fail(pInFile == NULL);
  397.     fail(pOutFile == NULL);
  398.     fail(pImg == NULL);
  399.  
  400.     /* Skip the bitmap info header */
  401.     tHeaderSize = (size_t)ulNextLong(pInFile);
  402.     (void)iSkipBytes(pInFile, tHeaderSize - 4);
  403.     /* Skip the colortable */
  404.     if (pImg->iBitsPerComponent <= 8) {
  405.         (void)iSkipBytes(pInFile,
  406.             (size_t)(pImg->iColorsUsed *
  407.              ((tHeaderSize > 12) ? 4 : 3)));
  408.     }
  409.  
  410.     switch (pImg->iBitsPerComponent) {
  411.     case 1:
  412.         fail(pImg->eCompression != compression_none);
  413.         vDecode1bpp(pInFile, pOutFile, pImg);
  414.         break;
  415.     case 4:
  416.         fail(pImg->eCompression != compression_none &&
  417.                 pImg->eCompression != compression_rle4);
  418.         if (pImg->eCompression == compression_rle4) {
  419.             vDecodeRle4(pInFile, pOutFile, pImg);
  420.         } else {
  421.             vDecode4bpp(pInFile, pOutFile, pImg);
  422.         }
  423.         break;
  424.     case 8:
  425.         fail(pImg->eCompression != compression_none &&
  426.                 pImg->eCompression != compression_rle8);
  427.         if (pImg->eCompression == compression_rle8) {
  428.             vDecodeRle8(pInFile, pOutFile, pImg);
  429.         } else {
  430.             vDecode8bpp(pInFile, pOutFile, pImg);
  431.         }
  432.         break;
  433.     case 24:
  434.         fail(pImg->eCompression != compression_none);
  435.         vDecode24bpp(pInFile, pOutFile, pImg);
  436.         break;
  437.     default:
  438.         DBG_DEC(pImg->iBitsPerComponent);
  439.         break;
  440.     }
  441. } /* end of vDecodeDIB */
  442.  
  443. #if defined(DEBUG)
  444. /*
  445.  * vCopy2File
  446.  */
  447. static void
  448. vCopy2File(FILE *pInFile, long lFileOffset, int iPictureLen)
  449. {
  450.     static int    iPicCounter = 0;
  451.     FILE    *pOutFile;
  452.     int    iIndex, iTmp;
  453.     char    szFilename[30];
  454.  
  455.     if (!bSetDataOffset(pInFile, lFileOffset)) {
  456.         return;
  457.     }
  458.  
  459.     sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
  460.     pOutFile = fopen(szFilename, "wb");
  461.     if (pOutFile == NULL) {
  462.         return;
  463.     }
  464.     /* Turn a dib into a bmp by adding a fake 14 byte header */
  465.     (void)putc('B', pOutFile);
  466.     (void)putc('M', pOutFile);
  467.     for (iTmp = 0; iTmp < 12; iTmp++) {
  468.         if (putc(0, pOutFile) == EOF) {
  469.             break;
  470.         }
  471.     }
  472.     for (iIndex = 0; iIndex < iPictureLen; iIndex++) {
  473.         iTmp = iNextByte(pInFile);
  474.         if (putc(iTmp, pOutFile) == EOF) {
  475.             break;
  476.         }
  477.     }
  478.     (void)fclose(pOutFile);
  479. } /* end of vCopy2File */
  480. #endif /* DEBUG */
  481.  
  482. /*
  483.  * bTranslateDIB - translate a DIB picture
  484.  *
  485.  * This function translates a picture from dib to eps
  486.  *
  487.  * return TRUE when sucessful, otherwise FALSE
  488.  */
  489. BOOL
  490. bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
  491.         long lFileOffset, const imagedata_type *pImg)
  492. {
  493. #if defined(DEBUG)
  494.     vCopy2File(pInFile, lFileOffset, pImg->iLength - pImg->iPosition);
  495. #endif /* DEBUG */
  496.  
  497.     /* Seek to start position of DIB data */
  498.     if (!bSetDataOffset(pInFile, lFileOffset)) {
  499.         return FALSE;
  500.     }
  501.  
  502.     vImagePrologue(pDiag, pImg);
  503.     vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
  504.     vImageEpilogue(pDiag);
  505.  
  506.     return TRUE;
  507. } /* end of bTranslateDIB */
  508.