examples/PIPS/antiword/src/dib2eps.c

00001 /*
00002  * dib2eps.c
00003  * Copyright (C) 2000-2003 A.J. van Os; Released under GPL
00004  *
00005  * Description:
00006  * Functions to translate dib pictures into eps
00007  *
00008  *================================================================
00009  * This part of the software is based on:
00010  * The Windows Bitmap Decoder Class part of paintlib
00011  * Paintlib is copyright (c) 1996-2000 Ulrich von Zadow
00012  *================================================================
00013  * The credit should go to him, but all the bugs are mine.
00014  */
00015 
00016 #include <stdio.h>
00017 #include "antiword.h"
00018 
00019 
00020 /*
00021  * vDecode1bpp - decode an uncompressed 1 bit per pixel image
00022  */
00023 static void
00024 vDecode1bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00025 {
00026         size_t  tPadding;
00027         int     iX, iY, iN, iByte, iTmp, iEighthWidth, iUse;
00028 
00029         DBG_MSG("vDecode1bpp");
00030 
00031         fail(pOutFile == NULL);
00032         fail(pImg == NULL);
00033         fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2);
00034 
00035         DBG_DEC(pImg->iWidth);
00036         DBG_DEC(pImg->iHeight);
00037 
00038         iEighthWidth = (pImg->iWidth + 7) / 8;
00039         tPadding = (size_t)(ROUND4(iEighthWidth) - iEighthWidth);
00040 
00041         for (iY = 0; iY < pImg->iHeight; iY++) {
00042                 for (iX = 0; iX < iEighthWidth; iX++) {
00043                         iByte = iNextByte(pInFile);
00044                         if (iByte == EOF) {
00045                                 vASCII85EncodeByte(pOutFile, EOF);
00046                                 return;
00047                         }
00048                         if (iX == iEighthWidth - 1 && pImg->iWidth % 8 != 0) {
00049                                 iUse = pImg->iWidth % 8;
00050                         } else {
00051                                 iUse = 8;
00052                         }
00053                         for (iN = 0; iN < iUse; iN++) {
00054                                 switch (iN) {
00055                                 case 0: iTmp = (iByte & 0x80) / 128; break;
00056                                 case 1: iTmp = (iByte & 0x40) / 64; break;
00057                                 case 2: iTmp = (iByte & 0x20) / 32; break;
00058                                 case 3: iTmp = (iByte & 0x10) / 16; break;
00059                                 case 4: iTmp = (iByte & 0x08) / 8; break;
00060                                 case 5: iTmp = (iByte & 0x04) / 4; break;
00061                                 case 6: iTmp = (iByte & 0x02) / 2; break;
00062                                 case 7: iTmp = (iByte & 0x01); break;
00063                                 default: iTmp = 0; break;
00064                                 }
00065                                 vASCII85EncodeByte(pOutFile, iTmp);
00066                         }
00067                 }
00068                 (void)tSkipBytes(pInFile, tPadding);
00069         }
00070         vASCII85EncodeByte(pOutFile, EOF);
00071 } /* end of vDecode1bpp */
00072 
00073 /*
00074  * vDecode4bpp - decode an uncompressed 4 bits per pixel image
00075  */
00076 static void
00077 vDecode4bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00078 {
00079         size_t  tPadding;
00080         int     iX, iY, iN, iByte, iTmp, iHalfWidth, iUse;
00081 
00082         DBG_MSG("vDecode4bpp");
00083 
00084         fail(pInFile == NULL);
00085         fail(pOutFile == NULL);
00086         fail(pImg == NULL);
00087         fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
00088 
00089         DBG_DEC(pImg->iWidth);
00090         DBG_DEC(pImg->iHeight);
00091 
00092         iHalfWidth = (pImg->iWidth + 1) / 2;
00093         tPadding = (size_t)(ROUND4(iHalfWidth) - iHalfWidth);
00094 
00095         for (iY = 0; iY < pImg->iHeight; iY++) {
00096                 for (iX = 0; iX < iHalfWidth; iX++) {
00097                         iByte = iNextByte(pInFile);
00098                         if (iByte == EOF) {
00099                                 vASCII85EncodeByte(pOutFile, EOF);
00100                                 return;
00101                         }
00102                         if (iX == iHalfWidth - 1 && odd(pImg->iWidth)) {
00103                                 iUse = 1;
00104                         } else {
00105                                 iUse = 2;
00106                         }
00107                         for (iN = 0; iN < iUse; iN++) {
00108                                 if (odd(iN)) {
00109                                         iTmp = iByte & 0x0f;
00110                                 } else {
00111                                         iTmp = (iByte & 0xf0) / 16;
00112                                 }
00113                                 vASCII85EncodeByte(pOutFile, iTmp);
00114                         }
00115                 }
00116                 (void)tSkipBytes(pInFile, tPadding);
00117         }
00118         vASCII85EncodeByte(pOutFile, EOF);
00119 } /* end of vDecode4bpp */
00120 
00121 /*
00122  * vDecode8bpp - decode an uncompressed 8 bits per pixel image
00123  */
00124 static void
00125 vDecode8bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00126 {
00127         size_t  tPadding;
00128         int     iX, iY, iByte;
00129 
00130         DBG_MSG("vDecode8bpp");
00131 
00132         fail(pInFile == NULL);
00133         fail(pOutFile == NULL);
00134         fail(pImg == NULL);
00135         fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
00136 
00137         DBG_DEC(pImg->iWidth);
00138         DBG_DEC(pImg->iHeight);
00139 
00140         tPadding = (size_t)(ROUND4(pImg->iWidth) - pImg->iWidth);
00141 
00142         for (iY = 0; iY < pImg->iHeight; iY++) {
00143                 for (iX = 0; iX < pImg->iWidth; iX++) {
00144                         iByte = iNextByte(pInFile);
00145                         if (iByte == EOF) {
00146                                 vASCII85EncodeByte(pOutFile, EOF);
00147                                 return;
00148                         }
00149                         vASCII85EncodeByte(pOutFile, iByte);
00150                 }
00151                 (void)tSkipBytes(pInFile, tPadding);
00152         }
00153         vASCII85EncodeByte(pOutFile, EOF);
00154 } /* end of vDecode8bpp */
00155 
00156 /*
00157  * vDecode24bpp - decode an uncompressed 24 bits per pixel image
00158  */
00159 static void
00160 vDecode24bpp(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00161 {
00162         size_t  tPadding;
00163         int     iX, iY, iBlue, iGreen, iRed, iTripleWidth;
00164 
00165         DBG_MSG("vDecode24bpp");
00166 
00167         fail(pInFile == NULL);
00168         fail(pOutFile == NULL);
00169         fail(pImg == NULL);
00170         fail(!pImg->bColorImage);
00171 
00172         DBG_DEC(pImg->iWidth);
00173         DBG_DEC(pImg->iHeight);
00174 
00175         iTripleWidth = pImg->iWidth * 3;
00176         tPadding = (size_t)(ROUND4(iTripleWidth) - iTripleWidth);
00177 
00178         for (iY = 0; iY < pImg->iHeight; iY++) {
00179                 for (iX = 0; iX < pImg->iWidth; iX++) {
00180                         /* Change from BGR order to RGB order */
00181                         iBlue = iNextByte(pInFile);
00182                         if (iBlue == EOF) {
00183                                 vASCII85EncodeByte(pOutFile, EOF);
00184                                 return;
00185                         }
00186                         iGreen = iNextByte(pInFile);
00187                         if (iGreen == EOF) {
00188                                 vASCII85EncodeByte(pOutFile, EOF);
00189                                 return;
00190                         }
00191                         iRed = iNextByte(pInFile);
00192                         if (iRed == EOF) {
00193                                 vASCII85EncodeByte(pOutFile, EOF);
00194                                 return;
00195                         }
00196                         vASCII85EncodeByte(pOutFile, iRed);
00197                         vASCII85EncodeByte(pOutFile, iGreen);
00198                         vASCII85EncodeByte(pOutFile, iBlue);
00199                 }
00200                 (void)tSkipBytes(pInFile, tPadding);
00201         }
00202         vASCII85EncodeByte(pOutFile, EOF);
00203 } /* end of vDecode24bpp */
00204 
00205 /*
00206  * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image
00207  */
00208 static void
00209 vDecodeRle4(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00210 {
00211         int     iX, iY, iByte, iTmp, iRunLength, iRun;
00212         BOOL    bEOF, bEOL;
00213 
00214         DBG_MSG("vDecodeRle4");
00215 
00216         fail(pInFile == NULL);
00217         fail(pOutFile == NULL);
00218         fail(pImg == NULL);
00219         fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16);
00220 
00221         DBG_DEC(pImg->iWidth);
00222         DBG_DEC(pImg->iHeight);
00223 
00224         bEOF = FALSE;
00225 
00226         for (iY =  0; iY < pImg->iHeight && !bEOF; iY++) {
00227                 bEOL = FALSE;
00228                 iX = 0;
00229                 while (!bEOL) {
00230                         iRunLength = iNextByte(pInFile);
00231                         if (iRunLength == EOF) {
00232                                 vASCII85EncodeByte(pOutFile, EOF);
00233                                 return;
00234                         }
00235                         if (iRunLength != 0) {
00236                                 /*
00237                                  * Encoded packet:
00238                                  * RunLength pixels, all the "same" value
00239                                  */
00240                                 iByte = iNextByte(pInFile);
00241                                 if (iByte == EOF) {
00242                                         vASCII85EncodeByte(pOutFile, EOF);
00243                                         return;
00244                                 }
00245                                 for (iRun = 0; iRun < iRunLength; iRun++) {
00246                                         if (odd(iRun)) {
00247                                                 iTmp = iByte & 0x0f;
00248                                         } else {
00249                                                 iTmp = (iByte & 0xf0) / 16;
00250                                         }
00251                                         if (iX < pImg->iWidth) {
00252                                                 vASCII85EncodeByte(pOutFile, iTmp);
00253                                         }
00254                                         iX++;
00255                                 }
00256                                 continue;
00257                         }
00258                         /* Literal or escape */
00259                         iRunLength = iNextByte(pInFile);
00260                         if (iRunLength == EOF) {
00261                                 vASCII85EncodeByte(pOutFile, EOF);
00262                                 return;
00263                         }
00264                         if (iRunLength == 0) {          /* End of line escape */
00265                                 bEOL = TRUE;
00266                         } else if (iRunLength == 1) {   /* End of file escape */
00267                                 bEOF = TRUE;
00268                                 bEOL = TRUE;
00269                         } else if (iRunLength == 2) {   /* Delta escape */
00270                                 DBG_MSG("RLE4: encountered delta escape");
00271                                 bEOF = TRUE;
00272                                 bEOL = TRUE;
00273                         } else {                        /* Literal packet */
00274                                 iByte = 0;
00275                                 for (iRun = 0; iRun < iRunLength; iRun++) {
00276                                         if (odd(iRun)) {
00277                                                 iTmp = iByte & 0x0f;
00278                                         } else {
00279                                                 iByte = iNextByte(pInFile);
00280                                                 if (iByte == EOF) {
00281                                                         vASCII85EncodeByte(pOutFile, EOF);
00282                                                         return;
00283                                                 }
00284                                                 iTmp = (iByte & 0xf0) / 16;
00285                                         }
00286                                         if (iX < pImg->iWidth) {
00287                                                 vASCII85EncodeByte(pOutFile, iTmp);
00288                                         }
00289                                         iX++;
00290                                 }
00291                                 /* Padding if the number of bytes is odd */
00292                                 if (odd((iRunLength + 1) / 2)) {
00293                                         (void)tSkipBytes(pInFile, 1);
00294                                 }
00295                         }
00296                 }
00297                 DBG_DEC_C(iX != pImg->iWidth, iX);
00298         }
00299         vASCII85EncodeByte(pOutFile, EOF);
00300 } /* end of vDecodeRle4 */
00301 
00302 /*
00303  * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image
00304  */
00305 static void
00306 vDecodeRle8(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00307 {
00308         int     iX, iY, iByte, iRunLength, iRun;
00309         BOOL    bEOF, bEOL;
00310 
00311         DBG_MSG("vDecodeRle8");
00312 
00313         fail(pInFile == NULL);
00314         fail(pOutFile == NULL);
00315         fail(pImg == NULL);
00316         fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256);
00317 
00318         DBG_DEC(pImg->iWidth);
00319         DBG_DEC(pImg->iHeight);
00320 
00321         bEOF = FALSE;
00322 
00323         for (iY = 0; iY < pImg->iHeight && !bEOF; iY++) {
00324                 bEOL = FALSE;
00325                 iX = 0;
00326                 while (!bEOL) {
00327                         iRunLength = iNextByte(pInFile);
00328                         if (iRunLength == EOF) {
00329                                 vASCII85EncodeByte(pOutFile, EOF);
00330                                 return;
00331                         }
00332                         if (iRunLength != 0) {
00333                                 /*
00334                                  * Encoded packet:
00335                                  * RunLength pixels, all the same value
00336                                  */
00337                                 iByte = iNextByte(pInFile);
00338                                 if (iByte == EOF) {
00339                                         vASCII85EncodeByte(pOutFile, EOF);
00340                                         return;
00341                                 }
00342                                 for (iRun = 0; iRun < iRunLength; iRun++) {
00343                                         if (iX < pImg->iWidth) {
00344                                                 vASCII85EncodeByte(pOutFile, iByte);
00345                                         }
00346                                         iX++;
00347                                 }
00348                                 continue;
00349                         }
00350                         /* Literal or escape */
00351                         iRunLength = iNextByte(pInFile);
00352                         if (iRunLength == EOF) {
00353                                 vASCII85EncodeByte(pOutFile, EOF);
00354                                 return;
00355                         }
00356                         if (iRunLength == 0) {          /* End of line escape */
00357                                 bEOL = TRUE;
00358                         } else if (iRunLength == 1) {   /* End of file escape */
00359                                 bEOF = TRUE;
00360                                 bEOL = TRUE;
00361                         } else if (iRunLength == 2) {   /* Delta escape */
00362                                 DBG_MSG("RLE8: encountered delta escape");
00363                                 bEOF = TRUE;
00364                                 bEOL = TRUE;
00365                         } else {                        /* Literal packet */
00366                                 for (iRun = 0; iRun < iRunLength; iRun++) {
00367                                         iByte = iNextByte(pInFile);
00368                                         if (iByte == EOF) {
00369                                                 vASCII85EncodeByte(pOutFile, EOF);
00370                                                 return;
00371                                         }
00372                                         if (iX < pImg->iWidth) {
00373                                                 vASCII85EncodeByte(pOutFile, iByte);
00374                                         }
00375                                         iX++;
00376                                 }
00377                                 /* Padding if the number of bytes is odd */
00378                                 if (odd(iRunLength)) {
00379                                         (void)tSkipBytes(pInFile, 1);
00380                                 }
00381                         }
00382                 }
00383                 DBG_DEC_C(iX != pImg->iWidth, iX);
00384         }
00385         vASCII85EncodeByte(pOutFile, EOF);
00386 } /* end of vDecodeRle8 */
00387 
00388 /*
00389  * vDecodeDIB - decode a dib picture
00390  */
00391 static void
00392 vDecodeDIB(FILE *pInFile, FILE *pOutFile, const imagedata_type *pImg)
00393 {
00394         size_t  tHeaderSize;
00395 
00396         fail(pInFile == NULL);
00397         fail(pOutFile == NULL);
00398         fail(pImg == NULL);
00399 
00400         /* Skip the bitmap info header */
00401         tHeaderSize = (size_t)ulNextLong(pInFile);
00402         (void)tSkipBytes(pInFile, tHeaderSize - 4);
00403         /* Skip the colortable */
00404         if (pImg->uiBitsPerComponent <= 8) {
00405                 (void)tSkipBytes(pInFile,
00406                         (size_t)(pImg->iColorsUsed *
00407                          ((tHeaderSize > 12) ? 4 : 3)));
00408         }
00409 
00410         switch (pImg->uiBitsPerComponent) {
00411         case 1:
00412                 fail(pImg->eCompression != compression_none);
00413                 vDecode1bpp(pInFile, pOutFile, pImg);
00414                 break;
00415         case 4:
00416                 fail(pImg->eCompression != compression_none &&
00417                                 pImg->eCompression != compression_rle4);
00418                 if (pImg->eCompression == compression_rle4) {
00419                         vDecodeRle4(pInFile, pOutFile, pImg);
00420                 } else {
00421                         vDecode4bpp(pInFile, pOutFile, pImg);
00422                 }
00423                 break;
00424         case 8:
00425                 fail(pImg->eCompression != compression_none &&
00426                                 pImg->eCompression != compression_rle8);
00427                 if (pImg->eCompression == compression_rle8) {
00428                         vDecodeRle8(pInFile, pOutFile, pImg);
00429                 } else {
00430                         vDecode8bpp(pInFile, pOutFile, pImg);
00431                 }
00432                 break;
00433         case 24:
00434                 fail(pImg->eCompression != compression_none);
00435                 vDecode24bpp(pInFile, pOutFile, pImg);
00436                 break;
00437         default:
00438                 DBG_DEC(pImg->uiBitsPerComponent);
00439                 break;
00440         }
00441 } /* end of vDecodeDIB */
00442 
00443 #if defined(DEBUG)
00444 /*
00445  * vCopy2File
00446  */
00447 static void
00448 vCopy2File(FILE *pInFile, ULONG ulFileOffset, size_t tPictureLen)
00449 {
00450         static int      iPicCounter = 0;
00451         FILE    *pOutFile;
00452         size_t  tIndex;
00453         int     iTmp;
00454         char    szFilename[30];
00455 
00456         if (!bSetDataOffset(pInFile, ulFileOffset)) {
00457                 return;
00458         }
00459 
00460         sprintf(szFilename, "/tmp/pic/pic%04d.bmp", ++iPicCounter);
00461         pOutFile = fopen(szFilename, "wb");
00462         if (pOutFile == NULL) {
00463                 return;
00464         }
00465         /* Turn a dib into a bmp by adding a fake 14 byte header */
00466         (void)putc('B', pOutFile);
00467         (void)putc('M', pOutFile);
00468         for (iTmp = 0; iTmp < 12; iTmp++) {
00469                 if (putc(0, pOutFile) == EOF) {
00470                         break;
00471                 }
00472         }
00473         for (tIndex = 0; tIndex < tPictureLen; tIndex++) {
00474                 iTmp = iNextByte(pInFile);
00475                 if (putc(iTmp, pOutFile) == EOF) {
00476                         break;
00477                 }
00478         }
00479         (void)fclose(pOutFile);
00480 } /* end of vCopy2File */
00481 #endif /* DEBUG */
00482 
00483 /*
00484  * bTranslateDIB - translate a DIB picture
00485  *
00486  * This function translates a picture from dib to eps
00487  *
00488  * return TRUE when sucessful, otherwise FALSE
00489  */
00490 BOOL
00491 bTranslateDIB(diagram_type *pDiag, FILE *pInFile,
00492                 ULONG ulFileOffset, const imagedata_type *pImg)
00493 {
00494 #if defined(DEBUG)
00495         fail(pImg->tPosition > pImg->tLength);
00496         vCopy2File(pInFile, ulFileOffset, pImg->tLength - pImg->tPosition);
00497 #endif /* DEBUG */
00498 
00499         /* Seek to start position of DIB data */
00500         if (!bSetDataOffset(pInFile, ulFileOffset)) {
00501                 return FALSE;
00502         }
00503 
00504         vImagePrologue(pDiag, pImg);
00505         vDecodeDIB(pInFile, pDiag->pOutFile, pImg);
00506         vImageEpilogue(pDiag);
00507 
00508         return TRUE;
00509 } /* end of bTranslateDIB */

Generated by  doxygen 1.6.2