code_app/modules/imgfmt/HGPnm.cpp

241 lines
4.4 KiB
C++

#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;
}