#include "HGImgFmt.h" #include "HGJpeg.h" #include "HGBmp.h" #include "HGPng.h" #include "HGTiff.h" #include "HGPdf.h" #include "HGOfd.h" #include "HGGif.h" #include "HGPnm.h" #include "../base/HGInc.h" #include #if defined(HG_CMP_MSC) #include "ximage.h" #endif #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) { return HGBASE_ERR_INVALIDARG; } FILE *handle = fopen(fileName, "rb"); if (NULL == handle) { return HGBASE_ERR_FAIL; } 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; } static HGResult LoadCxImage(const HGChar* fileName, HGUInt fmt, HGImgFmtLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { if (NULL == fileName) { return HGBASE_ERR_INVALIDARG; } if (NULL == image) { if (0 != imgType || 0 != imgOrigin) { return HGBASE_ERR_INVALIDARG; } } else { if (0 != imgType && HGBASE_IMGTYPE_BINARY != imgType && HGBASE_IMGTYPE_GRAY != imgType && HGBASE_IMGTYPE_BGR != imgType && HGBASE_IMGTYPE_RGB != imgType && HGBASE_IMGTYPE_BGRA != imgType && HGBASE_IMGTYPE_RGBA != imgType) { return HGBASE_ERR_INVALIDARG; } if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin) { return HGBASE_ERR_INVALIDARG; } } if (0 != _access(fileName, 0)) { return HGBASE_ERR_FILENOTEXIST; } HGBool isTrue = HGFALSE; CheckCxFile(fileName, fmt, &isTrue); if (!isTrue) { return HGBASE_ERR_FAIL; } CxImage cxImage(fileName, fmt); if (!cxImage.IsValid()) { return HGBASE_ERR_FAIL; } if (NULL != info) { info->width = cxImage.GetWidth(); info->height = cxImage.GetHeight(); info->bpp = cxImage.GetBpp(); info->xDpi = cxImage.GetXDPI(); info->yDpi = cxImage.GetYDPI(); } if (NULL != image) { HGUInt bpp = cxImage.GetBpp(); if (0 == imgType) { imgType = HGBASE_IMGTYPE_RGB; if (1 == bpp || 4 == bpp || 8 == bpp) { RGBQUAD *colourTable = cxImage.GetPalette(); uint32_t colors = cxImage.GetPaletteSize() / sizeof(RGBQUAD); bool bGray = true; bool bBinary = true; for (uint32_t i = 0; i < colors; ++i) { HGByte red = colourTable[i].rgbRed; HGByte green = colourTable[i].rgbGreen; HGByte blue = colourTable[i].rgbBlue; if (red != green || red != blue || green != blue) { bGray = false; bBinary = false; break; } if (red != 0 && red != 255) { bBinary = false; } } if (bBinary) imgType = HGBASE_IMGTYPE_BINARY; else if (bGray) imgType = HGBASE_IMGTYPE_GRAY; } else if (32 == bpp) { imgType = HGBASE_IMGTYPE_RGBA; } } if (0 == imgOrigin) { imgOrigin = HGBASE_IMGORIGIN_TOP; } cxImage.IncreaseBpp(24); HGImageInfo imageInfo; imageInfo.width = cxImage.GetWidth(); imageInfo.height = cxImage.GetHeight(); imageInfo.type = HGBASE_IMGTYPE_BGR; imageInfo.widthStep = cxImage.GetEffWidth(); imageInfo.origin = HGBASE_IMGORIGIN_BOTTOM; HGImage image2 = NULL; HGResult ret = HGBase_CreateImageWithData(cxImage.GetBits(), &imageInfo, &image2); if (HGBASE_ERR_OK != ret) { return ret; } HGBase_SetImageDpi(image2, cxImage.GetXDPI(), cxImage.GetYDPI()); ret = HGBase_CloneImage(image2, imgType, imgOrigin, image); HGBase_DestroyImage(image2); if (HGBASE_ERR_OK != ret) { return ret; } if (CXIMAGE_FORMAT_PCX == fmt) { if (1 == bpp) HGBase_ReverseImage(*image, *image); } } return HGBASE_ERR_OK; } static HGResult SaveCxImage(HGImage image, const HGImgFmtSaveInfo* info, const HGChar* fileName, HGUInt fmt) { if (NULL == image || NULL == fileName) { return HGBASE_ERR_INVALIDARG; } if (NULL != info) { // 检查合法性 } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); unsigned int bpp = 1; if (HGBASE_IMGTYPE_GRAY == imgInfo.type) bpp = 8; else if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_BGR == imgInfo.type) bpp = 24; else if (HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) bpp = 32; else assert(HGBASE_IMGTYPE_BINARY == imgInfo.type); CxImage cxImage; cxImage.Create(imgInfo.width, imgInfo.height, bpp, 0); if (!cxImage.IsValid()) { return HGBASE_ERR_FAIL; } bpp = cxImage.GetBpp(); if (1 == bpp) { RGBQUAD colorTable[2]; 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) { RGBQUAD colorTable[256]; for (int i = 0; i < 256; ++i) { colorTable[i].rgbRed = i; colorTable[i].rgbGreen = i; colorTable[i].rgbBlue = i; } cxImage.SetPalette(colorTable, 256); } HGUInt type = HGBASE_IMGTYPE_BINARY; if (8 == bpp) type = HGBASE_IMGTYPE_GRAY; else if (24 == bpp) type = HGBASE_IMGTYPE_BGR; else if (32 == bpp) type = HGBASE_IMGTYPE_BGRA; else assert(1 == bpp); HGImageInfo imgInfoDest; imgInfoDest.width = cxImage.GetWidth(); imgInfoDest.height = cxImage.GetHeight(); imgInfoDest.type = type; imgInfoDest.widthStep = cxImage.GetEffWidth(); imgInfoDest.origin = HGBASE_IMGORIGIN_BOTTOM; HGImage imageDest = NULL; HGResult ret = HGBase_CreateImageWithData(cxImage.GetBits(), &imgInfoDest, &imageDest); if (HGBASE_ERR_OK != ret) { return ret; } HGImageRoi imageRoi; HGBase_GetImageROI(image, &imageRoi); HGBase_ResetImageROI(image); HGBase_CopyImage(image, imageDest); HGBase_SetImageROI(image, &imageRoi); HGBase_DestroyImage(imageDest); HGUInt xDpi, yDpi; HGBase_GetImageDpi(image, &xDpi, &yDpi); cxImage.SetXDPI(xDpi); cxImage.SetYDPI(yDpi); if (CXIMAGE_FORMAT_TGA == fmt) { if (1 == bpp) cxImage.IncreaseBpp(8); } else if (CXIMAGE_FORMAT_PCX == fmt) { if (24 == bpp || 32 == bpp) cxImage.DecreaseBpp(8, true); else if (1 == bpp) cxImage.Negative(); } else if (CXIMAGE_FORMAT_RAS == fmt) { if (1 == bpp) cxImage.IncreaseBpp(24); } if (!cxImage.Save(fileName, fmt)) { return HGBASE_ERR_FAIL; } return HGBASE_ERR_OK; } #endif static HGResult CheckTgaFile(const HGChar* fileName, HGBool* isTga) { #if defined(HG_CMP_MSC) return CheckCxFile(fileName, CXIMAGE_FORMAT_TGA, isTga); #else return HGBASE_ERR_FAIL; #endif } static HGResult LoadTgaImage(const HGChar* fileName, HGImgFmtLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { #if defined(HG_CMP_MSC) return LoadCxImage(fileName, CXIMAGE_FORMAT_TGA, info, imgType, imgOrigin, image); #else return HGBASE_ERR_FAIL; #endif } static HGResult SaveTgaImage(HGImage image, const HGImgFmtSaveInfo* info, const HGChar* fileName) { #if defined(HG_CMP_MSC) return SaveCxImage(image, info, fileName, CXIMAGE_FORMAT_TGA); #else return HGBASE_ERR_FAIL; #endif } static HGResult CheckPcxFile(const HGChar* fileName, HGBool* isPcx) { #if defined(HG_CMP_MSC) return CheckCxFile(fileName, CXIMAGE_FORMAT_PCX, isPcx); #else return HGBASE_ERR_FAIL; #endif } static HGResult LoadPcxImage(const HGChar* fileName, HGImgFmtLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { #if defined(HG_CMP_MSC) return LoadCxImage(fileName, CXIMAGE_FORMAT_PCX, info, imgType, imgOrigin, image); #else return HGBASE_ERR_FAIL; #endif } static HGResult SavePcxImage(HGImage image, const HGImgFmtSaveInfo* info, const HGChar* fileName) { #if defined(HG_CMP_MSC) return SaveCxImage(image, info, fileName, CXIMAGE_FORMAT_PCX); #else return HGBASE_ERR_FAIL; #endif } static HGResult CheckRasFile(const HGChar* fileName, HGBool* isRas) { #if defined(HG_CMP_MSC) return CheckCxFile(fileName, CXIMAGE_FORMAT_RAS, isRas); #else return HGBASE_ERR_FAIL; #endif } static HGResult LoadRasImage(const HGChar* fileName, HGImgFmtLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { #if defined(HG_CMP_MSC) return LoadCxImage(fileName, CXIMAGE_FORMAT_RAS, info, imgType, imgOrigin, image); #else return HGBASE_ERR_FAIL; #endif } static HGResult SaveRasImage(HGImage image, const HGImgFmtSaveInfo* info, const HGChar* fileName) { #if defined(HG_CMP_MSC) return SaveCxImage(image, info, fileName, CXIMAGE_FORMAT_RAS); #else return HGBASE_ERR_FAIL; #endif } // -----------------CXIMAGE--------------------- struct HGImgFmtReaderImpl { HGImgFmtReaderImpl() { fmtType = 0; handle = NULL; } std::string fileName; HGUInt fmtType; HGPointer handle; HGGifLoadInfo gifLoadInfo; }; struct HGImgFmtWriterImpl { HGImgFmtWriterImpl() { fmtType = 0; handle = NULL; write = HGFALSE; } std::string fileName; HGUInt fmtType; HGPointer handle; HGBool write; // 用于标记JPEG、BMP、PNG、PNM、TGA、PCX和RAS是否已经写入 }; HGResult HGAPI HGImgFmt_GetImgFmtType(const HGChar* fileName, HGUInt* fmtType) { if (NULL == fileName || NULL == fmtType) { return HGBASE_ERR_INVALIDARG; } HGBool isJpeg = HGFALSE; HGResult ret = HGImgFmt_CheckJpegFile(fileName, &isJpeg); if (isJpeg) { *fmtType = HGIMGFMT_TYPE_JPEG; return HGBASE_ERR_OK; } HGBool isBmp = HGFALSE; ret = HGImgFmt_CheckBmpFile(fileName, &isBmp); if (isBmp) { *fmtType = HGIMGFMT_TYPE_BMP; return HGBASE_ERR_OK; } HGBool isPng = HGFALSE; ret = HGImgFmt_CheckPngFile(fileName, &isPng); if (isPng) { *fmtType = HGIMGFMT_TYPE_PNG; return HGBASE_ERR_OK; } HGBool isTiff = HGFALSE; ret = HGImgFmt_CheckTiffFile(fileName, &isTiff); if (isTiff) { *fmtType = HGIMGFMT_TYPE_TIFF; return HGBASE_ERR_OK; } HGBool isPdf = HGFALSE; ret = HGImgFmt_CheckPdfFile(fileName, &isPdf); if (isPdf) { *fmtType = HGIMGFMT_TYPE_PDF; return HGBASE_ERR_OK; } HGBool isOfd = HGFALSE; ret = HGImgFmt_CheckOfdFile(fileName, &isOfd); if (isOfd) { *fmtType = HGIMGFMT_TYPE_OFD; return HGBASE_ERR_OK; } HGBool isGif = HGFALSE; ret = HGImgFmt_CheckGifFile(fileName, &isGif); if (isGif) { *fmtType = HGIMGFMT_TYPE_GIF; return HGBASE_ERR_OK; } HGBool isPnm = HGFALSE; ret = HGImgFmt_CheckPnmFile(fileName, &isPnm); if (isPnm) { *fmtType = HGIMGFMT_TYPE_PNM; return HGBASE_ERR_OK; } HGBool isTga = HGFALSE; ret = CheckTgaFile(fileName, &isTga); if (isTga) { *fmtType = HGIMGFMT_TYPE_TGA; return HGBASE_ERR_OK; } HGBool isPcx = HGFALSE; ret = CheckPcxFile(fileName, &isPcx); if (isPcx) { *fmtType = HGIMGFMT_TYPE_PCX; return HGBASE_ERR_OK; } HGBool isRas = HGFALSE; ret = CheckRasFile(fileName, &isRas); if (isRas) { *fmtType = HGIMGFMT_TYPE_RAS; return HGBASE_ERR_OK; } return ret; } HGResult HGAPI HGImgFmt_GetImgFmtTypeFromFileName(const HGChar* fileName, HGUInt* fmtType) { if (NULL == fileName || NULL == fmtType) { return HGBASE_ERR_INVALIDARG; } const char* p = strrchr(fileName, '.'); if (NULL == p) { return HGBASE_ERR_INVALIDARG; } #if defined(HG_CMP_MSC) if (0 == _stricmp(p, ".jpe") || 0 == _stricmp(p, ".jpg") || 0 == _stricmp(p, ".jpeg")) { *fmtType = HGIMGFMT_TYPE_JPEG; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".bmp") || 0 == _stricmp(p, ".dib")) { *fmtType = HGIMGFMT_TYPE_BMP; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".png")) { *fmtType = HGIMGFMT_TYPE_PNG; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".tif") || 0 == _stricmp(p, ".tiff")) { *fmtType = HGIMGFMT_TYPE_TIFF; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".pdf")) { *fmtType = HGIMGFMT_TYPE_PDF; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".ofd")) { *fmtType = HGIMGFMT_TYPE_OFD; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".gif")) { *fmtType = HGIMGFMT_TYPE_GIF; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".pbm") || 0 == _stricmp(p, ".pgm") || 0 == _stricmp(p, ".ppm")) { *fmtType = HGIMGFMT_TYPE_PNM; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".tga")) { *fmtType = HGIMGFMT_TYPE_TGA; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".pcx")) { *fmtType = HGIMGFMT_TYPE_PCX; return HGBASE_ERR_OK; } if (0 == _stricmp(p, ".ras")) { *fmtType = HGIMGFMT_TYPE_RAS; return HGBASE_ERR_OK; } #else if (0 == strcasecmp(p, ".jpe") || 0 == strcasecmp(p, ".jpg") || 0 == strcasecmp(p, ".jpeg")) { *fmtType = HGIMGFMT_TYPE_JPEG; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".bmp") || 0 == strcasecmp(p, ".dib")) { *fmtType = HGIMGFMT_TYPE_BMP; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".png")) { *fmtType = HGIMGFMT_TYPE_PNG; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".tif") || 0 == strcasecmp(p, ".tiff")) { *fmtType = HGIMGFMT_TYPE_TIFF; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".pdf")) { *fmtType = HGIMGFMT_TYPE_PDF; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".ofd")) { *fmtType = HGIMGFMT_TYPE_OFD; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".gif")) { *fmtType = HGIMGFMT_TYPE_GIF; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".pbm") || 0 == strcasecmp(p, ".pgm") || 0 == strcasecmp(p, ".ppm")) { *fmtType = HGIMGFMT_TYPE_PNM; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".tga")) { *fmtType = HGIMGFMT_TYPE_TGA; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".pcx")) { *fmtType = HGIMGFMT_TYPE_PCX; return HGBASE_ERR_OK; } if (0 == strcasecmp(p, ".ras")) { *fmtType = HGIMGFMT_TYPE_RAS; return HGBASE_ERR_OK; } #endif return HGBASE_ERR_FAIL; } HGResult HGAPI HGImgFmt_IsMultiImgFmtType(HGUInt fmtType, HGBool* isMulti) { if (fmtType < HGIMGFMT_TYPE_JPEG || fmtType > HGIMGFMT_TYPE_RAS || NULL == isMulti) { return HGBASE_ERR_INVALIDARG; } if (HGIMGFMT_TYPE_JPEG == fmtType || HGIMGFMT_TYPE_BMP == fmtType || HGIMGFMT_TYPE_PNG == fmtType || HGIMGFMT_TYPE_PNM == fmtType || HGIMGFMT_TYPE_TGA == fmtType || HGIMGFMT_TYPE_PCX == fmtType || HGIMGFMT_TYPE_RAS == fmtType) *isMulti = HGFALSE; else *isMulti = HGTRUE; return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_LoadImage(const HGChar* fileName, HGUInt fmtType, HGImgFmtLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { if (fmtType > HGIMGFMT_TYPE_RAS) { return HGBASE_ERR_INVALIDARG; } if (HGIMGFMT_TYPE_JPEG == fmtType) { HGJpegLoadInfo jpegInfo; HGResult ret = HGImgFmt_LoadJpegImage(fileName, &jpegInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = jpegInfo.width; info->height = jpegInfo.height; info->bpp = jpegInfo.numComponents * 8; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_JPEGDENUNIT_INCH == jpegInfo.densityUnit) { info->xDpi = jpegInfo.xDensity; info->yDpi = jpegInfo.yDensity; } else if (HGIMGFMT_JPEGDENUNIT_CENTIMETER == jpegInfo.densityUnit) { info->xDpi = (uint32_t)((double)jpegInfo.xDensity / 0.393700787 + 0.5); info->yDpi = (uint32_t)((double)jpegInfo.yDensity / 0.393700787 + 0.5); } } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_BMP == fmtType) { HGBmpLoadInfo bmpInfo; HGResult ret = HGImgFmt_LoadBmpImage(fileName, &bmpInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = bmpInfo.width; info->height = bmpInfo.height; info->bpp = bmpInfo.bitCount; info->xDpi = (uint32_t)((double)bmpInfo.xPelsPerMeter / 39.3700787 + 0.5); info->yDpi = (uint32_t)((double)bmpInfo.yPelsPerMeter / 39.3700787 + 0.5); } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PNG == fmtType) { HGPngLoadInfo pngInfo; HGResult ret = HGImgFmt_LoadPngImage(fileName, &pngInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = pngInfo.width; info->height = pngInfo.height; info->bpp = pngInfo.pixelDepth; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_PNGPHYSUNIT_METER == pngInfo.physUnitType) { info->xDpi = (uint32_t)((double)pngInfo.xPixelsPerUnit / 39.3700787 + 0.5); info->yDpi = (uint32_t)((double)pngInfo.yPixelsPerUnit / 39.3700787 + 0.5); } } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_TIFF == fmtType) { HGTiffLoadInfo tiffInfo; HGResult ret = HGImgFmt_LoadTiffImage(fileName, &tiffInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = tiffInfo.width; info->height = tiffInfo.height; info->bpp = tiffInfo.bitsPerSample * tiffInfo.samplesPerPixel; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_TIFFRESUNIT_INCH == tiffInfo.resolutionUnit) { info->xDpi = (uint32_t)(tiffInfo.xResolution + 0.5f); info->yDpi = (uint32_t)(tiffInfo.yResolution + 0.5f); } else if (HGIMGFMT_TIFFRESUNIT_CENTIMETER == tiffInfo.resolutionUnit) { info->xDpi = (uint32_t)((double)tiffInfo.xResolution / 0.393700787 + 0.5); info->yDpi = (uint32_t)((double)tiffInfo.yResolution / 0.393700787 + 0.5); } } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PDF == fmtType) { HGPdfPageInfo pdfInfo; HGResult ret = HGImgFmt_LoadPdfImage(fileName, &pdfInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = pdfInfo.width; info->height = pdfInfo.height; info->bpp = pdfInfo.bpp; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_OFD == fmtType) { HGOfdPageInfo ofdInfo; HGResult ret = HGImgFmt_LoadOfdImage(fileName, &ofdInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = ofdInfo.width; info->height = ofdInfo.height; info->bpp = ofdInfo.bpp; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_GIF == fmtType) { HGGifLoadInfo gifInfo; HGResult ret = HGImgFmt_LoadGifImage(fileName, &gifInfo, NULL, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = gifInfo.width; info->height = gifInfo.height; info->bpp = gifInfo.colorResolution; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PNM == fmtType) { HGPnmLoadInfo pnmInfo; HGResult ret = HGImgFmt_LoadPnmImage(fileName, &pnmInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = pnmInfo.width; info->height = pnmInfo.height; info->bpp = 1; if (pnmInfo.type == HGIMGFMT_PNMTYPE_GRAY_ASCII || pnmInfo.type == HGIMGFMT_PNMTYPE_GRAY_BINARY) info->bpp = 8; else if (pnmInfo.type == HGIMGFMT_PNMTYPE_RGB_ASCII || pnmInfo.type == HGIMGFMT_PNMTYPE_RGB_BINARY) info->bpp = 24; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_TGA == fmtType) { return LoadTgaImage(fileName, info, imgType, imgOrigin, image); } else if (HGIMGFMT_TYPE_PCX == fmtType) { return LoadPcxImage(fileName, info, imgType, imgOrigin, image); } else if (HGIMGFMT_TYPE_RAS == fmtType) { return LoadRasImage(fileName, info, imgType, imgOrigin, image); } assert(0 == fmtType); HGJpegLoadInfo jpegInfo; HGResult ret = HGImgFmt_LoadJpegImage(fileName, &jpegInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = jpegInfo.width; info->height = jpegInfo.height; info->bpp = jpegInfo.numComponents * 8; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_JPEGDENUNIT_INCH == jpegInfo.densityUnit) { info->xDpi = jpegInfo.xDensity; info->yDpi = jpegInfo.yDensity; } else if (HGIMGFMT_JPEGDENUNIT_CENTIMETER == jpegInfo.densityUnit) { info->xDpi = (uint32_t)((double)jpegInfo.xDensity / 0.393700787 + 0.5); info->yDpi = (uint32_t)((double)jpegInfo.yDensity / 0.393700787 + 0.5); } } return HGBASE_ERR_OK; } HGBmpLoadInfo bmpInfo; ret = HGImgFmt_LoadBmpImage(fileName, &bmpInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = bmpInfo.width; info->height = bmpInfo.height; info->bpp = bmpInfo.bitCount; info->xDpi = (uint32_t)((double)bmpInfo.xPelsPerMeter / 39.3700787 + 0.5); info->yDpi = (uint32_t)((double)bmpInfo.yPelsPerMeter / 39.3700787 + 0.5); } return HGBASE_ERR_OK; } HGPngLoadInfo pngInfo; ret = HGImgFmt_LoadPngImage(fileName, &pngInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = pngInfo.width; info->height = pngInfo.height; info->bpp = pngInfo.pixelDepth; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_PNGPHYSUNIT_METER == pngInfo.physUnitType) { info->xDpi = (uint32_t)((double)pngInfo.xPixelsPerUnit / 39.3700787 + 0.5); info->yDpi = (uint32_t)((double)pngInfo.yPixelsPerUnit / 39.3700787 + 0.5); } } return HGBASE_ERR_OK; } HGTiffLoadInfo tiffInfo; ret = HGImgFmt_LoadTiffImage(fileName, &tiffInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = tiffInfo.width; info->height = tiffInfo.height; info->bpp = tiffInfo.bitsPerSample * tiffInfo.samplesPerPixel; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_TIFFRESUNIT_INCH == tiffInfo.resolutionUnit) { info->xDpi = (uint32_t)(tiffInfo.xResolution + 0.5f); info->yDpi = (uint32_t)(tiffInfo.yResolution + 0.5f); } else if (HGIMGFMT_TIFFRESUNIT_CENTIMETER == tiffInfo.resolutionUnit) { info->xDpi = (uint32_t)((double)tiffInfo.xResolution / 0.393700787 + 0.5); info->yDpi = (uint32_t)((double)tiffInfo.yResolution / 0.393700787 + 0.5); } } return HGBASE_ERR_OK; } HGPdfPageInfo pdfInfo; ret = HGImgFmt_LoadPdfImage(fileName, &pdfInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = pdfInfo.width; info->height = pdfInfo.height; info->bpp = pdfInfo.bpp; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } HGOfdPageInfo ofdInfo; ret = HGImgFmt_LoadOfdImage(fileName, &ofdInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = ofdInfo.width; info->height = ofdInfo.height; info->bpp = ofdInfo.bpp; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } HGGifLoadInfo gifInfo; ret = HGImgFmt_LoadGifImage(fileName, &gifInfo, NULL, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = gifInfo.width; info->height = gifInfo.height; info->bpp = gifInfo.colorResolution; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } HGPnmLoadInfo pnmInfo; ret = HGImgFmt_LoadPnmImage(fileName, &pnmInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { if (NULL != info) { info->width = pnmInfo.width; info->height = pnmInfo.height; info->bpp = 1; if (pnmInfo.type == HGIMGFMT_PNMTYPE_GRAY_ASCII || pnmInfo.type == HGIMGFMT_PNMTYPE_GRAY_BINARY) info->bpp = 8; else if (pnmInfo.type == HGIMGFMT_PNMTYPE_RGB_ASCII || pnmInfo.type == HGIMGFMT_PNMTYPE_RGB_BINARY) info->bpp = 24; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } ret = LoadTgaImage(fileName, info, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { return HGBASE_ERR_OK; } ret = LoadPcxImage(fileName, info, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { return HGBASE_ERR_OK; } ret = LoadRasImage(fileName, info, imgType, imgOrigin, image); if (HGBASE_ERR_OK == ret) { return HGBASE_ERR_OK; } return ret; } HGResult HGAPI HGImgFmt_SaveImage(HGImage image, HGUInt fmtType, const HGImgFmtSaveInfo* info, const HGChar* fileName) { if (fmtType > HGIMGFMT_TYPE_RAS) { return HGBASE_ERR_INVALIDARG; } if (0 == fmtType) { HGImgFmt_GetImgFmtTypeFromFileName(fileName, &fmtType); if (fmtType < HGIMGFMT_TYPE_JPEG || fmtType > HGIMGFMT_TYPE_RAS) { return HGBASE_ERR_INVALIDARG; } } HGUInt xDpi = 0, yDpi = 0; HGBase_GetImageDpi(image, &xDpi, &yDpi); if (HGIMGFMT_TYPE_JPEG == fmtType) { HGJpegSaveInfo jpegInfo; HGJpegSaveInfo* pJpegInfo = NULL; if (NULL != info) { jpegInfo.quality = info->jpegQuality; jpegInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH; jpegInfo.xDensity = xDpi; jpegInfo.yDensity = yDpi; pJpegInfo = &jpegInfo; } return HGImgFmt_SaveJpegImage(image, pJpegInfo, fileName); } else if (HGIMGFMT_TYPE_BMP == fmtType) { HGBmpSaveInfo bmpInfo; HGBmpSaveInfo* pBmpInfo = NULL; if (NULL != info) { bmpInfo.xPelsPerMeter = (uint32_t)((double)xDpi * 39.3700787 + 0.5); bmpInfo.yPelsPerMeter = (uint32_t)((double)yDpi * 39.3700787 + 0.5); pBmpInfo = &bmpInfo; } return HGImgFmt_SaveBmpImage(image, pBmpInfo, fileName); } else if (HGIMGFMT_TYPE_PNG == fmtType) { HGPngSaveInfo pngInfo; HGPngSaveInfo* pPngInfo = NULL; if (NULL != info) { pngInfo.physUnitType = HGIMGFMT_PNGPHYSUNIT_METER; pngInfo.xPixelsPerUnit = (uint32_t)((double)xDpi * 39.3700787 + 0.5); pngInfo.yPixelsPerUnit = (uint32_t)((double)yDpi * 39.3700787 + 0.5); pPngInfo = &pngInfo; } return HGImgFmt_SavePngImage(image, pPngInfo, fileName); } else if (HGIMGFMT_TYPE_TIFF == fmtType) { HGTiffSaveInfo tiffInfo; HGTiffSaveInfo* pTiffInfo = NULL; if (NULL != info) { tiffInfo.compression = info->tiffCompression; tiffInfo.jpegQuality = info->tiffJpegQuality; tiffInfo.resolutionUnit = HGIMGFMT_TIFFRESUNIT_INCH; tiffInfo.xResolution = (float)xDpi; tiffInfo.yResolution = (float)yDpi; pTiffInfo = &tiffInfo; } return HGImgFmt_SaveTiffImage(image, pTiffInfo, fileName); } else if (HGIMGFMT_TYPE_PDF == fmtType) { HGJpegSaveInfo jpegInfo; HGJpegSaveInfo* pJpegInfo = NULL; if (NULL != info) { jpegInfo.quality = info->jpegQuality; jpegInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH; jpegInfo.xDensity = xDpi; jpegInfo.yDensity = yDpi; pJpegInfo = &jpegInfo; } return HGImgFmt_SavePdfJpegImage(image, pJpegInfo, fileName); } else if (HGIMGFMT_TYPE_OFD == fmtType) { HGJpegSaveInfo jpegInfo; HGJpegSaveInfo* pJpegInfo = NULL; if (NULL != info) { jpegInfo.quality = info->jpegQuality; jpegInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH; jpegInfo.xDensity = xDpi; jpegInfo.yDensity = yDpi; pJpegInfo = &jpegInfo; } return HGImgFmt_SaveOfdJpegImage(image, pJpegInfo, fileName); } else if (HGIMGFMT_TYPE_GIF == fmtType) { return HGImgFmt_SaveGifImage(image, NULL, 50, HG_MAKECOLOR(255, 255, 255, 255), fileName); } else if (HGIMGFMT_TYPE_PNM == fmtType) { return HGImgFmt_SavePnmImage(image, NULL, fileName); } else if (HGIMGFMT_TYPE_TGA == fmtType) { return SaveTgaImage(image, NULL, fileName); } else if (HGIMGFMT_TYPE_PCX == fmtType) { return SavePcxImage(image, NULL, fileName); } assert(HGIMGFMT_TYPE_RAS == fmtType); return SaveRasImage(image, NULL, fileName); } HGResult HGAPI HGImgFmt_OpenImageReader(const HGChar* fileName, HGUInt fmtType, HGImgFmtReader* reader) { if (NULL == fileName || fmtType > HGIMGFMT_TYPE_RAS || NULL == reader) { return HGBASE_ERR_INVALIDARG; } if (HGIMGFMT_TYPE_JPEG == fmtType || HGIMGFMT_TYPE_BMP == fmtType || HGIMGFMT_TYPE_PNG == fmtType || HGIMGFMT_TYPE_PNM == fmtType || HGIMGFMT_TYPE_TGA == fmtType || HGIMGFMT_TYPE_PCX == fmtType || HGIMGFMT_TYPE_RAS == fmtType) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = fmtType; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_TIFF == fmtType) { HGTiffReader tiffReader = NULL; HGResult ret = HGImgFmt_OpenTiffReader(fileName, &tiffReader); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = fmtType; imgFmtReaderImpl->handle = tiffReader; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PDF == fmtType) { HGPdfReader pdfReader = NULL; HGResult ret = HGImgFmt_OpenPdfReader(fileName, &pdfReader); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = fmtType; imgFmtReaderImpl->handle = pdfReader; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_OFD == fmtType) { HGOfdReader ofdReader = NULL; HGResult ret = HGImgFmt_OpenOfdReader(fileName, &ofdReader); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = fmtType; imgFmtReaderImpl->handle = ofdReader; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_GIF == fmtType) { HGGifLoadInfo gifLoadInfo; HGGifReader gifReader = NULL; HGResult ret = HGImgFmt_OpenGifReader(fileName, &gifLoadInfo, &gifReader); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = fmtType; imgFmtReaderImpl->handle = gifReader; memcpy(&imgFmtReaderImpl->gifLoadInfo, &gifLoadInfo, sizeof(HGGifLoadInfo)); *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } assert(0 == fmtType); HGBool isJpeg = HGFALSE; HGResult ret = HGImgFmt_CheckJpegFile(fileName, &isJpeg); if (isJpeg) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_JPEG; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGBool isBmp = HGFALSE; ret = HGImgFmt_CheckBmpFile(fileName, &isBmp); if (isBmp) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_BMP; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGBool isPng = HGFALSE; ret = HGImgFmt_CheckPngFile(fileName, &isPng); if (isPng) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_PNG; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGTiffReader tiffReader = NULL; ret = HGImgFmt_OpenTiffReader(fileName, &tiffReader); if (HGBASE_ERR_OK == ret) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_TIFF; imgFmtReaderImpl->handle = tiffReader; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGPdfReader pdfReader = NULL; ret = HGImgFmt_OpenPdfReader(fileName, &pdfReader); if (HGBASE_ERR_OK == ret) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_PDF; imgFmtReaderImpl->handle = pdfReader; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGOfdReader ofdReader = NULL; ret = HGImgFmt_OpenOfdReader(fileName, &ofdReader); if (HGBASE_ERR_OK == ret) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_OFD; imgFmtReaderImpl->handle = ofdReader; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGGifLoadInfo gifLoadInfo; HGGifReader gifReader = NULL; ret = HGImgFmt_OpenGifReader(fileName, &gifLoadInfo, &gifReader); if (HGBASE_ERR_OK == ret) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_GIF; imgFmtReaderImpl->handle = gifReader; memcpy(&imgFmtReaderImpl->gifLoadInfo, &gifLoadInfo, sizeof(HGGifLoadInfo)); *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGBool isPnm = HGFALSE; ret = HGImgFmt_CheckPnmFile(fileName, &isPnm); if (isPnm) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_PNM; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGBool isTga = HGFALSE; ret = CheckTgaFile(fileName, &isTga); if (isTga) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_TGA; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGBool isPcx = HGFALSE; ret = CheckPcxFile(fileName, &isPcx); if (isPcx) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_PCX; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } HGBool isRas = HGFALSE; ret = CheckRasFile(fileName, &isRas); if (isRas) { HGImgFmtReaderImpl* imgFmtReaderImpl = new HGImgFmtReaderImpl; imgFmtReaderImpl->fileName = fileName; imgFmtReaderImpl->fmtType = HGIMGFMT_TYPE_RAS; imgFmtReaderImpl->handle = NULL; *reader = (HGImgFmtReader)imgFmtReaderImpl; return HGBASE_ERR_OK; } return ret; } HGResult HGAPI HGImgFmt_CloseImageReader(HGImgFmtReader reader) { if (NULL == reader) { return HGBASE_ERR_INVALIDARG; } HGImgFmtReaderImpl* imgFmtReaderImpl = (HGImgFmtReaderImpl*)reader; if (HGIMGFMT_TYPE_TIFF == imgFmtReaderImpl->fmtType) HGImgFmt_CloseTiffReader((HGTiffReader)imgFmtReaderImpl->handle); else if (HGIMGFMT_TYPE_PDF == imgFmtReaderImpl->fmtType) HGImgFmt_ClosePdfReader((HGPdfReader)imgFmtReaderImpl->handle); else if (HGIMGFMT_TYPE_OFD == imgFmtReaderImpl->fmtType) HGImgFmt_CloseOfdReader((HGOfdReader)imgFmtReaderImpl->handle); else if (HGIMGFMT_TYPE_GIF == imgFmtReaderImpl->fmtType) HGImgFmt_CloseGifReader((HGGifReader)imgFmtReaderImpl->handle); delete imgFmtReaderImpl; return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_GetImagePageCount(HGImgFmtReader reader, HGUInt* count) { if (NULL == reader || NULL == count) { return HGBASE_ERR_INVALIDARG; } HGImgFmtReaderImpl* imgFmtReaderImpl = (HGImgFmtReaderImpl*)reader; if (HGIMGFMT_TYPE_TIFF == imgFmtReaderImpl->fmtType) return HGImgFmt_GetTiffPageCount((HGTiffReader)imgFmtReaderImpl->handle, count); else if (HGIMGFMT_TYPE_PDF == imgFmtReaderImpl->fmtType) return HGImgFmt_GetPdfPageCount((HGPdfReader)imgFmtReaderImpl->handle, count); else if (HGIMGFMT_TYPE_OFD == imgFmtReaderImpl->fmtType) return HGImgFmt_GetOfdPageCount((HGOfdReader)imgFmtReaderImpl->handle, count); else if (HGIMGFMT_TYPE_GIF == imgFmtReaderImpl->fmtType) { *count = imgFmtReaderImpl->gifLoadInfo.imageCount; return HGBASE_ERR_OK; } *count = 1; return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_LoadImageFromReader(HGImgFmtReader reader, HGUInt index, HGImgFmtLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { if (NULL == reader) { return HGBASE_ERR_INVALIDARG; } HGImgFmtReaderImpl* imgFmtReaderImpl = (HGImgFmtReaderImpl*)reader; if (HGIMGFMT_TYPE_JPEG == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } HGJpegLoadInfo jpegInfo; HGResult ret = HGImgFmt_LoadJpegImage(imgFmtReaderImpl->fileName.c_str(), &jpegInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = jpegInfo.width; info->height = jpegInfo.height; info->bpp = jpegInfo.numComponents * 8; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_JPEGDENUNIT_INCH == jpegInfo.densityUnit) { info->xDpi = jpegInfo.xDensity; info->yDpi = jpegInfo.yDensity; } else if (HGIMGFMT_JPEGDENUNIT_CENTIMETER == jpegInfo.densityUnit) { info->xDpi = (uint32_t)((double)jpegInfo.xDensity / 0.393700787 + 0.5); info->yDpi = (uint32_t)((double)jpegInfo.yDensity / 0.393700787 + 0.5); } } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_BMP == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } HGBmpLoadInfo bmpInfo; HGResult ret = HGImgFmt_LoadBmpImage(imgFmtReaderImpl->fileName.c_str(), &bmpInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = bmpInfo.width; info->height = bmpInfo.height; info->bpp = bmpInfo.bitCount; info->xDpi = (uint32_t)((double)bmpInfo.xPelsPerMeter / 39.3700787 + 0.5); info->yDpi = (uint32_t)((double)bmpInfo.yPelsPerMeter / 39.3700787 + 0.5); } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PNG == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } HGPngLoadInfo pngInfo; HGResult ret = HGImgFmt_LoadPngImage(imgFmtReaderImpl->fileName.c_str(), &pngInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = pngInfo.width; info->height = pngInfo.height; info->bpp = pngInfo.pixelDepth; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_PNGPHYSUNIT_METER == pngInfo.physUnitType) { info->xDpi = (uint32_t)((double)pngInfo.xPixelsPerUnit / 39.3700787 + 0.5); info->yDpi = (uint32_t)((double)pngInfo.yPixelsPerUnit / 39.3700787 + 0.5); } } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_TIFF == imgFmtReaderImpl->fmtType) { HGTiffLoadInfo tiffInfo; HGResult ret = HGImgFmt_LoadImageFromTiffReader((HGTiffReader)imgFmtReaderImpl->handle, index, &tiffInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = tiffInfo.width; info->height = tiffInfo.height; info->bpp = tiffInfo.bitsPerSample * tiffInfo.samplesPerPixel; info->xDpi = 0; info->yDpi = 0; if (HGIMGFMT_TIFFRESUNIT_INCH == tiffInfo.resolutionUnit) { info->xDpi = (uint32_t)(tiffInfo.xResolution + 0.5f); info->yDpi = (uint32_t)(tiffInfo.yResolution + 0.5f); } else if (HGIMGFMT_TIFFRESUNIT_CENTIMETER == tiffInfo.resolutionUnit) { info->xDpi = (uint32_t)((double)tiffInfo.xResolution / 0.393700787 + 0.5); info->yDpi = (uint32_t)((double)tiffInfo.yResolution / 0.393700787 + 0.5); } } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PDF == imgFmtReaderImpl->fmtType) { HGResult ret = HGBASE_ERR_OK; if (NULL != info) { info->width = 0; info->height = 0; info->bpp = 0; info->xDpi = 0; info->yDpi = 0; HGPdfPageInfo pdfInfo; ret = HGImgFmt_GetPdfPageInfo((HGPdfReader)imgFmtReaderImpl->handle, index, &pdfInfo); if (HGBASE_ERR_OK == ret) { info->width = pdfInfo.width; info->height = pdfInfo.height; info->bpp = pdfInfo.bpp; } } if (ret == HGBASE_ERR_OK && NULL != image) { ret = HGImgFmt_LoadImageFromPdfReader((HGPdfReader)imgFmtReaderImpl->handle, index, 300.0f / 72.0f, 300.0f / 72.0f, imgType, imgOrigin, image); } return ret; } else if (HGIMGFMT_TYPE_OFD == imgFmtReaderImpl->fmtType) { HGResult ret = HGBASE_ERR_OK; if (NULL != info) { info->width = 0; info->height = 0; info->bpp = 0; info->xDpi = 0; info->yDpi = 0; HGOfdPageInfo ofdInfo; ret = HGImgFmt_GetOfdPageInfo((HGOfdReader)imgFmtReaderImpl->handle, index, &ofdInfo); if (HGBASE_ERR_OK == ret) { info->width = ofdInfo.width; info->height = ofdInfo.height; info->bpp = ofdInfo.bpp; } } if (ret == HGBASE_ERR_OK && NULL != image) { ret = HGImgFmt_LoadImageFromOfdReader((HGOfdReader)imgFmtReaderImpl->handle, index, 1.0f, 1.0f, imgType, imgOrigin, image); } return ret; } else if (HGIMGFMT_TYPE_PNM == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } HGPnmLoadInfo pnmInfo; HGResult ret = HGImgFmt_LoadPnmImage(imgFmtReaderImpl->fileName.c_str(), &pnmInfo, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } if (NULL != info) { info->width = pnmInfo.width; info->height = pnmInfo.height; info->bpp = 1; if (pnmInfo.type == HGIMGFMT_PNMTYPE_GRAY_ASCII || pnmInfo.type == HGIMGFMT_PNMTYPE_GRAY_BINARY) info->bpp = 8; else if (pnmInfo.type == HGIMGFMT_PNMTYPE_RGB_ASCII || pnmInfo.type == HGIMGFMT_PNMTYPE_RGB_BINARY) info->bpp = 24; info->xDpi = 0; info->yDpi = 0; } return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_TGA == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } return LoadTgaImage(imgFmtReaderImpl->fileName.c_str(), info, imgType, imgOrigin, image); } else if (HGIMGFMT_TYPE_PCX == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } return LoadPcxImage(imgFmtReaderImpl->fileName.c_str(), info, imgType, imgOrigin, image); } else if (HGIMGFMT_TYPE_RAS == imgFmtReaderImpl->fmtType) { if (0 != index) { return HGBASE_ERR_INVALIDARG; } return LoadRasImage(imgFmtReaderImpl->fileName.c_str(), info, imgType, imgOrigin, image); } assert(HGIMGFMT_TYPE_GIF == imgFmtReaderImpl->fmtType); if (NULL == image) { if (0 != imgType || 0 != imgOrigin) { return HGBASE_ERR_INVALIDARG; } } if (index >= imgFmtReaderImpl->gifLoadInfo.imageCount) { return HGBASE_ERR_INVALIDARG; } if (NULL != info) { info->width = imgFmtReaderImpl->gifLoadInfo.width; info->height = imgFmtReaderImpl->gifLoadInfo.height; info->bpp = imgFmtReaderImpl->gifLoadInfo.colorResolution; info->xDpi = 0; info->yDpi = 0; } if (NULL != image) { HGResult ret = HGImgFmt_LoadImageFromGifReader((HGGifReader)imgFmtReaderImpl->handle, index, NULL, imgType, imgOrigin, image); if (HGBASE_ERR_OK != ret) { return ret; } } return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_OpenImageWriter(const HGChar* fileName, HGUInt fmtType, HGImgFmtWriter* writer) { if (fmtType > HGIMGFMT_TYPE_RAS || NULL == writer) { return HGBASE_ERR_INVALIDARG; } if (0 == fmtType) { HGImgFmt_GetImgFmtTypeFromFileName(fileName, &fmtType); if (fmtType < HGIMGFMT_TYPE_JPEG || fmtType > HGIMGFMT_TYPE_RAS) { return HGBASE_ERR_INVALIDARG; } } if (HGIMGFMT_TYPE_JPEG == fmtType || HGIMGFMT_TYPE_BMP == fmtType || HGIMGFMT_TYPE_PNG == fmtType || HGIMGFMT_TYPE_PNM == fmtType || HGIMGFMT_TYPE_TGA == fmtType || HGIMGFMT_TYPE_PCX == fmtType || HGIMGFMT_TYPE_RAS == fmtType) { HGImgFmtWriterImpl* imgFmtWriterImpl = new HGImgFmtWriterImpl; imgFmtWriterImpl->fileName = fileName; imgFmtWriterImpl->fmtType = fmtType; imgFmtWriterImpl->handle = NULL; imgFmtWriterImpl->write = HGFALSE; *writer = (HGImgFmtWriter)imgFmtWriterImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_TIFF == fmtType) { HGTiffWriter tiffWriter = NULL; HGResult ret = HGImgFmt_OpenTiffWriter(fileName, &tiffWriter); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtWriterImpl* imgFmtWriterImpl = new HGImgFmtWriterImpl; imgFmtWriterImpl->fileName = fileName; imgFmtWriterImpl->fmtType = fmtType; imgFmtWriterImpl->handle = tiffWriter; imgFmtWriterImpl->write = HGFALSE; *writer = (HGImgFmtWriter)imgFmtWriterImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_PDF == fmtType) { HGPdfImageWriter pdfWriter = NULL; HGResult ret = HGImgFmt_OpenPdfImageWriter(fileName, &pdfWriter); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtWriterImpl* imgFmtWriterImpl = new HGImgFmtWriterImpl; imgFmtWriterImpl->fileName = fileName; imgFmtWriterImpl->fmtType = fmtType; imgFmtWriterImpl->handle = pdfWriter; imgFmtWriterImpl->write = HGFALSE; *writer = (HGImgFmtWriter)imgFmtWriterImpl; return HGBASE_ERR_OK; } else if (HGIMGFMT_TYPE_OFD == fmtType) { HGOfdImageWriter ofdWriter = NULL; HGResult ret = HGImgFmt_OpenOfdImageWriter(fileName, &ofdWriter); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtWriterImpl* imgFmtWriterImpl = new HGImgFmtWriterImpl; imgFmtWriterImpl->fileName = fileName; imgFmtWriterImpl->fmtType = fmtType; imgFmtWriterImpl->handle = ofdWriter; imgFmtWriterImpl->write = HGFALSE; *writer = (HGImgFmtWriter)imgFmtWriterImpl; return HGBASE_ERR_OK; } assert(HGIMGFMT_TYPE_GIF == fmtType); HGGifWriter gifWriter = NULL; HGResult ret = HGImgFmt_OpenGifWriter(fileName, NULL, &gifWriter); if (HGBASE_ERR_OK != ret) { return ret; } HGImgFmtWriterImpl* imgFmtWriterImpl = new HGImgFmtWriterImpl; imgFmtWriterImpl->fileName = fileName; imgFmtWriterImpl->fmtType = fmtType; imgFmtWriterImpl->handle = gifWriter; imgFmtWriterImpl->write = HGFALSE; *writer = (HGImgFmtWriter)imgFmtWriterImpl; return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_CloseImageWriter(HGImgFmtWriter writer) { if (NULL == writer) { return HGBASE_ERR_INVALIDARG; } HGImgFmtWriterImpl* imgFmtWriterImpl = (HGImgFmtWriterImpl*)writer; if (HGIMGFMT_TYPE_TIFF == imgFmtWriterImpl->fmtType) HGImgFmt_CloseTiffWriter((HGTiffWriter)imgFmtWriterImpl->handle); else if (HGIMGFMT_TYPE_PDF == imgFmtWriterImpl->fmtType) HGImgFmt_ClosePdfImageWriter((HGPdfImageWriter)imgFmtWriterImpl->handle); else if (HGIMGFMT_TYPE_OFD == imgFmtWriterImpl->fmtType) HGImgFmt_CloseOfdImageWriter((HGOfdImageWriter)imgFmtWriterImpl->handle); else if (HGIMGFMT_TYPE_GIF == imgFmtWriterImpl->fmtType) HGImgFmt_CloseGifWriter((HGGifWriter)imgFmtWriterImpl->handle); delete imgFmtWriterImpl; return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_SaveImageToWriter(HGImgFmtWriter writer, HGImage image, const HGImgFmtSaveInfo* info) { if (NULL == writer) { return HGBASE_ERR_INVALIDARG; } HGUInt xDpi = 0, yDpi = 0; HGBase_GetImageDpi(image, &xDpi, &yDpi); HGImgFmtWriterImpl* imgFmtWriterImpl = (HGImgFmtWriterImpl*)writer; if (HGIMGFMT_TYPE_JPEG == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGJpegSaveInfo jpegInfo; HGJpegSaveInfo* pJpegInfo = NULL; if (NULL != info) { jpegInfo.quality = info->jpegQuality; jpegInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH; jpegInfo.xDensity = xDpi; jpegInfo.yDensity = yDpi; pJpegInfo = &jpegInfo; } HGResult ret = HGImgFmt_SaveJpegImage(image, pJpegInfo, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } else if (HGIMGFMT_TYPE_BMP == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGBmpSaveInfo bmpInfo; HGBmpSaveInfo* pBmpInfo = NULL; if (NULL != info) { bmpInfo.xPelsPerMeter = (uint32_t)((double)xDpi * 39.3700787 + 0.5); bmpInfo.yPelsPerMeter = (uint32_t)((double)yDpi * 39.3700787 + 0.5); pBmpInfo = &bmpInfo; } HGResult ret = HGImgFmt_SaveBmpImage(image, pBmpInfo, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } else if (HGIMGFMT_TYPE_PNG == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGPngSaveInfo pngInfo; HGPngSaveInfo* pPngInfo = NULL; if (NULL != info) { pngInfo.physUnitType = HGIMGFMT_PNGPHYSUNIT_METER; pngInfo.xPixelsPerUnit = (uint32_t)((double)xDpi * 39.3700787 + 0.5); pngInfo.yPixelsPerUnit = (uint32_t)((double)yDpi * 39.3700787 + 0.5); pPngInfo = &pngInfo; } HGResult ret = HGImgFmt_SavePngImage(image, pPngInfo, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } else if (HGIMGFMT_TYPE_TIFF == imgFmtWriterImpl->fmtType) { HGTiffSaveInfo tiffInfo; HGTiffSaveInfo* pTiffInfo = NULL; if (NULL != info) { tiffInfo.compression = info->tiffCompression; tiffInfo.jpegQuality = info->tiffJpegQuality; tiffInfo.resolutionUnit = HGIMGFMT_TIFFRESUNIT_INCH; tiffInfo.xResolution = (float)xDpi; tiffInfo.yResolution = (float)yDpi; pTiffInfo = &tiffInfo; } return HGImgFmt_SaveImageToTiffWriter((HGTiffWriter)imgFmtWriterImpl->handle, image, pTiffInfo); } else if (HGIMGFMT_TYPE_PDF == imgFmtWriterImpl->fmtType) { HGJpegSaveInfo jpegInfo; HGJpegSaveInfo* pJpegInfo = NULL; if (NULL != info) { jpegInfo.quality = info->jpegQuality; jpegInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH; jpegInfo.xDensity = xDpi; jpegInfo.yDensity = yDpi; pJpegInfo = &jpegInfo; } return HGImgFmt_SaveJpegImageToPdfImageWriter((HGPdfImageWriter)imgFmtWriterImpl->handle, image, pJpegInfo); } else if (HGIMGFMT_TYPE_OFD == imgFmtWriterImpl->fmtType) { HGJpegSaveInfo jpegInfo; HGJpegSaveInfo* pJpegInfo = NULL; if (NULL != info) { jpegInfo.quality = info->jpegQuality; jpegInfo.densityUnit = HGIMGFMT_JPEGDENUNIT_INCH; jpegInfo.xDensity = xDpi; jpegInfo.yDensity = yDpi; pJpegInfo = &jpegInfo; } return HGImgFmt_SaveJpegImageToOfdImageWriter((HGOfdImageWriter)imgFmtWriterImpl->handle, image, pJpegInfo); } else if (HGIMGFMT_TYPE_PNM == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGResult ret = HGImgFmt_SavePnmImage(image, NULL, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } else if (HGIMGFMT_TYPE_TGA == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGResult ret = SaveTgaImage(image, NULL, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } else if (HGIMGFMT_TYPE_PCX == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGResult ret = SavePcxImage(image, NULL, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } else if (HGIMGFMT_TYPE_RAS == imgFmtWriterImpl->fmtType) { if (imgFmtWriterImpl->write) { return HGBASE_ERR_FAIL; } HGResult ret = SaveRasImage(image, NULL, imgFmtWriterImpl->fileName.c_str()); if (HGBASE_ERR_OK == ret) { imgFmtWriterImpl->write = HGTRUE; } return ret; } assert(HGIMGFMT_TYPE_GIF == imgFmtWriterImpl->fmtType); return HGImgFmt_SaveImageToGifWriter((HGGifWriter)imgFmtWriterImpl->handle, 50, HG_MAKECOLOR(255, 255, 255, 255), image); }