Alien-FreeImage

 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, &parameters) ) {
				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, &parameters) ) {
				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);
		}



( run in 0.748 second using v1.01-cache-2.11-cpan-496ff517765 )