00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <string.h>
00018 #include <ctype.h>
00019 #include "antiword.h"
00020
00021
00022 #define BI_RGB 0
00023 #define BI_RLE8 1
00024 #define BI_RLE4 2
00025
00026
00027 #define PNG_CB_PALETTE 0x01
00028 #define PNG_CB_COLOR 0x02
00029 #define PNG_CB_ALPHA 0x04
00030
00031
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
00040 typedef enum {
00041 M_SOF0 = 0xc0,
00042 M_SOF1 = 0xc1,
00043 M_SOF2 = 0xc2,
00044 M_SOF3 = 0xc3,
00045
00046 M_SOF5 = 0xc5,
00047 M_SOF6 = 0xc6,
00048 M_SOF7 = 0xc7,
00049
00050 M_JPG = 0xc8,
00051 M_SOF9 = 0xc9,
00052 M_SOF10 = 0xca,
00053 M_SOF11 = 0xcb,
00054
00055 M_SOF13 = 0xcd,
00056 M_SOF14 = 0xce,
00057 M_SOF15 = 0xcf,
00058
00059 M_DHT = 0xc4,
00060
00061 M_DAC = 0xcc,
00062
00063 M_RST0 = 0xd0,
00064 M_RST1 = 0xd1,
00065 M_RST2 = 0xd2,
00066 M_RST3 = 0xd3,
00067 M_RST4 = 0xd4,
00068 M_RST5 = 0xd5,
00069 M_RST6 = 0xd6,
00070 M_RST7 = 0xd7,
00071
00072 M_SOI = 0xd8,
00073 M_EOI = 0xd9,
00074 M_SOS = 0xda,
00075 M_DQT = 0xdb,
00076 M_DNL = 0xdc,
00077 M_DRI = 0xdd,
00078 M_DHP = 0xde,
00079 M_EXP = 0xdf,
00080
00081 M_APP0 = 0xe0,
00082 M_APP1 = 0xe1,
00083 M_APP2 = 0xe2,
00084 M_APP3 = 0xe3,
00085 M_APP4 = 0xe4,
00086 M_APP5 = 0xe5,
00087 M_APP6 = 0xe6,
00088 M_APP7 = 0xe7,
00089 M_APP8 = 0xe8,
00090 M_APP9 = 0xe9,
00091 M_APP10 = 0xea,
00092 M_APP11 = 0xeb,
00093 M_APP12 = 0xec,
00094 M_APP13 = 0xed,
00095 M_APP14 = 0xee,
00096 M_APP15 = 0xef,
00097
00098 M_JPG0 = 0xf0,
00099 M_JPG13 = 0xfd,
00100 M_COM = 0xfe,
00101
00102 M_TEM = 0x01
00103 } JPEG_MARKER;
00104
00105
00106
00107
00108
00109
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
00122 return TRUE;
00123 }
00124
00125 if (pImg->iColorsUsed <= 0) {
00126
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
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 }
00155
00156
00157
00158
00159
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
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 }
00249
00250
00251
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);
00269
00270 return iMarker;
00271 }
00272
00273
00274
00275
00276
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
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
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
00321
00322
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:
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:
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
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
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 }
00397
00398
00399
00400
00401
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
00413 return TRUE;
00414 }
00415
00416 if (!pImg->bColorImage) {
00417
00418 return FALSE;
00419 }
00420
00421 if (tLength % 3 != 0) {
00422
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 }
00451
00452
00453
00454
00455
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
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
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
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
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
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
00571 DBG_DEC(pImg->iComponents);
00572 return FALSE;
00573 }
00574
00575 if (pImg->uiBitsPerComponent > 8) {
00576
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
00586
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
00598 pImg->bColorImage = FALSE;
00599 }
00600
00601 pImg->eCompression = compression_zlib;
00602
00603 return TRUE;
00604 }
00605
00606
00607
00608
00609
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 }
00635
00636 #if !defined(__riscos)
00637
00638
00639
00640
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
00656 vGetOptions(&tOptions);
00657
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
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
00681 pImg->iVerSizeScaled = (int)(pImg->iVerSizeScaled * dFactor);
00682 pImg->iHorSizeScaled = (int)(pImg->iHorSizeScaled * dFactor);
00683 }
00684 #endif
00685
00686
00687
00688
00689
00690
00691
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
00754
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
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 }
00775
00776
00777
00778
00779
00780
00781
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
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 }
00888
00889
00890
00891
00892
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
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
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
00951 lTmp = (long)iHorSize * (long)usHorScalingFactor;
00952 if (lTmp < 2835) {
00953
00954 DBG_DEC(lTmp);
00955 return image_no_information;
00956 }
00957 lTmp = (long)iVerSize * (long)usVerScalingFactor;
00958 if (lTmp < 2835) {
00959
00960 DBG_DEC(lTmp);
00961 return image_no_information;
00962 }
00963
00964
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
00976 return image_no_information;
00977 }
00978 DBG_HEX(tPos);
00979 break;
00980 case 94:
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
00988 return image_no_information;
00989 }
00990 DBG_HEX(tPos);
00991 break;
00992 case 102:
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
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
01013
01014
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 }