#include "HGPnm.h" #include "../base/HGInc.h" HGResult HGAPI HGImgFmt_CheckPnmFile(const HGChar* fileName, HGBool* isPnm) { if (NULL == fileName || NULL == isPnm) { return HGBASE_ERR_INVALIDARG; } HGPnmLoadInfo info; HGResult ret = HGImgFmt_LoadPnmImage(fileName, &info, 0, 0, NULL); *isPnm = (HGBASE_ERR_OK == ret ? HGTRUE : HGFALSE); return HGBASE_ERR_OK; } static HGResult bnm_load_P6(FILE &file, HGPnmLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image) { HGChar c; HGInt rgbMaxColor, width, height; c = getc(&file); while (c == '#') { while (getc(&file) != '\n'); c = getc(&file); } ungetc(c, &file); while (c == '\n' || c == '\r' || c == '\t' || c == ' ') { c = fgetc(&file); while (c == '#') { while (getc(&file) != '\n'); c = getc(&file); } } ungetc(c, &file); fscanf(&file, "%d", &width); c = getc(&file); while (c == '\n' || c == '\r' || c == '\t' || c == ' ') { c = fgetc(&file); while (c == '#') { while (getc(&file) != '\n'); c = getc(&file); } } ungetc(c, &file); fscanf(&file, "%d", &height); if (width <= 0 || height <= 0) { return HGBASE_ERR_INVALIDARG; } c = getc(&file); while (c == '\n' || c == '\r' || c == '\t' || c == ' ') { c = fgetc(&file); while (c == '#') { while (getc(&file) != '\n'); c = getc(&file); } } ungetc(c, &file); fscanf(&file, "%d", &rgbMaxColor); if (rgbMaxColor <= 0) { return HGBASE_ERR_INVALIDARG; } c = fgetc(&file); while (c == '\n' || c == '\r' || c == '\t' || c == ' ') { c = fgetc(&file); while (c == '#') { while (getc(&file) != '\n'); c = getc(&file); } } ungetc(c, &file); _fseeki64(&file, 0, SEEK_CUR); uint64_t headerSize = _ftelli64(&file); _fseeki64(&file, 0, SEEK_END); uint64_t totalSize = _ftelli64(&file); if (0 == headerSize || 0 == totalSize) { fclose(&file); return HGBASE_ERR_FAIL; } size_t dataSize = (size_t)totalSize - (size_t)headerSize; uint8_t* buffer = (uint8_t*)malloc(dataSize); if (NULL == buffer) { fclose(&file); return HGBASE_ERR_FAIL; } _fseeki64(&file, headerSize, SEEK_SET); size_t readSize = fread(buffer, 1, dataSize, &file); if (readSize != dataSize || dataSize != (size_t)width * (size_t)height * 3) { free(buffer); buffer = NULL; fclose(&file); return HGBASE_ERR_FAIL; } HGImage image2 = NULL; if (info != NULL) { info->width = width; info->height = height; info->type = HGIMGFMT_PNMTYPE_RGB_BINRAY; } if (image != NULL) { if (imgType == 0) { imgType = HGBASE_IMGTYPE_RGB; } HGBase_CreateImage(width, height, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2); uint8_t* data; HGBase_GetImageData(image2, &data); HGImageInfo imgInfo; HGBase_GetImageInfo(image2, &imgInfo); memcpy(data, buffer, dataSize); if(HGBASE_ERR_OK != HGBase_CloneImage(image2, imgType, imgOrigin, image)) { return HGBASE_ERR_FAIL; } } HGBase_DestroyImage(image2); image2 = NULL; free(buffer); buffer = NULL; fclose(&file); return HGBASE_ERR_OK; } HGResult HGAPI HGImgFmt_LoadPnmImage(const HGChar* fileName, HGPnmLoadInfo* 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 (HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin) { return HGBASE_ERR_INVALIDARG; } } FILE* file = fopen(fileName, "rb"); if (NULL == file) { return HGBASE_ERR_ACCESSDENIED; } HGChar header[1024] = {0}; HGChar c = NULL; c = getc(file); while (c == '#') { while (getc(file) != '\n'); c = getc(file); } while (c == '\n' || c == '\r' || c == '\t' || c == ' ') { c = getc(file); while (c == '#') { while (getc(file) != '\n'); c = getc(file); } } if (c != 'P') { return HGBASE_ERR_INVALIDDATA; } else { c = getc(file); if (c < '1' || c > '6') { return HGBASE_ERR_INVALIDDATA; } if (c == '6') { bnm_load_P6(*file, info, imgType, imgOrigin, image); } } } HGResult HGAPI HGImgFmt_SavePnmImage(HGImage image, const HGPnmSaveInfo* info, const HGChar* fileName) { return HGBASE_ERR_OK; }