view release on metacpan or search on metacpan
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
// initialize FIICCPROFILE link
FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(bitmap);
iccProfile->size = 0;
iccProfile->data = 0;
iccProfile->flags = 0;
// initialize metadata models list
fih->metadata = new(std::nothrow) METADATAMAP;
// initialize attached thumbnail
fih->thumbnail = NULL;
// store a pointer to user provided pixel buffer (if any)
fih->external_bits = ext_bits;
fih->external_pitch = ext_pitch;
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
FreeImage_CreateICCProfile(new_dib, src_iccProfile->data, src_iccProfile->size);
dst_iccProfile->flags = src_iccProfile->flags;
// copy metadata models
for(METADATAMAP::iterator i = (*src_metadata).begin(); i != (*src_metadata).end(); i++) {
int model = (*i).first;
TAGMAP *src_tagmap = (*i).second;
if(src_tagmap) {
// create a metadata model
TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
if(dst_tagmap) {
// fill the model
for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
std::string dst_key = (*j).first;
FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
// assign key and tag value
(*dst_tagmap)[dst_key] = dst_tag;
}
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
}
TAGMAP *src_tagmap = (*i).second;
if(src_tagmap) {
if( dst_metadata->find(model) != dst_metadata->end() ) {
// destroy dst model
FreeImage_SetMetadata((FREE_IMAGE_MDMODEL)model, dst, NULL, NULL);
}
// create a metadata model
TAGMAP *dst_tagmap = new(std::nothrow) TAGMAP();
if(dst_tagmap) {
// fill the model
for(TAGMAP::iterator j = src_tagmap->begin(); j != src_tagmap->end(); j++) {
std::string dst_key = (*j).first;
FITAG *dst_tag = FreeImage_CloneTag( (*j).second );
// assign key and tag value
(*dst_tagmap)[dst_key] = dst_tag;
}
src/Source/FreeImage/BitmapAccess.cpp view on Meta::CPAN
METADATAMAP *metadata = ((FREEIMAGEHEADER *)dib->data)->metadata;
METADATAMAP::iterator model_iterator = metadata->find(model);
if (model_iterator != metadata->end()) {
tagmap = model_iterator->second;
}
if(key != NULL) {
if(!tagmap) {
// this model, doesn't exist: create it
tagmap = new(std::nothrow) TAGMAP();
(*metadata)[model] = tagmap;
}
if(tag) {
// first check the tag
if(FreeImage_GetTagKey(tag) == NULL) {
FreeImage_SetTagKey(tag, key);
} else if(strcmp(key, FreeImage_GetTagKey(tag)) != 0) {
// set the tag key
FreeImage_SetTagKey(tag, key);
src/Source/FreeImage/J2KHelper.cpp view on Meta::CPAN
break;
}
}
bIsValid &= ((numcomps == 1) || (numcomps == 3) || (numcomps == 4));
if(!bIsValid) {
if(numcomps) {
FreeImage_OutputMessageProc(format_id, "Warning: image contains %d greyscale components. Only the first will be loaded.\n", numcomps);
numcomps = 1;
} else {
// unknown type
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
}
// create a new DIB
if(image->comps[0].prec <= 8) {
switch(numcomps) {
case 1:
dib = FreeImage_AllocateHeader(header_only, wrr, hrr, 8);
break;
src/Source/FreeImage/J2KHelper.cpp view on Meta::CPAN
dib = FreeImage_AllocateHeaderT(header_only, FIT_UINT16, wrr, hrr);
break;
case 3:
dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, wrr, hrr);
break;
case 4:
dib = FreeImage_AllocateHeaderT(header_only, FIT_RGBA16, wrr, hrr);
break;
}
} else {
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// "header only" FIBITMAP ?
if(header_only) {
return dib;
}
if(image->comps[0].prec <= 8) {
if(numcomps == 1) {
// 8-bit greyscale
src/Source/FreeImage/J2KHelper.cpp view on Meta::CPAN
cmptparm[i].dy = parameters->subsampling_dy;
cmptparm[i].w = w;
cmptparm[i].h = h;
cmptparm[i].prec = prec;
cmptparm[i].bpp = prec;
cmptparm[i].sgnd = 0;
}
// create the image
image = opj_image_create(numcomps, &cmptparm[0], color_space);
if(!image) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set image offset and reference grid
image->x0 = parameters->image_offset_x0;
image->y0 = parameters->image_offset_y0;
image->x1 = parameters->image_offset_x0 + (w - 1) * parameters->subsampling_dx + 1;
image->y1 = parameters->image_offset_y0 + (h - 1) * parameters->subsampling_dy + 1;
// set image data
if(prec == 8) {
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
// go to the start of the file
io->seek_proc(handle, inPos, SEEK_SET);
try {
// parse chunks
while(mEnd == FALSE) {
// chunk length
mPos = io->tell_proc(handle);
if(mPos + 4 > mLOF) {
throw(1);
}
io->read_proc(&mLength, 1, 4, handle);
mng_SwapLong(&mLength);
// chunk name
mPos = io->tell_proc(handle);
if(mPos + 4 > mLOF) {
throw(1);
}
io->read_proc(&mChunkName[0], 1, 4, handle);
mChunkName[4] = '\0';
// go to next chunk
mPos = io->tell_proc(handle);
// 4 = size of the CRC
if(mPos + (long)mLength + 4 > mLOF) {
throw(1);
}
io->seek_proc(handle, mLength + 4, SEEK_CUR);
switch( mng_GetChunckType(mChunkName) ) {
case IHDR:
if(mLength != 13) {
throw(1);
}
break;
case IEND:
mEnd = TRUE;
// the length below includes 4 bytes CRC, but no bytes for Length
*m_TotalBytesOfChunks = io->tell_proc(handle) - inPos;
break;
case UNKNOWN_CHUNCK:
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
io->read_proc(&mLength, 1, sizeof(mLength), handle);
mng_SwapLong(&mLength);
// read name
io->read_proc(&mChunkName[0], 1, 4, handle);
mChunkName[4] = '\0';
if(mLength > 0) {
mChunk = (BYTE*)realloc(mChunk, mLength);
if(!mChunk) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
throw (const char*)NULL;
}
Offset = io->tell_proc(handle);
if(Offset + (long)mLength > mLOF) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: unexpected end of file", mChunkName);
throw (const char*)NULL;
}
// read chunk
io->read_proc(mChunk, 1, mLength, handle);
}
// read crc
io->read_proc(&crc_file, 1, sizeof(crc_file), handle);
mng_SwapLong(&crc_file);
// check crc
DWORD crc_check = FreeImage_ZLibCRC32(0, &mChunkName[0], 4);
crc_check = FreeImage_ZLibCRC32(crc_check, mChunk, mLength);
if(crc_check != crc_file) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: bad CRC", mChunkName);
throw (const char*)NULL;
}
switch( mng_GetChunckType(mChunkName) ) {
case MHDR:
// The MHDR chunk is always first in all MNG datastreams except for those
// that consist of a single PNG or JNG datastream with a PNG or JNG signature.
if(mLength == 28) {
memcpy(&mng_frame_width, &mChunk[0], 4);
memcpy(&mng_frame_height, &mChunk[4], 4);
memcpy(&mng_ticks_per_second, &mChunk[8], 4);
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
case BACK:
break;
// Global "PLTE" and "tRNS" (if any). PNG "PLTE" will be of 0 byte, as it uses global data.
case PLTE: // Global
m_HasGlobalPalette = TRUE;
PLTE_file_size = mLength + 12; // (lentgh, name, array, crc) = (4, 4, mLength, 4)
PLTE_file_chunk = (BYTE*)realloc(PLTE_file_chunk, PLTE_file_size);
if(!PLTE_file_chunk) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
throw (const char*)NULL;
} else {
mOrigPos = io->tell_proc(handle);
// seek to the start of the chunk
io->seek_proc(handle, LastOffset, SEEK_SET);
// load the whole chunk
io->read_proc(PLTE_file_chunk, 1, PLTE_file_size, handle);
// go to the start of the next chunk
io->seek_proc(handle, mOrigPos, SEEK_SET);
}
break;
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
mOrigPos = io->tell_proc(handle);
// write PNG file signature
FreeImage_SeekMemory(hPngMemory, 0, SEEK_SET);
FreeImage_WriteMemory(g_png_signature, 1, 8, hPngMemory);
mChunk = (BYTE*)realloc(mChunk, m_TotalBytesOfChunks);
if(!mChunk) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
throw (const char*)NULL;
}
// on calling CountPNGChunks earlier, we were in Offset pos,
// go back there
io->seek_proc(handle, Offset, SEEK_SET);
io->read_proc(mChunk, 1, m_TotalBytesOfChunks, handle);
// Put back to original pos
io->seek_proc(handle, mOrigPos, SEEK_SET);
// write the PNG chunks
FreeImage_WriteMemory(mChunk, 1, m_TotalBytesOfChunks, hPngMemory);
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
jng_image_sample_depth = mChunk[9];
jng_image_compression_method = mChunk[10];
//BYTE jng_image_interlace_method = mChunk[11]; // for debug only
jng_alpha_sample_depth = mChunk[12];
jng_alpha_compression_method = mChunk[13];
jng_alpha_filter_method = mChunk[14];
jng_alpha_interlace_method = mChunk[15];
} else {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: invalid chunk length", mChunkName);
throw (const char*)NULL;
}
break;
case JDAT:
if(hJpegMemory == NULL) {
hJpegMemory = FreeImage_OpenMemory();
}
// as there may be several JDAT chunks, concatenate them
FreeImage_WriteMemory(mChunk, 1, mLength, hJpegMemory);
break;
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
buffer[12] = jng_alpha_sample_depth;
buffer[13] = jng_alpha_compression_method;
buffer[14] = jng_alpha_filter_method;
buffer[15] = jng_alpha_interlace_method;
mng_WriteChunk(mng_JHDR, &buffer[0], 16, hJngMemory);
// --- write a sequence of JDAT chunks ---
hJpegMemory = FreeImage_OpenMemory();
flags |= JPEG_BASELINE;
if(!FreeImage_SaveToMemory(FIF_JPEG, dib_rgb, hJpegMemory, flags)) {
throw (const char*)NULL;
}
if(dib_rgb != dib) {
FreeImage_Unload(dib_rgb);
dib_rgb = NULL;
}
{
BYTE *jpeg_data = NULL;
DWORD size_in_bytes = 0;
// get a pointer to the stream buffer
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
}
FreeImage_CloseMemory(hJpegMemory);
hJpegMemory = NULL;
// --- write alpha layer as a sequence of IDAT chunk ---
if((bpp == 32) && (jng_color_type == MNG_COLORTYPE_JPEGCOLORA)) {
dib_alpha = FreeImage_GetChannel(dib, FICC_ALPHA);
hPngMemory = FreeImage_OpenMemory();
if(!FreeImage_SaveToMemory(FIF_PNG, dib_alpha, hPngMemory, PNG_DEFAULT)) {
throw (const char*)NULL;
}
FreeImage_Unload(dib_alpha);
dib_alpha = NULL;
// get the IDAT chunk
{
BOOL bResult = FALSE;
DWORD start_pos = 0;
DWORD next_pos = 0;
long offset = 8;
src/Source/FreeImage/MultiPage.cpp view on Meta::CPAN
// set up the cache
if (!read_only) {
std::string cache_name;
ReplaceExtension(cache_name, filename, "ficache");
std::auto_ptr<CacheFile> cache_file (new CacheFile(cache_name, keep_cache_in_memory));
if (cache_file->open()) {
// we can use release() as std::bad_alloc won't be thrown from here on
header->m_cachefile = cache_file.release();
} else {
// an error occured ...
fclose(handle);
return NULL;
}
}
// return the multibitmap
// std::bad_alloc won't be thrown from here on
header.release(); // now owned by bitmap
io.release(); // now owned by bitmap
return bitmap.release(); // now owned by caller
}
}
} catch (std::bad_alloc &) {
/** @todo report error */
}
if (handle)
fclose(handle);
src/Source/FreeImage/MultiPage.cpp view on Meta::CPAN
if(!FreeImage_AcquireMemory(hmem, &compressed_data, &compressed_size)) {
FreeImage_CloseMemory(hmem);
return NULL;
}
// write the compressed data to the cache
int ref = header->m_cachefile->writeFile(compressed_data, compressed_size);
// get rid of the compressed data
FreeImage_CloseMemory(hmem);
return new(std::nothrow) BlockReference(ref, compressed_size);
}
void DLL_CALLCONV
FreeImage_AppendPage(FIMULTIBITMAP *bitmap, FIBITMAP *data) {
if (!bitmap || !data)
return;
MULTIBITMAPHEADER *header = FreeImage_GetMultiBitmapHeader(bitmap);
BlockReference *block = FreeImage_SavePageToBlock(header, data);
src/Source/FreeImage/MultiPage.cpp view on Meta::CPAN
BOOL read_only = FALSE; // modifications (if any) will be stored into the memory cache
// retrieve the plugin list to find the node belonging to this plugin
PluginList *list = FreeImage_GetPluginList();
if (list) {
PluginNode *node = list->FindNodeFromFIF(fif);
if (node) {
FreeImageIO *io = new(std::nothrow) FreeImageIO;
if (io) {
SetMemoryIO(io);
FIMULTIBITMAP *bitmap = new(std::nothrow) FIMULTIBITMAP;
if (bitmap) {
MULTIBITMAPHEADER *header = new(std::nothrow) MULTIBITMAPHEADER;
if (header) {
header->m_filename = NULL;
header->node = node;
header->fif = fif;
header->io = io;
header->handle = (fi_handle)stream;
header->changed = FALSE;
header->read_only = read_only;
header->m_cachefile = NULL;
src/Source/FreeImage/MultiPage.cpp view on Meta::CPAN
// cache the page count
header->page_count = FreeImage_InternalGetPageCount(bitmap);
// allocate a continueus block to describe the bitmap
header->m_blocks.push_back((BlockTypeS *)new BlockContinueus(0, header->page_count - 1));
if (!read_only) {
// set up the cache
CacheFile *cache_file = new(std::nothrow) CacheFile("", TRUE);
if (cache_file && cache_file->open()) {
header->m_cachefile = cache_file;
}
}
return bitmap;
}
delete bitmap;
src/Source/FreeImage/NNQuantizer.cpp view on Meta::CPAN
network = (pixel *)malloc(netsize * sizeof(pixel));
bias = (int *)malloc(netsize * sizeof(int));
freq = (int *)malloc(netsize * sizeof(int));
radpower = (int *)malloc(initrad * sizeof(int));
if( !network || !bias || !freq || !radpower ) {
if(network) free(network);
if(bias) free(bias);
if(freq) free(freq);
if(radpower) free(radpower);
throw FI_MSG_ERROR_MEMORY;
}
}
NNQuantizer::~NNQuantizer()
{
if(network) free(network);
if(bias) free(bias);
if(freq) free(freq);
if(radpower) free(radpower);
}
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
for (unsigned i = 0; i < 4; ++i) {
n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
nBytes += n * sizeof(ShortValue);
_Colour[i] = (short)psdGetValue(ShortValue, sizeof(_Colour[i]) );
}
n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
nBytes += n * sizeof(ShortValue);
_Opacity = (short)psdGetValue(ShortValue, sizeof(_Opacity) );
if((_Opacity < 0) || (_Opacity > 100)) {
throw "Invalid DisplayInfo::Opacity value";
}
BYTE c[1];
n = (int)io->read_proc(&c, sizeof(c), 1, handle);
nBytes += n * sizeof(c);
_Kind = (BYTE)psdGetValue(c, sizeof(c));
n = (int)io->read_proc(&c, sizeof(c), 1, handle);
nBytes += n * sizeof(c);
_padding = (BYTE)psdGetValue(c, sizeof(c));
if(_padding != 0) {
throw "Invalid DisplayInfo::Padding value";
}
return nBytes;
}
// --------------------------------------------------------------------------
psdThumbnail::psdThumbnail() :
_Format(-1), _Width(-1), _Height(-1), _WidthBytes(-1), _Size(-1), _CompressedSize(-1), _BitPerPixel(-1), _Planes(-1), _dib(NULL) {
}
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
clear();
}
void psdICCProfile::clear() { SAFE_DELETE_ARRAY(_ProfileData); _ProfileSize = 0;}
int psdICCProfile::Read(FreeImageIO *io, fi_handle handle, int size) {
int nBytes = 0, n;
clear();
_ProfileData = new (std::nothrow) BYTE[size];
if(NULL != _ProfileData) {
n = (int)io->read_proc(_ProfileData, 1, size, handle);
_ProfileSize = size;
nBytes += n * sizeof(BYTE);
}
return nBytes;
}
//---------------------------------------------------------------------------
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
break;
}
break;
case PSDP_RGB:
case PSDP_LAB:
case PSDP_CMYK :
case PSDP_MULTICHANNEL :
// force PSDP_MULTICHANNEL CMY as CMYK
dstCh = (mode == PSDP_MULTICHANNEL && !header_only) ? 4 : MIN<unsigned>(nChannels, 4);
if(dstCh < 3) {
throw "Invalid number of channels";
}
switch(depth) {
case 16:
bitmap = FreeImage_AllocateHeaderT(header_only, dstCh < 4 ? FIT_RGB16 : FIT_RGBA16, nWidth, nHeight, depth*dstCh);
break;
case 32:
bitmap = FreeImage_AllocateHeaderT(header_only, dstCh < 4 ? FIT_RGBF : FIT_RGBAF, nWidth, nHeight, depth*dstCh);
break;
default:
bitmap = FreeImage_AllocateHeader(header_only, nWidth, nHeight, depth*dstCh);
break;
}
break;
default:
throw "Unsupported color mode";
break;
}
if(!bitmap) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// write thumbnail
FreeImage_SetThumbnail(bitmap, _thumbnail.getDib());
// @todo Add some metadata model
if(header_only) {
return bitmap;
}
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
}
break;
case PSDP_COMPRESSION_RLE: // RLE compression
{
// The RLE-compressed data is preceeded by a 2-byte line size for each row in the data,
// store an array of these
// later use this array as WORD rleLineSizeList[nChannels][nHeight];
WORD *rleLineSizeList = new (std::nothrow) WORD[nChannels*nHeight];
if(!rleLineSizeList) {
FreeImage_Unload(bitmap);
SAFE_DELETE_ARRAY(line_start);
throw std::bad_alloc();
}
io->read_proc(rleLineSizeList, 2, nChannels * nHeight, handle);
WORD largestRLELine = 0;
for(unsigned ch = 0; ch < nChannels; ++ch) {
for(unsigned h = 0; h < nHeight; ++h) {
const unsigned index = ch * nHeight + h;
#ifndef FREEIMAGE_BIGENDIAN
SwapShort(&rleLineSizeList[index]);
#endif
if(largestRLELine < rleLineSizeList[index]) {
largestRLELine = rleLineSizeList[index];
}
}
}
BYTE* rle_line_start = new (std::nothrow) BYTE[largestRLELine];
if(!rle_line_start) {
FreeImage_Unload(bitmap);
SAFE_DELETE_ARRAY(line_start);
SAFE_DELETE_ARRAY(rleLineSizeList);
throw std::bad_alloc();
}
// Read the RLE data (assume 8-bit)
const BYTE* const line_end = line_start + lineSize;
for (unsigned ch = 0; ch < nChannels; ch++) {
const unsigned channelOffset = ch * bytes;
BYTE* dst_line_start = dst_first_line;
src/Source/FreeImage/PSDParser.cpp view on Meta::CPAN
}
FIBITMAP* psdParser::Load(FreeImageIO *io, fi_handle handle, int s_format_id, int flags) {
FIBITMAP *Bitmap = NULL;
_fi_flags = flags;
_fi_format_id = s_format_id;
try {
if (NULL == handle) {
throw("Cannot open file");
}
if (!_headerInfo.Read(io, handle)) {
throw("Error in header");
}
if (!_colourModeData.Read(io, handle)) {
throw("Error in ColourMode Data");
}
if (!ReadImageResources(io, handle)) {
throw("Error in Image Resource");
}
if (!ReadLayerAndMaskInfoSection(io, handle)) {
throw("Error in Mask Info");
}
Bitmap = ReadImageData(io, handle);
if (NULL == Bitmap) {
throw("Error in Image Data");
}
// set resolution info
if(NULL != Bitmap) {
unsigned res_x = 2835; // 72 dpi
unsigned res_y = 2835; // 72 dpi
if (_bResolutionInfoFilled) {
_resolutionInfo.GetResolutionInfo(res_x, res_y);
}
FreeImage_SetDotsPerMeterX(Bitmap, res_x);
src/Source/FreeImage/Plugin.cpp view on Meta::CPAN
// =====================================================================
PluginList::PluginList() :
m_plugin_map(),
m_node_count(0) {
}
FREE_IMAGE_FORMAT
PluginList::AddNode(FI_InitProc init_proc, void *instance, const char *format, const char *description, const char *extension, const char *regexpr) {
if (init_proc != NULL) {
PluginNode *node = new(std::nothrow) PluginNode;
Plugin *plugin = new(std::nothrow) Plugin;
if(!node || !plugin) {
if(node) delete node;
if(plugin) delete plugin;
FreeImage_OutputMessageProc(FIF_UNKNOWN, FI_MSG_ERROR_MEMORY);
return FIF_UNKNOWN;
}
memset(plugin, 0, sizeof(Plugin));
// fill-in the plugin structure
src/Source/FreeImage/Plugin.cpp view on Meta::CPAN
/*
Note: initialize all singletons here
in order to avoid race conditions with multi-threading
*/
// initialise the TagLib singleton
TagLib& s = TagLib::instance();
// internal plugin initialization
s_plugins = new(std::nothrow) PluginList;
if (s_plugins) {
/* NOTE :
The order used to initialize internal plugins below MUST BE the same order
as the one used to define the FREE_IMAGE_FORMAT enum.
*/
s_plugins->AddNode(InitBMP);
s_plugins->AddNode(InitICO);
s_plugins->AddNode(InitJPEG);
s_plugins->AddNode(InitJNG);
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
int status_byte = 0;
BYTE second_byte = 0;
int bits = 0;
BYTE *pixels = NULL; // temporary 8-bit buffer
try {
height = abs(height);
pixels = (BYTE*)malloc(width * height * sizeof(BYTE));
if(!pixels) throw(1);
memset(pixels, 0, width * height * sizeof(BYTE));
BYTE *q = pixels;
BYTE *end = pixels + height * width;
for (int scanline = 0; scanline < height; ) {
if (q < pixels || q >= end) {
break;
}
if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
if (status_byte != 0) {
status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q));
// Encoded mode
if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
for (int i = 0; i < status_byte; i++) {
*q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
}
bits += status_byte;
}
else {
// Escape mode
if(io->read_proc(&status_byte, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
switch (status_byte) {
case RLE_ENDOFLINE:
{
// End of line
bits = 0;
scanline++;
q = pixels + scanline*width;
}
break;
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
break;
case RLE_DELTA:
{
// read the delta values
BYTE delta_x = 0;
BYTE delta_y = 0;
if(io->read_proc(&delta_x, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
if(io->read_proc(&delta_y, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
// apply them
bits += delta_x;
scanline += delta_y;
q = pixels + scanline*width+bits;
}
break;
default:
{
// Absolute mode
status_byte = (int)MIN((size_t)status_byte, (size_t)(end - q));
for (int i = 0; i < status_byte; i++) {
if ((i & 0x01) == 0) {
if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
}
*q++=(BYTE)((i & 0x01) ? (second_byte & 0x0f) : ((second_byte >> 4) & 0x0f));
}
bits += status_byte;
// Read pad byte
if (((status_byte & 0x03) == 1) || ((status_byte & 0x03) == 2)) {
BYTE padding = 0;
if(io->read_proc(&padding, sizeof(BYTE), 1, handle) != 1) {
throw(1);
}
}
}
break;
}
}
}
{
// Convert to 4-bit
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
case 8 :
{
if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count))) {
used_colors = CalculateUsedPaletteEntries(bit_count);
}
// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
// seek to the end of the header (depending on the BMP header version)
// type == sizeof(BITMAPVxINFOHEADER)
switch(type) {
case 40: // sizeof(BITMAPINFOHEADER) - all Windows versions since Windows 3.0
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
// this is needed because sometimes the palette is larger than the entries it contains predicts
io->seek_proc(handle, bitmap_bits_offset, SEEK_SET);
// read the pixel data
switch (compression) {
case BI_RGB :
if( LoadPixelData(io, handle, dib, height, pitch, bit_count) ) {
return dib;
} else {
throw "Error encountered while decoding BMP data";
}
break;
case BI_RLE4 :
if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
return dib;
} else {
throw "Error encountered while decoding RLE4 BMP data";
}
break;
case BI_RLE8 :
if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
return dib;
} else {
throw "Error encountered while decoding RLE8 BMP data";
}
break;
default :
throw FI_MSG_ERROR_UNSUPPORTED_COMPRESSION;
}
}
break; // 1-, 4-, 8-bit
case 16 :
{
int use_bitfields = 0;
if (bih.biCompression == BI_BITFIELDS) use_bitfields = 3;
else if (bih.biCompression == BI_ALPHABITFIELDS) use_bitfields = 4;
else if (type == 52) use_bitfields = 3;
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
if (use_bitfields > 0) {
DWORD bitfields[4];
io->read_proc(bitfields, use_bitfields * sizeof(DWORD), 1, handle);
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
} else {
if( bit_count == 32 ) {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
}
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
case 8 :
{
if ((used_colors == 0) || (used_colors > CalculateUsedPaletteEntries(bit_count)))
used_colors = CalculateUsedPaletteEntries(bit_count);
// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
// load the palette
// note that it may contain RGB or RGBA values : we will calculate this
unsigned pal_size = (bitmap_bits_offset - sizeof(BITMAPFILEHEADER) - bih.biSize) / used_colors;
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
switch (compression) {
case BI_RGB :
// load pixel data
LoadPixelData(io, handle, dib, height, pitch, bit_count);
return dib;
case BI_RLE4 :
if( LoadPixelDataRLE4(io, handle, width, height, dib) ) {
return dib;
} else {
throw "Error encountered while decoding RLE4 BMP data";
}
break;
case BI_RLE8 :
if( LoadPixelDataRLE8(io, handle, width, height, dib) ) {
return dib;
} else {
throw "Error encountered while decoding RLE8 BMP data";
}
break;
default :
throw FI_MSG_ERROR_UNSUPPORTED_COMPRESSION;
}
}
case 16 :
{
if (bih.biCompression == 3) {
DWORD bitfields[3];
io->read_proc(bitfields, 3 * sizeof(DWORD), 1, handle);
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, bitfields[0], bitfields[1], bitfields[2]);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
case 24 :
case 32 :
{
if( bit_count == 32 ) {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information
FreeImage_SetDotsPerMeterX(dib, bih.biXPelsPerMeter);
FreeImage_SetDotsPerMeterY(dib, bih.biYPelsPerMeter);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
case 4 :
case 8 :
{
used_colors = CalculateUsedPaletteEntries(bit_count);
// allocate enough memory to hold the bitmap (header, palette, pixels) and read the palette
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information to default values (72 dpi in english units)
FreeImage_SetDotsPerMeterX(dib, 2835);
FreeImage_SetDotsPerMeterY(dib, 2835);
// load the palette
RGBQUAD *pal = FreeImage_GetPalette(dib);
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
LoadPixelData(io, handle, dib, height, pitch, bit_count);
return dib;
}
case 16 :
{
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information to default values (72 dpi in english units)
FreeImage_SetDotsPerMeterX(dib, 2835);
FreeImage_SetDotsPerMeterY(dib, 2835);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginBMP.cpp view on Meta::CPAN
case 24 :
case 32 :
{
if( bit_count == 32 ) {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bit_count, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// set resolution information to default values (72 dpi in english units)
FreeImage_SetDotsPerMeterX(dib, 2835);
FreeImage_SetDotsPerMeterY(dib, 2835);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginCUT.cpp view on Meta::CPAN
}
try {
CUTHEADER header;
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
// read the cut header
if(io->read_proc(&header, 1, sizeof(CUTHEADER), handle) != sizeof(CUTHEADER)) {
throw FI_MSG_ERROR_PARSING;
}
#ifdef FREEIMAGE_BIGENDIAN
SwapShort((WORD *)&header.width);
SwapShort((WORD *)&header.height);
#endif
if ((header.width == 0) || (header.height == 0)) {
return NULL;
}
// allocate a new bitmap
dib = FreeImage_AllocateHeader(header_only, header.width, header.height, 8);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// stuff it with a palette
RGBQUAD *palette = FreeImage_GetPalette(dib);
for (int j = 0; j < 256; ++j) {
palette[j].rgbBlue = palette[j].rgbGreen = palette[j].rgbRed = (BYTE)j;
}
src/Source/FreeImage/PluginCUT.cpp view on Meta::CPAN
BYTE *bits = FreeImage_GetScanLine(dib, header.height - 1);
unsigned i = 0, k = 0;
unsigned pitch = FreeImage_GetPitch(dib);
unsigned size = header.width * header.height;
BYTE count = 0, run = 0;
while (i < size) {
if(io->read_proc(&count, 1, sizeof(BYTE), handle) != 1) {
throw FI_MSG_ERROR_PARSING;
}
if (count == 0) {
k = 0;
bits -= pitch;
// paint shop pro adds two useless bytes here...
io->read_proc(&count, 1, sizeof(BYTE), handle);
io->read_proc(&count, 1, sizeof(BYTE), handle);
continue;
}
if (count & 0x80) {
count &= ~(0x80);
if(io->read_proc(&run, 1, sizeof(BYTE), handle) != 1) {
throw FI_MSG_ERROR_PARSING;
}
if(k + count <= header.width) {
memset(bits + k, run, count);
} else {
throw FI_MSG_ERROR_PARSING;
}
} else {
if(k + count <= header.width) {
if(io->read_proc(&bits[k], count, sizeof(BYTE), handle) != 1) {
throw FI_MSG_ERROR_PARSING;
}
} else {
throw FI_MSG_ERROR_PARSING;
}
}
k += count;
i += count;
}
return dib;
} catch(const char* text) {
src/Source/FreeImage/PluginDDS.cpp view on Meta::CPAN
FreeImage_Unload (old);
}
return dib;
}
template <class DECODER> static void
LoadDXT_Helper (FreeImageIO *io, fi_handle handle, int page, int flags, void *data, FIBITMAP *dib, int width, int height, int line) {
typedef typename DECODER::INFO INFO;
typedef typename INFO::Block Block;
Block *input_buffer = new(std::nothrow) Block[(width + 3) / 4];
if(!input_buffer) return;
int widthRest = (int) width & 3;
int heightRest = (int) height & 3;
int inputLine = (width + 3) / 4;
int y = 0;
if (height >= 4) {
for (; y < height; y += 4) {
io->read_proc (input_buffer, sizeof (typename INFO::Block), inputLine, handle);
src/Source/FreeImage/PluginEXR.cpp view on Meta::CPAN
FreeImageIO *_io;
fi_handle _handle;
public:
C_OStream (FreeImageIO *io, fi_handle handle) :
Imf::OStream(""), _io (io), _handle(handle) {
}
virtual void write(const char c[/*n*/], int n) {
if((unsigned)n != _io->write_proc((void*)&c[0], 1, n, _handle)) {
Iex::throwErrnoExc();
}
}
virtual Imath::Int64 tellp() {
return _io->tell_proc(_handle);
}
virtual void seekp(Imath::Int64 pos) {
_io->seek_proc(_handle, (unsigned)pos, SEEK_SET);
}
src/Source/FreeImage/PluginEXR.cpp view on Meta::CPAN
Imf::FrameBuffer frameBuffer;
BYTE *bits = NULL; // pointer to our pixel buffer
size_t bytespp = 0; // size of our pixel in bytes
size_t bytespc = 0; // size of our pixel component in bytes
unsigned pitch = 0; // size of our yStride in bytes
if(pixelType == Imf::HALF) {
// convert from float to half
halfData = new(std::nothrow) half[width * height * components];
if(!halfData) {
THROW (Iex::NullExc, FI_MSG_ERROR_MEMORY);
}
for(int y = 0; y < height; y++) {
float *src_bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
half *dst_bits = halfData + y * width * components;
for(int x = 0; x < width; x++) {
for(int c = 0; c < components; c++) {
dst_bits[c] = src_bits[c];
src/Source/FreeImage/PluginG3.cpp view on Meta::CPAN
uint16 badfaxrun;
uint32 badfaxlines;
int ok;
try {
uint32 linesize = TIFFhowmany8(xsize);
rowbuf = (BYTE*) _TIFFmalloc(linesize);
refbuf = (BYTE*) _TIFFmalloc(linesize);
if (rowbuf == NULL || refbuf == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
tifin->tif_rawdatasize = G3GetFileSize(io, handle);
tifin->tif_rawdata = (tidata_t) _TIFFmalloc(tifin->tif_rawdatasize);
if (tifin->tif_rawdata == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
if(!G3ReadFile(io, handle, tifin->tif_rawdata, tifin->tif_rawdatasize)) {
throw "Read error at scanline 0";
}
tifin->tif_rawcp = tifin->tif_rawdata;
tifin->tif_rawcc = tifin->tif_rawdatasize;
(*tifin->tif_setupdecode)(tifin);
(*tifin->tif_predecode)(tifin, (uint16) 0);
tifin->tif_row = 0;
badfaxlines = 0;
badfaxrun = 0;
src/Source/FreeImage/PluginG3.cpp view on Meta::CPAN
case 'v': // -v for info
verbose++;
break;
}
}
*/
// open a temporary memory buffer to save decoded scanlines
memory = FreeImage_OpenMemory();
if(!memory) throw FI_MSG_ERROR_MEMORY;
// wrap the raw fax file
faxTIFF = TIFFClientOpen("(FakeInput)", "w",
// TIFFClientOpen() fails if we don't set existing value here
NULL,
_g3ReadProc, _g3WriteProc,
_g3SeekProc, _g3CloseProc,
_g3SizeProc, _g3MapProc,
_g3UnmapProc);
if (faxTIFF == NULL) {
throw "Can not create fake input file";
}
TIFFSetMode(faxTIFF, O_RDONLY);
TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH, xsize);
TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1);
TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE, 1);
TIFFSetField(faxTIFF, TIFFTAG_FILLORDER, fillorder_in);
TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC, photometric_in);
TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION, resY);
TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
src/Source/FreeImage/PluginG3.cpp view on Meta::CPAN
resX = 204;
if (!stretch) {
TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY);
} else {
resY = 196;
}
// decode the raw fax data
rows = copyFaxFile(io, handle, faxTIFF, xsize, stretch, memory);
if(rows <= 0) throw "Error when decoding raw fax file : check the decoder options";
// allocate the output dib
dib = FreeImage_Allocate(xsize, rows, 1);
unsigned pitch = FreeImage_GetPitch(dib);
uint32 linesize = TIFFhowmany8(xsize);
// fill the bitmap structure ...
// ... palette
RGBQUAD *pal = FreeImage_GetPalette(dib);
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
return FALSE;
}
StringTable::StringTable()
{
m_buffer = NULL;
firstPixelPassed = 0; // Still no pixel read
// Maximum number of entries in the map is MAX_LZW_CODE * 256
// (aka 2**12 * 2**8 => a 20 bits key)
// This Map could be optmized to only handle MAX_LZW_CODE * 2**(m_bpp)
m_strmap = new(std::nothrow) int[1<<20];
}
StringTable::~StringTable()
{
if( m_buffer != NULL ) {
delete [] m_buffer;
}
if( m_strmap != NULL ) {
delete [] m_strmap;
m_strmap = NULL;
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
m_partialSize = 0;
m_bufferSize = 0;
ClearCompressorTable();
ClearDecompressorTable();
}
BYTE *StringTable::FillInputBuffer(int len)
{
if( m_buffer == NULL ) {
m_buffer = new(std::nothrow) BYTE[len];
m_bufferRealSize = len;
} else if( len > m_bufferRealSize ) {
delete [] m_buffer;
m_buffer = new(std::nothrow) BYTE[len];
m_bufferRealSize = len;
}
m_bufferSize = len;
m_bufferPos = 0;
m_bufferShift = 8 - m_bpp;
return m_buffer;
}
void StringTable::CompressStart(int bpp, int width)
{
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
static BOOL DLL_CALLCONV
SupportsExportType(FREE_IMAGE_TYPE type) {
return (type == FIT_BITMAP) ? TRUE : FALSE;
}
// ----------------------------------------------------------
static void *DLL_CALLCONV
Open(FreeImageIO *io, fi_handle handle, BOOL read) {
GIFinfo *info = new(std::nothrow) GIFinfo;
if( info == NULL ) {
return NULL;
}
// 25/02/2008 MDA: Not safe to memset GIFinfo structure with VS 2008 (safe iterators),
// perform initialization in constructor instead.
// memset(info, 0, sizeof(GIFinfo));
info->read = read;
if( read ) {
try {
//Header
if( !Validate(io, handle) ) {
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
io->seek_proc(handle, 6, SEEK_CUR);
//Logical Screen Descriptor
io->seek_proc(handle, 4, SEEK_CUR);
BYTE packed;
if( io->read_proc(&packed, 1, 1, handle) < 1 ) {
throw "EOF reading Logical Screen Descriptor";
}
if( io->read_proc(&info->background_color, 1, 1, handle) < 1 ) {
throw "EOF reading Logical Screen Descriptor";
}
io->seek_proc(handle, 1, SEEK_CUR);
//Global Color Table
if( packed & GIF_PACKED_LSD_HAVEGCT ) {
info->global_color_table_offset = io->tell_proc(handle);
info->global_color_table_size = 2 << (packed & GIF_PACKED_LSD_GCTSIZE);
io->seek_proc(handle, 3 * info->global_color_table_size, SEEK_CUR);
}
//Scan through all the rest of the blocks, saving offsets
size_t gce_offset = 0;
BYTE block = 0;
while( block != GIF_BLOCK_TRAILER ) {
if( io->read_proc(&block, 1, 1, handle) < 1 ) {
throw "EOF reading blocks";
}
if( block == GIF_BLOCK_IMAGE_DESCRIPTOR ) {
info->image_descriptor_offsets.push_back(io->tell_proc(handle));
//GCE may be 0, meaning no GCE preceded this ID
info->graphic_control_extension_offsets.push_back(gce_offset);
gce_offset = 0;
io->seek_proc(handle, 8, SEEK_CUR);
if( io->read_proc(&packed, 1, 1, handle) < 1 ) {
throw "EOF reading Image Descriptor";
}
//Local Color Table
if( packed & GIF_PACKED_ID_HAVELCT ) {
io->seek_proc(handle, 3 * (2 << (packed & GIF_PACKED_ID_LCTSIZE)), SEEK_CUR);
}
//LZW Minimum Code Size
io->seek_proc(handle, 1, SEEK_CUR);
} else if( block == GIF_BLOCK_EXTENSION ) {
BYTE ext;
if( io->read_proc(&ext, 1, 1, handle) < 1 ) {
throw "EOF reading extension";
}
if( ext == GIF_EXT_GRAPHIC_CONTROL ) {
//overwrite previous offset if more than one GCE found before an ID
gce_offset = io->tell_proc(handle);
} else if( ext == GIF_EXT_COMMENT ) {
info->comment_extension_offsets.push_back(io->tell_proc(handle));
} else if( ext == GIF_EXT_APPLICATION ) {
info->application_extension_offsets.push_back(io->tell_proc(handle));
}
} else if( block == GIF_BLOCK_TRAILER ) {
continue;
} else {
throw "Invalid GIF block found";
}
//Data Sub-blocks
BYTE len;
if( io->read_proc(&len, 1, 1, handle) < 1 ) {
throw "EOF reading sub-block";
}
while( len != 0 ) {
io->seek_proc(handle, len, SEEK_CUR);
if( io->read_proc(&len, 1, 1, handle) < 1 ) {
throw "EOF reading sub-block";
}
}
}
} catch (const char *msg) {
FreeImage_OutputMessageProc(s_format_id, msg);
delete info;
return NULL;
}
} else {
//Header
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
} else {
background.rgbRed = 0;
background.rgbGreen = 0;
background.rgbBlue = 0;
}
background.rgbReserved = 0;
//allocate entire logical area
dib = FreeImage_Allocate(logicalwidth, logicalheight, 32);
if( dib == NULL ) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
//fill with background color to start
int x, y;
RGBQUAD *scanline;
for( y = 0; y < logicalheight; y++ ) {
scanline = (RGBQUAD *)FreeImage_GetScanLine(dib, y);
for( x = 0; x < logicalwidth; x++ ) {
*scanline++ = background;
}
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
int size = 2 << (packed & GIF_PACKED_ID_LCTSIZE);
if( size <= 2 ) bpp = 1;
else if( size <= 16 ) bpp = 4;
} else if( info->global_color_table_offset != 0 ) {
if( info->global_color_table_size <= 2 ) bpp = 1;
else if( info->global_color_table_size <= 16 ) bpp = 4;
}
}
dib = FreeImage_Allocate(width, height, bpp);
if( dib == NULL ) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameLeft", ANIMTAG_FRAMELEFT, FIDT_SHORT, 1, 2, &left);
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "FrameTop", ANIMTAG_FRAMETOP, FIDT_SHORT, 1, 2, &top);
b = no_local_palette ? 1 : 0;
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "NoLocalPalette", ANIMTAG_NOLOCALPALETTE, FIDT_BYTE, 1, 1, &b);
b = interlaced ? 1 : 0;
FreeImage_SetMetadataEx(FIMD_ANIMATION, dib, "Interlaced", ANIMTAG_INTERLACED, FIDT_BYTE, 1, 1, &b);
//Palette
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
//its legal to have no palette, but we're going to generate *something*
for( int i = 0; i < 256; i++ ) {
pal[i].rgbRed = (BYTE)i;
pal[i].rgbGreen = (BYTE)i;
pal[i].rgbBlue = (BYTE)i;
}
}
//LZW Minimum Code Size
io->read_proc(&b, 1, 1, handle);
StringTable *stringtable = new(std::nothrow) StringTable;
stringtable->Initialize(b);
//Image Data Sub-blocks
int x = 0, xpos = 0, y = 0, shift = 8 - bpp, mask = (1 << bpp) - 1, interlacepass = 0;
BYTE *scanline = FreeImage_GetScanLine(dib, height - 1);
BYTE buf[4096];
io->read_proc(&b, 1, 1, handle);
while( b ) {
io->read_proc(stringtable->FillInputBuffer(b), b, 1, handle);
int size = sizeof(buf);
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
page = 0;
}
try {
BYTE packed, b;
WORD w;
FITAG *tag;
int bpp = FreeImage_GetBPP(dib);
if( bpp != 1 && bpp != 4 && bpp != 8 ) {
throw "Only 1, 4, or 8 bpp images supported";
}
bool have_transparent = false, no_local_palette = false, interlaced = false;
int disposal_method = GIF_DISPOSAL_BACKGROUND, delay_time = 100, transparent_color = 0;
WORD left = 0, top = 0, width = (WORD)FreeImage_GetWidth(dib), height = (WORD)FreeImage_GetHeight(dib);
WORD output_height = height;
if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "FrameLeft", FIDT_SHORT, &tag) ) {
left = *(WORD *)FreeImage_GetTagValue(tag);
}
if( FreeImage_GetMetadataEx(FIMD_ANIMATION, dib, "FrameTop", FIDT_SHORT, &tag) ) {
src/Source/FreeImage/PluginGIF.cpp view on Meta::CPAN
io->write_proc(&pal[i].rgbRed, 1, 1, handle);
io->write_proc(&pal[i].rgbGreen, 1, 1, handle);
io->write_proc(&pal[i].rgbBlue, 1, 1, handle);
}
}
//LZW Minimum Code Size
b = (BYTE)(bpp == 1 ? 2 : bpp);
io->write_proc(&b, 1, 1, handle);
StringTable *stringtable = new(std::nothrow) StringTable;
stringtable->Initialize(b);
stringtable->CompressStart(bpp, width);
//Image Data Sub-blocks
int y = 0, interlacepass = 0, line = FreeImage_GetLine(dib);
BYTE buf[255], *bufptr = buf; //255 is the max sub-block length
int size = sizeof(buf);
b = sizeof(buf);
while( y < output_height ) {
memcpy(stringtable->FillInputBuffer(line), FreeImage_GetScanLine(dib, output_height - y - 1), line);
src/Source/FreeImage/PluginHDR.cpp view on Meta::CPAN
unsigned width, height;
// Read the header
if(rgbe_ReadHeader(io, handle, &width, &height, &header_info) == FALSE) {
return NULL;
}
// allocate a RGBF image
dib = FreeImage_AllocateHeaderT(header_only, FIT_RGBF, width, height);
if(!dib) {
throw FI_MSG_ERROR_MEMORY;
}
// set the metadata as comments
rgbe_ReadMetadata(dib, &header_info);
if(header_only) {
// header only mode
return dib;
}
src/Source/FreeImage/PluginICO.cpp view on Meta::CPAN
// get the icon header
icon_header = (ICONHEADER*)data;
try {
FIBITMAP *icon_dib = NULL;
// load all icons
for(k = 0; k < icon_header->idCount; k++) {
icon_dib = Load(io, handle, k, flags, data);
if(!icon_dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
vPages.push_back(icon_dib);
}
// add the page
icon_dib = FreeImage_Clone(dib);
vPages.push_back(icon_dib);
icon_header->idCount++;
// write the header
src/Source/FreeImage/PluginICO.cpp view on Meta::CPAN
SwapIconHeader(icon_header);
#endif
// write all icons
// ...
// save the icon descriptions
ICONDIRENTRY *icon_list = (ICONDIRENTRY *)malloc(icon_header->idCount * sizeof(ICONDIRENTRY));
if(!icon_list) {
throw FI_MSG_ERROR_MEMORY;
}
memset(icon_list, 0, icon_header->idCount * sizeof(ICONDIRENTRY));
for(k = 0; k < icon_header->idCount; k++) {
icon_dib = (FIBITMAP*)vPages[k];
// convert internal format to ICONDIRENTRY
// take into account Vista icons whose size is 256x256
const BITMAPINFOHEADER *bmih = FreeImage_GetInfoHeader(icon_dib);
icon_list[k].bWidth = (bmih->biWidth > 255) ? 0 : (BYTE)bmih->biWidth;
src/Source/FreeImage/PluginJ2K.cpp view on Meta::CPAN
d_codec = opj_create_decompress(OPJ_CODEC_J2K);
// configure the event callbacks
// catch events using our callbacks (no local context needed here)
opj_set_info_handler(d_codec, NULL, NULL);
opj_set_warning_handler(d_codec, j2k_warning_callback, NULL);
opj_set_error_handler(d_codec, j2k_error_callback, NULL);
// setup the decoder decoding parameters using user parameters
if( !opj_setup_decoder(d_codec, ¶meters) ) {
throw "Failed to setup the decoder\n";
}
// read the main header of the codestream and if necessary the JP2 boxes
if( !opj_read_header(d_stream, d_codec, &image)) {
throw "Failed to read the header\n";
}
// --- header only mode
if (header_only) {
// create output image
dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
if(!dib) {
throw "Failed to import JPEG2000 image";
}
// clean-up and return header data
opj_destroy_codec(d_codec);
opj_image_destroy(image);
return dib;
}
// decode the stream and fill the image structure
if( !( opj_decode(d_codec, d_stream, image) && opj_end_decompress(d_codec, d_stream) ) ) {
throw "Failed to decode image!\n";
}
// free the codec context
opj_destroy_codec(d_codec);
d_codec = NULL;
// create output image
dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
if(!dib) {
throw "Failed to import JPEG2000 image";
}
// free image data structure
opj_image_destroy(image);
return dib;
} catch (const char *text) {
if(dib) {
FreeImage_Unload(dib);
src/Source/FreeImage/PluginJ2K.cpp view on Meta::CPAN
// encode the image
bSuccess = opj_start_compress(c_codec, image, c_stream);
if(bSuccess) {
bSuccess = bSuccess && opj_encode(c_codec, c_stream);
if(bSuccess) {
bSuccess = bSuccess && opj_end_compress(c_codec, c_stream);
}
}
if (!bSuccess) {
throw "Failed to encode image";
}
// free remaining compression structures
opj_destroy_codec(c_codec);
// free image data
opj_image_destroy(image);
return TRUE;
src/Source/FreeImage/PluginJP2.cpp view on Meta::CPAN
d_codec = opj_create_decompress(OPJ_CODEC_JP2);
// configure the event callbacks
// catch events using our callbacks (no local context needed here)
opj_set_info_handler(d_codec, NULL, NULL);
opj_set_warning_handler(d_codec, jp2_warning_callback, NULL);
opj_set_error_handler(d_codec, jp2_error_callback, NULL);
// setup the decoder decoding parameters using user parameters
if( !opj_setup_decoder(d_codec, ¶meters) ) {
throw "Failed to setup the decoder\n";
}
// read the main header of the codestream and if necessary the JP2 boxes
if( !opj_read_header(d_stream, d_codec, &image)) {
throw "Failed to read the header\n";
}
// --- header only mode
if (header_only) {
// create output image
dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
if(!dib) {
throw "Failed to import JPEG2000 image";
}
// clean-up and return header data
opj_destroy_codec(d_codec);
opj_image_destroy(image);
return dib;
}
// decode the stream and fill the image structure
if( !( opj_decode(d_codec, d_stream, image) && opj_end_decompress(d_codec, d_stream) ) ) {
throw "Failed to decode image!\n";
}
// free the codec context
opj_destroy_codec(d_codec);
d_codec = NULL;
// create output image
dib = J2KImageToFIBITMAP(s_format_id, image, header_only);
if(!dib) {
throw "Failed to import JPEG2000 image";
}
// free image data structure
opj_image_destroy(image);
return dib;
} catch (const char *text) {
if(dib) {
FreeImage_Unload(dib);
src/Source/FreeImage/PluginJP2.cpp view on Meta::CPAN
// encode the image
bSuccess = opj_start_compress(c_codec, image, c_stream);
if(bSuccess) {
bSuccess = bSuccess && opj_encode(c_codec, c_stream);
if(bSuccess) {
bSuccess = bSuccess && opj_end_compress(c_codec, c_stream);
}
}
if (!bSuccess) {
throw "Failed to encode image";
}
// free remaining compression structures
opj_destroy_codec(c_codec);
// free image data
opj_image_destroy(image);
return TRUE;
src/Source/FreeImage/PluginJPEG.cpp view on Meta::CPAN
// we set up the normal JPEG error routines, then override error_exit & output_message
cinfo.err = jpeg_std_error(&fi_error_mgr.pub);
fi_error_mgr.pub.error_exit = jpeg_error_exit;
fi_error_mgr.pub.output_message = jpeg_output_message;
// establish the setjmp return context for jpeg_error_exit to use
if (setjmp(fi_error_mgr.setjmp_buffer)) {
// If we get here, the JPEG code has signaled an error.
// We need to clean up the JPEG object, close the input file, and return.
jpeg_destroy_decompress(&cinfo);
throw (const char*)NULL;
}
jpeg_create_decompress(&cinfo);
// step 2a: specify data source (eg, a handle)
jpeg_freeimage_src(&cinfo, handle, io);
// step 2b: save special markers for later reading
src/Source/FreeImage/PluginJPEG.cpp view on Meta::CPAN
jpeg_start_decompress(&cinfo);
// step 5b: allocate dib and init header
if((cinfo.output_components == 4) && (cinfo.out_color_space == JCS_CMYK)) {
// CMYK image
if((flags & JPEG_CMYK) == JPEG_CMYK) {
// load as CMYK
dib = FreeImage_AllocateHeader(header_only, cinfo.output_width, cinfo.output_height, 32, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
} else {
// load as CMYK and convert to RGB
dib = FreeImage_AllocateHeader(header_only, cinfo.output_width, cinfo.output_height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
}
} else {
// RGB or greyscale image
dib = FreeImage_AllocateHeader(header_only, cinfo.output_width, cinfo.output_height, 8 * cinfo.output_components, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
if (cinfo.output_components == 1) {
// build a greyscale palette
RGBQUAD *colors = FreeImage_GetPalette(dib);
for (int i = 0; i < 256; i++) {
colors[i].rgbRed = (BYTE)i;
colors[i].rgbGreen = (BYTE)i;
colors[i].rgbBlue = (BYTE)i;
}
src/Source/FreeImage/PluginJPEG.cpp view on Meta::CPAN
if ((dib) && (handle)) {
try {
// Check dib format
const char *sError = "only 24-bit highcolor or 8-bit greyscale/palette bitmaps can be saved as JPEG";
FREE_IMAGE_COLOR_TYPE color_type = FreeImage_GetColorType(dib);
WORD bpp = (WORD)FreeImage_GetBPP(dib);
if ((bpp != 24) && (bpp != 8)) {
throw sError;
}
if(bpp == 8) {
// allow grey, reverse grey and palette
if ((color_type != FIC_MINISBLACK) && (color_type != FIC_MINISWHITE) && (color_type != FIC_PALETTE)) {
throw sError;
}
}
struct jpeg_compress_struct cinfo;
ErrorManager fi_error_mgr;
// Step 1: allocate and initialize JPEG compression object
// we set up the normal JPEG error routines, then override error_exit & output_message
cinfo.err = jpeg_std_error(&fi_error_mgr.pub);
fi_error_mgr.pub.error_exit = jpeg_error_exit;
fi_error_mgr.pub.output_message = jpeg_output_message;
// establish the setjmp return context for jpeg_error_exit to use
if (setjmp(fi_error_mgr.setjmp_buffer)) {
// If we get here, the JPEG code has signaled an error.
// We need to clean up the JPEG object, close the input file, and return.
jpeg_destroy_compress(&cinfo);
throw (const char*)NULL;
}
// Now we can initialize the JPEG compression object
jpeg_create_compress(&cinfo);
// Step 2: specify data destination (eg, a file)
jpeg_freeimage_dst(&cinfo, handle, io);
src/Source/FreeImage/PluginJPEG.cpp view on Meta::CPAN
write_markers(&cinfo, dib);
}
// Step 7: while (scan lines remain to be written)
if(color_type == FIC_RGB) {
// 24-bit RGB image : need to swap red and blue channels
unsigned pitch = FreeImage_GetPitch(dib);
BYTE *target = (BYTE*)malloc(pitch * sizeof(BYTE));
if (target == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
while (cinfo.next_scanline < cinfo.image_height) {
// get a copy of the scanline
memcpy(target, FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1), pitch);
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
// swap R and B channels
BYTE *target_p = target;
for(unsigned x = 0; x < cinfo.image_width; x++) {
INPLACESWAP(target_p[0], target_p[2]);
src/Source/FreeImage/PluginJPEG.cpp view on Meta::CPAN
JSAMPROW b = FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1);
jpeg_write_scanlines(&cinfo, &b, 1);
}
}
else if(color_type == FIC_PALETTE) {
// 8-bit palettized images are converted to 24-bit images
RGBQUAD *palette = FreeImage_GetPalette(dib);
BYTE *target = (BYTE*)malloc(cinfo.image_width * 3);
if (target == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
while (cinfo.next_scanline < cinfo.image_height) {
BYTE *source = FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1);
FreeImage_ConvertLine8To24(target, source, cinfo.image_width, palette);
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
// swap R and B channels
BYTE *target_p = target;
for(unsigned x = 0; x < cinfo.image_width; x++) {
src/Source/FreeImage/PluginJPEG.cpp view on Meta::CPAN
}
free(target);
}
else if(color_type == FIC_MINISWHITE) {
// reverse 8-bit greyscale image, so reverse grey value on the fly
unsigned i;
BYTE reverse[256];
BYTE *target = (BYTE *)malloc(cinfo.image_width);
if (target == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for(i = 0; i < 256; i++) {
reverse[i] = (BYTE)(255 - i);
}
while(cinfo.next_scanline < cinfo.image_height) {
BYTE *source = FreeImage_GetScanLine(dib, FreeImage_GetHeight(dib) - cinfo.next_scanline - 1);
for(i = 0; i < cinfo.image_width; i++) {
target[i] = reverse[ source[i] ];
src/Source/FreeImage/PluginJXR.cpp view on Meta::CPAN
}
}
// ==========================================================
// Helper functions & macro
// ==========================================================
#define JXR_CHECK(error_code) \
if(error_code < 0) { \
const char *error_message = JXR_ErrorMessage(error_code); \
throw error_message; \
}
// --------------------------------------------------------------------------
/**
Input conversions natively understood by FreeImage
@see GetNativePixelFormat
*/
typedef struct tagJXRInputConversion {
BITDEPTH_BITS bdBitDepth;
src/Source/FreeImage/PluginJXR.cpp view on Meta::CPAN
error_code = GetInputPixelFormat(pDecoder, &guid_format, &image_type, &bpp, &red_mask, &green_mask, &blue_mask);
JXR_CHECK(error_code);
// get image dimensions
pDecoder->GetSize(pDecoder, &width, &height);
// allocate dst image
{
dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height, bpp, red_mask, green_mask, blue_mask);
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
if(FreeImage_GetBPP(dib) == 1) {
// BD_1 - build a FIC_MINISBLACK palette
RGBQUAD *pal = FreeImage_GetPalette(dib);
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255;
}
}
// get image resolution
src/Source/FreeImage/PluginJXR.cpp view on Meta::CPAN
}
try {
// get image dimensions
unsigned width = FreeImage_GetWidth(dib);
unsigned height = FreeImage_GetHeight(dib);
// check JPEG-XR limits
if((width < MB_WIDTH_PIXEL) || (height < MB_HEIGHT_PIXEL)) {
FreeImage_OutputMessageProc(s_format_id, "Unsupported image size: width x height = %d x %d", width, height);
throw (const char*)NULL;
}
// get output pixel format
error_code = GetOutputPixelFormat(dib, &guid_format, &bHasAlpha);
JXR_CHECK(error_code);
pixelInfo.pGUIDPixFmt = &guid_format;
error_code = PixelFormatLookup(&pixelInfo, LOOKUP_FORWARD);
JXR_CHECK(error_code);
// create a JXR encoder interface and initialize function pointers with *_WMP functions
src/Source/FreeImage/PluginPCD.cpp view on Meta::CPAN
default :
seek = 0x30000;
width = 768;
height = 512;
break;
}
try {
// allocate the dib and write out the header
dib = FreeImage_AllocateHeader(header_only, width, height, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
if(!dib) throw FI_MSG_ERROR_DIB_MEMORY;
if(header_only) {
return dib;
}
// check if the PCD is bottom-up
if (VerticalOrientation(io, handle)) {
scan_line_add = -1;
start_scan_line = height - 1;
}
// temporary stuff to load PCD
BYTE *y1 = (BYTE*)malloc(width * sizeof(BYTE));
BYTE *y2 = (BYTE*)malloc(width * sizeof(BYTE));
BYTE *cbcr = (BYTE*)malloc(width * sizeof(BYTE));
if(!y1 || !y2 || !cbcr) throw FI_MSG_ERROR_MEMORY;
BYTE *yl[] = { y1, y2 };
// seek to the part where the bitmap data begins
io->seek_proc(handle, offset_in_file, SEEK_SET);
io->seek_proc(handle, seek, SEEK_CUR);
// read the data
src/Source/FreeImage/PluginPCX.cpp view on Meta::CPAN
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
try {
// check PCX identifier
long start_pos = io->tell_proc(handle);
BOOL validated = pcx_validate(io, handle);
io->seek_proc(handle, start_pos, SEEK_SET);
if(!validated) {
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
// process the header
PCXHEADER header;
if(io->read_proc(&header, sizeof(PCXHEADER), 1, handle) != 1) {
throw FI_MSG_ERROR_PARSING;
}
#ifdef FREEIMAGE_BIGENDIAN
SwapHeader(&header);
#endif
// allocate a new DIB
unsigned width = header.window[2] - header.window[0] + 1;
unsigned height = header.window[3] - header.window[1] + 1;
unsigned bitcount = header.bpp * header.planes;
if (bitcount == 24) {
dib = FreeImage_AllocateHeader(header_only, width, height, bitcount, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
} else {
dib = FreeImage_AllocateHeader(header_only, width, height, bitcount);
}
// if the dib couldn't be allocated, throw an error
if (!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// metrics handling code
FreeImage_SetDotsPerMeterX(dib, (unsigned) (((float)header.hdpi) / 0.0254000 + 0.5));
FreeImage_SetDotsPerMeterY(dib, (unsigned) (((float)header.vdpi) / 0.0254000 + 0.5));
// Set up the palette if needed
// ----------------------------
src/Source/FreeImage/PluginPCX.cpp view on Meta::CPAN
unsigned pitch = FreeImage_GetPitch(dib);
// run-length encoding ?
bIsRLE = (header.encoding == 1) ? TRUE : FALSE;
// load image data
// ---------------
line = (BYTE*)malloc(linelength * sizeof(BYTE));
if(!line) throw FI_MSG_ERROR_MEMORY;
ReadBuf = (BYTE*)malloc(IO_BUF_SIZE * sizeof(BYTE));
if(!ReadBuf) throw FI_MSG_ERROR_MEMORY;
bits = FreeImage_GetScanLine(dib, height - 1);
int ReadPos = IO_BUF_SIZE;
if ((header.planes == 1) && ((header.bpp == 1) || (header.bpp == 8))) {
BYTE skip;
unsigned written;
for (unsigned y = 0; y < height; y++) {
src/Source/FreeImage/PluginPCX.cpp view on Meta::CPAN
bits -= pitch;
}
} else if ((header.planes == 4) && (header.bpp == 1)) {
BYTE bit, mask, skip;
unsigned index;
BYTE *buffer;
unsigned x, y, written;
buffer = (BYTE*)malloc(width * sizeof(BYTE));
if(!buffer) throw FI_MSG_ERROR_MEMORY;
for (y = 0; y < height; y++) {
written = readline(*io, handle, line, linelength, bIsRLE, ReadBuf, &ReadPos);
// build a nibble using the 4 planes
memset(buffer, 0, width * sizeof(BYTE));
for(int plane = 0; plane < 4; plane++) {
bit = (BYTE)(1 << plane);
src/Source/FreeImage/PluginPCX.cpp view on Meta::CPAN
pline += header.bytes_per_line;
for (x = 0; x < width; x++) {
bits[x * 3 + FI_RGBA_BLUE] = pline[x];
}
pline += header.bytes_per_line;
bits -= pitch;
}
} else {
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
free(line);
free(ReadBuf);
return dib;
} catch (const char *text) {
// free allocated memory
src/Source/FreeImage/PluginPFM.cpp view on Meta::CPAN
Get an integer value from the actual position pointed by handle
*/
static int
pfm_get_int(FreeImageIO *io, fi_handle handle) {
char c = 0;
BOOL bFirstChar;
// skip forward to start of next number
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
while (1) {
// eat comments
if (c == '#') {
// if we're at a comment, read to end of line
bFirstChar = TRUE;
while (1) {
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
if (bFirstChar && c == ' ') {
// loop off 1 sp after #
bFirstChar = FALSE;
} else if (c == '\n') {
break;
}
}
}
if (c >= '0' && c <='9') {
// we've found what we were looking for
break;
}
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
}
// we're at the start of a number, continue until we hit a non-number
int i = 0;
while (1) {
i = (i * 10) + (c - '0');
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
if (c < '0' || c > '9') {
break;
}
}
return i;
}
src/Source/FreeImage/PluginPFM.cpp view on Meta::CPAN
if(id_one == 'P') {
if(id_two == 'F') {
image_type = FIT_RGBF;
} else if(id_two == 'f') {
image_type = FIT_FLOAT;
}
}
if(image_type == FIT_UNKNOWN) {
// signature error
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
// Read the header information: width, height and the scale value
unsigned width = (unsigned) pfm_get_int(io, handle);
unsigned height = (unsigned) pfm_get_int(io, handle);
float scalefactor = 1;
BOOL bResult = pfm_get_line(io, handle, line_buffer, PFM_MAXLINE);
if(bResult) {
bResult = (sscanf(line_buffer, "%f", &scalefactor) == 1) ? TRUE : FALSE;
}
if(!bResult) {
throw "Read error: invalid PFM header";
}
// Create a new DIB
dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
if(header_only) {
// header only mode
return dib;
}
// Read the image...
if(image_type == FIT_RGBF) {
const unsigned lineWidth = 3 * width;
lineBuffer = (float*)malloc(lineWidth * sizeof(float));
if(!lineBuffer) {
throw FI_MSG_ERROR_MEMORY;
}
for (unsigned y = 0; y < height; y++) {
FIRGBF *bits = (FIRGBF*)FreeImage_GetScanLine(dib, height - 1 - y);
if(io->read_proc(lineBuffer, sizeof(float), lineWidth, handle) != lineWidth) {
throw "Read error";
}
float *channel = lineBuffer;
if(scalefactor > 0) {
// MSB
for (unsigned x = 0; x < width; x++) {
REVERSEBYTES(channel++, &bits[x].red);
REVERSEBYTES(channel++, &bits[x].green);
REVERSEBYTES(channel++, &bits[x].blue);
}
} else {
src/Source/FreeImage/PluginPFM.cpp view on Meta::CPAN
}
}
free(lineBuffer);
lineBuffer = NULL;
} else if(image_type == FIT_FLOAT) {
const unsigned lineWidth = width;
lineBuffer = (float*)malloc(lineWidth * sizeof(float));
if(!lineBuffer) {
throw FI_MSG_ERROR_MEMORY;
}
for (unsigned y = 0; y < height; y++) {
float *bits = (float*)FreeImage_GetScanLine(dib, height - 1 - y);
if(io->read_proc(lineBuffer, sizeof(float), lineWidth, handle) != lineWidth) {
throw "Read error";
}
float *channel = lineBuffer;
if(scalefactor > 0) {
// MSB - File is Big endian
for (unsigned x = 0; x < width; x++) {
REVERSEBYTES(channel++, &bits[x]);
}
} else {
// LSB - File is Little Endian
for (unsigned x = 0; x < width; x++) {
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
for (i = 0; i < numColors; i++) {
val = Read16( io, handle );
if (ctFlags & 0x8000) {
// The indicies in a device colour table are bogus and
// usually == 0, so I assume we allocate up the list of
// colours in order.
val = (WORD)i;
}
if (val >= numColors) {
throw "pixel value greater than color table size.";
}
// Mac colour tables contain 16-bit values for R, G, and B...
pPal[val].rgbRed = ((BYTE) (((WORD) (Read16( io, handle )) >> 8) & 0xFF));
pPal[val].rgbGreen = ((BYTE) (((WORD) (Read16( io, handle )) >> 8) & 0xFF));
pPal[val].rgbBlue = ((BYTE) (((WORD) (Read16( io, handle )) >> 8) & 0xFF));
}
}
/**
skips unneeded packbits.
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
for ( int i=0; i<width; i++) {
WORD src = Read16( io, handle );
dst[ FI_RGBA_BLUE ] = (src & 31)*8; // Blue
dst[ FI_RGBA_GREEN ] = ((src >> 5) & 31)*8; // Green
dst[ FI_RGBA_RED ] = ((src >> 10) & 31)*8; // Red
dst[ FI_RGBA_ALPHA ] = 0xFF; // Alpha
dst += 4;
}
break;
default:
throw "Bad bits per pixel in expandBuf.";
}
}
/**
Expands Width units to 8-bit pixel data.
Max. 8 bpp source format.
*/
static void
expandBuf8( FreeImageIO *io, fi_handle handle, int width, int bpp, BYTE* dst )
{
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
}
if (width & 7) { // Check for leftover pixels
for (int i = 7; i > (8-width & 7); i--) {
WORD src = Read8( io, handle );
*dst = (src >> i) & 1;
dst++;
}
}
break;
default:
throw "Bad bits per pixel in expandBuf8.";
}
}
static BYTE*
UnpackPictRow( FreeImageIO *io, fi_handle handle, BYTE* pLineBuf, int width, int rowBytes, int srcBytes ) {
if (rowBytes < 8) { // Ah-ha! The bits aren't actually packed. This will be easy.
io->read_proc( pLineBuf, rowBytes, 1, handle );
}
else {
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
dst[ FI_RGBA_RED ] = (*(pBuf+width)); // Red
dst[ FI_RGBA_ALPHA ] = (*pBuf);
dst += 4;
pBuf++;
}
}
}
}
catch( ... ) {
free( pLineBuf );
throw;
}
}
free( pLineBuf );
}
/**
Decompression routine for 8 bpp.
rowBytes is the number of bytes each source row would take if it were uncompressed.
This _isn't_ equal to the number of pixels in the row - it seems apple pads the data to a word boundary and then compresses it.
Of course, we have to decompress the excess data and then throw it away.
*/
static void
Unpack8Bits( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, MacRect* bounds, WORD rowBytes ) {
int height = bounds->bottom - bounds->top;
int width = bounds->right - bounds->left;
// High bit of rowBytes is flag.
rowBytes &= 0x7fff;
if (rowBytes == 0) {
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
PixelPerRLEUnit = 2;
break;
case 8:
PixelPerRLEUnit = 1;
break;
case 16:
PixelPerRLEUnit = 1;
break;
default:
sprintf( outputMessage, "Illegal bpp value in unpackbits: %d\n", pixelSize );
throw outputMessage;
}
if (rowBytes < 8) {
// ah-ha! The bits aren't actually packed. This will be easy.
for ( int i = 0; i < height; i++ ) {
BYTE* dst = (BYTE*)FreeImage_GetScanLine( dib, height - 1 - i);
if (pixelSize == 16) {
expandBuf( io, handle, width, pixelSize, dst );
} else {
expandBuf8( io, handle, width, pixelSize, dst );
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
static void
DecodeBitmap( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, BOOL isRegion, MacRect* bounds, WORD rowBytes ) {
WORD mode = Read16( io, handle );
if ( isRegion ) {
SkipPolyOrRegion( io, handle );
}
RGBQUAD* pal = FreeImage_GetPalette( dib );
if ( !pal ) {
throw "No palette for bitmap!";
}
for (int i = 0; i < 2; i++) {
unsigned char val = i ? 0xFF : 0x0;
pal[i].rgbRed = val;
pal[i].rgbGreen = val;
pal[i].rgbBlue = val;
}
UnpackBits( io, handle, dib, bounds, rowBytes, 1 );
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
static void
DecodePixmap( FreeImageIO *io, fi_handle handle, FIBITMAP* dib, BOOL isRegion, MacpixMap* pixMap, WORD rowBytes ) {
// Read mac colour table into windows palette.
WORD numColors; // Palette size.
RGBQUAD ct[256];
ReadColorTable( io, handle, &numColors, ct );
if ( FreeImage_GetBPP( dib ) == 8 ) {
RGBQUAD* pal = FreeImage_GetPalette( dib );
if ( !pal ) {
throw "No palette for bitmap!";
}
for (int i = 0; i < numColors; i++) {
pal[i].rgbRed = ct[ i ].rgbRed;
pal[i].rgbGreen = ct[ i ].rgbGreen;
pal[i].rgbBlue = ct[ i ].rgbBlue;
}
}
// Ignore source & destination rectangle as well as transfer mode.
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
// Read PICT header
Read16( io, handle ); // Skip version 1 picture size
MacRect frame;
ReadRect( io, handle, &frame );
BYTE b = 0;
while ((b = Read8(io, handle)) == 0);
if ( b != 0x11 ) {
throw "invalid header: version number missing.";
}
int version = Read8( io, handle );
if ( version == 2 && Read8( io, handle ) != 0xff ) {
throw "invalid header: illegal version number.";
}
enum PICTType {none, op9a, jpeg, pixmap, bitmap};
PICTType pictType = none;
MacRect bounds;
MacpixMap pixMap;
int hRes = 0x480000; // in pixels/inch (72 by default == 0x480000 in fixed point)
int vRes = 0x480000; // in pixels/inch (72 by default == 0x480000 in fixed point)
WORD rowBytes = 0;
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
if ((version == 1) || ((io->tell_proc( handle ) % 2) != 0)) {
// align to word for version 2
opcode = Read8( io, handle );
}
if (version == 2) {
opcode = Read16( io, handle );
}
if (opcode == 0xFF || opcode == 0xFFFF) {
done = TRUE;
throw "PICT contained only vector data!";
}
else if (opcode < 0xa2) {
switch (opcode) {
case 0x01:
{
// skip clipping rectangle
MacRect clipRect;
WORD len = Read16( io, handle );
if (len == 0x000a) {
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
rowBytes = Read16( io, handle );
ReadRect( io, handle, &p.Bounds );
ReadPixmap( io, handle, &p);
RGBQUAD ct[256];
ReadColorTable(io, handle, &numColors, ct );
SkipBits( io, handle, &p.Bounds, rowBytes, p.pixelSize );
break;
}
default:
throw "Unknown pattern type.";
}
break;
}
case 0x70:
case 0x71:
case 0x72:
case 0x73:
case 0x74:
case 0x75:
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
Read8( io, handle );
i++;
}
}
}
if ( found ) {
// Pass the data to the JPEG decoder.
pictType = jpeg;
} else {
throw "PICT file contains unrecognized quicktime data.";
}
done = TRUE;
}
else if (opcode >= 0xa2 && opcode <= 0xaf) {
// reserved
WORD len = Read16( io, handle );
io->seek_proc(handle, len, SEEK_CUR);
}
else if ((opcode >= 0xb0 && opcode <= 0xcf) || (opcode >= 0x8000 && opcode <= 0x80ff)) {
// just a reserved opcode, no data
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
// reserved
LONG len = Read32( io, handle );
io->seek_proc(handle, len, SEEK_CUR);
}
else if (opcode >= 0x100 && opcode <= 0x7fff) {
// reserved
io->seek_proc(handle, ((opcode >> 7) & 255), SEEK_CUR);
}
else {
sprintf( outputMessage, "Can't handle opcode %x.\n", opcode );
throw outputMessage;
}
if(currentPos == io->tell_proc(handle)) {
// we probaly reached the end of file as we can no longer move forward ...
throw "Invalid PICT file";
}
}
switch ( pictType ) {
case op9a:
{
bounds = pixMap.Bounds;
int width = bounds.right - bounds.left;
int height = bounds.bottom - bounds.top;
src/Source/FreeImage/PluginPICT.cpp view on Meta::CPAN
case jpeg:
// Already decoded if the embedded format was valid.
break;
case pixmap:
DecodePixmap( io, handle, dib, isRegion, &pixMap, rowBytes );
break;
case bitmap:
DecodeBitmap( io, handle, dib, isRegion, &bounds, rowBytes );
break;
default:
throw "invalid pict type";
}
}
return dib;
}
catch(const char *message) {
FreeImage_Unload( dib );
FreeImage_OutputMessageProc(s_format_id, message);
}
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
// ==========================================================
// libpng interface
// ==========================================================
static void
_ReadProc(png_structp png_ptr, unsigned char *data, png_size_t size) {
pfi_ioStructure pfio = (pfi_ioStructure)png_get_io_ptr(png_ptr);
unsigned n = pfio->s_io->read_proc(data, (unsigned int)size, 1, pfio->s_handle);
if(size && (n == 0)) {
throw "Read error: invalid or corrupted PNG file";
}
}
static void
_WriteProc(png_structp png_ptr, unsigned char *data, png_size_t size) {
pfi_ioStructure pfio = (pfi_ioStructure)png_get_io_ptr(png_ptr);
pfio->s_io->write_proc(data, (unsigned int)size, 1, pfio->s_handle);
}
static void
_FlushProc(png_structp png_ptr) {
(png_structp)png_ptr;
// empty flush implementation
}
static void
error_handler(png_structp png_ptr, const char *error) {
(png_structp)png_ptr;
throw error;
}
// in FreeImage warnings disabled
static void
warning_handler(png_structp png_ptr, const char *warning) {
(png_structp)png_ptr;
(char*)warning;
}
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
// read the IHDR chunk
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
// configure the decoder
FREE_IMAGE_TYPE image_type = FIT_BITMAP;
if(!ConfigureDecoder(png_ptr, info_ptr, flags, &image_type)) {
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
// update image info
color_type = png_get_color_type(png_ptr, info_ptr);
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
pixel_depth = bit_depth * png_get_channels(png_ptr, info_ptr);
// create a dib and write the bitmap header
// set up the dib palette, if needed
src/Source/FreeImage/PluginPNG.cpp view on Meta::CPAN
for(int i = 0; i < palette_entries; i++) {
palette[i].rgbRed =
palette[i].rgbGreen =
palette[i].rgbBlue = (BYTE)((i * 255) / (palette_entries - 1));
}
}
break;
default:
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// store the transparency table
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
// array of alpha (transparency) entries for palette
png_bytep trans_alpha = NULL;
// number of transparent entries
int num_trans = 0;
// graylevel or color sample values of the single transparent color for non-paletted images
src/Source/FreeImage/PluginPNM.cpp view on Meta::CPAN
Get an integer value from the actual position pointed by handle
*/
static int
GetInt(FreeImageIO *io, fi_handle handle) {
char c = 0;
BOOL bFirstChar;
// skip forward to start of next number
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
while (1) {
// eat comments
if (c == '#') {
// if we're at a comment, read to end of line
bFirstChar = TRUE;
while (1) {
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
if (bFirstChar && c == ' ') {
// loop off 1 sp after #
bFirstChar = FALSE;
} else if (c == '\n') {
break;
}
}
}
if (c >= '0' && c <='9') {
// we've found what we were looking for
break;
}
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
}
// we're at the start of a number, continue until we hit a non-number
int i = 0;
while (1) {
i = (i * 10) + (c - '0');
if(!io->read_proc(&c, 1, 1, handle)) {
throw FI_MSG_ERROR_PARSING;
}
if (c < '0' || c > '9') {
break;
}
}
return i;
}
src/Source/FreeImage/PluginPNM.cpp view on Meta::CPAN
// Read the first two bytes of the file to determine the file format
// "P1" = ascii bitmap, "P2" = ascii greymap, "P3" = ascii pixmap,
// "P4" = raw bitmap, "P5" = raw greymap, "P6" = raw pixmap
io->read_proc(&id_one, 1, 1, handle);
io->read_proc(&id_two, 1, 1, handle);
if ((id_one != 'P') || (id_two < '1') || (id_two > '6')) {
// signature error
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
// Read the header information: width, height and the 'max' value if any
int width = GetInt(io, handle);
int height = GetInt(io, handle);
int maxval = 1;
if((id_two == '2') || (id_two == '5') || (id_two == '3') || (id_two == '6')) {
maxval = GetInt(io, handle);
if((maxval <= 0) || (maxval > 65535)) {
FreeImage_OutputMessageProc(s_format_id, "Invalid max value : %d", maxval);
throw (const char*)NULL;
}
}
// Create a new DIB
switch (id_two) {
case '1':
case '4':
// 1-bit
dib = FreeImage_AllocateHeader(header_only, width, height, 1);
src/Source/FreeImage/PluginPNM.cpp view on Meta::CPAN
image_type = FIT_RGB16;
dib = FreeImage_AllocateHeaderT(header_only, image_type, width, height);
} else {
// 24-bit RGB
dib = FreeImage_AllocateHeader(header_only, width, height, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
}
break;
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// Build a greyscale palette if needed
if(image_type == FIT_BITMAP) {
switch(id_two) {
case '1':
case '4':
pal = FreeImage_GetPalette(dib);
pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 0;
src/Source/FreeImage/PluginRAS.cpp view on Meta::CPAN
SwapLong(&header.depth);
SwapLong(&header.length);
SwapLong(&header.type);
SwapLong(&header.maptype);
SwapLong(&header.maplength);
#endif
// Verify SUN identifier
if (header.magic != RAS_MAGIC) {
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
// Allocate a new DIB
switch(header.depth) {
case 1:
case 8:
dib = FreeImage_AllocateHeader(header_only, header.width, header.height, header.depth);
break;
case 24:
dib = FreeImage_AllocateHeader(header_only, header.width, header.height, header.depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
break;
case 32:
dib = FreeImage_AllocateHeader(header_only, header.width, header.height, header.depth, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
break;
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// Check the file format
rle = FALSE;
isRGB = FALSE;
switch(header.type) {
case RT_OLD:
case RT_STANDARD:
src/Source/FreeImage/PluginRAS.cpp view on Meta::CPAN
case RT_BYTE_ENCODED:
rle = TRUE;
break;
case RT_FORMAT_RGB:
isRGB = TRUE;
break;
default:
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
// set up the colormap if needed
switch(header.maptype) {
case RMT_NONE :
{
if (header.depth < 24) {
// Create linear color ramp
src/Source/FreeImage/PluginRAS.cpp view on Meta::CPAN
{
BYTE *r, *g, *b;
// Read SUN raster colormap
int numcolors = 1 << header.depth;
if((DWORD)(3 * numcolors) > header.maplength) {
// some RAS may have less colors than the full palette
numcolors = header.maplength / 3;
} else {
throw "Invalid palette";
}
r = (BYTE*)malloc(3 * numcolors * sizeof(BYTE));
g = r + numcolors;
b = g + numcolors;
RGBQUAD *pal = FreeImage_GetPalette(dib);
io->read_proc(r, 3 * numcolors, 1, handle);
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
int width, height, colors, bpp;
try {
int bgr = 0; // pixel copy order: RGB if (bgr == 0) and BGR otherwise
// get image info
RawProcessor->get_mem_image_format(&width, &height, &colors, &bpp);
// only 3-color images supported...
if(colors != 3) {
throw "LibRaw : only 3-color images supported";
}
if(bpp == 16) {
// allocate output dib
dib = FreeImage_AllocateT(FIT_RGB16, width, height);
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
} else if(bpp == 8) {
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
bgr = 1; // only useful for FIT_BITMAP types
#endif
// allocate output dib
dib = FreeImage_AllocateT(FIT_BITMAP, width, height, 24);
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
}
// copy post-processed bitmap data into FIBITMAP buffer
if(RawProcessor->copy_mem_image(FreeImage_GetBits(dib), FreeImage_GetPitch(dib), bgr) != LIBRAW_SUCCESS) {
throw "LibRaw : failed to copy data into dib";
}
// flip vertically
FreeImage_FlipVertical(dib);
return dib;
} catch(const char *text) {
FreeImage_Unload(dib);
FreeImage_OutputMessageProc(s_format_id, text);
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
FIBITMAP *dib = NULL;
try {
unsigned width = image->width;
unsigned height = image->height;
unsigned bpp = image->bits;
if(bpp == 16) {
// allocate output dib
dib = FreeImage_AllocateT(FIT_RGB16, width, height);
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// write data
WORD *raw_data = (WORD*)image->data;
for(unsigned y = 0; y < height; y++) {
FIRGB16 *output = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
for(unsigned x = 0; x < width; x++) {
output[x].red = raw_data[0];
output[x].green = raw_data[1];
output[x].blue = raw_data[2];
raw_data += 3;
}
}
} else if(bpp == 8) {
// allocate output dib
dib = FreeImage_AllocateT(FIT_BITMAP, width, height, 24);
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// write data
BYTE *raw_data = (BYTE*)image->data;
for(unsigned y = 0; y < height; y++) {
RGBTRIPLE *output = (RGBTRIPLE*)FreeImage_GetScanLine(dib, height - 1 - y);
for(unsigned x = 0; x < width; x++) {
output[x].rgbtRed = raw_data[0];
output[x].rgbtGreen = raw_data[1];
output[x].rgbtBlue = raw_data[2];
raw_data += 3;
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
}
// load an image from the memory stream
dib = FreeImage_LoadFromMemory(fif, hmem, flags);
// close the stream
FreeImage_CloseMemory(hmem);
} else if((flags & FIF_LOAD_NOPIXELS) != FIF_LOAD_NOPIXELS) {
// convert processed data to output dib
dib = libraw_ConvertProcessedImageToDib(thumb_image);
}
} else {
throw "LibRaw : failed to run dcraw_make_mem_thumb";
}
// clean-up and return
RawProcessor->dcraw_clear_mem(thumb_image);
return dib;
} catch(const char *text) {
// clean-up and return
if(thumb_image) {
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
RawProcessor->imgdata.params.no_auto_bright = 1;
// (-a) Use automatic white balance obtained after averaging over the entire image
RawProcessor->imgdata.params.use_auto_wb = 1;
// (-q 3) Adaptive homogeneity-directed demosaicing algorithm (AHD)
RawProcessor->imgdata.params.user_qual = 3;
// -----------------------
// unpack data
if(RawProcessor->unpack() != LIBRAW_SUCCESS) {
throw "LibRaw : failed to unpack data";
}
// process data (... most consuming task ...)
if(RawProcessor->dcraw_process() != LIBRAW_SUCCESS) {
throw "LibRaw : failed to process data";
}
// retrieve processed image
dib = libraw_ConvertProcessedRawToDib(RawProcessor);
return dib;
} catch(const char *text) {
FreeImage_OutputMessageProc(s_format_id, text);
return NULL;
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
@param RawProcessor Libraw handle
@return Returns the loaded dib if successfull, returns NULL otherwise
*/
static FIBITMAP *
libraw_LoadUnprocessedData(LibRaw *RawProcessor) {
FIBITMAP *dib = NULL;
try {
// unpack data
if(RawProcessor->unpack() != LIBRAW_SUCCESS) {
throw "LibRaw : failed to unpack data";
}
// check for a supported Bayer format
if(!(RawProcessor->imgdata.idata.filters || RawProcessor->imgdata.idata.colors == 1)) {
throw "LibRaw : only Bayer-pattern RAW files are supported";
}
// allocate output dib
const unsigned width = RawProcessor->imgdata.sizes.raw_width;
const unsigned height = RawProcessor->imgdata.sizes.raw_height;
const size_t line_size = width * sizeof(WORD);
const WORD *src_bits = (WORD*)RawProcessor->imgdata.rawdata.raw_image;
if(src_bits) {
dib = FreeImage_AllocateT(FIT_UINT16, width, height);
}
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// retrieve the raw image
for(unsigned y = 0; y < height; y++) {
WORD *dst_bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);
memcpy(dst_bits, src_bits, line_size);
src_bits += width;
}
// store metadata needed for post-processing
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
if( HasMagicHeader(io, handle) ) {
return TRUE;
} else {
io->seek_proc(handle, tell, SEEK_SET);
}
}
// no magic signature : we need to open the file (it will take more time to identify it)
// do not declare RawProcessor on the stack as it may be huge (300 KB)
{
LibRaw *RawProcessor = new(std::nothrow) LibRaw;
if(RawProcessor) {
BOOL bSuccess = TRUE;
// wrap the input datastream
LibRaw_freeimage_datastream datastream(io, handle);
// open the datastream
if(RawProcessor->open_datastream(&datastream) != LIBRAW_SUCCESS) {
bSuccess = FALSE; // LibRaw : failed to open input stream (unknown format)
src/Source/FreeImage/PluginRAW.cpp view on Meta::CPAN
static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
FIBITMAP *dib = NULL;
LibRaw *RawProcessor = NULL;
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
try {
// do not declare RawProcessor on the stack as it may be huge (300 KB)
RawProcessor = new(std::nothrow) LibRaw;
if(!RawProcessor) {
throw FI_MSG_ERROR_MEMORY;
}
// wrap the input datastream
LibRaw_freeimage_datastream datastream(io, handle);
// set decoding parameters
// the following parameters affect data reading
// --------------------------------------------
// (-s [0..N-1]) Select one raw image from input file
RawProcessor->imgdata.params.shot_select = 0;
// (-w) Use camera white balance, if possible (otherwise, fallback to auto_wb)
RawProcessor->imgdata.params.use_camera_wb = 1;
// (-M) Use any color matrix from the camera metadata. This option only affects Olympus, Leaf, and Phase One cameras.
RawProcessor->imgdata.params.use_camera_matrix = 1;
// (-h) outputs the image in 50% size
RawProcessor->imgdata.params.half_size = ((flags & RAW_HALFSIZE) == RAW_HALFSIZE) ? 1 : 0;
// open the datastream
if(RawProcessor->open_datastream(&datastream) != LIBRAW_SUCCESS) {
throw "LibRaw : failed to open input stream (unknown format)";
}
if(header_only) {
// header only mode
dib = FreeImage_AllocateHeaderT(header_only, FIT_RGB16, RawProcessor->imgdata.sizes.width, RawProcessor->imgdata.sizes.height);
}
else if((flags & RAW_UNPROCESSED) == RAW_UNPROCESSED) {
// load raw data without post-processing (i.e. as a Bayer matrix)
dib = libraw_LoadUnprocessedData(RawProcessor);
}
src/Source/FreeImage/PluginSGI.cpp view on Meta::CPAN
int bitcount;
SGIHeader sgiHeader;
RLEStatus my_rle_status;
FIBITMAP *dib = NULL;
LONG *pRowIndex = NULL;
try {
// read the header
memset(&sgiHeader, 0, sizeof(SGIHeader));
if(io->read_proc(&sgiHeader, 1, sizeof(SGIHeader), handle) < sizeof(SGIHeader)) {
throw SGI_LESS_THAN_HEADER_LENGTH;
}
#ifndef FREEIMAGE_BIGENDIAN
SwapHeader(&sgiHeader);
#endif
if(sgiHeader.magic != 474) {
throw FI_MSG_ERROR_MAGIC_NUMBER;
}
BOOL bIsRLE = (sgiHeader.storage == 1) ? TRUE : FALSE;
// check for unsupported image types
if (sgiHeader.bpc != 1) {
// Expected one byte per color component
throw SGI_16_BIT_COMPONENTS_NOT_SUPPORTED;
}
if (sgiHeader.colormap != 0) {
// Indexed or dithered images not supported
throw SGI_COLORMAPS_NOT_SUPPORTED;
}
// get the width & height
dim = sgiHeader.dimension;
width = sgiHeader.xsize;
if (dim < 3) {
zsize = 1;
} else {
zsize = sgiHeader.zsize;
}
src/Source/FreeImage/PluginSGI.cpp view on Meta::CPAN
height = 1;
} else {
height = sgiHeader.ysize;
}
if(bIsRLE) {
// read the Offset Tables
int index_len = height * zsize;
pRowIndex = (LONG*)malloc(index_len * sizeof(LONG));
if(!pRowIndex) {
throw FI_MSG_ERROR_MEMORY;
}
if ((unsigned)index_len != io->read_proc(pRowIndex, sizeof(LONG), index_len, handle)) {
throw SGI_EOF_IN_RLE_INDEX;
}
#ifndef FREEIMAGE_BIGENDIAN
// Fix byte order in index
for (i = 0; i < index_len; i++) {
SwapLong((DWORD*)&pRowIndex[i]);
}
#endif
// Discard row size index
for (i = 0; i < (int)(index_len * sizeof(LONG)); i++) {
BYTE packed = 0;
if( io->read_proc(&packed, sizeof(BYTE), 1, handle) < 1 ) {
throw SGI_EOF_IN_RLE_INDEX;
}
}
}
switch(zsize) {
case 1:
bitcount = 8;
break;
case 2:
//Grayscale+Alpha. Need to fake RGBA
bitcount = 32;
break;
case 3:
bitcount = 24;
break;
case 4:
bitcount = 32;
break;
default:
throw SGI_INVALID_CHANNEL_COUNT;
}
dib = FreeImage_Allocate(width, height, bitcount);
if(!dib) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
if (bitcount == 8) {
// 8-bit SGI files are grayscale images, so we'll generate
// a grayscale palette.
RGBQUAD *pclrs = FreeImage_GetPalette(dib);
for (i = 0; i < 256; i++) {
pclrs[i].rgbRed = (BYTE)i;
pclrs[i].rgbGreen = (BYTE)i;
pclrs[i].rgbBlue = (BYTE)i;
src/Source/FreeImage/PluginSGI.cpp view on Meta::CPAN
int ch;
BYTE packed = 0;
if (bIsRLE) {
ch = get_rlechar(io, handle, &my_rle_status);
packed = (BYTE)ch;
}
else {
ch = io->read_proc(&packed, sizeof(BYTE), 1, handle);
}
if (ch == EOF) {
throw SGI_EOF_IN_IMAGE_DATA;
}
*p = packed;
}
}
}
if (zsize == 2)
{
BYTE *pRow = pStartRow;
//If faking RGBA from grayscale + alpha, copy first channel to second and third
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
Used for all 32 and 24 bit loading of uncompressed images
*/
static void
loadTrueColor(FIBITMAP* dib, int width, int height, int file_pixel_size, FreeImageIO* io, fi_handle handle, BOOL as24bit) {
const int pixel_size = as24bit ? 3 : file_pixel_size;
// input line cache
BYTE* file_line = (BYTE*)malloc( width * file_pixel_size);
if (!file_line) {
throw FI_MSG_ERROR_MEMORY;
}
for (int y = 0; y < height; y++) {
BYTE *bits = FreeImage_GetScanLine(dib, y);
io->read_proc(file_line, file_pixel_size, width, handle);
BYTE *bgra = file_line;
for (int x = 0; x < width; x++) {
bits[FI_RGBA_BLUE] = bgra[0];
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
int flipvert = (header.is_image_descriptor & 0x20) ? 1 : 0;
// skip comment
io->seek_proc(handle, header.id_length, SEEK_CUR);
switch (header.is_pixel_depth) {
case 8 : {
dib = FreeImage_AllocateHeader(header_only, header.is_width, header.is_height, 8);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// read the palette (even if header only)
RGBQUAD *palette = FreeImage_GetPalette(dib);
if (header.color_map_type > 0) {
unsigned count, csize;
// calculate the color map size
csize = header.cm_length * header.cm_size / 8;
// read the color map
BYTE *cmap = (BYTE*)malloc(csize * sizeof(BYTE));
if (cmap == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
io->read_proc(cmap, sizeof(BYTE), csize, handle);
// build the palette
switch (header.cm_size) {
case 16: {
WORD *rgb555 = (WORD*)&cmap[0];
unsigned start = (unsigned)header.cm_first_entry;
unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
if (TARGA_LOAD_RGB888 & flags) {
pixel_bits = 24;
dib = FreeImage_AllocateHeader(header_only, header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
} else {
dib = FreeImage_AllocateHeader(header_only, header.is_width, header.is_height, pixel_bits, FI16_555_RED_MASK, FI16_555_GREEN_MASK, FI16_555_BLUE_MASK);
}
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// handle thumbnail
FIBITMAP* th = thumbnail.toFIBITMAP();
if(th) {
if(TARGA_LOAD_RGB888 & flags) {
FIBITMAP* t = FreeImage_ConvertTo24Bits(th);
FreeImage_Unload(th);
th = t;
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
io->seek_proc(handle, sizeof(tagTGAHEADER) + header.id_length + garblen, SEEK_SET);
// read in the bitmap bits
switch (header.image_type) {
case TGA_RGB: { //(16 bit)
// input line cache
BYTE *in_line = (BYTE*)malloc(header.is_width * sizeof(WORD));
if (!in_line)
throw FI_MSG_ERROR_MEMORY;
const int h = header.is_height;
for (int y = 0; y < h; y++) {
BYTE *bits = FreeImage_GetScanLine(dib, y);
io->read_proc(in_line, src_pixel_size, header.is_width, handle);
BYTE *val = in_line;
for (int x = 0; x < line; x += pixel_size) {
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
return NULL;
}
}
break; // header.is_pixel_depth == 15 or 16
case 24 : {
dib = FreeImage_AllocateHeader(header_only, header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
FIBITMAP* th = thumbnail.toFIBITMAP();
if(th) {
FreeImage_SetThumbnail(dib, th);
FreeImage_Unload(th);
}
if(header_only) {
return dib;
src/Source/FreeImage/PluginTARGA.cpp view on Meta::CPAN
case 32 : {
int pixel_bits = 32;
if (TARGA_LOAD_RGB888 & flags) {
pixel_bits = 24;
}
dib = FreeImage_AllocateHeader(header_only, header.is_width, header.is_height, pixel_bits, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK);
if (dib == NULL) {
throw FI_MSG_ERROR_DIB_MEMORY;
}
// handle thumbnail
FIBITMAP* th = thumbnail.toFIBITMAP();
if(th) {
if(TARGA_LOAD_RGB888 & flags) {
FIBITMAP* t = FreeImage_ConvertTo24Bits(th);
FreeImage_Unload(th);
th = t;
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
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);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
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
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// 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;
}
}
// TIFFReadRGBAImage always deliveres 3 or 4 samples per pixel images
// (RGB or RGBA, see below). Cut-off possibly present channels (additional
// alpha channels) from e.g. Photoshop. Any CMYK(A..) is now treated as RGB,
// any additional alpha channel on RGB(AA..) is lost on conversion to RGB(A)
if(samplesperpixel > 4) { // TODO Write to Extra Channels
FreeImage_OutputMessageProc(s_format_id, "Warning: %d additional alpha channel(s) ignored", samplesperpixel-4);
samplesperpixel = 4;
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
if (photometric == PHOTOMETRIC_SEPARATED && samplesperpixel == 4) {
samplesperpixel = 3;
}
dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
if (dib == NULL) {
// free the raster pointer and output an error if allocation failed
if(raster) {
_TIFFfree(raster);
}
throw FI_MSG_ERROR_DIB_MEMORY;
}
// fill in the resolution (english or universal)
ReadResolution(tif, dib);
if(!header_only) {
// read the raster lines and save them in the DIB
// with RGB mode, we have to change the order of the 3 samples RGB
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
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);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// 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];
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
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);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), grey, nrow * src_line) == -1) {
free(buf);
throw FI_MSG_ERROR_PARSING;
}
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 1), alpha, nrow * src_line) == -1) {
free(buf);
throw FI_MSG_ERROR_PARSING;
}
for (int l = 0; l < nrow; l++) {
BYTE *p = bits;
BYTE *g = grey + l * src_line;
BYTE *a = alpha + l * src_line;
for(uint32 x = 0; x < (uint32)(src_line); x++) {
// copy the 8-bit layer
*p = g[0];
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
alpha_Bpp = FreeImage_GetBPP(alpha) / 8;
}
}
// create a new DIB
const uint16 chCount = MIN<uint16>(samplesperpixel, 4);
dib = CreateImageType(header_only, image_type, width, height, bitspersample, chCount);
if (dib == NULL) {
FreeImage_Unload(alpha);
throw FI_MSG_ERROR_MEMORY;
}
// fill in the resolution (english or universal)
ReadResolution(tif, dib);
if(!header_only) {
// calculate the line + pitch (separate for scr & dest)
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// In the tiff file the lines are save 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
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
if(buf == NULL) {
FreeImage_Unload(alpha);
throw FI_MSG_ERROR_MEMORY;
}
if(planar_config == PLANARCONFIG_CONTIG) {
// - loop for strip blocks -
for (uint32 y = 0; y < height; y += rowsperstrip) {
const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, strips * src_line) == -1) {
free(buf);
FreeImage_Unload(alpha);
throw FI_MSG_ERROR_PARSING;
}
// - loop for strips -
if(src_line != dst_line) {
// CMYKA+
if(alpha) {
for (int l = 0; l < strips; l++) {
for(BYTE *pixel = bits, *al_pixel = alpha_bits, *src_pixel = buf + l * src_line; pixel < bits + dib_pitch; pixel += dibBpp, al_pixel += alpha_Bpp, src_pixel += srcBpp) {
// copy pixel byte by byte
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
for (uint32 y = 0; y < height; y += rowsperstrip) {
const int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
// - loop for channels (planes) -
for(uint16 sample = 0; sample < samplesperpixel; sample++) {
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, sample), buf, strips * src_line) == -1) {
free(buf);
FreeImage_Unload(alpha);
throw FI_MSG_ERROR_PARSING;
}
BYTE *dst_strip = dib_strip;
unsigned dst_pitch = dib_pitch;
uint16 ch = sample;
unsigned Bpp = dibBpp;
if(sample >= chCount) {
// TODO Write to Extra Channel
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
} else if(loadMethod == LoadAsGenericStrip) {
// ---------------------------------------------------------------------------------
// Generic loading
// ---------------------------------------------------------------------------------
// create a new DIB
const uint16 chCount = MIN<uint16>(samplesperpixel, 4);
dib = CreateImageType(header_only, image_type, width, height, bitspersample, chCount);
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);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// In the tiff file the lines are save 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
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
if(buf == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
memset(buf, 0, TIFFStripSize(tif) * sizeof(BYTE));
BOOL bThrowMessage = FALSE;
if(planar_config == PLANARCONFIG_CONTIG) {
for (uint32 y = 0; y < height; y += rowsperstrip) {
int32 strips = (y + rowsperstrip > height ? height - y : rowsperstrip);
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, y, 0), buf, strips * src_line) == -1) {
// ignore errors as they can be frequent and not really valid errors, especially with fax images
bThrowMessage = TRUE;
/*
free(buf);
throw FI_MSG_ERROR_PARSING;
*/
}
if(src_line == dst_line) {
// channel count match
for (int l = 0; l < strips; l++) {
memcpy(bits, buf + l * src_line, src_line);
bits -= dst_pitch;
}
}
else {
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// ---------------------------------------------------------------------------------
// Tiled image loading
// ---------------------------------------------------------------------------------
uint32 tileWidth, tileHeight;
uint32 src_line = 0;
// create a new DIB
dib = CreateImageType( header_only, image_type, width, height, bitspersample, 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);
// get the tile geometry
if(!TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth) || !TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileHeight)) {
throw "Invalid tiled TIFF image";
}
// read the tiff lines and save them in the DIB
if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
// get the maximum number of bytes required to contain a tile
tmsize_t tileSize = TIFFTileSize(tif);
// allocate tile buffer
BYTE *tileBuffer = (BYTE*)malloc(tileSize * sizeof(BYTE));
if(tileBuffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
// calculate src line and dst pitch
int dst_pitch = FreeImage_GetPitch(dib);
uint32 tileRowSize = (uint32)TIFFTileRowSize(tif);
uint32 imageRowSize = (uint32)TIFFScanlineSize(tif);
// In the tiff file the lines are saved from up to down
// In a DIB the lines must be saved from down to up
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
for (uint32 y = 0; y < height; y += tileHeight) {
int32 nrows = (y + tileHeight > height ? height - y : tileHeight);
for (uint32 x = 0, rowSize = 0; x < width; x += tileWidth, rowSize += tileRowSize) {
memset(tileBuffer, 0, tileSize);
// read one tile
if (TIFFReadTile(tif, tileBuffer, x, y, 0, 0) < 0) {
free(tileBuffer);
throw "Corrupted tiled TIFF file";
}
// convert to strip
if(x + tileWidth > width) {
src_line = imageRowSize - rowSize;
} else {
src_line = tileRowSize;
}
BYTE *src_bits = tileBuffer;
BYTE *dst_bits = bits + rowSize;
for(int k = 0; k < nrows; k++) {
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
bits -= nrows * dst_pitch;
}
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
SwapRedBlue32(dib);
#endif
free(tileBuffer);
}
else if(planar_config == PLANARCONFIG_SEPARATE) {
throw "Separated tiled TIFF images are not supported";
}
} else if(loadMethod == LoadAsLogLuv) {
// ---------------------------------------------------------------------------------
// RGBF LogLuv compressed loading
// ---------------------------------------------------------------------------------
double stonits; // input conversion to nits
if (!TIFFGetField(tif, TIFFTAG_STONITS, &stonits)) {
stonits = 1;
}
// create a new DIB
dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
if (dib == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
// fill in the resolution (english or universal)
ReadResolution(tif, dib);
if(planar_config == PLANARCONFIG_CONTIG && !header_only) {
// calculate the line + pitch (separate for scr & dest)
tmsize_t src_line = TIFFScanlineSize(tif);
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// In the tiff file the lines are save 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
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;
}
// convert from XYZ to RGB
for (int l = 0; l < nrow; l++) {
tiff_ConvertLineXYZToRGB(bits, buf + l * src_line, stonits, width);
bits -= dst_pitch;
}
}
free(buf);
}
else if(planar_config == PLANARCONFIG_SEPARATE) {
// this cannot happen according to the LogLuv specification
throw "Unable to handle PLANARCONFIG_SEPARATE LogLuv images";
}
} else if(loadMethod == LoadAsHalfFloat) {
// ---------------------------------------------------------------------------------
// RGBF loading from a half format
// ---------------------------------------------------------------------------------
// create a new DIB
dib = CreateImageType(header_only, image_type, width, height, bitspersample, samplesperpixel);
if (dib == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
// fill in the resolution (english or universal)
ReadResolution(tif, dib);
if(!header_only) {
// calculate the line + pitch (separate for scr & dest)
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// 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) {
BYTE *buf = (BYTE*)malloc(TIFFStripSize(tif) * sizeof(BYTE));
if(buf == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (uint32 y = 0; y < height; y += rowsperstrip) {
uint32 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;
}
// convert from half (16-bit) to float (32-bit)
// !!! use OpenEXR half helper class
half half_value;
for (uint32 l = 0; l < nrow; l++) {
WORD *src_pixel = (WORD*)(buf + l * src_line);
float *dst_pixel = (float*)bits;
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
}
bits -= dst_pitch;
}
}
free(buf);
}
else if(planar_config == PLANARCONFIG_SEPARATE) {
// this use case was never encountered yet
throw "Unable to handle PLANARCONFIG_SEPARATE RGB half float images";
}
} // !header only
} else {
// ---------------------------------------------------------------------------------
// Unknown or unsupported format
// ---------------------------------------------------------------------------------
throw FI_MSG_ERROR_UNSUPPORTED_FORMAT;
}
// copy ICC profile data (must be done after FreeImage_Allocate)
FreeImage_CreateICCProfile(dib, iccBuf, iccSize);
if (photometric == PHOTOMETRIC_SEPARATED && asCMYK) {
FreeImage_GetICCProfile(dib)->flags |= FIICC_COLOR_IS_CMYK;
}
// copy TIFF metadata (must be done after FreeImage_Allocate)
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
// palettes (image colormaps are automatically scaled to 16-bits)
if (photometric == PHOTOMETRIC_PALETTE) {
uint16 *r, *g, *b;
uint16 nColors = (uint16)FreeImage_GetColorsUsed(dib);
RGBQUAD *pal = FreeImage_GetPalette(dib);
r = (uint16 *) _TIFFmalloc(sizeof(uint16) * 3 * nColors);
if(r == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
g = r + nColors;
b = g + nColors;
for (int i = nColors - 1; i >= 0; i--) {
r[i] = SCALE((uint16)pal[i].rgbRed);
g[i] = SCALE((uint16)pal[i].rgbGreen);
b[i] = SCALE((uint16)pal[i].rgbBlue);
}
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
case 8 :
{
if((bitsperpixel == 8) && FreeImage_IsTransparent(dib)) {
// 8-bit transparent picture : convert to 8-bit + 8-bit alpha
// get the transparency table
BYTE *trns = FreeImage_GetTransparencyTable(dib);
BYTE *buffer = (BYTE *)malloc(2 * width * sizeof(BYTE));
if(buffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (int y = height - 1; y >= 0; y--) {
BYTE *bits = FreeImage_GetScanLine(dib, y);
BYTE *p = bits, *b = buffer;
for(uint32 x = 0; x < width; x++) {
// copy the 8-bit layer
b[0] = *p;
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
TIFFWriteScanline(out, buffer, height - y - 1, 0);
}
free(buffer);
}
else {
// other cases
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
if(buffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (uint32 y = 0; y < height; y++) {
// get a copy of the scanline
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
// write the scanline to disc
TIFFWriteScanline(out, buffer, y, 0);
}
free(buffer);
}
break;
}
case 24:
case 32:
{
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
if(buffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (uint32 y = 0; y < height; y++) {
// get a copy of the scanline
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
if (photometric != PHOTOMETRIC_SEPARATED) {
// TIFFs store color data RGB(A) instead of BGR(A)
src/Source/FreeImage/PluginTIFF.cpp view on Meta::CPAN
break;
}
}//< switch (bitsperpixel)
} else if(image_type == FIT_RGBF && (flags & TIFF_LOGLUV) == TIFF_LOGLUV) {
// RGBF image => store as XYZ using a LogLuv encoding
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
if(buffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (uint32 y = 0; y < height; y++) {
// get a copy of the scanline and convert from RGB to XYZ
tiff_ConvertLineRGBToXYZ(buffer, FreeImage_GetScanLine(dib, height - y - 1), width);
// write the scanline to disc
TIFFWriteScanline(out, buffer, y, 0);
}
free(buffer);
} else {
// just dump the dib (tiff supports all dib types)
BYTE *buffer = (BYTE *)malloc(pitch * sizeof(BYTE));
if(buffer == NULL) {
throw FI_MSG_ERROR_MEMORY;
}
for (uint32 y = 0; y < height; y++) {
// get a copy of the scanline
memcpy(buffer, FreeImage_GetScanLine(dib, height - y - 1), pitch);
// write the scanline to disc
TIFFWriteScanline(out, buffer, y, 0);
}
free(buffer);
}