📄 imgexam.c
字号:
if (iFilterMethod != 0) { DBG_DEC(iFilterMethod); return FALSE; } iInterlaceMethod = iNextByte(pFile); if (iInterlaceMethod != 0) { DBG_DEC(iInterlaceMethod); return FALSE; } pImg->iColorsUsed = 0; (void)tSkipBytes(pFile, tLength - 13 + 4); break; case PNG_CN_PLTE: if (!bHasPalette) { return FALSE; } if (!bFillPalettePNG(pFile, pImg, tLength)) { return FALSE; } (void)tSkipBytes(pFile, 4); break; default: (void)tSkipBytes(pFile, tLength + 4); break; } } DBG_DEC(pImg->iWidth); DBG_DEC(pImg->iHeight); DBG_DEC(pImg->uiBitsPerComponent); DBG_DEC(pImg->iColorsUsed); DBG_DEC(pImg->iComponents); /* Do some sanity checks with the parameters */ if (pImg->iWidth <= 0 || pImg->iHeight <= 0) { return FALSE; } if (pImg->uiBitsPerComponent != 1 && pImg->uiBitsPerComponent != 2 && pImg->uiBitsPerComponent != 4 && pImg->uiBitsPerComponent != 8 && pImg->uiBitsPerComponent != 16) { DBG_DEC(pImg->uiBitsPerComponent); return FALSE; } if (pImg->iComponents != 1 && pImg->iComponents != 3) { /* Not supported */ DBG_DEC(pImg->iComponents); return FALSE; } if (pImg->uiBitsPerComponent > 8) { /* Not supported */ DBG_DEC(pImg->uiBitsPerComponent); return FALSE; } if (pImg->iColorsUsed == 0 && pImg->iComponents == 1 && pImg->uiBitsPerComponent <= 4) { /* * No palette is supplied, but PostScript needs one in these * cases, so we add a default palette here */ pImg->iColorsUsed = 1 << pImg->uiBitsPerComponent; iIncrement = 0xff / (pImg->iColorsUsed - 1); for (iIndex = 0, iColor = 0x00; iIndex < pImg->iColorsUsed; iIndex++, iColor += iIncrement) { pImg->aucPalette[iIndex][0] = (UCHAR)iColor; pImg->aucPalette[iIndex][1] = (UCHAR)iColor; pImg->aucPalette[iIndex][2] = (UCHAR)iColor; } /* Just to be sure */ pImg->bColorImage = FALSE; } pImg->eCompression = compression_zlib; return TRUE;} /* end of bExaminePNG *//* * bExamineWMF - Examine a WMF header * * return TRUE if successful, otherwise FALSE */static BOOLbExamineWMF(FILE *pFile, imagedata_type *pImg){ ULONG ulFileSize, ulMaxRecord, ulMagic; USHORT usType, usHeaderSize, usVersion, usNoObjects; usType = usNextWord(pFile); usHeaderSize = usNextWord(pFile); ulMagic = ((ULONG)usHeaderSize << 16) | (ULONG)usType; usVersion = usNextWord(pFile); ulFileSize = ulNextLong(pFile); usNoObjects = usNextWord(pFile); ulMaxRecord = ulNextLong(pFile); DBG_HEX(ulMagic); DBG_DEC(usType); DBG_DEC(usHeaderSize); DBG_HEX(usVersion); DBG_DEC(ulFileSize); DBG_DEC(usNoObjects); DBG_DEC(ulMaxRecord); return FALSE;} /* end of bExamineWMF */#if !defined(__riscos)/* * vImage2Papersize - make sure the image fits on the paper * * This function should not be needed if Word would do a proper job */static voidvImage2Papersize(imagedata_type *pImg){ static int iNetPageHeight = -1; static int iNetPageWidth = -1; options_type tOptions; double dVerFactor, dHorFactor, dFactor; DBG_MSG("vImage2Papersize"); fail(pImg == NULL); if (iNetPageHeight < 0 || iNetPageWidth < 0) { /* Get the page dimensions from the options */ vGetOptions(&tOptions); /* Add 999 to err on the save side */ iNetPageHeight = tOptions.iPageHeight - (lDrawUnits2MilliPoints( PS_TOP_MARGIN + PS_BOTTOM_MARGIN) + 999) / 1000; iNetPageWidth = tOptions.iPageWidth - (lDrawUnits2MilliPoints( PS_LEFT_MARGIN + PS_RIGHT_MARGIN) + 999) / 1000; DBG_DEC(iNetPageHeight); DBG_DEC(iNetPageWidth); } if (pImg->iVerSizeScaled < iNetPageHeight && pImg->iHorSizeScaled < iNetPageWidth) { /* The image fits on the paper */ return; } dVerFactor = (double)iNetPageHeight / (double)pImg->iVerSizeScaled; dHorFactor = (double)iNetPageWidth / (double)pImg->iHorSizeScaled; dFactor = min(dVerFactor, dHorFactor); DBG_FLT(dFactor); /* Round down, just to be on the save side */ pImg->iVerSizeScaled = (int)(pImg->iVerSizeScaled * dFactor); pImg->iHorSizeScaled = (int)(pImg->iHorSizeScaled * dFactor);} /* end of vImage2Papersize */#endif /* !__riscos *//* * tFind6Image - skip until the image is found * * Find the image in Word 6/7 files * * returns the new position when a image is found, otherwise -1 */static size_ttFind6Image(FILE *pFile, size_t tPosition, size_t tLength, imagetype_enum *peImageType){ ULONG ulMarker; size_t tRecordLength, tToSkip; USHORT usMarker; fail(pFile == NULL); fail(peImageType == NULL); *peImageType = imagetype_is_unknown; if (tPosition + 18 >= tLength) { return (size_t)-1; } ulMarker = ulNextLong(pFile); if (ulMarker != 0x00090001) { DBG_HEX(ulMarker); return (size_t)-1; } usMarker = usNextWord(pFile); if (usMarker != 0x0300) { DBG_HEX(usMarker); return (size_t)-1; } (void)tSkipBytes(pFile, 10); usMarker = usNextWord(pFile); if (usMarker != 0x0000) { DBG_HEX(usMarker); return (size_t)-1; } tPosition += 18; while (tPosition + 6 <= tLength) { tRecordLength = (size_t)ulNextLong(pFile); usMarker = usNextWord(pFile); tPosition += 6; NO_DBG_DEC(tRecordLength); NO_DBG_HEX(usMarker); switch (usMarker) { case 0x0000: DBG_HEX(ulGetDataOffset(pFile)); return (size_t)-1; case 0x0b41: DBG_MSG("DIB"); *peImageType = imagetype_is_dib; tPosition += tSkipBytes(pFile, 20); return tPosition; case 0x0f43: DBG_MSG("DIB"); *peImageType = imagetype_is_dib; tPosition += tSkipBytes(pFile, 22); return tPosition; default: if (tRecordLength < 3) { break; } if (tRecordLength > SIZE_T_MAX / 2) { /* * No need to compute the number of bytes * to skip */ DBG_DEC(tRecordLength); DBG_HEX(tRecordLength); DBG_FIXME(); return (size_t)-1; } tToSkip = tRecordLength * 2 - 6; if (tToSkip > tLength - tPosition) { /* You can't skip this number of bytes */ DBG_DEC(tToSkip); DBG_DEC(tLength - tPosition); return (size_t)-1; } tPosition += tSkipBytes(pFile, tToSkip); break; } } return (size_t)-1;} /* end of tFind6Image *//* * tFind8Image - skip until the image is found * * Find the image in Word 8/9/10 files * * returns the new position when a image is found, otherwise -1 */static size_ttFind8Image(FILE *pFile, size_t tPosition, size_t tLength, imagetype_enum *peImageType){ size_t tRecordLength, tNameLen; USHORT usRecordVersion, usRecordType, usRecordInstance; USHORT usTmp; fail(pFile == NULL); fail(peImageType == NULL); *peImageType = imagetype_is_unknown; while (tPosition + 8 <= tLength) { usTmp = usNextWord(pFile); usRecordVersion = usTmp & 0x000f; usRecordInstance = usTmp >> 4; usRecordType = usNextWord(pFile); tRecordLength = (size_t)ulNextLong(pFile); tPosition += 8; NO_DBG_HEX(usRecordVersion); NO_DBG_HEX(usRecordInstance); NO_DBG_HEX(usRecordType); NO_DBG_DEC(tRecordLength); switch (usRecordType) { case 0xf000: case 0xf001: case 0xf002: case 0xf003: case 0xf004: case 0xf005: break; case 0xf007: tPosition += tSkipBytes(pFile, 33); tNameLen = (size_t)iNextByte(pFile); tPosition++; DBG_DEC_C(tNameLen != 0, tNameLen); tPosition += tSkipBytes(pFile, 2 + tNameLen * 2); break; case 0xf008: tPosition += tSkipBytes(pFile, 8); break; case 0xf009: tPosition += tSkipBytes(pFile, 16); break; case 0xf006: case 0xf00a: case 0xf00b: case 0xf00d: case 0xf00e: case 0xf00f: case 0xf010: case 0xf011: case 0xf122: tPosition += tSkipBytes(pFile, tRecordLength); break; case 0xf01a: DBG_MSG("EMF"); *peImageType = imagetype_is_emf; tPosition += tSkipBytes(pFile, 50); if ((usRecordInstance ^ MSOBI_EMF) == 1) { tPosition += tSkipBytes(pFile, 16); } return tPosition; case 0xf01b: DBG_MSG("WMF"); *peImageType = imagetype_is_wmf; tPosition += tSkipBytes(pFile, 50); if ((usRecordInstance ^ MSOBI_WMF) == 1) { tPosition += tSkipBytes(pFile, 16); } return tPosition; case 0xf01c: DBG_MSG("PICT"); *peImageType = imagetype_is_pict; tPosition += tSkipBytes(pFile, 50); if ((usRecordInstance ^ MSOBI_PICT) == 1) { tPosition += tSkipBytes(pFile, 16); } return tPosition; case 0xf01d: DBG_MSG("JPEG"); *peImageType = imagetype_is_jpeg; tPosition += tSkipBytes(pFile, 17); if ((usRecordInstance ^ MSOBI_JPEG) == 1) { tPosition += tSkipBytes(pFile, 16); } return tPosition; case 0xf01e: DBG_MSG("PNG"); *peImageType = imagetype_is_png; tPosition += tSkipBytes(pFile, 17); if ((usRecordInstance ^ MSOBI_PNG) == 1) { tPosition += tSkipBytes(pFile, 16); } return tPosition; case 0xf01f: DBG_MSG("DIB"); /* DIB is a BMP minus its 14 byte header */ *peImageType = imagetype_is_dib; tPosition += tSkipBytes(pFile, 17); if ((usRecordInstance ^ MSOBI_DIB) == 1) { tPosition += tSkipBytes(pFile, 16); } return tPosition; case 0xf00c: default: DBG_HEX(usRecordType); DBG_DEC_C(tRecordLength % 4 != 0, tRecordLength); DBG_FIXME(); return (size_t)-1; } } return (size_t)-1;} /* end of tFind8Image *//* * eExamineImage - Examine the image * * Returns an indication of the amount of information found */image_info_enumeExamineImage(FILE *pFile, ULONG ulFileOffsetImage, imagedata_type *pImg){ long lTmp; size_t tWordHeaderLen, tLength, tPos; int iType, iHorSize, iVerSize; USHORT usHorScalingFactor, usVerScalingFactor; if (ulFileOffsetImage == FC_INVALID) { return image_no_information; } DBG_HEX(ulFileOffsetImage); if (!bSetDataOffset(pFile, ulFileOffsetImage)) { return image_no_information; } tLength = (size_t)ulNextLong(pFile); DBG_DEC(tLength); if (tLength < 46) { /* Smaller than the smallest known header */ DBG_FIXME(); return image_no_information; } tWordHeaderLen = (size_t)usNextWord(pFile); DBG_DEC(tWordHeaderLen); fail(tWordHeaderLen != 46 && tWordHeaderLen != 58 && tWordHeaderLen != 68); if (tLength < tWordHeaderLen) { /* Smaller than the current header */ return image_no_information; } iType = (int)usNextWord(pFile); DBG_DEC(iType); (void)tSkipBytes(pFile, 28 - 8); lTmp = lTwips2MilliPoints(usNextWord(pFile)); iHorSize = (int)(lTmp / 1000); if (lTmp % 1000 != 0) { iHorSize++; } DBG_DEC(iHorSize); lTmp = lTwips2MilliPoints(usNextWord(pFile)); iVerSize = (int)(lTmp / 1000); if (lTmp % 1000 != 0) { iVerSize++; } DBG_DEC(iVerSize); usHorScalingFactor = usNextWord(pFile); DBG_DEC(usHorScalingFactor); usVerScalingFactor = usNextWord(pFile); DBG_DEC(usVerScalingFactor); /* Sanity checks */ lTmp = (long)iHorSize * (long)usHorScalingFactor; if (lTmp < 2835) { /* This image would be less than 1 millimeter wide */ DBG_DEC(lTmp); return image_no_information; } lTmp = (long)iVerSize * (long)usVerScalingFactor; if (lTmp < 2835) { /* This image would be less than 1 millimeter high */ DBG_DEC(lTmp); return image_no_information; } /* Skip the rest of the header */ (void)tSkipBytes(pFile, tWordHeaderLen - 36); tPos = tWordHeaderLen; (void)memset(pImg, 0, sizeof(*pImg)); switch (iType) { case 7: case 8: tPos = tFind6Image(pFile, tPos, tLength, &pImg->eImageType); if (tPos == (size_t)-1) { /* No image found */ return image_no_information; } DBG_HEX(tPos); break; case 94: /* Word 6/7, no image just a pathname */ pImg->eImageType = imagetype_is_external; DBG_HEX(ulFileOffsetImage + tPos); break; case 100: tPos = tFind8Image(pFile, tPos, tLength, &pImg->eImageType); if (tPos == (size_t)-1) { /* No image found */ return image_no_information; } DBG_HEX(tPos); break; case 102: /* Word 8/9/10, no image just a pathname or URL */ pImg->eImageType = imagetype_is_external; DBG_HEX(ulFileOffsetImage + tPos); break; default: DBG_DEC(iType); DBG_HEX(ulFileOffsetImage + tPos); DBG_FIXME(); return image_no_information; } /* Minimal information is now available */ pImg->tLength = tLength; pImg->tPosition = tPos; pImg->iHorSizeScaled = (int)(((long)iHorSize * (long)usHorScalingFactor + 500) / 1000); pImg->iVerSizeScaled = (int)(((long)iVerSize * (long)usVerScalingFactor + 500) / 1000);#if !defined(__riscos) vImage2Papersize(pImg);#endif /* !__riscos */ /* Image type specific examinations */ switch (pImg->eImageType) { case imagetype_is_dib: if (bExamineDIB(pFile, pImg)) { return image_full_information; } return image_minimal_information; case imagetype_is_jpeg: if (bExamineJPEG(pFile, pImg)) { return image_full_information; } return image_minimal_information; case imagetype_is_png: if (bExaminePNG(pFile, pImg)) { return image_full_information; } return image_minimal_information; case imagetype_is_wmf: if (bExamineWMF(pFile, pImg)) { return image_full_information; } return image_minimal_information; case imagetype_is_emf: case imagetype_is_pict: case imagetype_is_external: return image_minimal_information; case imagetype_is_unknown: default: return image_no_information; }} /* end of eExamineImage */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -