pnm格式优化

This commit is contained in:
luoliangyi 2022-11-04 16:55:46 +08:00
parent d4abcf0240
commit 065a890253
1 changed files with 190 additions and 68 deletions

View File

@ -123,7 +123,7 @@ static HGResult BnmLoadInfo(FILE* file, HGUInt pnmType, HGUInt *width, HGUInt *h
static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image)
{
HGUInt width, height, maxColor;
HGResult ret = BnmLoadInfo(file , pnmType, &width, &height, &maxColor);
HGResult ret = BnmLoadInfo(file, pnmType, &width, &height, &maxColor);
if (HGBASE_ERR_OK != ret)
{
return ret;
@ -131,7 +131,7 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
if (pnmType != HGIMGFMT_PNMTYPE_BINARY_ASCII && pnmType != HGIMGFMT_PNMTYPE_BINARY_BINARY)
{
if (maxColor > 255 || maxColor < 0)
if (maxColor > 255)
return HGBASE_ERR_INVALIDDATA;
}
@ -167,13 +167,11 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
ret = HGBase_CreateImage(width, height, HGBASE_IMGTYPE_GRAY, HGBASE_IMGORIGIN_TOP, &image2);
else if (pnmType == HGIMGFMT_PNMTYPE_RGB_ASCII || pnmType == HGIMGFMT_PNMTYPE_RGB_BINARY)
ret = HGBase_CreateImage(width, height, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
std::vector<char> buf;
uint8_t* data;
HGBase_GetImageData(image2, &data);
HGImageInfo imgInfo;
@ -181,9 +179,9 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
if (pnmType == HGIMGFMT_PNMTYPE_BINARY_BINARY)
{
HGUInt lineSize = ((width + 7) & ~7) >> 3;
for (HGUInt i = 0; i < height; ++i)
{
HGUInt lineSize = ((width + 7) & ~7) >> 3;
if (lineSize != fread(data + i * imgInfo.widthStep, 1, lineSize, file))
{
HGBase_DestroyImage(image2);
@ -191,6 +189,8 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
}
}
HGBase_ReverseImage(image2, image2);
if (HGBASE_IMGTYPE_BINARY == imgType && HGBASE_IMGORIGIN_TOP == imgOrigin)
{
*image = image2;
@ -199,13 +199,11 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
}
}
}
else if (pnmType == HGIMGFMT_PNMTYPE_GRAY_BINARY)
{
@ -226,14 +224,13 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
}
}
else if(pnmType == HGIMGFMT_PNMTYPE_RGB_BINARY)
else if (pnmType == HGIMGFMT_PNMTYPE_RGB_BINARY)
{
for (HGUInt i = 0; i < height; ++i)
{
@ -252,42 +249,37 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
}
}
else if (pnmType == HGIMGFMT_PNMTYPE_BINARY_ASCII || pnmType == HGIMGFMT_PNMTYPE_GRAY_ASCII || pnmType == HGIMGFMT_PNMTYPE_RGB_ASCII)
else if (pnmType == HGIMGFMT_PNMTYPE_BINARY_ASCII)
{
std::vector<HGChar> buf;
HGByte* p = data;
HGUInt idx = 0;
while (1)
{
HGByte c = 0;
if (1 != fread(&c, 1, 1, file))
size_t readSize = fread(&c, 1, 1, file);
if (1 != readSize || c == '#' || c == '\n' || c == '\r' || c == '\t' || c == ' ')
{
if (!buf.empty())
{
buf.push_back(0);
HGInt pixel = atoi(&buf[0]);
if (pnmType != HGIMGFMT_PNMTYPE_BINARY_ASCII && pnmType != HGIMGFMT_PNMTYPE_BINARY_BINARY)
if (0 != pixel && 1 != pixel)
{
if (pixel > 255 || pixel < 0)
return HGBASE_ERR_INVALIDDATA;
}
else
{
if (pixel > 1 || pixel < 0)
return HGBASE_ERR_INVALIDDATA;
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
p[idx] = pixel;
SetBit(p, idx, (HGByte)pixel);
++idx;
if (idx == width * 3)
if (idx == width)
{
p += imgInfo.widthStep;
idx = 0;
@ -296,37 +288,9 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
buf.clear();
}
break;
}
if (c == '#' || c == '\n' || c == '\r' || c == '\t' || c == ' ')
{
if (!buf.empty())
if (1 != readSize)
{
buf.push_back(0);
HGInt pixel = atoi(&buf[0]);
if (pnmType != HGIMGFMT_PNMTYPE_BINARY_ASCII && pnmType != HGIMGFMT_PNMTYPE_BINARY_BINARY)
{
if (pixel > 255 || pixel < 0)
return HGBASE_ERR_INVALIDDATA;
}
else
{
if (pixel > 1 || pixel < 0)
return HGBASE_ERR_INVALIDDATA;
}
p[idx] = pixel;
++idx;
if (idx == width * 3)
{
p += imgInfo.widthStep;
idx = 0;
}
buf.clear();
break;
}
if (c == '#')
@ -335,6 +299,7 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
{
if (1 != fread(&c, 1, 1, file))
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
}
@ -346,6 +311,169 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
}
else
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
if (p == data + height * imgInfo.widthStep)
{
break;
}
}
HGBase_ReverseImage(image2, image2);
if (HGBASE_IMGTYPE_BINARY == imgType && HGBASE_IMGORIGIN_TOP == imgOrigin)
{
*image = image2;
}
else
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
}
}
else if (pnmType == HGIMGFMT_PNMTYPE_GRAY_ASCII)
{
std::vector<HGChar> buf;
HGByte* p = data;
HGUInt idx = 0;
while (1)
{
HGByte c = 0;
size_t readSize = fread(&c, 1, 1, file);
if (1 != readSize || c == '#' || c == '\n' || c == '\r' || c == '\t' || c == ' ')
{
if (!buf.empty())
{
buf.push_back(0);
HGInt pixel = atoi(&buf[0]);
if (pixel < 0 || pixel > 255)
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
p[idx] = (HGByte)pixel;
++idx;
if (idx == width)
{
p += imgInfo.widthStep;
idx = 0;
}
buf.clear();
}
if (1 != readSize)
{
break;
}
if (c == '#')
{
while (c != '\n')
{
if (1 != fread(&c, 1, 1, file))
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
}
}
}
else if (c >= '0' && c <= '9')
{
buf.push_back(c);
}
else
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
if (p == data + height * imgInfo.widthStep)
{
break;
}
}
if (HGBASE_IMGTYPE_GRAY == imgType && HGBASE_IMGORIGIN_TOP == imgOrigin)
{
*image = image2;
}
else
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
}
}
else if (pnmType == HGIMGFMT_PNMTYPE_RGB_ASCII)
{
std::vector<HGChar> buf;
HGByte* p = data;
HGUInt idx = 0;
while (1)
{
HGByte c = 0;
size_t readSize = fread(&c, 1, 1, file);
if (1 != readSize || c == '#' || c == '\n' || c == '\r' || c == '\t' || c == ' ')
{
if (!buf.empty())
{
buf.push_back(0);
HGInt pixel = atoi(&buf[0]);
if (pixel < 0 || pixel > 255)
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
p[idx] = (HGByte)pixel;
++idx;
if (idx == width)
{
p += imgInfo.widthStep;
idx = 0;
}
buf.clear();
}
if (1 != readSize)
{
break;
}
if (c == '#')
{
while (c != '\n')
{
if (1 != fread(&c, 1, 1, file))
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
}
}
}
else if (c >= '0' && c <= '9')
{
buf.push_back(c);
}
else
{
HGBase_DestroyImage(image2);
return HGBASE_ERR_INVALIDDATA;
}
@ -363,18 +491,12 @@ static HGResult BnmLoadImage(FILE* file, HGUInt pnmType, HGPnmLoadInfo* info, HG
{
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
HGBase_DestroyImage(image2);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
}
}
if (pnmType == HGIMGFMT_PNMTYPE_BINARY_ASCII || pnmType == HGIMGFMT_PNMTYPE_BINARY_BINARY)
{
HGBase_ReverseImage(image2, image2);
}
}
return HGBASE_ERR_OK;
@ -419,10 +541,10 @@ HGResult HGAPI HGImgFmt_LoadPnmImage(const HGChar* fileName, HGPnmLoadInfo* info
HGByte magicKey[2] = {0};
if (2 != fread(magicKey, 1, 2, file))
{
fclose(file);
return HGBASE_ERR_INVALIDDATA;
}
HGResult ret = HGBASE_ERR_INVALIDDATA;
HGUInt pnmType = 0;
if (magicKey[0] == 'P' && (magicKey[1] == '1'))
{
@ -448,22 +570,20 @@ HGResult HGAPI HGImgFmt_LoadPnmImage(const HGChar* fileName, HGPnmLoadInfo* info
{
pnmType = HGIMGFMT_PNMTYPE_RGB_BINARY;
}
else
if (0 == pnmType)
{
return HGBASE_ERR_INVALIDARG;
fclose(file);
return HGBASE_ERR_INVALIDDATA;
}
ret = BnmLoadImage(file, pnmType, info, imgType, imgOrigin, image);
HGResult ret = BnmLoadImage(file, pnmType, info, imgType, imgOrigin, image);
fclose(file);
return ret;
}
static HGResult BnmSaveImage(HGImage image, const HGChar* fileName, HGUInt type)
{
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
FILE* file = fopen(fileName, "wb");
if (NULL == file)
{
@ -472,6 +592,8 @@ static HGResult BnmSaveImage(HGImage image, const HGChar* fileName, HGUInt type)
HGByte* data = NULL;
HGBase_GetImageData(image, &data);
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
char magicKey[4] = {0};
if (HGIMGFMT_PNMTYPE_BINARY_ASCII == type)