From 8e22858284ee0aa2383c085b72c897e2aa65ab70 Mon Sep 17 00:00:00 2001 From: luoliangyi <87842688@qq.com> Date: Tue, 28 May 2024 10:44:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=AF=B9freeimage=E5=BA=93?= =?UTF-8?q?=E7=9A=84=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build2/qt/HGImgFmt/HGImgFmt.pro | 2 - modules/imgfmt/HGImgFmt.cpp | 202 ++++++++++++++++++++++++++++---- modules/imgfmt/dllmain.cpp | 5 - 3 files changed, 181 insertions(+), 28 deletions(-) diff --git a/build2/qt/HGImgFmt/HGImgFmt.pro b/build2/qt/HGImgFmt/HGImgFmt.pro index 950fa513..31d0f9fe 100644 --- a/build2/qt/HGImgFmt/HGImgFmt.pro +++ b/build2/qt/HGImgFmt/HGImgFmt.pro @@ -66,7 +66,6 @@ win32 { INCLUDEPATH += $$PWD/../../../third_party/mupdf/$${MY_OS}/include INCLUDEPATH += $$PWD/../../../third_party/pdflib/$${MY_OS}/include INCLUDEPATH += $$PWD/../../../third_party/cximage/$${MY_OS}/include - INCLUDEPATH += $$PWD/../../../third_party/freeimage/$${MY_OS}/include INCLUDEPATH += $$PWD/../../../third_party/libzip/$${MY_OS}/include INCLUDEPATH += $$PWD/../../../third_party/tinyxml2/$${MY_OS}/include LIBS += $$PWD/../../../third_party/libjpeg-turbo/$${MY_OS}/lib/$${MY_ARCH}/turbojpeg-static.lib @@ -78,7 +77,6 @@ win32 { LIBS += $$PWD/../../../third_party/libzip/$${MY_OS}/lib/$${MY_ARCH}/zip.lib LIBS += $$PWD/../../../third_party/cximage/$${MY_OS}/lib/$${MY_ARCH}/cximage.lib LIBS += $$PWD/../../../third_party/cximage/$${MY_OS}/lib/$${MY_ARCH}/jasper.lib - LIBS += $$PWD/../../../third_party/freeimage/$${MY_OS}/lib/$${MY_ARCH}/FreeImage.lib } unix { diff --git a/modules/imgfmt/HGImgFmt.cpp b/modules/imgfmt/HGImgFmt.cpp index 3a69f0dc..dd96291b 100644 --- a/modules/imgfmt/HGImgFmt.cpp +++ b/modules/imgfmt/HGImgFmt.cpp @@ -11,12 +11,173 @@ #include #if defined(HG_CMP_MSC) #include "ximage.h" -#include "FreeImage.h" #endif -// -----------------CXIMAGE--------------------- - #if defined(HG_CMP_MSC) + +#define TGA_NULL 0 // no image data included +#define TGA_CMAP 1 // uncompressed, color-mapped image +#define TGA_RGB 2 // uncompressed, true-color image +#define TGA_MONO 3 // uncompressed, black-and-white image +#define TGA_RLECMAP 9 // run-length encoded, color-mapped image +#define TGA_RLERGB 10 // run-length encoded, true-color image +#define TGA_RLEMONO 11 // run-length encoded, black-and-white image +#define TGA_CMPCMAP 32 // compressed (Huffman/Delta/RLE) color-mapped image (e.g., VDA/D) - Obsolete +#define TGA_CMPCMAP4 33 // compressed (Huffman/Delta/RLE) color-mapped four pass image (e.g., VDA/D) - Obsolete + +#pragma pack(push, 1) +typedef struct tagTGAHEADER +{ + BYTE id_length; //! length of the image ID field + BYTE color_map_type; //! whether a color map is included + BYTE image_type; //! compression and color types + + WORD cm_first_entry; //! first entry index (offset into the color map table) + WORD cm_length; //! color map length (number of entries) + BYTE cm_size; //! color map entry size, in bits (number of bits per pixel) + + WORD is_xorigin; //! X-origin of image (absolute coordinate of lower-left corner for displays where origin is at the lower left) + WORD is_yorigin; //! Y-origin of image (as for X-origin) + WORD is_width; //! image width + WORD is_height; //! image height + BYTE is_pixel_depth; //! bits per pixel + BYTE is_image_descriptor; //! image descriptor, bits 3-0 give the alpha channel depth, bits 5-4 give direction +} TGAHEADER; +#pragma pack(pop) + +static BOOL TGAValid(FILE* handle) +{ + const unsigned sizeofSig = 18; + BYTE signature[sizeofSig] = { 0 }; + // tga_signature = "TRUEVISION-XFILE." (TGA 2.0 only) + BYTE tga_signature[sizeofSig] = { 84, 82, 85, 69, 86, 73, 83, 73, 79, 78, 45, 88, 70, 73, 76, 69, 46, 0 }; + // get the start offset + const long start_offset = ftell(handle); + // get the end-of-file + fseek(handle, 0, SEEK_END); + const long eof = ftell(handle); + // read the signature + const long start_of_signature = start_offset + eof - sizeofSig; + if (start_of_signature > 0) + { + fseek(handle, start_of_signature, SEEK_SET); + fread(&signature, 1, sizeofSig, handle); + } + // rewind + fseek(handle, start_offset, SEEK_SET); + + if ((memcmp(tga_signature, signature, sizeofSig) == 0)) + { + return TRUE; + } + + // not a 2.0 image, try testing if it's a valid TGA anyway (not robust) + { + const long start_offset = ftell(handle); + + // get the header + TGAHEADER header; + if (fread(&header, sizeof(tagTGAHEADER), 1, handle) < 1) + { + return FALSE; + } + + //BIGENDIAN + //SwapHeader(&header); + + // rewind + fseek(handle, start_offset, SEEK_SET); + + // the color map type should be a 0 or a 1... + if (header.color_map_type != 0 && header.color_map_type != 1) + { + return FALSE; + } + // if the color map type is 1 then we validate the map entry information... + if (header.color_map_type == 1) + { + // it doesn't make any sense if the first entry is larger than the color map table + if (header.cm_first_entry >= header.cm_length) + { + return FALSE; + } + // check header.cm_size, don't allow 0 or anything bigger than 32 + if (header.cm_size == 0 || header.cm_size > 32) + { + return FALSE; + } + } + // the width/height shouldn't be 0, right ? + if (header.is_width == 0 || header.is_height == 0) + { + return FALSE; + } + // let's now verify all the types that are supported by FreeImage (this is our final verification) + switch (header.image_type) + { + case TGA_CMAP: + case TGA_RGB: + case TGA_MONO: + case TGA_RLECMAP: + case TGA_RLERGB: + case TGA_RLEMONO: + switch (header.is_pixel_depth) + { + case 8: + case 16: + case 24: + case 32: + return TRUE; + default: + return FALSE; + } + break; + default: + return FALSE; + } + } +} + +static BOOL PCXValid(FILE* handle) +{ + BYTE pcx_signature = 0x0A; + BYTE signature[4] = { 0, 0, 0, 0 }; + + if (fread(&signature, 1, 4, handle) != 4) + { + return FALSE; + } + // magic number (0x0A = ZSoft Z) + if (signature[0] == pcx_signature) + { + // version + if (signature[1] <= 5) + { + // encoding + if ((signature[2] == 0) || (signature[2] == 1)) + { + // bits per pixel per plane + if ((signature[3] == 1) || (signature[3] == 8)) + { + return TRUE; + } + } + } + } + + return FALSE; +} + +static BOOL RASValid(FILE* handle) +{ + BYTE ras_signature[] = { 0x59, 0xA6, 0x6A, 0x95 }; + BYTE signature[4] = { 0, 0, 0, 0 }; + + fread(signature, 1, sizeof(ras_signature), handle); + + return (memcmp(ras_signature, signature, sizeof(ras_signature)) == 0); +} + static HGResult CheckCxFile(const HGChar* fileName, HGUInt fmt, HGBool* isTrue) { if (NULL == fileName || NULL == isTrue) @@ -24,18 +185,20 @@ static HGResult CheckCxFile(const HGChar* fileName, HGUInt fmt, HGBool* isTrue) return HGBASE_ERR_INVALIDARG; } - FREE_IMAGE_FORMAT fif = FIF_TARGA; - if (CXIMAGE_FORMAT_PCX == fmt) - fif = FIF_PCX; - else if (CXIMAGE_FORMAT_RAS == fmt) - fif = FIF_RAS; - - if (!FreeImage_Validate(fif, fileName)) + FILE *handle = fopen(fileName, "rb"); + if (NULL == handle) { return HGBASE_ERR_FAIL; } - *isTrue = HGTRUE; + if (CXIMAGE_FORMAT_TGA == fmt) + *isTrue = TGAValid(handle); + else if (CXIMAGE_FORMAT_PCX == fmt) + *isTrue = PCXValid(handle); + else if (CXIMAGE_FORMAT_RAS == fmt) + *isTrue = RASValid(handle); + + fclose(handle); return HGBASE_ERR_OK; } @@ -69,11 +232,7 @@ static HGResult LoadCxImage(const HGChar* fileName, HGUInt fmt, HGImgFmtLoadInfo } } -#if defined(HG_CMP_MSC) if (0 != _access(fileName, 0)) -#else - if (0 != access(fileName, 0)) -#endif { return HGBASE_ERR_FILENOTEXIST; } @@ -219,12 +378,12 @@ static HGResult SaveCxImage(HGImage image, const HGImgFmtSaveInfo* info, const H if (1 == bpp) { RGBQUAD colorTable[2]; - colorTable[0].rgbRed = 0; - colorTable[0].rgbGreen = 0; - colorTable[0].rgbBlue = 0; - colorTable[1].rgbRed = 255; - colorTable[1].rgbGreen = 255; - colorTable[1].rgbBlue = 255; + for (int i = 0; i < 2; ++i) + { + colorTable[i].rgbRed = i * 255; + colorTable[i].rgbGreen = i * 255; + colorTable[i].rgbBlue = i * 255; + } cxImage.SetPalette(colorTable, 2); } else if (8 == bpp) @@ -300,6 +459,7 @@ static HGResult SaveCxImage(HGImage image, const HGImgFmtSaveInfo* info, const H return HGBASE_ERR_OK; } + #endif static HGResult CheckTgaFile(const HGChar* fileName, HGBool* isTga) diff --git a/modules/imgfmt/dllmain.cpp b/modules/imgfmt/dllmain.cpp index eda9649b..88c936b8 100644 --- a/modules/imgfmt/dllmain.cpp +++ b/modules/imgfmt/dllmain.cpp @@ -1,7 +1,4 @@ #include "../base/HGDef.h" -#if defined(HG_CMP_MSC) -#include "FreeImage.h" -#endif #if defined(HG_CMP_MSC) @@ -10,14 +7,12 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReser switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: - FreeImage_Initialise(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: - FreeImage_DeInitialise(); break; }