diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/imgexam_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/imgexam_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1060 +0,0 @@ - - - - -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
- -