Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
if((photometric == PHOTOMETRIC_MINISWHITE) || (photometric == PHOTOMETRIC_MINISBLACK) || (photometric == PHOTOMETRIC_LOGLUV)) {
return TRUE;
} else {
return FALSE;
}
break;
case 64:
case 128:
if(photometric == PHOTOMETRIC_MINISBLACK) {
return TRUE;
} else {
return FALSE;
}
break;
default:
return FALSE;
}
}
static TIFFLoadMethod
FindLoadMethod(TIFF *tif, FREE_IMAGE_TYPE image_type, int flags) {
uint16 bitspersample = (uint16)-1;
uint16 samplesperpixel = (uint16)-1;
uint16 photometric = (uint16)-1;
uint16 planar_config = (uint16)-1;
TIFFLoadMethod loadMethod = LoadAsGenericStrip;
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planar_config);
BOOL bIsTiled = (TIFFIsTiled(tif) == 0) ? FALSE:TRUE;
switch(photometric) {
// convert to 24 or 32 bits RGB if the image is full color
case PHOTOMETRIC_RGB:
if((image_type == FIT_RGB16) || (image_type == FIT_RGBA16)) {
// load 48-bit RGB and 64-bit RGBA without conversion
loadMethod = LoadAsGenericStrip;
}
else if(image_type == FIT_RGBF) {
if((samplesperpixel == 3) && (bitspersample == 16)) {
// load 3 x 16-bit half as RGBF
loadMethod = LoadAsHalfFloat;
}
}
break;
case PHOTOMETRIC_YCBCR:
case PHOTOMETRIC_CIELAB:
case PHOTOMETRIC_ICCLAB:
case PHOTOMETRIC_ITULAB:
loadMethod = LoadAsRBGA;
break;
case PHOTOMETRIC_LOGLUV:
loadMethod = LoadAsLogLuv;
break;
case PHOTOMETRIC_SEPARATED:
// if image is PHOTOMETRIC_SEPARATED _and_ comes with an ICC profile,
// then the image should preserve its original (CMYK) colour model and
// should be read as CMYK (to keep the match of pixel and profile and
// to avoid multiple conversions. Conversion can be done by changing
// the profile from it's original CMYK to an RGB profile with an
// apropriate color management system. Works with non-tiled TIFFs.
if(!bIsTiled) {
loadMethod = LoadAsCMYK;
}
break;
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
case PHOTOMETRIC_PALETTE:
// When samplesperpixel = 2 and bitspersample = 8, set the image as a
// 8-bit indexed image + 8-bit alpha layer image
// and convert to a 8-bit image with a transparency table
if((samplesperpixel > 1) && (bitspersample == 8)) {
loadMethod = LoadAs8BitTrns;
} else {
loadMethod = LoadAsGenericStrip;
}
break;
default:
loadMethod = LoadAsGenericStrip;
break;
}
if((loadMethod == LoadAsGenericStrip) && bIsTiled) {
loadMethod = LoadAsTiled;
}
return loadMethod;
}
// ==========================================================
// TIFF thumbnail routines
// ==========================================================
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data);
/**
Read embedded thumbnail
*/
static void
ReadThumbnail(FreeImageIO *io, fi_handle handle, void *data, TIFF *tiff, FIBITMAP *dib) {
FIBITMAP* thumbnail = NULL;
// read exif thumbnail (IFD 1) ...
uint32 exif_offset = 0;
if(TIFFGetField(tiff, TIFFTAG_EXIFIFD, &exif_offset)) {
if(TIFFLastDirectory(tiff) != 0) {
// save current position
long tell_pos = io->tell_proc(handle);
uint16 cur_dir = TIFFCurrentDirectory(tiff);
// load the thumbnail
int page = 1;
int flags = TIFF_DEFAULT;
thumbnail = Load(io, handle, page, flags, data);
// store the thumbnail (remember to release it later ...)
FreeImage_SetThumbnail(dib, thumbnail);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// 32-bit RGBA
for (uint32 y = 0; y < height; y++) {
BYTE *bits = FreeImage_GetScanLine(dib, y);
for (uint32 x = 0; x < width; x++) {
bits[FI_RGBA_BLUE] = (BYTE)TIFFGetB(row[x]);
bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
bits[FI_RGBA_RED] = (BYTE)TIFFGetR(row[x]);
bits[FI_RGBA_ALPHA] = (BYTE)TIFFGetA(row[x]);
if (bits[FI_RGBA_ALPHA] != 0) {
has_alpha = TRUE;
}
bits += 4;
}
row += width;
}
} else {
// 24-bit RGB
for (uint32 y = 0; y < height; y++) {
BYTE *bits = FreeImage_GetScanLine(dib, y);
for (uint32 x = 0; x < width; x++) {
bits[FI_RGBA_BLUE] = (BYTE)TIFFGetB(row[x]);
bits[FI_RGBA_GREEN] = (BYTE)TIFFGetG(row[x]);
bits[FI_RGBA_RED] = (BYTE)TIFFGetR(row[x]);
bits += 3;
}
row += width;
}
}
_TIFFfree(raster);
}
// ### Not correct when header only
FreeImage_SetTransparent(dib, has_alpha);
} else if(loadMethod == LoadAs8BitTrns) {
// ---------------------------------------------------------------------------------
// 8-bit + 8-bit alpha layer loading
// ---------------------------------------------------------------------------------
// create a new 8-bit DIB
dib = CreateImageType(header_only, image_type, width, height, bitspersample, MIN<uint16>(2, samplesperpixel));
if (dib == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
// fill in the resolution (english or universal)
ReadResolution(tif, dib);
// set up the colormap based on photometric
ReadPalette(tif, photometric, bitspersample, dib);
// calculate the line + pitch (separate for scr & dest)
const tmsize_t src_line = TIFFScanlineSize(tif);
// here, the pitch is 2x less than the original as we only keep the first layer
int dst_pitch = FreeImage_GetPitch(dib);
// transparency table for 8-bit + 8-bit alpha images
BYTE trns[256];
// clear the transparency table
memset(trns, 0xFF, 256 * sizeof(BYTE));
// In the tiff file the lines are saved from up to down
// In a DIB the lines must be saved from down to up
BYTE *bits = FreeImage_GetScanLine(dib, height - 1);
// read the tiff lines and save them in the DIB
if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
if(buf == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (uint32 y = 0; y < height; y += rowsperstrip) {
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, nrow * src_line) == -1) {
free(buf);
throw FI_MSG_ERROR_PARSING;
}
for (int l = 0; l < nrow; l++) {
BYTE *p = bits;
BYTE *b = buf + l * src_line;
for(uint32 x = 0; x < (uint32)(src_line / samplesperpixel); x++) {
// copy the 8-bit layer
*p = b[0];
// convert the 8-bit alpha layer to a trns table
trns[ b[0] ] = b[1];
p++;
b += samplesperpixel;
}
bits -= dst_pitch;
}
}
free(buf);
}
else if(planar_config == PLANARCONFIG_SEPARATE && !header_only) {
tmsize_t stripsize = TIFFStripSize(tif) * sizeof(BYTE);
BYTE *buf = (BYTE*)malloc(2 * stripsize);
if(buf == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
BYTE *grey = buf;
BYTE *alpha = buf + stripsize;
for (uint32 y = 0; y < height; y += rowsperstrip) {
int32 nrow = (y + rowsperstrip > height ? height - y : rowsperstrip);
( run in 0.854 second using v1.01-cache-2.11-cpan-5623c5533a1 )