diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/imgexam_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/imgexam_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,1060 @@ + + + + +TB9.2 Example Applications: examples/PIPS/antiword/src/imgexam.c Source File + + + + + +

examples/PIPS/antiword/src/imgexam.c

00001 /*
+00002  * imgexam.c
+00003  * Copyright (C) 2000-2004 A.J. van Os; Released under GNU GPL
+00004  *
+00005  * Description:
+00006  * Functions to examine image headers
+00007  *
+00008  *================================================================
+00009  * Part of this software is based on:
+00010  * jpeg2ps - convert JPEG compressed images to PostScript Level 2
+00011  * Copyright (C) 1994-99 Thomas Merz (tm@muc.de)
+00012  *================================================================
+00013  * The credit should go to him, but all the bugs are mine.
+00014  */
+00015 
+00016 #include <stdio.h>
+00017 #include <string.h>
+00018 #include <ctype.h>
+00019 #include "antiword.h"
+00020 
+00021 /* BMP compression types */
+00022 #define BI_RGB          0
+00023 #define BI_RLE8         1
+00024 #define BI_RLE4         2
+00025 
+00026 /* PNG colortype bits */
+00027 #define PNG_CB_PALETTE          0x01
+00028 #define PNG_CB_COLOR            0x02
+00029 #define PNG_CB_ALPHA            0x04
+00030 
+00031 /* Instance signature */
+00032 #define MSOBI_WMF       0x0216
+00033 #define MSOBI_EMF       0x03d4
+00034 #define MSOBI_PICT      0x0542
+00035 #define MSOBI_PNG       0x06e0
+00036 #define MSOBI_JPEG      0x046a
+00037 #define MSOBI_DIB       0x07a8
+00038 
+00039 /* The following enum is stolen from the IJG JPEG library */
+00040 typedef enum {          /* JPEG marker codes                    */
+00041         M_SOF0  = 0xc0, /* baseline DCT                         */
+00042         M_SOF1  = 0xc1, /* extended sequential DCT              */
+00043         M_SOF2  = 0xc2, /* progressive DCT                      */
+00044         M_SOF3  = 0xc3, /* lossless (sequential)                */
+00045 
+00046         M_SOF5  = 0xc5, /* differential sequential DCT          */
+00047         M_SOF6  = 0xc6, /* differential progressive DCT         */
+00048         M_SOF7  = 0xc7, /* differential lossless                */
+00049 
+00050         M_JPG   = 0xc8, /* JPEG extensions                      */
+00051         M_SOF9  = 0xc9, /* extended sequential DCT              */
+00052         M_SOF10 = 0xca, /* progressive DCT                      */
+00053         M_SOF11 = 0xcb, /* lossless (sequential)                */
+00054 
+00055         M_SOF13 = 0xcd, /* differential sequential DCT          */
+00056         M_SOF14 = 0xce, /* differential progressive DCT         */
+00057         M_SOF15 = 0xcf, /* differential lossless                */
+00058 
+00059         M_DHT   = 0xc4, /* define Huffman tables                */
+00060 
+00061         M_DAC   = 0xcc, /* define arithmetic conditioning table */
+00062 
+00063         M_RST0  = 0xd0, /* restart                              */
+00064         M_RST1  = 0xd1, /* restart                              */
+00065         M_RST2  = 0xd2, /* restart                              */
+00066         M_RST3  = 0xd3, /* restart                              */
+00067         M_RST4  = 0xd4, /* restart                              */
+00068         M_RST5  = 0xd5, /* restart                              */
+00069         M_RST6  = 0xd6, /* restart                              */
+00070         M_RST7  = 0xd7, /* restart                              */
+00071 
+00072         M_SOI   = 0xd8, /* start of image                       */
+00073         M_EOI   = 0xd9, /* end of image                         */
+00074         M_SOS   = 0xda, /* start of scan                        */
+00075         M_DQT   = 0xdb, /* define quantization tables           */
+00076         M_DNL   = 0xdc, /* define number of lines               */
+00077         M_DRI   = 0xdd, /* define restart interval              */
+00078         M_DHP   = 0xde, /* define hierarchical progression      */
+00079         M_EXP   = 0xdf, /* expand reference image(s)            */
+00080 
+00081         M_APP0  = 0xe0, /* application marker, used for JFIF    */
+00082         M_APP1  = 0xe1, /* application marker                   */
+00083         M_APP2  = 0xe2, /* application marker                   */
+00084         M_APP3  = 0xe3, /* application marker                   */
+00085         M_APP4  = 0xe4, /* application marker                   */
+00086         M_APP5  = 0xe5, /* application marker                   */
+00087         M_APP6  = 0xe6, /* application marker                   */
+00088         M_APP7  = 0xe7, /* application marker                   */
+00089         M_APP8  = 0xe8, /* application marker                   */
+00090         M_APP9  = 0xe9, /* application marker                   */
+00091         M_APP10 = 0xea, /* application marker                   */
+00092         M_APP11 = 0xeb, /* application marker                   */
+00093         M_APP12 = 0xec, /* application marker                   */
+00094         M_APP13 = 0xed, /* application marker                   */
+00095         M_APP14 = 0xee, /* application marker, used by Adobe    */
+00096         M_APP15 = 0xef, /* application marker                   */
+00097 
+00098         M_JPG0  = 0xf0, /* reserved for JPEG extensions         */
+00099         M_JPG13 = 0xfd, /* reserved for JPEG extensions         */
+00100         M_COM   = 0xfe, /* comment                              */
+00101 
+00102         M_TEM   = 0x01  /* temporary use                        */
+00103 } JPEG_MARKER;
+00104 
+00105 
+00106 /*
+00107  * bFillPaletteDIB - fill the palette part of the imagesdata
+00108  *
+00109  * returns TRUE if the images must be a color image, otherwise FALSE;
+00110  */
+00111 static BOOL
+00112 bFillPaletteDIB(FILE *pFile, imagedata_type *pImg, BOOL bNewFormat)
+00113 {
+00114         int     iIndex;
+00115         BOOL    bIsColorPalette;
+00116 
+00117         fail(pFile == NULL);
+00118         fail(pImg == NULL);
+00119 
+00120         if (pImg->uiBitsPerComponent > 8) {
+00121                 /* No palette, image uses more than 256 colors */
+00122                 return TRUE;
+00123         }
+00124 
+00125         if (pImg->iColorsUsed <= 0) {
+00126                 /* Not specified, so compute the number of colors used */
+00127                 pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent;
+00128         }
+00129 
+00130         fail(pImg->iColorsUsed > 256);
+00131         if (pImg->iColorsUsed > 256) {
+00132                 pImg->iColorsUsed = 256;
+00133         }
+00134 
+00135         bIsColorPalette = FALSE;
+00136         for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) {
+00137                 /* From BGR order to RGB order */
+00138                 pImg->aucPalette[iIndex][2] = (UCHAR)iNextByte(pFile);
+00139                 pImg->aucPalette[iIndex][1] = (UCHAR)iNextByte(pFile);
+00140                 pImg->aucPalette[iIndex][0] = (UCHAR)iNextByte(pFile);
+00141                 if (bNewFormat) {
+00142                         (void)iNextByte(pFile);
+00143                 }
+00144                 NO_DBG_PRINT_BLOCK(pImg->aucPalette[iIndex], 3);
+00145                 if (pImg->aucPalette[iIndex][0] !=
+00146                      pImg->aucPalette[iIndex][1] ||
+00147                     pImg->aucPalette[iIndex][1] !=
+00148                      pImg->aucPalette[iIndex][2]) {
+00149                         bIsColorPalette = TRUE;
+00150                 }
+00151         }
+00152 
+00153         return bIsColorPalette;
+00154 } /* end of bFillPaletteDIB */
+00155 
+00156 /*
+00157  * bExamineDIB - Examine a DIB header
+00158  *
+00159  * return TRUE if successful, otherwise FALSE
+00160  */
+00161 static BOOL
+00162 bExamineDIB(FILE *pFile, imagedata_type *pImg)
+00163 {
+00164         size_t  tHeaderSize;
+00165         int     iPlanes, iCompression;
+00166 
+00167         tHeaderSize = (size_t)ulNextLong(pFile);
+00168         switch (tHeaderSize) {
+00169         case 12:
+00170                 pImg->iWidth = (int)usNextWord(pFile);
+00171                 pImg->iHeight = (int)usNextWord(pFile);
+00172                 iPlanes = (int)usNextWord(pFile);
+00173                 pImg->uiBitsPerComponent = (UINT)usNextWord(pFile);
+00174                 iCompression = BI_RGB;
+00175                 pImg->iColorsUsed = 0;
+00176                 break;
+00177         case 40:
+00178         case 64:
+00179                 pImg->iWidth = (int)ulNextLong(pFile);
+00180                 pImg->iHeight = (int)ulNextLong(pFile);
+00181                 iPlanes = (int)usNextWord(pFile);
+00182                 pImg->uiBitsPerComponent = (UINT)usNextWord(pFile);
+00183                 iCompression = (int)ulNextLong(pFile);
+00184                 (void)tSkipBytes(pFile, 12);
+00185                 pImg->iColorsUsed = (int)ulNextLong(pFile);
+00186                 (void)tSkipBytes(pFile, tHeaderSize - 36);
+00187                 break;
+00188         default:
+00189                 DBG_DEC(tHeaderSize);
+00190                 return FALSE;
+00191         }
+00192         DBG_DEC(pImg->iWidth);
+00193         DBG_DEC(pImg->iHeight);
+00194         DBG_DEC(pImg->uiBitsPerComponent);
+00195         DBG_DEC(iCompression);
+00196         DBG_DEC(pImg->iColorsUsed);
+00197 
+00198         /* Do some sanity checks with the parameters */
+00199         if (iPlanes != 1) {
+00200                 DBG_DEC(iPlanes);
+00201                 return FALSE;
+00202         }
+00203         if (pImg->iWidth <= 0 || pImg->iHeight <= 0) {
+00204                 DBG_DEC(pImg->iWidth);
+00205                 DBG_DEC(pImg->iHeight);
+00206                 return FALSE;
+00207         }
+00208         if (pImg->uiBitsPerComponent != 1 && pImg->uiBitsPerComponent != 4 &&
+00209             pImg->uiBitsPerComponent != 8 && pImg->uiBitsPerComponent != 24) {
+00210                 DBG_DEC(pImg->uiBitsPerComponent);
+00211                 return FALSE;
+00212         }
+00213         if (iCompression != BI_RGB &&
+00214             (pImg->uiBitsPerComponent == 1 || pImg->uiBitsPerComponent == 24)) {
+00215                 return FALSE;
+00216         }
+00217         if (iCompression == BI_RLE8 && pImg->uiBitsPerComponent == 4) {
+00218                 return FALSE;
+00219         }
+00220         if (iCompression == BI_RLE4 && pImg->uiBitsPerComponent == 8) {
+00221                 return FALSE;
+00222         }
+00223 
+00224         switch (iCompression) {
+00225         case BI_RGB:
+00226                 pImg->eCompression = compression_none;
+00227                 break;
+00228         case BI_RLE4:
+00229                 pImg->eCompression = compression_rle4;
+00230                 break;
+00231         case BI_RLE8:
+00232                 pImg->eCompression = compression_rle8;
+00233                 break;
+00234         default:
+00235                 DBG_DEC(iCompression);
+00236                 return FALSE;
+00237         }
+00238 
+00239         pImg->bColorImage = bFillPaletteDIB(pFile, pImg, tHeaderSize > 12);
+00240 
+00241         if (pImg->uiBitsPerComponent <= 8) {
+00242                 pImg->iComponents = 1;
+00243         } else {
+00244                 pImg->iComponents = (int)(pImg->uiBitsPerComponent / 8);
+00245         }
+00246 
+00247         return TRUE;
+00248 } /* end of bExamineDIB */
+00249 
+00250 /*
+00251  * iNextMarker - read the next JPEG marker
+00252  */
+00253 static int
+00254 iNextMarker(FILE *pFile)
+00255 {
+00256         int     iMarker;
+00257 
+00258         do {
+00259                 do {
+00260                         iMarker = iNextByte(pFile);
+00261                 } while (iMarker != 0xff && iMarker != EOF);
+00262                 if (iMarker == EOF) {
+00263                         return EOF;
+00264                 }
+00265                 do {
+00266                         iMarker = iNextByte(pFile);
+00267                 } while (iMarker == 0xff);
+00268         } while (iMarker == 0x00);                      /* repeat if ff/00 */
+00269 
+00270         return iMarker;
+00271 } /* end of iNextMarker */
+00272 
+00273 /*
+00274  * bExamineJPEG - Examine a JPEG header
+00275  *
+00276  * return TRUE if successful, otherwise FALSE
+00277  */
+00278 static BOOL
+00279 bExamineJPEG(FILE *pFile, imagedata_type *pImg)
+00280 {
+00281         size_t  tLength;
+00282         int     iMarker, iIndex;
+00283         char    appstring[10];
+00284         BOOL    bSOFDone;
+00285 
+00286         tLength = 0;
+00287         bSOFDone = FALSE;
+00288 
+00289         /* process JPEG markers */
+00290         while (!bSOFDone && (iMarker = iNextMarker(pFile)) != (int)M_EOI) {
+00291                 switch (iMarker) {
+00292                 case EOF:
+00293                         DBG_MSG("Error: unexpected end of JPEG file");
+00294                         return FALSE;
+00295         /* The following are not officially supported in PostScript level 2 */
+00296                 case M_SOF2:
+00297                 case M_SOF3:
+00298                 case M_SOF5:
+00299                 case M_SOF6:
+00300                 case M_SOF7:
+00301                 case M_SOF9:
+00302                 case M_SOF10:
+00303                 case M_SOF11:
+00304                 case M_SOF13:
+00305                 case M_SOF14:
+00306                 case M_SOF15:
+00307                         DBG_HEX(iMarker);
+00308                         return FALSE;
+00309                 case M_SOF0:
+00310                 case M_SOF1:
+00311                         tLength = (size_t)usNextWordBE(pFile);
+00312                         pImg->uiBitsPerComponent = (UINT)iNextByte(pFile);
+00313                         pImg->iHeight = (int)usNextWordBE(pFile);
+00314                         pImg->iWidth = (int)usNextWordBE(pFile);
+00315                         pImg->iComponents = iNextByte(pFile);
+00316                         bSOFDone = TRUE;
+00317                         break;
+00318                 case M_APP14:
+00319                 /*
+00320                  * Check for Adobe application marker. It is known (per Adobe's
+00321                  * TN5116) to contain the string "Adobe" at the start of the
+00322                  * APP14 marker.
+00323                  */
+00324                         tLength = (size_t)usNextWordBE(pFile);
+00325                         if (tLength < 12) {
+00326                                 (void)tSkipBytes(pFile, tLength - 2);
+00327                         } else {
+00328                                 for (iIndex = 0; iIndex < 5; iIndex++) {
+00329                                         appstring[iIndex] =
+00330                                                         (char)iNextByte(pFile);
+00331                                 }
+00332                                 appstring[5] = '\0';
+00333                                 if (STREQ(appstring, "Adobe")) {
+00334                                         pImg->bAdobe = TRUE;
+00335                                 }
+00336                                 (void)tSkipBytes(pFile, tLength - 7);
+00337                         }
+00338                         break;
+00339                 case M_SOI:             /* ignore markers without parameters */
+00340                 case M_EOI:
+00341                 case M_TEM:
+00342                 case M_RST0:
+00343                 case M_RST1:
+00344                 case M_RST2:
+00345                 case M_RST3:
+00346                 case M_RST4:
+00347                 case M_RST5:
+00348                 case M_RST6:
+00349                 case M_RST7:
+00350                         break;
+00351                 default:                /* skip variable length markers */
+00352                         tLength = (size_t)usNextWordBE(pFile);
+00353                         (void)tSkipBytes(pFile, tLength - 2);
+00354                         break;
+00355                 }
+00356         }
+00357 
+00358         DBG_DEC(pImg->iWidth);
+00359         DBG_DEC(pImg->iHeight);
+00360         DBG_DEC(pImg->uiBitsPerComponent);
+00361         DBG_DEC(pImg->iComponents);
+00362 
+00363         /* Do some sanity checks with the parameters */
+00364         if (pImg->iHeight <= 0 ||
+00365             pImg->iWidth <= 0 ||
+00366             pImg->iComponents <= 0) {
+00367                 DBG_DEC(pImg->iHeight);
+00368                 DBG_DEC(pImg->iWidth);
+00369                 DBG_DEC(pImg->iComponents);
+00370                 return FALSE;
+00371         }
+00372 
+00373         /* Some broken JPEG files have this but they print anyway... */
+00374         if (pImg->iComponents * 3 + 8 != (int)tLength) {
+00375                 DBG_MSG("Warning: SOF marker has incorrect length - ignored");
+00376         }
+00377 
+00378         if (pImg->uiBitsPerComponent != 8) {
+00379                 DBG_DEC(pImg->uiBitsPerComponent);
+00380                 DBG_MSG("Not supported in PostScript level 2");
+00381                 return FALSE;
+00382         }
+00383 
+00384         if (pImg->iComponents != 1 &&
+00385             pImg->iComponents != 3 &&
+00386             pImg->iComponents != 4) {
+00387                 DBG_DEC(pImg->iComponents);
+00388                 return FALSE;
+00389         }
+00390 
+00391         pImg->bColorImage = pImg->iComponents >= 3;
+00392         pImg->iColorsUsed = 0;
+00393         pImg->eCompression = compression_jpeg;
+00394 
+00395         return TRUE;
+00396 } /* end of bExamineJPEG */
+00397 
+00398 /*
+00399  * bFillPalettePNG - fill the palette part of the imagesdata
+00400  *
+00401  * returns TRUE if sucessful, otherwise FALSE;
+00402  */
+00403 static BOOL
+00404 bFillPalettePNG(FILE *pFile, imagedata_type *pImg, size_t tLength)
+00405 {
+00406         int     iIndex, iEntries;
+00407 
+00408         fail(pFile == NULL);
+00409         fail(pImg == NULL);
+00410 
+00411         if (pImg->uiBitsPerComponent > 8) {
+00412                 /* No palette, image uses more than 256 colors */
+00413                 return TRUE;
+00414         }
+00415 
+00416         if (!pImg->bColorImage) {
+00417                 /* Only color images can have a palette */
+00418                 return FALSE;
+00419         }
+00420 
+00421         if (tLength % 3 != 0) {
+00422                 /* Each palette entry takes three bytes */
+00423                 DBG_DEC(tLength);
+00424                 return FALSE;
+00425         }
+00426 
+00427         iEntries = (int)(tLength / 3);
+00428         DBG_DEC(iEntries);
+00429         pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent;
+00430         DBG_DEC(pImg->iColorsUsed);
+00431 
+00432         if (iEntries > 256) {
+00433                 DBG_DEC(iEntries);
+00434                 return FALSE;
+00435         }
+00436 
+00437         for (iIndex = 0; iIndex < iEntries; iIndex++) {
+00438                 pImg->aucPalette[iIndex][0] = (UCHAR)iNextByte(pFile);
+00439                 pImg->aucPalette[iIndex][1] = (UCHAR)iNextByte(pFile);
+00440                 pImg->aucPalette[iIndex][2] = (UCHAR)iNextByte(pFile);
+00441                 NO_DBG_PRINT_BLOCK(pImg->aucPalette[iIndex], 3);
+00442         }
+00443         for (;iIndex < pImg->iColorsUsed; iIndex++) {
+00444                 pImg->aucPalette[iIndex][0] = 0;
+00445                 pImg->aucPalette[iIndex][1] = 0;
+00446                 pImg->aucPalette[iIndex][2] = 0;
+00447         }
+00448 
+00449         return TRUE;
+00450 } /* end of bFillPalettePNG */
+00451 
+00452 /*
+00453  * bExaminePNG - Examine a PNG header
+00454  *
+00455  * return TRUE if successful, otherwise FALSE
+00456  */
+00457 static BOOL
+00458 bExaminePNG(FILE *pFile, imagedata_type *pImg)
+00459 {
+00460         size_t          tLength;
+00461         ULONG           ulLong1, ulLong2, ulName;
+00462         int             iIndex, iTmp;
+00463         int             iCompressionMethod, iFilterMethod, iInterlaceMethod;
+00464         int             iColor, iIncrement;
+00465         BOOL            bHasPalette, bHasAlpha;
+00466         UCHAR   aucBuf[4];
+00467 
+00468         /* Check signature */
+00469         ulLong1 = ulNextLongBE(pFile);
+00470         ulLong2 = ulNextLongBE(pFile);
+00471         if (ulLong1 != 0x89504e47UL || ulLong2 != 0x0d0a1a0aUL) {
+00472                 DBG_HEX(ulLong1);
+00473                 DBG_HEX(ulLong2);
+00474                 return FALSE;
+00475         }
+00476 
+00477         ulName = 0x00;
+00478         bHasPalette = FALSE;
+00479 
+00480         /* Examine chunks */
+00481         while (ulName != PNG_CN_IEND) {
+00482                 tLength = (size_t)ulNextLongBE(pFile);
+00483                 ulName = 0x00;
+00484                 for (iIndex = 0; iIndex < (int)elementsof(aucBuf); iIndex++) {
+00485                         aucBuf[iIndex] = (UCHAR)iNextByte(pFile);
+00486                         if (!isalpha(aucBuf[iIndex])) {
+00487                                 DBG_HEX(aucBuf[iIndex]);
+00488                                 return FALSE;
+00489                         }
+00490                         ulName <<= 8;
+00491                         ulName |= aucBuf[iIndex];
+00492                 }
+00493 
+00494                 switch (ulName) {
+00495                 case PNG_CN_IHDR:
+00496                         /* Header chunck */
+00497                         if (tLength < 13) {
+00498                                 DBG_DEC(tLength);
+00499                                 return FALSE;
+00500                         }
+00501                         pImg->iWidth = (int)ulNextLongBE(pFile);
+00502                         pImg->iHeight = (int)ulNextLongBE(pFile);
+00503                         pImg->uiBitsPerComponent = (UINT)iNextByte(pFile);
+00504                         iTmp = iNextByte(pFile);
+00505                         NO_DBG_HEX(iTmp);
+00506                         pImg->bColorImage = (iTmp & PNG_CB_COLOR) != 0;
+00507                         bHasPalette = (iTmp & PNG_CB_PALETTE) != 0;
+00508                         bHasAlpha = (iTmp & PNG_CB_ALPHA) != 0;
+00509                         if (bHasPalette && pImg->uiBitsPerComponent > 8) {
+00510                                 /* This should not happen */
+00511                                 return FALSE;
+00512                         }
+00513                         pImg->iComponents =
+00514                                 (bHasPalette || !pImg->bColorImage) ? 1 : 3;
+00515                         if (bHasAlpha) {
+00516                                 pImg->iComponents++;
+00517                         }
+00518                         iCompressionMethod = iNextByte(pFile);
+00519                         if (iCompressionMethod != 0) {
+00520                                 DBG_DEC(iCompressionMethod);
+00521                                 return FALSE;
+00522                         }
+00523                         iFilterMethod = iNextByte(pFile);
+00524                         if (iFilterMethod != 0) {
+00525                                 DBG_DEC(iFilterMethod);
+00526                                 return FALSE;
+00527                         }
+00528                         iInterlaceMethod = iNextByte(pFile);
+00529                         if (iInterlaceMethod != 0) {
+00530                                 DBG_DEC(iInterlaceMethod);
+00531                                 return FALSE;
+00532                         }
+00533                         pImg->iColorsUsed = 0;
+00534                         (void)tSkipBytes(pFile, tLength - 13 + 4);
+00535                         break;
+00536                 case PNG_CN_PLTE:
+00537                         if (!bHasPalette) {
+00538                                 return FALSE;
+00539                         }
+00540                         if (!bFillPalettePNG(pFile, pImg, tLength)) {
+00541                                 return FALSE;
+00542                         }
+00543                         (void)tSkipBytes(pFile, 4);
+00544                         break;
+00545                 default:
+00546                         (void)tSkipBytes(pFile, tLength + 4);
+00547                         break;
+00548                 }
+00549         }
+00550 
+00551         DBG_DEC(pImg->iWidth);
+00552         DBG_DEC(pImg->iHeight);
+00553         DBG_DEC(pImg->uiBitsPerComponent);
+00554         DBG_DEC(pImg->iColorsUsed);
+00555         DBG_DEC(pImg->iComponents);
+00556 
+00557         /* Do some sanity checks with the parameters */
+00558         if (pImg->iWidth <= 0 || pImg->iHeight <= 0) {
+00559                 return FALSE;
+00560         }
+00561 
+00562         if (pImg->uiBitsPerComponent != 1 && pImg->uiBitsPerComponent != 2 &&
+00563             pImg->uiBitsPerComponent != 4 && pImg->uiBitsPerComponent != 8 &&
+00564             pImg->uiBitsPerComponent != 16) {
+00565                 DBG_DEC(pImg->uiBitsPerComponent);
+00566                 return  FALSE;
+00567         }
+00568 
+00569         if (pImg->iComponents != 1 && pImg->iComponents != 3) {
+00570                 /* Not supported */
+00571                 DBG_DEC(pImg->iComponents);
+00572                 return FALSE;
+00573         }
+00574 
+00575         if (pImg->uiBitsPerComponent > 8) {
+00576                 /* Not supported */
+00577                 DBG_DEC(pImg->uiBitsPerComponent);
+00578                 return FALSE;
+00579         }
+00580 
+00581         if (pImg->iColorsUsed == 0 &&
+00582             pImg->iComponents == 1 &&
+00583             pImg->uiBitsPerComponent <= 4) {
+00584                 /*
+00585                  * No palette is supplied, but PostScript needs one in these
+00586                  * cases, so we add a default palette here
+00587                  */
+00588                 pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent;
+00589                 iIncrement = 0xff / (pImg->iColorsUsed - 1);
+00590                 for (iIndex = 0, iColor = 0x00;
+00591                      iIndex < pImg->iColorsUsed;
+00592                      iIndex++, iColor += iIncrement) {
+00593                         pImg->aucPalette[iIndex][0] = (UCHAR)iColor;
+00594                         pImg->aucPalette[iIndex][1] = (UCHAR)iColor;
+00595                         pImg->aucPalette[iIndex][2] = (UCHAR)iColor;
+00596                 }
+00597                 /* Just to be sure */
+00598                 pImg->bColorImage = FALSE;
+00599         }
+00600 
+00601         pImg->eCompression = compression_zlib;
+00602 
+00603         return TRUE;
+00604 } /* end of bExaminePNG */
+00605 
+00606 /*
+00607  * bExamineWMF - Examine a WMF header
+00608  *
+00609  * return TRUE if successful, otherwise FALSE
+00610  */
+00611 static BOOL
+00612 bExamineWMF(FILE *pFile, imagedata_type *pImg)
+00613 {
+00614         ULONG   ulFileSize, ulMaxRecord, ulMagic;
+00615         USHORT  usType, usHeaderSize, usVersion, usNoObjects;
+00616 
+00617         usType = usNextWord(pFile);
+00618         usHeaderSize = usNextWord(pFile);
+00619         ulMagic = ((ULONG)usHeaderSize << 16) | (ULONG)usType;
+00620         usVersion = usNextWord(pFile);
+00621         ulFileSize = ulNextLong(pFile);
+00622         usNoObjects = usNextWord(pFile);
+00623         ulMaxRecord = ulNextLong(pFile);
+00624 
+00625         DBG_HEX(ulMagic);
+00626         DBG_DEC(usType);
+00627         DBG_DEC(usHeaderSize);
+00628         DBG_HEX(usVersion);
+00629         DBG_DEC(ulFileSize);
+00630         DBG_DEC(usNoObjects);
+00631         DBG_DEC(ulMaxRecord);
+00632 
+00633         return FALSE;
+00634 } /* end of bExamineWMF */
+00635 
+00636 #if !defined(__riscos)
+00637 /*
+00638  * vImage2Papersize - make sure the image fits on the paper
+00639  *
+00640  * This function should not be needed if Word would do a proper job
+00641  */
+00642 static void
+00643 vImage2Papersize(imagedata_type *pImg)
+00644 {
+00645         static int      iNetPageHeight = -1;
+00646         static int      iNetPageWidth = -1;
+00647         options_type    tOptions;
+00648         double  dVerFactor, dHorFactor, dFactor;
+00649 
+00650         DBG_MSG("vImage2Papersize");
+00651 
+00652         fail(pImg == NULL);
+00653 
+00654         if (iNetPageHeight < 0 || iNetPageWidth < 0) {
+00655                 /* Get the page dimensions from the options */
+00656                 vGetOptions(&tOptions);
+00657                 /* Add 999 to err on the save side */
+00658                 iNetPageHeight = tOptions.iPageHeight -
+00659                                 (lDrawUnits2MilliPoints(
+00660                                         PS_TOP_MARGIN + PS_BOTTOM_MARGIN) +
+00661                                         999) / 1000;
+00662                 iNetPageWidth = tOptions.iPageWidth -
+00663                                 (lDrawUnits2MilliPoints(
+00664                                         PS_LEFT_MARGIN + PS_RIGHT_MARGIN) +
+00665                                         999) / 1000;
+00666                 DBG_DEC(iNetPageHeight);
+00667                 DBG_DEC(iNetPageWidth);
+00668         }
+00669 
+00670         if (pImg->iVerSizeScaled < iNetPageHeight &&
+00671             pImg->iHorSizeScaled < iNetPageWidth) {
+00672                 /* The image fits on the paper */
+00673                 return;
+00674         }
+00675 
+00676         dVerFactor = (double)iNetPageHeight / (double)pImg->iVerSizeScaled;
+00677         dHorFactor = (double)iNetPageWidth / (double)pImg->iHorSizeScaled;
+00678         dFactor = min(dVerFactor, dHorFactor);
+00679         DBG_FLT(dFactor);
+00680         /* Round down, just to be on the save side */
+00681         pImg->iVerSizeScaled = (int)(pImg->iVerSizeScaled * dFactor);
+00682         pImg->iHorSizeScaled = (int)(pImg->iHorSizeScaled * dFactor);
+00683 } /* end of vImage2Papersize */
+00684 #endif /* !__riscos */
+00685 
+00686 /*
+00687  * tFind6Image - skip until the image is found
+00688  *
+00689  * Find the image in Word 6/7 files
+00690  *
+00691  * returns the new position when a image is found, otherwise -1
+00692  */
+00693 static size_t
+00694 tFind6Image(FILE *pFile, size_t tPosition, size_t tLength,
+00695         imagetype_enum *peImageType)
+00696 {
+00697         ULONG   ulMarker;
+00698         size_t  tRecordLength, tToSkip;
+00699         USHORT  usMarker;
+00700 
+00701         fail(pFile == NULL);
+00702         fail(peImageType == NULL);
+00703 
+00704         *peImageType = imagetype_is_unknown;
+00705         if (tPosition + 18 >= tLength) {
+00706                 return (size_t)-1;
+00707         }
+00708 
+00709         ulMarker = ulNextLong(pFile);
+00710         if (ulMarker != 0x00090001) {
+00711                 DBG_HEX(ulMarker);
+00712                 return (size_t)-1;
+00713         }
+00714         usMarker = usNextWord(pFile);
+00715         if (usMarker != 0x0300) {
+00716                 DBG_HEX(usMarker);
+00717                 return (size_t)-1;
+00718         }
+00719         (void)tSkipBytes(pFile, 10);
+00720         usMarker = usNextWord(pFile);
+00721         if (usMarker != 0x0000) {
+00722                 DBG_HEX(usMarker);
+00723                 return (size_t)-1;
+00724         }
+00725         tPosition += 18;
+00726 
+00727         while (tPosition + 6 <= tLength) {
+00728                 tRecordLength = (size_t)ulNextLong(pFile);
+00729                 usMarker = usNextWord(pFile);
+00730                 tPosition += 6;
+00731                 NO_DBG_DEC(tRecordLength);
+00732                 NO_DBG_HEX(usMarker);
+00733                 switch (usMarker) {
+00734                 case 0x0000:
+00735                         DBG_HEX(ulGetDataOffset(pFile));
+00736                         return (size_t)-1;
+00737                 case 0x0b41:
+00738                         DBG_MSG("DIB");
+00739                         *peImageType = imagetype_is_dib;
+00740                         tPosition += tSkipBytes(pFile, 20);
+00741                         return tPosition;
+00742                 case 0x0f43:
+00743                         DBG_MSG("DIB");
+00744                         *peImageType = imagetype_is_dib;
+00745                         tPosition += tSkipBytes(pFile, 22);
+00746                         return tPosition;
+00747                 default:
+00748                         if (tRecordLength < 3) {
+00749                                 break;
+00750                         }
+00751                         if (tRecordLength > SIZE_T_MAX / 2) {
+00752                                 /*
+00753                                  * No need to compute the number of bytes
+00754                                  * to skip
+00755                                  */
+00756                                 DBG_DEC(tRecordLength);
+00757                                 DBG_HEX(tRecordLength);
+00758                                 DBG_FIXME();
+00759                                 return (size_t)-1;
+00760                         }
+00761                         tToSkip = tRecordLength * 2 - 6;
+00762                         if (tToSkip > tLength - tPosition) {
+00763                                 /* You can't skip this number of bytes */
+00764                                 DBG_DEC(tToSkip);
+00765                                 DBG_DEC(tLength - tPosition);
+00766                                 return (size_t)-1;
+00767                         }
+00768                         tPosition += tSkipBytes(pFile, tToSkip);
+00769                         break;
+00770                 }
+00771         }
+00772 
+00773         return (size_t)-1;
+00774 } /* end of tFind6Image */
+00775 
+00776 /*
+00777  * tFind8Image - skip until the image is found
+00778  *
+00779  * Find the image in Word 8/9/10 files
+00780  *
+00781  * returns the new position when a image is found, otherwise -1
+00782  */
+00783 static size_t
+00784 tFind8Image(FILE *pFile, size_t tPosition, size_t tLength,
+00785         imagetype_enum *peImageType)
+00786 {
+00787         size_t  tRecordLength, tNameLen;
+00788         USHORT  usRecordVersion, usRecordType, usRecordInstance;
+00789         USHORT  usTmp;
+00790 
+00791         fail(pFile == NULL);
+00792         fail(peImageType == NULL);
+00793 
+00794         *peImageType = imagetype_is_unknown;
+00795         while (tPosition + 8 <= tLength) {
+00796                 usTmp = usNextWord(pFile);
+00797                 usRecordVersion = usTmp & 0x000f;
+00798                 usRecordInstance = usTmp >> 4;
+00799                 usRecordType = usNextWord(pFile);
+00800                 tRecordLength = (size_t)ulNextLong(pFile);
+00801                 tPosition += 8;
+00802                 NO_DBG_HEX(usRecordVersion);
+00803                 NO_DBG_HEX(usRecordInstance);
+00804                 NO_DBG_HEX(usRecordType);
+00805                 NO_DBG_DEC(tRecordLength);
+00806                 switch (usRecordType) {
+00807                 case 0xf000: case 0xf001: case 0xf002: case 0xf003:
+00808                 case 0xf004: case 0xf005:
+00809                         break;
+00810                 case 0xf007:
+00811                         tPosition += tSkipBytes(pFile, 33);
+00812                         tNameLen = (size_t)iNextByte(pFile);
+00813                         tPosition++;
+00814                         DBG_DEC_C(tNameLen != 0, tNameLen);
+00815                         tPosition += tSkipBytes(pFile, 2 + tNameLen * 2);
+00816                         break;
+00817                 case 0xf008:
+00818                         tPosition += tSkipBytes(pFile, 8);
+00819                         break;
+00820                 case 0xf009:
+00821                         tPosition += tSkipBytes(pFile, 16);
+00822                         break;
+00823                 case 0xf006: case 0xf00a: case 0xf00b: case 0xf00d:
+00824                 case 0xf00e: case 0xf00f: case 0xf010: case 0xf011:
+00825                 case 0xf122:
+00826                         tPosition += tSkipBytes(pFile, tRecordLength);
+00827                         break;
+00828                 case 0xf01a:
+00829                         DBG_MSG("EMF");
+00830                         *peImageType = imagetype_is_emf;
+00831                         tPosition += tSkipBytes(pFile, 50);
+00832                         if ((usRecordInstance ^ MSOBI_EMF) == 1) {
+00833                                 tPosition += tSkipBytes(pFile, 16);
+00834                         }
+00835                         return tPosition;
+00836                 case 0xf01b:
+00837                         DBG_MSG("WMF");
+00838                         *peImageType = imagetype_is_wmf;
+00839                         tPosition += tSkipBytes(pFile, 50);
+00840                         if ((usRecordInstance ^ MSOBI_WMF) == 1) {
+00841                                 tPosition += tSkipBytes(pFile, 16);
+00842                         }
+00843                         return tPosition;
+00844                 case 0xf01c:
+00845                         DBG_MSG("PICT");
+00846                         *peImageType = imagetype_is_pict;
+00847                         tPosition += tSkipBytes(pFile, 50);
+00848                         if ((usRecordInstance ^ MSOBI_PICT) == 1) {
+00849                                 tPosition += tSkipBytes(pFile, 16);
+00850                         }
+00851                         return tPosition;
+00852                 case 0xf01d:
+00853                         DBG_MSG("JPEG");
+00854                         *peImageType = imagetype_is_jpeg;
+00855                         tPosition += tSkipBytes(pFile, 17);
+00856                         if ((usRecordInstance ^ MSOBI_JPEG) == 1) {
+00857                                 tPosition += tSkipBytes(pFile, 16);
+00858                         }
+00859                         return tPosition;
+00860                 case 0xf01e:
+00861                         DBG_MSG("PNG");
+00862                         *peImageType = imagetype_is_png;
+00863                         tPosition += tSkipBytes(pFile, 17);
+00864                         if ((usRecordInstance ^ MSOBI_PNG) == 1) {
+00865                                 tPosition += tSkipBytes(pFile, 16);
+00866                         }
+00867                         return tPosition;
+00868                 case 0xf01f:
+00869                         DBG_MSG("DIB");
+00870                         /* DIB is a BMP minus its 14 byte header */
+00871                         *peImageType = imagetype_is_dib;
+00872                         tPosition += tSkipBytes(pFile, 17);
+00873                         if ((usRecordInstance ^ MSOBI_DIB) == 1) {
+00874                                 tPosition += tSkipBytes(pFile, 16);
+00875                         }
+00876                         return tPosition;
+00877                 case 0xf00c:
+00878                 default:
+00879                         DBG_HEX(usRecordType);
+00880                         DBG_DEC_C(tRecordLength % 4 != 0, tRecordLength);
+00881                         DBG_FIXME();
+00882                         return (size_t)-1;
+00883                 }
+00884         }
+00885 
+00886         return (size_t)-1;
+00887 } /* end of tFind8Image */
+00888 
+00889 /*
+00890  * eExamineImage - Examine the image
+00891  *
+00892  * Returns an indication of the amount of information found
+00893  */
+00894 image_info_enum
+00895 eExamineImage(FILE *pFile, ULONG ulFileOffsetImage, imagedata_type *pImg)
+00896 {
+00897         long    lTmp;
+00898         size_t  tWordHeaderLen, tLength, tPos;
+00899         int     iType, iHorSize, iVerSize;
+00900         USHORT  usHorScalingFactor, usVerScalingFactor;
+00901 
+00902         if (ulFileOffsetImage == FC_INVALID) {
+00903                 return image_no_information;
+00904         }
+00905         DBG_HEX(ulFileOffsetImage);
+00906 
+00907         if (!bSetDataOffset(pFile, ulFileOffsetImage)) {
+00908                 return image_no_information;
+00909         }
+00910 
+00911         tLength = (size_t)ulNextLong(pFile);
+00912         DBG_DEC(tLength);
+00913         if (tLength < 46) {
+00914                 /* Smaller than the smallest known header */
+00915                 DBG_FIXME();
+00916                 return image_no_information;
+00917         }
+00918         tWordHeaderLen = (size_t)usNextWord(pFile);
+00919         DBG_DEC(tWordHeaderLen);
+00920         fail(tWordHeaderLen != 46 &&
+00921                 tWordHeaderLen != 58 &&
+00922                 tWordHeaderLen != 68);
+00923 
+00924         if (tLength < tWordHeaderLen) {
+00925                 /* Smaller than the current header */
+00926                 return image_no_information;
+00927         }
+00928         iType = (int)usNextWord(pFile);
+00929         DBG_DEC(iType);
+00930         (void)tSkipBytes(pFile, 28 - 8);
+00931 
+00932         lTmp = lTwips2MilliPoints(usNextWord(pFile));
+00933         iHorSize = (int)(lTmp / 1000);
+00934         if (lTmp % 1000 != 0) {
+00935                 iHorSize++;
+00936         }
+00937         DBG_DEC(iHorSize);
+00938         lTmp = lTwips2MilliPoints(usNextWord(pFile));
+00939         iVerSize = (int)(lTmp / 1000);
+00940         if (lTmp % 1000 != 0) {
+00941                 iVerSize++;
+00942         }
+00943         DBG_DEC(iVerSize);
+00944 
+00945         usHorScalingFactor = usNextWord(pFile);
+00946         DBG_DEC(usHorScalingFactor);
+00947         usVerScalingFactor = usNextWord(pFile);
+00948         DBG_DEC(usVerScalingFactor);
+00949 
+00950         /* Sanity checks */
+00951         lTmp = (long)iHorSize * (long)usHorScalingFactor;
+00952         if (lTmp < 2835) {
+00953                 /* This image would be less than 1 millimeter wide */
+00954                 DBG_DEC(lTmp);
+00955                 return image_no_information;
+00956         }
+00957         lTmp = (long)iVerSize * (long)usVerScalingFactor;
+00958         if (lTmp < 2835) {
+00959                 /* This image would be less than 1 millimeter high */
+00960                 DBG_DEC(lTmp);
+00961                 return image_no_information;
+00962         }
+00963 
+00964         /* Skip the rest of the header */
+00965         (void)tSkipBytes(pFile, tWordHeaderLen - 36);
+00966         tPos = tWordHeaderLen;
+00967 
+00968         (void)memset(pImg, 0, sizeof(*pImg));
+00969 
+00970         switch (iType) {
+00971         case   7:
+00972         case   8:
+00973                 tPos = tFind6Image(pFile, tPos, tLength, &pImg->eImageType);
+00974                 if (tPos == (size_t)-1) {
+00975                         /* No image found */
+00976                         return image_no_information;
+00977                 }
+00978                 DBG_HEX(tPos);
+00979                 break;
+00980         case  94:       /* Word 6/7, no image just a pathname */
+00981                 pImg->eImageType = imagetype_is_external;
+00982                 DBG_HEX(ulFileOffsetImage + tPos);
+00983                 break;
+00984         case 100:
+00985                 tPos = tFind8Image(pFile, tPos, tLength, &pImg->eImageType);
+00986                 if (tPos == (size_t)-1) {
+00987                         /* No image found */
+00988                         return image_no_information;
+00989                 }
+00990                 DBG_HEX(tPos);
+00991                 break;
+00992         case 102:       /* Word 8/9/10, no image just a pathname or URL */
+00993                 pImg->eImageType = imagetype_is_external;
+00994                 DBG_HEX(ulFileOffsetImage + tPos);
+00995                 break;
+00996         default:
+00997                 DBG_DEC(iType);
+00998                 DBG_HEX(ulFileOffsetImage + tPos);
+00999                 DBG_FIXME();
+01000                 return image_no_information;
+01001         }
+01002 
+01003         /* Minimal information is now available */
+01004         pImg->tLength = tLength;
+01005         pImg->tPosition = tPos;
+01006         pImg->iHorSizeScaled =
+01007                 (int)(((long)iHorSize * (long)usHorScalingFactor + 500) / 1000);
+01008         pImg->iVerSizeScaled =
+01009                 (int)(((long)iVerSize * (long)usVerScalingFactor + 500) / 1000);
+01010 #if !defined(__riscos)
+01011         vImage2Papersize(pImg);
+01012 #endif /* !__riscos */
+01013 
+01014         /* Image type specific examinations */
+01015         switch (pImg->eImageType) {
+01016         case imagetype_is_dib:
+01017                 if (bExamineDIB(pFile, pImg)) {
+01018                         return image_full_information;
+01019                 }
+01020                 return image_minimal_information;
+01021         case imagetype_is_jpeg:
+01022                 if (bExamineJPEG(pFile, pImg)) {
+01023                         return image_full_information;
+01024                 }
+01025                 return image_minimal_information;
+01026         case imagetype_is_png:
+01027                 if (bExaminePNG(pFile, pImg)) {
+01028                         return image_full_information;
+01029                 }
+01030                 return image_minimal_information;
+01031         case imagetype_is_wmf:
+01032                 if (bExamineWMF(pFile, pImg)) {
+01033                         return image_full_information;
+01034                 }
+01035                 return image_minimal_information;
+01036         case imagetype_is_emf:
+01037         case imagetype_is_pict:
+01038         case imagetype_is_external:
+01039                 return image_minimal_information;
+01040         case imagetype_is_unknown:
+01041         default:
+01042                 return image_no_information;
+01043         }
+01044 } /* end of eExamineImage */
+
+
Generated by  + +doxygen 1.6.2
+ +