2022-05-03 10:25:52 +00:00
|
|
|
|
#include "HGTiff.h"
|
|
|
|
|
#include "../base/HGInc.h"
|
|
|
|
|
#include "tiffio.h"
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_CheckTiffFile(const HGChar* fileName, HGBool* isTiff)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == fileName || NULL == isTiff)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*isTiff = HGFALSE;
|
|
|
|
|
HGTiffReader reader = NULL;
|
|
|
|
|
HGImgFmt_OpenTiffReader(fileName, &reader);
|
|
|
|
|
if (NULL != reader)
|
|
|
|
|
{
|
|
|
|
|
*isTiff = HGTRUE;
|
|
|
|
|
HGImgFmt_CloseTiffReader(reader);
|
|
|
|
|
}
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_OpenTiffReader(const HGChar* fileName, HGTiffReader* reader)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == fileName || NULL == reader)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFF* tif = TIFFOpen(fileName, "r");
|
|
|
|
|
if (NULL == tif)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_ACCESSDENIED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*reader = (HGTiffReader)tif;
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_CloseTiffReader(HGTiffReader reader)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == reader)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFF* tif = (TIFF*)reader;
|
|
|
|
|
TIFFClose(tif);
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_GetTiffPageCount(HGTiffReader reader, HGUInt* count)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == reader || NULL == count)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFF* tif = (TIFF*)reader;
|
|
|
|
|
*count = TIFFNumberOfDirectories(tif);
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_LoadImageFromTiffReader(HGTiffReader reader, HGUInt index, UPTiffLoadInfo* info,
|
|
|
|
|
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == reader)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL == image)
|
|
|
|
|
{
|
|
|
|
|
if (0 != imgType || 0 != imgOrigin)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (0 != imgType && HGBASE_IMGTYPE_GRAY != imgType && HGBASE_IMGTYPE_RGB != imgType
|
|
|
|
|
&& HGBASE_IMGTYPE_RGBA != imgType && HGBASE_IMGTYPE_BGR != imgType
|
|
|
|
|
&& HGBASE_IMGTYPE_BGRA != imgType)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFF* tif = (TIFF*)reader;
|
|
|
|
|
if (0 == TIFFSetDirectory(tif, index))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32 width;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
|
|
|
|
|
uint32 height;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
|
|
|
|
|
uint16 bitsPerSample;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
|
|
|
|
|
uint16 samplesPerPixel;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);
|
|
|
|
|
uint16 compression;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
|
|
|
|
|
|
|
|
|
|
uint16 resolutionUnit;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit);
|
|
|
|
|
float xResolution;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xResolution);
|
|
|
|
|
float yResolution;
|
|
|
|
|
TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yResolution);
|
|
|
|
|
|
|
|
|
|
if (NULL != info)
|
|
|
|
|
{
|
|
|
|
|
info->width = width;
|
|
|
|
|
info->height = height;
|
|
|
|
|
info->bitsPerSample = bitsPerSample;
|
|
|
|
|
info->samplesPerPixel = samplesPerPixel;
|
|
|
|
|
info->compression = compression;
|
|
|
|
|
info->resolutionUnit = resolutionUnit;
|
|
|
|
|
info->xResolution = xResolution;
|
|
|
|
|
info->yResolution = yResolution;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != image)
|
|
|
|
|
{
|
|
|
|
|
uint32* buffer = (uint32*)malloc(width * height * sizeof(uint32));
|
|
|
|
|
if (NULL == buffer)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == TIFFReadRGBAImageOriented(tif, width, height, buffer, ORIENTATION_TOPLEFT))
|
|
|
|
|
{
|
|
|
|
|
free(buffer);
|
|
|
|
|
buffer = NULL;
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 == imgType)
|
|
|
|
|
{
|
|
|
|
|
if (4 == samplesPerPixel)
|
|
|
|
|
{
|
|
|
|
|
imgType = HGBASE_IMGTYPE_RGBA;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
imgType = HGBASE_IMGTYPE_RGB;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGImage image2 = NULL;
|
|
|
|
|
HGResult result = HGBase_CreateImage(width, height, imgType, imgOrigin, &image2);
|
|
|
|
|
if (HGBASE_ERR_OK != result)
|
|
|
|
|
{
|
|
|
|
|
free(buffer);
|
|
|
|
|
buffer = NULL;
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-13 03:56:46 +00:00
|
|
|
|
if (RESUNIT_INCH == resolutionUnit)
|
2022-05-03 10:25:52 +00:00
|
|
|
|
{
|
|
|
|
|
uint32_t xDpi = (uint32_t)(xResolution + 0.5f);
|
|
|
|
|
uint32_t yDpi = (uint32_t)(yResolution + 0.5f);
|
|
|
|
|
HGBase_SetImageDpi(image2, xDpi, yDpi);
|
|
|
|
|
}
|
2022-05-13 03:56:46 +00:00
|
|
|
|
else if (RESUNIT_CENTIMETER == resolutionUnit)
|
|
|
|
|
{
|
|
|
|
|
uint32_t xDpi = (uint32_t)(xResolution / 0.393700787402 + 0.5);
|
|
|
|
|
uint32_t yDpi = (uint32_t)(yResolution / 0.393700787402 + 0.5);
|
|
|
|
|
HGBase_SetImageDpi(image2, xDpi, yDpi);
|
|
|
|
|
}
|
2022-05-03 10:25:52 +00:00
|
|
|
|
|
|
|
|
|
uint8_t* data;
|
|
|
|
|
HGBase_GetImageData(image2, &data);
|
|
|
|
|
HGImageInfo imgInfo;
|
|
|
|
|
HGBase_GetImageInfo(image2, &imgInfo);
|
|
|
|
|
|
|
|
|
|
HGByte* dest = data;
|
|
|
|
|
HGSize destStep = (HGSize)imgInfo.widthStep;
|
|
|
|
|
if (HGBASE_IMGORIGIN_BOTTOM == imgOrigin)
|
|
|
|
|
{
|
|
|
|
|
dest = data + (HGUSize)(imgInfo.height - 1) * (HGUSize)imgInfo.widthStep;
|
|
|
|
|
destStep = -(HGSize)imgInfo.widthStep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (HGBASE_IMGTYPE_GRAY == imgType)
|
|
|
|
|
{
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32 i = 0; i < (int32)height; i++)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* pEx = (uint8_t*)buffer + (uintptr_t)i * (uintptr_t)width * (uintptr_t)4;
|
|
|
|
|
uint8_t* pExEnd = pEx + width * 4;
|
|
|
|
|
uint8_t* pDestEx = dest + (HGSize)i * (HGSize)destStep;
|
|
|
|
|
|
|
|
|
|
while (pEx < pExEnd)
|
|
|
|
|
{
|
|
|
|
|
uint8_t value = (pEx[0] * 76 + pEx[1] * 150 + pEx[2] * 30) >> 8;
|
|
|
|
|
*pDestEx = value;
|
|
|
|
|
|
|
|
|
|
pEx += 4;
|
|
|
|
|
++pDestEx;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (HGBASE_IMGTYPE_RGB == imgType)
|
|
|
|
|
{
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32 i = 0; i < (int32)height; i++)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* pEx = (uint8_t*)buffer + (uintptr_t)i * (uintptr_t)width * (uintptr_t)4;
|
|
|
|
|
uint8_t* pExEnd = pEx + width * 4;
|
|
|
|
|
uint8_t* pDestEx = dest + (HGSize)i * (HGSize)destStep;
|
|
|
|
|
|
|
|
|
|
while (pEx < pExEnd)
|
|
|
|
|
{
|
|
|
|
|
pDestEx[0] = pEx[0];
|
|
|
|
|
pDestEx[1] = pEx[1];
|
|
|
|
|
pDestEx[2] = pEx[2];
|
|
|
|
|
|
|
|
|
|
pEx += 4;
|
|
|
|
|
pDestEx += 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (HGBASE_IMGTYPE_BGR == imgType)
|
|
|
|
|
{
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32 i = 0; i < (int32)height; i++)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* pEx = (uint8_t*)buffer + (uintptr_t)i * (uintptr_t)width * (uintptr_t)4;
|
|
|
|
|
uint8_t* pExEnd = pEx + width * 4;
|
|
|
|
|
uint8_t* pDestEx = dest + (HGSize)i * (HGSize)destStep;
|
|
|
|
|
|
|
|
|
|
while (pEx < pExEnd)
|
|
|
|
|
{
|
|
|
|
|
pDestEx[0] = pEx[2];
|
|
|
|
|
pDestEx[1] = pEx[1];
|
|
|
|
|
pDestEx[2] = pEx[0];
|
|
|
|
|
|
|
|
|
|
pEx += 4;
|
|
|
|
|
pDestEx += 3;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (HGBASE_IMGTYPE_BGRA == imgType)
|
|
|
|
|
{
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32 i = 0; i < (int32)height; i++)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* pEx = (uint8_t*)buffer + (uintptr_t)i * (uintptr_t)width * (uintptr_t)4;
|
|
|
|
|
uint8_t* pExEnd = pEx + width * 4;
|
|
|
|
|
uint8_t* pDestEx = dest + (HGSize)i * (HGSize)destStep;
|
|
|
|
|
|
|
|
|
|
while (pEx < pExEnd)
|
|
|
|
|
{
|
|
|
|
|
pDestEx[0] = pEx[2];
|
|
|
|
|
pDestEx[1] = pEx[1];
|
|
|
|
|
pDestEx[2] = pEx[0];
|
|
|
|
|
pDestEx[3] = pEx[3];
|
|
|
|
|
|
|
|
|
|
pEx += 4;
|
|
|
|
|
pDestEx += 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(HGBASE_IMGTYPE_RGBA == imgType);
|
|
|
|
|
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32 i = 0; i < (int32)height; i++)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* pEx = (uint8_t*)buffer + (uintptr_t)i * (uintptr_t)width * (uintptr_t)4;
|
|
|
|
|
uint8_t* pDestEx = dest + (HGSize)i * (HGSize)destStep;
|
|
|
|
|
memcpy(pDestEx, pEx, width * 4);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(buffer);
|
|
|
|
|
buffer = NULL;
|
|
|
|
|
*image = image2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-14 02:32:45 +00:00
|
|
|
|
HGResult HGAPI HGImgFmt_LoadTiffImage(const HGChar* fileName, UPTiffLoadInfo* info,
|
|
|
|
|
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
|
|
|
|
{
|
|
|
|
|
HGTiffReader reader = NULL;
|
|
|
|
|
HGResult ret = HGImgFmt_OpenTiffReader(fileName, &reader);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
{
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = HGImgFmt_LoadImageFromTiffReader(reader, 0, info, imgType, imgOrigin, image);
|
|
|
|
|
HGImgFmt_CloseTiffReader(reader);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 10:25:52 +00:00
|
|
|
|
HGResult HGAPI HGImgFmt_OpenTiffWriter(const HGChar* fileName, HGTiffWriter* writer)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == fileName || NULL == writer)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFF* tif = TIFFOpen(fileName, "w");
|
|
|
|
|
if (NULL == tif)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_ACCESSDENIED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*writer = (HGTiffWriter)tif;
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_CloseTiffWriter(HGTiffWriter writer)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == writer)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFF* tif = (TIFF*)writer;
|
|
|
|
|
TIFFClose(tif);
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_SaveImageToTiffWriter(HGTiffWriter writer, HGImage image, const UPTiffSaveInfo* info)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == writer || NULL == image)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != info)
|
|
|
|
|
{
|
|
|
|
|
// 判断合法性
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGImageInfo imgInfo;
|
|
|
|
|
HGBase_GetImageInfo(image, &imgInfo);
|
|
|
|
|
|
|
|
|
|
uint32_t width = imgInfo.width;
|
|
|
|
|
uint32_t height = imgInfo.height;
|
|
|
|
|
uint32_t widthStep = imgInfo.widthStep;
|
|
|
|
|
uint32_t type = imgInfo.type;
|
|
|
|
|
uint32_t origin = imgInfo.origin;
|
|
|
|
|
|
|
|
|
|
if (HGBASE_IMGTYPE_GRAY != type && HGBASE_IMGTYPE_RGB != type
|
|
|
|
|
&& HGBASE_IMGTYPE_RGBA != type)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t* data;
|
|
|
|
|
HGBase_GetImageData(image, &data);
|
|
|
|
|
|
|
|
|
|
uint8 samplesPerPixel = 0;
|
|
|
|
|
if (HGBASE_IMGTYPE_GRAY == type)
|
|
|
|
|
samplesPerPixel = 1;
|
|
|
|
|
else if (HGBASE_IMGTYPE_RGB == type)
|
|
|
|
|
samplesPerPixel = 3;
|
|
|
|
|
else if (HGBASE_IMGTYPE_RGBA == type)
|
|
|
|
|
samplesPerPixel = 4;
|
|
|
|
|
assert(0 != samplesPerPixel);
|
|
|
|
|
|
|
|
|
|
TIFF* tif = (TIFF*)writer;
|
|
|
|
|
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, samplesPerPixel);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, (1 == samplesPerPixel) ? PHOTOMETRIC_PALETTE : PHOTOMETRIC_RGB);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, height);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
|
|
|
|
|
|
|
|
|
|
uint16 rTable[256], gTable[256], bTable[256];
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32_t i = 0; i < 256; ++i)
|
|
|
|
|
{
|
|
|
|
|
rTable[i] = i;
|
|
|
|
|
gTable[i] = i;
|
|
|
|
|
bTable[i] = i;
|
|
|
|
|
}
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_COLORMAP, rTable, gTable, bTable);
|
|
|
|
|
|
|
|
|
|
if (NULL != info)
|
|
|
|
|
{
|
2022-05-13 03:56:46 +00:00
|
|
|
|
TIFFSetField(tif, TIFFTAG_COMPRESSION, info->compression);
|
2022-05-13 12:38:58 +00:00
|
|
|
|
TIFFSetField(tif, TIFFTAG_JPEGQUALITY, info->jpegQuality);
|
2022-05-03 10:25:52 +00:00
|
|
|
|
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, info->resolutionUnit);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_XRESOLUTION, info->xResolution);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_YRESOLUTION, info->yResolution);
|
|
|
|
|
}
|
2022-05-13 12:38:58 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
HGUInt xDpi, yDpi;
|
|
|
|
|
HGBase_GetImageDpi(image, &xDpi, &yDpi);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_JPEGQUALITY, 80);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_XRESOLUTION, xDpi);
|
|
|
|
|
TIFFSetField(tif, TIFFTAG_YRESOLUTION, yDpi);
|
|
|
|
|
}
|
2022-05-03 10:25:52 +00:00
|
|
|
|
|
|
|
|
|
HGByte* p = data;
|
|
|
|
|
HGSize step = (HGSize)widthStep;
|
|
|
|
|
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
|
|
|
|
{
|
|
|
|
|
p = data + (HGUSize)(height - 1) * (HGUSize)widthStep;
|
|
|
|
|
step = -(HGSize)widthStep;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//#pragma omp parallel for
|
|
|
|
|
for (int32_t i = 0; i < (int32_t)height; ++i)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* pEx = p + (HGSize)i * (HGSize)step;
|
|
|
|
|
TIFFWriteScanline(tif, pEx, i, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TIFFWriteDirectory(tif);
|
|
|
|
|
return HGBASE_ERR_OK;
|
2022-05-14 02:32:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGAPI HGImgFmt_SaveTiffImage(HGImage image, const UPTiffSaveInfo* info, const HGChar* fileName)
|
|
|
|
|
{
|
|
|
|
|
HGTiffWriter writer = NULL;
|
|
|
|
|
HGResult ret = HGImgFmt_OpenTiffWriter(fileName, &writer);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
{
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = HGImgFmt_SaveImageToTiffWriter(writer, image, info);
|
|
|
|
|
HGImgFmt_CloseTiffWriter(writer);
|
|
|
|
|
return ret;
|
2022-05-03 10:25:52 +00:00
|
|
|
|
}
|