Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
FreeImage_CloseMemory(handle);
}
}
// release thumbnail
FreeImage_Unload(thumbnail);
}
// --------------------------------------------------------------------------
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
if (!handle || !data ) {
return NULL;
}
TIFF *tif = NULL;
uint32 height = 0;
uint32 width = 0;
uint16 bitspersample = 1;
uint16 samplesperpixel = 1;
uint32 rowsperstrip = (uint32)-1;
uint16 photometric = PHOTOMETRIC_MINISWHITE;
uint16 compression = (uint16)-1;
uint16 planar_config;
FIBITMAP *dib = NULL;
uint32 iccSize = 0; // ICC profile length
void *iccBuf = NULL; // ICC profile data
const BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
try {
fi_TIFFIO *fio = (fi_TIFFIO*)data;
tif = fio->tif;
if (page != -1) {
if (!tif || !TIFFSetDirectory(tif, (uint16)page)) {
throw "Error encountered while opening TIFF file";
}
}
const BOOL asCMYK = (flags & TIFF_CMYK) == TIFF_CMYK;
// first, get the photometric, the compression and basic metadata
// ---------------------------------------------------------------------------------
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
// check for HDR formats
// ---------------------------------------------------------------------------------
if(photometric == PHOTOMETRIC_LOGLUV) {
// check the compression
if(compression != COMPRESSION_SGILOG && compression != COMPRESSION_SGILOG24) {
throw "Only support SGILOG compressed LogLuv data";
}
// set decoder to output in IEEE 32-bit float XYZ values
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
}
// ---------------------------------------------------------------------------------
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
TIFFGetField(tif, TIFFTAG_ICCPROFILE, &iccSize, &iccBuf);
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
// check for unsupported formats
// ---------------------------------------------------------------------------------
if(IsValidBitsPerSample(photometric, bitspersample) == FALSE) {
FreeImage_OutputMessageProc(s_format_id,
"Unable to handle this format: bitspersample = %d, samplesperpixel = %d, photometric = %d",
(int)bitspersample, (int)samplesperpixel, (int)photometric);
throw (char*)NULL;
}
// ---------------------------------------------------------------------------------
// get image data type
FREE_IMAGE_TYPE image_type = ReadImageType(tif, bitspersample, samplesperpixel);
// get the most appropriate loading method
TIFFLoadMethod loadMethod = FindLoadMethod(tif, image_type, flags);
// ---------------------------------------------------------------------------------
if(loadMethod == LoadAsRBGA) {
// ---------------------------------------------------------------------------------
// RGB[A] loading using the TIFFReadRGBAImage() API
// ---------------------------------------------------------------------------------
BOOL has_alpha = FALSE;
// Read the whole image into one big RGBA buffer and then
// convert it to a DIB. This is using the traditional
// TIFFReadRGBAImage() API that we trust.
uint32 *raster = NULL;
if(!header_only) {
raster = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
if (raster == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
// read the image in one chunk into an RGBA array
if (!TIFFReadRGBAImage(tif, width, height, raster, 1)) {
_TIFFfree(raster);
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
samplesperpixel = ((bitsperpixel == 24) ? 3 : ((bitsperpixel == 32) ? 4 : 1));
bitspersample = bitsperpixel / samplesperpixel;
photometric = GetPhotometric(dib);
if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
// 8-bit transparent picture : convert later to 8-bit + 8-bit alpha
samplesperpixel = 2;
bitspersample = 8;
}
else if(bitsperpixel == 32) {
// 32-bit images : check for CMYK or alpha transparency
if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
// CMYK support
photometric = PHOTOMETRIC_SEPARATED;
TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
}
else if(photometric == PHOTOMETRIC_RGB) {
// transparency mask support
uint16 sampleinfo[1];
// unassociated alpha data is transparency information
sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
}
}
} else if(image_type == FIT_RGB16) {
// 48-bit RGB
samplesperpixel = 3;
bitspersample = bitsperpixel / samplesperpixel;
photometric = PHOTOMETRIC_RGB;
} else if(image_type == FIT_RGBA16) {
// 64-bit RGBA
samplesperpixel = 4;
bitspersample = bitsperpixel / samplesperpixel;
if((((iccProfile->flags & FIICC_COLOR_IS_CMYK) == FIICC_COLOR_IS_CMYK) || ((flags & TIFF_CMYK) == TIFF_CMYK))) {
// CMYK support
photometric = PHOTOMETRIC_SEPARATED;
TIFFSetField(out, TIFFTAG_INKSET, INKSET_CMYK);
TIFFSetField(out, TIFFTAG_NUMBEROFINKS, 4);
}
else {
photometric = PHOTOMETRIC_RGB;
// transparency mask support
uint16 sampleinfo[1];
// unassociated alpha data is transparency information
sampleinfo[0] = EXTRASAMPLE_UNASSALPHA;
TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, sampleinfo);
}
} else if(image_type == FIT_RGBF) {
// 96-bit RGBF => store with a LogLuv encoding ?
samplesperpixel = 3;
bitspersample = bitsperpixel / samplesperpixel;
// the library converts to and from floating-point XYZ CIE values
if((flags & TIFF_LOGLUV) == TIFF_LOGLUV) {
photometric = PHOTOMETRIC_LOGLUV;
TIFFSetField(out, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT);
// TIFFSetField(out, TIFFTAG_STONITS, 1.0); // assume unknown
}
else {
// store with default compression (LZW) or with input compression flag
photometric = PHOTOMETRIC_RGB;
}
} else if (image_type == FIT_RGBAF) {
// 128-bit RGBAF => store with default compression (LZW) or with input compression flag
samplesperpixel = 4;
bitspersample = bitsperpixel / samplesperpixel;
photometric = PHOTOMETRIC_RGB;
} else {
// special image type (int, long, double, ...)
samplesperpixel = 1;
bitspersample = bitsperpixel;
photometric = PHOTOMETRIC_MINISBLACK;
}
// set image data type
WriteImageType(out, image_type);
// write possible ICC profile
if (iccProfile->size && iccProfile->data) {
TIFFSetField(out, TIFFTAG_ICCPROFILE, iccProfile->size, iccProfile->data);
}
// handle standard width/height/bpp stuff
TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width);
TIFFSetField(out, TIFFTAG_IMAGELENGTH, height);
TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, bitspersample);
TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); // single image plane
TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
TIFFSetField(out, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB);
TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(out, (uint32) -1));
// handle metrics
WriteResolution(out, dib);
// multi-paging
if (page >= 0) {
char page_number[20];
sprintf(page_number, "Page %d", page);
TIFFSetField(out, TIFFTAG_SUBFILETYPE, (uint32)FILETYPE_PAGE);
TIFFSetField(out, TIFFTAG_PAGENUMBER, (uint16)page, (uint16)0);
TIFFSetField(out, TIFFTAG_PAGENAME, page_number);
} else {
// is it a thumbnail ?
TIFFSetField(out, TIFFTAG_SUBFILETYPE, (ifd == 0) ? (uint32)0 : (uint32)FILETYPE_REDUCEDIMAGE);
( run in 1.137 second using v1.01-cache-2.11-cpan-13bb782fe5a )