code_app/modules/imgfmt/HGPnm.cpp

284 lines
5.6 KiB
C++
Raw Normal View History

#include "HGPnm.h"
2022-10-27 10:31:51 +00:00
#include "../base/HGInc.h"
#include <vector>
2022-10-27 10:31:51 +00:00
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 BnmLoadP6Info(FILE* file, HGUInt *width, HGUInt *height, HGUInt *maxColor)
2022-10-27 10:31:51 +00:00
{
assert(NULL != file && NULL != width && NULL != height && NULL != maxColor);
2022-10-27 10:31:51 +00:00
bool getWidth = false;
bool getHeight = false;
bool getMaxColor = false;
std::vector<char> buf;
2022-10-27 10:31:51 +00:00
while (1)
2022-10-27 10:31:51 +00:00
{
HGByte c = 0;
if (1 != fread(&c, 1, 1, file))
2022-10-27 10:31:51 +00:00
{
return HGBASE_ERR_INVALIDDATA;
2022-10-27 10:31:51 +00:00
}
if (c == '#' || c == '\n' || c == '\r' || c == '\t' || c == ' ')
2022-10-27 10:31:51 +00:00
{
if (!buf.empty())
{
buf.push_back(0);
if (!getWidth)
{
*width = atoi(&buf[0]);
if (*width == 0)
return HGBASE_ERR_INVALIDDATA;
getWidth = true;
}
else if (!getHeight)
{
*height = atoi(&buf[0]);
if (*height == 0)
return HGBASE_ERR_INVALIDDATA;
getHeight = true;
}
else if (!getMaxColor)
{
*maxColor = atoi(&buf[0]);
if (*maxColor == 0)
return HGBASE_ERR_INVALIDDATA;
getMaxColor = true;
}
buf.clear();
}
if (c == '#')
{
while (c != '\n')
{
if (1 != fread(&c, 1, 1, file))
{
return HGBASE_ERR_INVALIDDATA;
}
}
}
2022-10-27 10:31:51 +00:00
}
else if (c >= '0' && c <= '9')
2022-10-27 10:31:51 +00:00
{
buf.push_back(c);
2022-10-27 10:31:51 +00:00
}
else
2022-10-27 10:31:51 +00:00
{
return HGBASE_ERR_INVALIDDATA;
2022-10-27 10:31:51 +00:00
}
if (getMaxColor)
{
break;
}
2022-10-27 10:31:51 +00:00
}
return HGBASE_ERR_OK;
}
2022-10-27 10:31:51 +00:00
static HGResult BnmLoadP6Image(FILE* file, HGPnmLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image)
{
HGUInt width, height, maxColor;
HGResult ret = BnmLoadP6Info(file , &width, &height, &maxColor);
if (HGBASE_ERR_OK != ret || 255 != maxColor)
2022-10-27 10:31:51 +00:00
{
return ret;
2022-10-27 10:31:51 +00:00
}
if (NULL != info)
2022-10-27 10:31:51 +00:00
{
info->width = width;
info->height = height;
info->type = HGIMGFMT_PNMTYPE_RGB_BINRAY;
}
if (NULL != image)
2022-10-27 10:31:51 +00:00
{
if (imgType == 0)
{
imgType = HGBASE_IMGTYPE_RGB;
}
2022-10-27 10:31:51 +00:00
if (imgOrigin == 0)
{
imgOrigin = HGBASE_IMGORIGIN_TOP;
2022-10-27 10:31:51 +00:00
}
HGImage image2 = NULL;
ret = HGBase_CreateImage(width, height, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
2022-10-27 10:31:51 +00:00
uint8_t* data;
HGBase_GetImageData(image2, &data);
HGImageInfo imgInfo;
HGBase_GetImageInfo(image2, &imgInfo);
for (HGUInt i = 0; i < height; ++i)
{
2022-10-28 04:22:17 +00:00
if (width * 3 != fread(data + i * imgInfo.widthStep, 1, width * 3, file))
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
}
2022-10-28 09:45:37 +00:00
if (HGBASE_IMGTYPE_RGB == imgType && HGBASE_IMGORIGIN_TOP == imgOrigin)
2022-10-27 10:31:51 +00:00
{
2022-10-28 09:45:37 +00:00
*image = image2;
}
else
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
2022-10-27 10:31:51 +00:00
}
}
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 (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
2022-10-27 10:31:51 +00:00
{
return HGBASE_ERR_INVALIDARG;
}
}
FILE* file = fopen(fileName, "rb");
if (NULL == file)
{
return HGBASE_ERR_ACCESSDENIED;
}
HGByte magicKey[2] = {0};
if (2 != fread(magicKey, 1, 2, file))
2022-10-27 10:31:51 +00:00
{
return HGBASE_ERR_INVALIDDATA;
2022-10-27 10:31:51 +00:00
}
HGResult ret = HGBASE_ERR_INVALIDDATA;
if (magicKey[0] == 'P' && magicKey[1] == '6')
2022-10-27 10:31:51 +00:00
{
ret = BnmLoadP6Image(file, info, imgType, imgOrigin, image);
2022-10-27 10:31:51 +00:00
}
fclose(file);
return ret;
2022-10-27 10:31:51 +00:00
}
2022-10-28 03:17:16 +00:00
static HGResult BnmSaveP6Image(HGImage image, const HGChar* fileName)
2022-10-27 10:31:51 +00:00
{
2022-10-28 03:17:16 +00:00
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
assert(imgInfo.type == HGBASE_IMGTYPE_RGB);
FILE* file = fopen(fileName, "wb");
if (NULL == file)
{
return HGBASE_ERR_ACCESSDENIED;
}
HGByte* data = NULL;
HGBase_GetImageData(image, &data);
char magicKey[] = "P6\n";
fwrite(magicKey, 1, strlen(magicKey), file);
char width[20], height[20];
sprintf(width, "%u\n", imgInfo.width);
sprintf(height, "%u\n", imgInfo.height);
fwrite(width, 1, strlen(width), file);
fwrite(height, 1, strlen(height), file);
char maxColor[] = "255\n";
fwrite(maxColor, 1, strlen(maxColor), file);
HGByte* p = data;
HGInt step = (HGInt)imgInfo.widthStep;
if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin)
{
p = data + (imgInfo.height - 1) * imgInfo.widthStep;
step = -(HGInt)imgInfo.widthStep;
}
for (HGUInt i = 0; i < imgInfo.height; ++i)
{
uint8_t* pEx = p + (HGSize)i * (HGSize)step;
fwrite(pEx, 1, imgInfo.width * 3, file);
}
fclose(file);
2022-10-27 10:31:51 +00:00
return HGBASE_ERR_OK;
}
2022-10-28 03:17:16 +00:00
HGResult HGAPI HGImgFmt_SavePnmImage(HGImage image, const HGPnmSaveInfo* info, const HGChar* fileName)
{
if (NULL == image || NULL == fileName)
{
return HGBASE_ERR_INVALIDARG;
}
if (NULL != info)
{
if (info->type != HGIMGFMT_PNMTYPE_RGB_BINRAY)
{
return HGBASE_ERR_INVALIDARG;
}
}
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
if (imgInfo.type != HGBASE_IMGTYPE_RGB)
{
return HGBASE_ERR_INVALIDDATA;
}
return BnmSaveP6Image(image, fileName);
}