241 lines
4.4 KiB
C++
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;
|
||
|
}
|