Alien-FreeImage

 view release on metacpan or  search on metacpan

patches/FreeImage-3.17.0-ALL-IN-ONE.patch  view on Meta::CPAN

+  "ulw        %[temp1],  " #B "(%[out])                \n\t"                   \
+  "ulw        %[temp2],  " #C "(%[out])                \n\t"                   \
+  "ulw        %[temp3],  " #D "(%[out])                \n\t"                   \
   "absq_s.ph  %[temp0],  %[temp0]                      \n\t"                   \
   "absq_s.ph  %[temp1],  %[temp1]                      \n\t"                   \
   "absq_s.ph  %[temp2],  %[temp2]                      \n\t"                   \
diff -ru src.3170/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c src/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c
--- src.3170/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c	2015-02-20 02:34:34.000000000 +0100
+++ src/Source/LibWebP/src/dsp/dsp.filters_mips_dsp_r2.c	2017-06-22 22:17:19.462540500 +0200
@@ -48,7 +48,7 @@
       "srl       %[temp0],    %[length],    0x2         \n\t"                  \
       "beqz      %[temp0],    4f                        \n\t"                  \
       " andi     %[temp6],    %[length],    0x3         \n\t"                  \
-    ".if "#INVERSE"                                     \n\t"                  \
+    ".if " #INVERSE "                                   \n\t"                  \
       "lbu       %[temp1],    -1(%[src])                \n\t"                  \
     "1:                                                 \n\t"                  \
       "lbu       %[temp2],    0(%[src])                 \n\t"                  \
@@ -84,7 +84,7 @@
       "lbu       %[temp1],    -1(%[src])                \n\t"                  \
       "lbu       %[temp2],    0(%[src])                 \n\t"                  \
       "addiu     %[src],      %[src],       1           \n\t"                  \
-    ".if "#INVERSE"                                     \n\t"                  \

src/Source/FreeImage.h  view on Meta::CPAN

DLL_API FREE_IMAGE_MDTYPE DLL_CALLCONV FreeImage_GetTagType(FITAG *tag);
DLL_API DWORD DLL_CALLCONV FreeImage_GetTagCount(FITAG *tag);
DLL_API DWORD DLL_CALLCONV FreeImage_GetTagLength(FITAG *tag);
DLL_API const void *DLL_CALLCONV FreeImage_GetTagValue(FITAG *tag);

DLL_API BOOL DLL_CALLCONV FreeImage_SetTagKey(FITAG *tag, const char *key);
DLL_API BOOL DLL_CALLCONV FreeImage_SetTagDescription(FITAG *tag, const char *description);
DLL_API BOOL DLL_CALLCONV FreeImage_SetTagID(FITAG *tag, WORD id);
DLL_API BOOL DLL_CALLCONV FreeImage_SetTagType(FITAG *tag, FREE_IMAGE_MDTYPE type);
DLL_API BOOL DLL_CALLCONV FreeImage_SetTagCount(FITAG *tag, DWORD count);
DLL_API BOOL DLL_CALLCONV FreeImage_SetTagLength(FITAG *tag, DWORD length);
DLL_API BOOL DLL_CALLCONV FreeImage_SetTagValue(FITAG *tag, const void *value);

// iterator
DLL_API FIMETADATA *DLL_CALLCONV FreeImage_FindFirstMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, FITAG **tag);
DLL_API BOOL DLL_CALLCONV FreeImage_FindNextMetadata(FIMETADATA *mdhandle, FITAG **tag);
DLL_API void DLL_CALLCONV FreeImage_FindCloseMetadata(FIMETADATA *mdhandle);

// metadata setter and getter
DLL_API BOOL DLL_CALLCONV FreeImage_SetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG *tag);
DLL_API BOOL DLL_CALLCONV FreeImage_GetMetadata(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, FITAG **tag);

src/Source/FreeImage/BitmapAccess.cpp  view on Meta::CPAN

BOOL DLL_CALLCONV 
FreeImage_SetMetadataKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value) {
	if(!dib || !key || !value) {
		return FALSE;
	}
	// create a tag
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		BOOL bSuccess = TRUE;
		// fill the tag
		DWORD tag_length = (DWORD)(strlen(value) + 1);
		bSuccess &= FreeImage_SetTagKey(tag, key);
		bSuccess &= FreeImage_SetTagLength(tag, tag_length);
		bSuccess &= FreeImage_SetTagCount(tag, tag_length);
		bSuccess &= FreeImage_SetTagType(tag, FIDT_ASCII);
		bSuccess &= FreeImage_SetTagValue(tag, value);
		if(bSuccess) {
			// set the tag
			bSuccess &= FreeImage_SetMetadata(model, dib, FreeImage_GetTagKey(tag), tag);
		}
		// delete the tag
		FreeImage_DeleteTag(tag);

		return bSuccess;

src/Source/FreeImage/FreeImage.cpp  view on Meta::CPAN


	if ((fmt != NULL) && ((freeimage_outputmessage_proc != NULL) || (freeimage_outputmessagestdcall_proc != NULL))) {
		char message[MSG_SIZE];
		memset(message, 0, MSG_SIZE);

		// initialize the optional parameter list

		va_list arg;
		va_start(arg, fmt);

		// check the length of the format string

		int str_length = (int)( (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt) );

		// parse the format string and put the result in 'message'

		for (int i = 0, j = 0; i < str_length; ++i) {
			if (fmt[i] == '%') {
				if (i + 1 < str_length) {
					switch(tolower(fmt[i + 1])) {
						case '%' :
							message[j++] = '%';
							break;

						case 'o' : // octal numbers
						{
							char tmp[16];

							_itoa(va_arg(arg, int), tmp, 8);

src/Source/FreeImage/FreeImageIO.cpp  view on Meta::CPAN

// Memory IO functions
// =====================================================================

unsigned DLL_CALLCONV 
_MemoryReadProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
	unsigned x;

	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);

	for(x = 0; x < count; x++) {
		long remaining_bytes = mem_header->file_length - mem_header->current_position;
		//if there isn't size bytes left to read, set pos to eof and return a short count
		if( remaining_bytes < (long)size ) {
			if(remaining_bytes > 0) {
				memcpy( buffer, (char *)mem_header->data + mem_header->current_position, remaining_bytes );
			}
			mem_header->current_position = mem_header->file_length;
			break;
		}
		//copy size bytes count times
		memcpy( buffer, (char *)mem_header->data + mem_header->current_position, size );
		mem_header->current_position += size;
		buffer = (char *)buffer + size;
	}
	return x;
}

unsigned DLL_CALLCONV 
_MemoryWriteProc(void *buffer, unsigned size, unsigned count, fi_handle handle) {
	void *newdata;
	long newdatalen;

	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);

	//double the data block size if we need to
	while( (mem_header->current_position + (long)(size * count)) >= mem_header->data_length ) {
		//if we are at or above 1G, we cant double without going negative
		if( mem_header->data_length & 0x40000000 ) {
			//max 2G
			if( mem_header->data_length == 0x7FFFFFFF ) {
				return 0;
			}
			newdatalen = 0x7FFFFFFF;
		} else if( mem_header->data_length == 0 ) {
			//default to 4K if nothing yet
			newdatalen = 4096;
		} else {
			//double size
			newdatalen = mem_header->data_length << 1;
		}
		newdata = realloc( mem_header->data, newdatalen );
		if( !newdata ) {
			return 0;
		}
		mem_header->data = newdata;
		mem_header->data_length = newdatalen;
	}
	memcpy( (char *)mem_header->data + mem_header->current_position, buffer, size * count );
	mem_header->current_position += size * count;
	if( mem_header->current_position > mem_header->file_length ) {
		mem_header->file_length = mem_header->current_position;
	}
	return count;
}

int DLL_CALLCONV 
_MemorySeekProc(fi_handle handle, long offset, int origin) {
	FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(((FIMEMORY*)handle)->data);

	// you can use _MemorySeekProc to reposition the pointer anywhere in a file
	// the pointer can also be positioned beyond the end of the file

src/Source/FreeImage/FreeImageIO.cpp  view on Meta::CPAN

			break;

		case SEEK_CUR:
			if( mem_header->current_position + offset >= 0 ) {
				mem_header->current_position += offset;
				return 0;
			}
			break;

		case SEEK_END:
			if( mem_header->file_length + offset >= 0 ) {
				mem_header->current_position = mem_header->file_length + offset;
				return 0;
			}
			break;
	}

	return -1;
}

long DLL_CALLCONV 
_MemoryTellProc(fi_handle handle) {

src/Source/FreeImage/J2KHelper.cpp  view on Meta::CPAN

#include "Utilities.h"
#include "../LibOpenJPEG/openjpeg.h"
#include "J2KHelper.h"

// --------------------------------------------------------------------------

static OPJ_UINT64 
_LengthProc(J2KFIO_t *fio) {
	long start_pos = fio->io->tell_proc(fio->handle);
	fio->io->seek_proc(fio->handle, 0, SEEK_END);
	unsigned file_length = fio->io->tell_proc(fio->handle) - start_pos;
	fio->io->seek_proc(fio->handle, start_pos, SEEK_SET);
	return (OPJ_UINT64)file_length;
}

static OPJ_SIZE_T 
_ReadProc(void *p_buffer, OPJ_SIZE_T p_nb_bytes, void *p_user_data) {
	J2KFIO_t *fio = (J2KFIO_t*)p_user_data;
	OPJ_SIZE_T l_nb_read = fio->io->read_proc(p_buffer, 1, (unsigned)p_nb_bytes, fio->handle);
	return l_nb_read ? l_nb_read : (OPJ_SIZE_T)-1;
}

static OPJ_SIZE_T 

src/Source/FreeImage/J2KHelper.cpp  view on Meta::CPAN

		return NULL;
	}
	J2KFIO_t *fio = (J2KFIO_t*)malloc(sizeof(J2KFIO_t));
	if(fio) {
		fio->io = io;
		fio->handle = handle;

		opj_stream_t *l_stream = opj_stream_create(OPJ_J2K_STREAM_CHUNK_SIZE, bRead ? OPJ_TRUE : OPJ_FALSE);
		if (l_stream) {
			opj_stream_set_user_data(l_stream, fio, NULL);
			opj_stream_set_user_data_length(l_stream, _LengthProc(fio));
			opj_stream_set_read_function(l_stream, (opj_stream_read_fn)_ReadProc);
			opj_stream_set_write_function(l_stream, (opj_stream_write_fn)_WriteProc);
			opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn)_SkipProc);
			opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn)_SeekProc);
			fio->stream = l_stream;
			return fio;
		} else {
			free(fio);
		}
	}

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

#endif
}

/**
Returns the size, in bytes, of a FreeImageIO stream, from the current position. 
*/
static long
mng_LOF(FreeImageIO *io, fi_handle handle) {
	long start_pos = io->tell_proc(handle);
	io->seek_proc(handle, 0, SEEK_END);
	long file_length = io->tell_proc(handle);
	io->seek_proc(handle, start_pos, SEEK_SET);
	return file_length;
}

/**
Count the number of bytes in a PNG stream, from IHDR to IEND. 
If successful, the stream position, as given by io->tell_proc(handle), 
should be the end of the PNG stream at the return of the function. 
@param io
@param handle
@param inPos
@param m_TotalBytesOfChunks

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

static BOOL 
mng_CountPNGChunks(FreeImageIO *io, fi_handle handle, long inPos, unsigned *m_TotalBytesOfChunks) {
	long mLOF;
	long mPos;
	BOOL mEnd = FALSE;
	DWORD mLength = 0;
	BYTE mChunkName[5];

	*m_TotalBytesOfChunks = 0;

	// get the length of the file
	mLOF = mng_LOF(io, handle);

	// 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);

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN


			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:
				default:
					break;
			}

		} // while(!mEnd)

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

		// not enough space to read a signature(8 bytes) + a chunk(at least 12 bytes)
		return FALSE;
	}

	try {
	
		// skip the signature and/or any following chunk(s)
		DWORD chunk_pos = offset;

		while(1) {
			// get chunk length
			if(chunk_pos + 4 > size_in_bytes) {
				break;
			}

			memcpy(&mLength, &data[chunk_pos], 4);
			mng_SwapLong(&mLength);
			chunk_pos += 4;

			const DWORD next_chunk_pos = chunk_pos + 4 + mLength + 4;
			if(next_chunk_pos > size_in_bytes) {

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

@param hPngMemory PNG stream handle
@param start_pos Start position of the chunk
@param next_pos Start position of the next chunk
@return Returns TRUE if successfull, returns FALSE otherwise
*/
static BOOL 
mng_CopyRemoveChunks(FIMEMORY *hPngMemory, DWORD start_pos, DWORD next_pos) {
	BYTE *data = NULL;
	DWORD size_in_bytes = 0;

	// length of the chunk to remove
	DWORD chunk_length = next_pos - start_pos;
	if(chunk_length == 0) {
		return TRUE;
	}

	// get a pointer to the stream buffer
	FreeImage_AcquireMemory(hPngMemory, &data, &size_in_bytes);
	if(!(data && size_in_bytes) || (size_in_bytes < 20) || (chunk_length >= size_in_bytes)) {
		// not enough space to read a signature(8 bytes) + a chunk(at least 12 bytes)
		return FALSE;
	}
	
	// new file length
	unsigned buffer_size = size_in_bytes + chunk_length;

	BYTE *buffer = (BYTE*)malloc(buffer_size * sizeof(BYTE));
	if(!buffer) {
		return FALSE;
	}
	memcpy(&buffer[0], &data[0], start_pos);
	memcpy(&buffer[start_pos], &data[next_pos], size_in_bytes - next_pos);

	// seek to the start of the stream
	FreeImage_SeekMemory(hPngMemory, 0, SEEK_SET);

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

@param hPngMemory PNG stream handle
@param start_pos Start position of the inNextChunkName chunk
@param next_pos Start position of the next chunk
@return Returns TRUE if successfull, returns FALSE otherwise
*/
static BOOL 
mng_CopyInsertChunks(FIMEMORY *hPngMemory, BYTE *inNextChunkName, BYTE *inInsertChunk, DWORD inChunkLength, DWORD start_pos, DWORD next_pos) {
	BYTE *data = NULL;
	DWORD size_in_bytes = 0;

	// length of the chunk to check
	DWORD chunk_length = next_pos - start_pos;
	if(chunk_length == 0) {
		return TRUE;
	}

	// get a pointer to the stream buffer
	FreeImage_AcquireMemory(hPngMemory, &data, &size_in_bytes);
	if(!(data && size_in_bytes) || (size_in_bytes < 20) || (chunk_length >= size_in_bytes)) {
		// not enough space to read a signature(8 bytes) + a chunk(at least 12 bytes)
		return FALSE;
	}
	
	// new file length
	unsigned buffer_size = inChunkLength + size_in_bytes;

	BYTE *buffer = (BYTE*)malloc(buffer_size * sizeof(BYTE));
	if(!buffer) {
		return FALSE;
	}
	unsigned p = 0;
	memcpy(&buffer[p], &data[0], start_pos);
	p += start_pos;
	memcpy(&buffer[p], inInsertChunk, inChunkLength);

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN


	bResult = mng_CopyRemoveChunks(hPngMemory, start_pos, next_pos);
	if(!bResult) {
		return FALSE;
	}

	return TRUE;
}

static BOOL 
mng_InsertChunk(FIMEMORY *hPngMemory, BYTE *inNextChunkName, BYTE *inInsertChunk, unsigned chunk_length) {
	BOOL bResult = FALSE;

	DWORD start_pos = 0;
	DWORD next_pos = 0;
	
	bResult = mng_FindChunk(hPngMemory, inNextChunkName, 8, &start_pos, &next_pos);
	if(!bResult) {
		return FALSE;
	}

	bResult = mng_CopyInsertChunks(hPngMemory, inNextChunkName, inInsertChunk, chunk_length, start_pos, next_pos);
	if(!bResult) {
		return FALSE;
	}

	return TRUE;
}

static FIBITMAP* 
mng_LoadFromMemoryHandle(FIMEMORY *hmem, int flags = 0) {
	long offset = 0;

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

		}
	}
	
	return dib;
}

/**
Write a chunk in a PNG stream from the current position. 
@param chunk_name Name of the chunk
@param chunk_data Chunk array
@param length Chunk length
@param hPngMemory PNG stream handle
*/
static void
mng_WriteChunk(BYTE *chunk_name, BYTE *chunk_data, DWORD length, FIMEMORY *hPngMemory) {
	DWORD crc_file = 0;
	// write a PNG chunk ...
	// - length
	mng_SwapLong(&length);
	FreeImage_WriteMemory(&length, 1, 4, hPngMemory);
	mng_SwapLong(&length);
	// - chunk name
	FreeImage_WriteMemory(chunk_name, 1, 4, hPngMemory);
	if(chunk_data && length) {
		// - chunk data
		FreeImage_WriteMemory(chunk_data, 1, length, hPngMemory);
		// - crc
		crc_file = FreeImage_ZLibCRC32(0, chunk_name, 4);
		crc_file = FreeImage_ZLibCRC32(crc_file, chunk_data, length);
		mng_SwapLong(&crc_file);
		FreeImage_WriteMemory(&crc_file, 1, 4, hPngMemory);
	} else {
		// - crc
		crc_file = FreeImage_ZLibCRC32(0, chunk_name, 4);
		mng_SwapLong(&crc_file);
		FreeImage_WriteMemory(&crc_file, 1, 4, hPngMemory);
	}

}

/**
Wrap a IDAT chunk as a PNG stream. 
The stream has the structure { g_png_signature, IHDR, IDAT, IEND }
The image is assumed to be a greyscale image. 

@param jng_width Image width
@param jng_height Image height
@param jng_alpha_sample_depth Bits per pixel
@param mChunk PNG grayscale IDAT format
@param mLength IDAT chunk length
@param hPngMemory Output memory stream
*/
static void 
mng_WritePNGStream(DWORD jng_width, DWORD jng_height, BYTE jng_alpha_sample_depth, BYTE *mChunk, DWORD mLength, FIMEMORY *hPngMemory) {
	// PNG grayscale IDAT format

	BYTE data[14];

	// wrap the IDAT chunk as a PNG stream

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

static BOOL 
mng_SetKeyValue(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, const char *value) {
	if(!dib || !key || !value) {
		return FALSE;
	}
	// create a tag
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		BOOL bSuccess = TRUE;
		// fill the tag
		DWORD tag_length = (DWORD)(strlen(value) + 1);
		bSuccess &= FreeImage_SetTagKey(tag, key);
		bSuccess &= FreeImage_SetTagLength(tag, tag_length);
		bSuccess &= FreeImage_SetTagCount(tag, tag_length);
		bSuccess &= FreeImage_SetTagType(tag, FIDT_ASCII);
		bSuccess &= FreeImage_SetTagValue(tag, value);
		if(bSuccess) {
			// set the tag
			FreeImage_SetMetadata(model, dib, FreeImage_GetTagKey(tag), tag);
		}
		FreeImage_DeleteTag(tag);
		return bSuccess;
	}

	return FALSE;
}

/**
Read a tEXt chunk and extract the key/value pair. 
@param key_value_pair [returned value] Array of key/value pairs
@param mChunk Chunk data
@param mLength Chunk length
@return Returns TRUE if successful, returns FALSE otherwise
*/
static BOOL 
mng_SetMetadata_tEXt(tEXtMAP &key_value_pair, const BYTE *mChunk, DWORD mLength) {
	std::string key;
	std::string value;
	BYTE *buffer = (BYTE*)malloc(mLength * sizeof(BYTE));
	if(!buffer) {
		return FALSE;
	}

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

	const long mLOF = mng_LOF(io, handle);
	// go to the first chunk
	io->seek_proc(handle, Offset, SEEK_SET);

	try {
		BOOL mEnd = FALSE;

		while(mEnd == FALSE) {
			// start of the chunk
			LastOffset = io->tell_proc(handle);
			// read length
			mLength = 0;			
			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) {

src/Source/FreeImage/MNGHelper.cpp  view on Meta::CPAN

						jng_color_type = mChunk[8];
						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);

src/Source/FreeImage/MemoryIO.cpp  view on Meta::CPAN

		if(stream->data) {
			FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);

			// initialize the memory header
			memset(mem_header, 0, sizeof(FIMEMORYHEADER));
			
			if(data && size_in_bytes) {
				// wrap a user buffer
				mem_header->delete_me = FALSE;
				mem_header->data = (BYTE*)data;
				mem_header->data_length = mem_header->file_length = size_in_bytes;
			} else {
				mem_header->delete_me = TRUE;
			}

			return stream;
		}
		free(stream);
	}

	return NULL;

src/Source/FreeImage/MemoryIO.cpp  view on Meta::CPAN

// =====================================================================
// Memory stream buffer access
// =====================================================================

BOOL DLL_CALLCONV
FreeImage_AcquireMemory(FIMEMORY *stream, BYTE **data, DWORD *size_in_bytes) {
	if (stream) {
		FIMEMORYHEADER *mem_header = (FIMEMORYHEADER*)(stream->data);

		*data = (BYTE*)mem_header->data;
		*size_in_bytes = mem_header->file_length;
		return TRUE;
	}

	return FALSE;
}

// =====================================================================
// Memory stream file type access
// =====================================================================

src/Source/FreeImage/NNQuantizer.cpp  view on Meta::CPAN

// April 2004:   Algorithm rewritten as a C++ class. 
//               Fixed a bug in the algorithm with handling of 4-byte boundary alignment.
//               Author: Hervé Drolon (drolon@infonie.fr)
///////////////////////////////////////////////////////////////////////

#include "Quantizers.h"
#include "FreeImage.h"
#include "Utilities.h"


// Four primes near 500 - assume no image has a length so large
// that it is divisible by all four primes
// ==========================================================

#define prime1		499
#define prime2		491
#define prime3		487
#define prime4		503

// ----------------------------------------------------------------

src/Source/FreeImage/NNQuantizer.cpp  view on Meta::CPAN


	*b = bits[FI_RGBA_BLUE] << netbiasshift;
	*g = bits[FI_RGBA_GREEN] << netbiasshift;
	*r = bits[FI_RGBA_RED] << netbiasshift;
}

void NNQuantizer::learn(int sampling_factor) {
	int i, j, b, g, r;
	int radius, rad, alpha, step, delta, samplepixels;
	int alphadec; // biased by 10 bits
	long pos, lengthcount;

	// image size as viewed by the scan algorithm
	lengthcount = img_width * img_height * 3;

	// number of samples used for the learning phase
	samplepixels = lengthcount / (3 * sampling_factor);

	// decrease learning rate after delta pixel presentations
	delta = samplepixels / ncycles;
	if(delta == 0) {
		// avoid a 'divide by zero' error with very small images
		delta = 1;
	}

	// initialize learning parameters
	alphadec = 30 + ((sampling_factor - 1) / 3);
	alpha = initalpha;
	radius = initradius;
	
	rad = radius >> radiusbiasshift;
	if (rad <= 1) rad = 0;
	for (i = 0; i < rad; i++) 
		radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));
	
	// initialize pseudo-random scan
	if ((lengthcount % prime1) != 0)
		step = 3*prime1;
	else {
		if ((lengthcount % prime2) != 0)
			step = 3*prime2;
		else {
			if ((lengthcount % prime3) != 0) 
				step = 3*prime3;
			else
				step = 3*prime4;
		}
	}
	
	i = 0;		// iteration
	pos = 0;	// pixel position

	while (i < samplepixels) {

src/Source/FreeImage/NNQuantizer.cpp  view on Meta::CPAN

		j = contest(b, g, r);

		// alter winner
		altersingle(alpha, j, b, g, r);

		// alter neighbours 
		if (rad) alterneigh(rad, j, b, g, r);

		// next sample
		pos += step;
		while (pos >= lengthcount) pos -= lengthcount;
	
		i++;
		if (i % delta == 0) {	
			// decrease learning rate and also the neighborhood
			alpha -= alpha / alphadec;
			radius -= radius / radiusdec;
			rad = radius >> radiusbiasshift;
			if (rad <= 1) rad = 0;
			for (j = 0; j < rad; j++) 
				radpower[j] = alpha * (((rad*rad - j*j) * radbias) / (rad*rad));

src/Source/FreeImage/NNQuantizer.cpp  view on Meta::CPAN

	// 1) Select a sampling factor in range 1..30 (input parameter 'sampling')
	//    1 => slower, 30 => faster. Default value is 1


	// 2) Get DIB parameters

	dib_ptr = dib;
	
	img_width  = FreeImage_GetWidth(dib);	// DIB width
	img_height = FreeImage_GetHeight(dib);	// DIB height
	img_line   = FreeImage_GetLine(dib);	// DIB line length in bytes (should be equal to 3 x W)

	// For small images, adjust the sampling factor to avoid a 'divide by zero' error later 
	// (see delta in learn() routine)
	int adjust = (img_width * img_height) / ncycles;
	if(sampling >= adjust)
		sampling = 1;


	// 3) Initialize the network and apply the learning algorithm

src/Source/FreeImage/PSDParser.cpp  view on Meta::CPAN

		nBytes += n * sizeof(data);
	}
	
	if ( nBytes == nTotalBytes ) {
		bSuccess = true;
	}
	
	return bSuccess;
}

bool psdParser::ReadImageResources(FreeImageIO *io, fi_handle handle, LONG length) {
	psdImageResource oResource;
	bool bSuccess = false;
	
	if(length > 0) {
		oResource._Length = length;
	} else {
		BYTE Length[4];
		int n = (int)io->read_proc(&Length, sizeof(Length), 1, handle);
		
		oResource._Length = psdGetValue( Length, sizeof(oResource._Length) );
	}
	
	int nBytes = 0;
	int nTotalBytes = oResource._Length;
	

src/Source/FreeImage/PSDParser.cpp  view on Meta::CPAN

					// 2 bytes for the index of transparent color, if any.
					case 1047:
						n = (int)io->read_proc(&ShortValue, sizeof(ShortValue), 1, handle);
						nBytes += n * sizeof(ShortValue);
						_TransparentIndex = (short)psdGetValue(ShortValue, sizeof(ShortValue) );
						break;
						
					default:
					{
						// skip resource
						unsigned skip_length = MIN(oResource._Size, nTotalBytes - nBytes);
						io->seek_proc(handle, skip_length, SEEK_CUR);
						nBytes += skip_length;
					}
					break;
				}
			}
		}
  }
  
  if (nBytes == nTotalBytes) {
	  bSuccess = true;
  }

src/Source/FreeImage/PSDParser.h  view on Meta::CPAN

	/**
	@return Returns the number of bytes read
	*/
	bool Read(FreeImageIO *io, fi_handle handle);
};

/**
Table 2-13 Color mode data section

Only indexed color and duotone have color mode data. For all other modes,
this section is just 4 bytes: the length field, which is set to zero.
For indexed color images, the length will be equal to 768, and the color data
will contain the color table for the image, in non-interleaved order.
For duotone images, the color data will contain the duotone specification,
the format of which is not documented. Other applications that read
Photoshop files can treat a duotone image as a grayscale image, and just
preserve the contents of the duotone information when reading and writing
the file.
*/
class psdColourModeData {
public:
	int _Length;			//! The length of the following color data
	BYTE * _plColourData;	//! The color data

public:
	psdColourModeData();
	~psdColourModeData();
	/**
	@return Returns the number of bytes read
	*/
	bool Read(FreeImageIO *io, fi_handle handle);
	bool FillPalette(FIBITMAP *dib);

src/Source/FreeImage/PSDParser.h  view on Meta::CPAN

private:
	/**	Actually ignore it */
	bool ReadLayerAndMaskInfoSection(FreeImageIO *io, fi_handle handle);
	FIBITMAP* ReadImageData(FreeImageIO *io, fi_handle handle);

public:
	psdParser();
	~psdParser();
	FIBITMAP* Load(FreeImageIO *io, fi_handle handle, int s_format_id, int flags=0);
	/** Also used by the TIFF plugin */
	bool ReadImageResources(FreeImageIO *io, fi_handle handle, LONG length=0);
	/** Used by the TIFF plugin */
	FIBITMAP* GetThumbnail() {
		return _thumbnail.getDib();
	}
};

#endif // PSDPARSER_H

src/Source/FreeImage/PluginBMP.cpp  view on Meta::CPAN

						}

						int count = MIN((int)status_byte, width - bits);

						BYTE *sline = FreeImage_GetScanLine(dib, scanline);

						if(io->read_proc((void *)(sline + bits), sizeof(BYTE) * count, 1, handle) != 1) {
							return FALSE;
						}
						
						// align run length to even number of bytes 

						if ((status_byte & 1) == 1) {
							if(io->read_proc(&second_byte, sizeof(BYTE), 1, handle) != 1) {
								return FALSE;
							}
						}

						bits += status_byte;													

						break;	

src/Source/FreeImage/PluginGIF.cpp  view on Meta::CPAN


#define GIF_INTERLACE_PASSES		4
static int g_GifInterlaceOffset[GIF_INTERLACE_PASSES] = {0, 4, 2, 1};
static int g_GifInterlaceIncrement[GIF_INTERLACE_PASSES] = {8, 8, 4, 2};

// ==========================================================
// Helpers Functions
// ==========================================================

static BOOL 
FreeImage_SetMetadataEx(FREE_IMAGE_MDMODEL model, FIBITMAP *dib, const char *key, WORD id, FREE_IMAGE_MDTYPE type, DWORD count, DWORD length, const void *value)
{
	BOOL bResult = FALSE;
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		FreeImage_SetTagKey(tag, key);
		FreeImage_SetTagID(tag, id);
		FreeImage_SetTagType(tag, type);
		FreeImage_SetTagCount(tag, count);
		FreeImage_SetTagLength(tag, length);
		FreeImage_SetTagValue(tag, value);
		if(model == FIMD_ANIMATION) {
			TagLib& s = TagLib::instance();
			// get the tag description
			const char *description = s.getTagDescription(TagLib::ANIMATION, id);
			FreeImage_SetTagDescription(tag, description);
		}
		// store the tag
		bResult = FreeImage_SetMetadata(model, dib, key, tag);
		FreeImage_DeleteTag(tag);

src/Source/FreeImage/PluginGIF.cpp  view on Meta::CPAN

				io->write_proc(&b, 1, 1, handle);
			}

			//Comment Extension
			FIMETADATA *mdhandle = NULL;
			FITAG *tag = NULL;
			mdhandle = FreeImage_FindFirstMetadata(FIMD_COMMENTS, dib, &tag);
			if( mdhandle ) {
				do {
					if( FreeImage_GetTagType(tag) == FIDT_ASCII ) {
						int length = FreeImage_GetTagLength(tag) - 1;
						char *value = (char *)FreeImage_GetTagValue(tag);
						io->write_proc((void *)"\x21\xFE", 2, 1, handle);
						while( length > 0 ) {
							b = (BYTE)(length >= 255 ? 255 : length);
							io->write_proc(&b, 1, 1, handle);
							io->write_proc(value, b, 1, handle);
							value += b;
							length -= b;
						}
						b = 0;
						io->write_proc(&b, 1, 1, handle);
					}
				} while(FreeImage_FindNextMetadata(mdhandle, &tag));

				FreeImage_FindCloseMetadata(mdhandle);
			}
		}

src/Source/FreeImage/PluginGIF.cpp  view on Meta::CPAN


		//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);
			while( stringtable->Compress(bufptr, &size) ) {
				bufptr += size;
				if( bufptr - buf == sizeof(buf) ) {
					io->write_proc(&b, 1, 1, handle);
					io->write_proc(buf, sizeof(buf), 1, handle);
					size = sizeof(buf);

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN

	rgbe_write_error,
	rgbe_format_error,
	rgbe_memory_error
} rgbe_error_code;

// ----------------------------------------------------------
// Prototypes
// ----------------------------------------------------------

static BOOL rgbe_Error(rgbe_error_code error_code, const char *msg);
static BOOL rgbe_GetLine(FreeImageIO *io, fi_handle handle, char *buffer, int length);
static inline void rgbe_FloatToRGBE(BYTE rgbe[4], FIRGBF *rgbf);
static inline void rgbe_RGBEToFloat(FIRGBF *rgbf, BYTE rgbe[4]);
static BOOL rgbe_ReadHeader(FreeImageIO *io, fi_handle handle, unsigned *width, unsigned *height, rgbeHeaderInfo *header_info);
static BOOL rgbe_WriteHeader(FreeImageIO *io, fi_handle handle, unsigned width, unsigned height, rgbeHeaderInfo *info);
static BOOL rgbe_ReadPixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels);
static BOOL rgbe_WritePixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels);
static BOOL rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanline_width, unsigned num_scanlines);
static BOOL rgbe_WriteBytes_RLE(FreeImageIO *io, fi_handle handle, BYTE *data, int numbytes);
static BOOL rgbe_WritePixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned scanline_width, unsigned num_scanlines);
static BOOL rgbe_ReadMetadata(FIBITMAP *dib, rgbeHeaderInfo *header_info);

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN

			FreeImage_OutputMessageProc(s_format_id, "RGBE error: %s\n",msg);
	}

	return FALSE;
}

/**
Get a line from a ASCII io stream
*/
static BOOL 
rgbe_GetLine(FreeImageIO *io, fi_handle handle, char *buffer, int length) {
	int i;
	memset(buffer, 0, length);
	for(i = 0; i < length; i++) {
		if(!io->read_proc(&buffer[i], 1, 1, handle))
			return FALSE;
		if(buffer[i] == 0x0A)
			break;
	}
	
	return (i < length) ? TRUE : FALSE;
}

/**
Standard conversion from float pixels to rgbe pixels. 
Note: you can remove the "inline"s if your compiler complains about it 
*/
static inline void 
rgbe_FloatToRGBE(BYTE rgbe[4], FIRGBF *rgbf) {
	float v;
	int e;

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN

rgbe_WriteMetadata(FIBITMAP *dib, rgbeHeaderInfo *header_info) {
	header_info->gamma = 1;
	header_info->valid |= RGBE_VALID_GAMMA;
	header_info->exposure = 0;
	header_info->valid |= RGBE_VALID_EXPOSURE;

	return TRUE;
}

/** 
Simple read routine. Will not correctly handle run length encoding 
*/
static BOOL 
rgbe_ReadPixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels) {
  BYTE rgbe[4];

  for(unsigned x = 0; x < numpixels; x++) {
	if(io->read_proc(rgbe, 1, sizeof(rgbe), handle) < 1) {
		return rgbe_Error(rgbe_read_error, NULL);
	}
	rgbe_RGBEToFloat(&data[x], rgbe);
  }

  return TRUE;
}

/**
 Simple write routine that does not use run length encoding. 
 These routines can be made faster by allocating a larger buffer and
 fread-ing and fwrite-ing the data in larger chunks.
*/
static BOOL 
rgbe_WritePixels(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned numpixels) {
  BYTE rgbe[4];

  for(unsigned x = 0; x < numpixels; x++) {
	  rgbe_FloatToRGBE(rgbe, &data[x]);
	  if(io->write_proc(rgbe, sizeof(rgbe), 1, handle) < 1)

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN

  return TRUE;
}

static BOOL 
rgbe_ReadPixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, int scanline_width, unsigned num_scanlines) {
	BYTE rgbe[4], *scanline_buffer, *ptr, *ptr_end;
	int i, count;
	BYTE buf[2];
	
	if ((scanline_width < 8)||(scanline_width > 0x7fff)) {
		// run length encoding is not allowed so read flat
		return rgbe_ReadPixels(io, handle, data, scanline_width * num_scanlines);
	}
	scanline_buffer = NULL;
	// read in each successive scanline 
	while(num_scanlines > 0) {
		if(io->read_proc(rgbe, 1, sizeof(rgbe), handle) < 1) {
			free(scanline_buffer);
			return rgbe_Error(rgbe_read_error,NULL);
		}
		if((rgbe[0] != 2) || (rgbe[1] != 2) || (rgbe[2] & 0x80)) {
			// this file is not run length encoded
			rgbe_RGBEToFloat(data, rgbe);
			data ++;
			free(scanline_buffer);
			return rgbe_ReadPixels(io, handle, data, scanline_width * num_scanlines - 1);
		}
		if((((int)rgbe[2]) << 8 | rgbe[3]) != scanline_width) {
			free(scanline_buffer);
			return rgbe_Error(rgbe_format_error,"wrong scanline width");
		}
		if(scanline_buffer == NULL) {

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN


		num_scanlines--;
	}

	free(scanline_buffer);
	
	return TRUE;
}

/**
 The code below is only needed for the run-length encoded files.
 Run length encoding adds considerable complexity but does 
 save some space.  For each scanline, each channel (r,g,b,e) is 
 encoded separately for better compression. 
 @return Returns TRUE if successful, returns FALSE otherwise
*/
static BOOL 
rgbe_WriteBytes_RLE(FreeImageIO *io, fi_handle handle, BYTE *data, int numbytes) {
	static const int MINRUNLENGTH = 4;
	int cur, beg_run, run_count, old_run_count, nonrun_count;
	BYTE buf[2];
	
	cur = 0;
	while(cur < numbytes) {
		beg_run = cur;
		// find next run of length at least 4 if one exists 
		run_count = old_run_count = 0;
		while((run_count < MINRUNLENGTH) && (beg_run < numbytes)) {
			beg_run += run_count;
			old_run_count = run_count;
			run_count = 1;
			while((beg_run + run_count < numbytes) && (run_count < 127) && (data[beg_run] == data[beg_run + run_count])) {
				run_count++;
			}
		}
		// if data before next big run is a short run then write it as such 

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN

	
	return TRUE;
}

static BOOL 
rgbe_WritePixels_RLE(FreeImageIO *io, fi_handle handle, FIRGBF *data, unsigned scanline_width, unsigned num_scanlines) {
	BYTE rgbe[4];
	BYTE *buffer;
	
	if ((scanline_width < 8)||(scanline_width > 0x7fff)) {
		// run length encoding is not allowed so write flat
		return rgbe_WritePixels(io, handle, data, scanline_width * num_scanlines);
	}
	buffer = (BYTE*)malloc(sizeof(BYTE) * 4 * scanline_width);
	if (buffer == NULL) {
		// no buffer space so write flat 
		return rgbe_WritePixels(io, handle, data, scanline_width * num_scanlines);
	}
	while(num_scanlines-- > 0) {
		rgbe[0] = (BYTE)2;
		rgbe[1] = (BYTE)2;

src/Source/FreeImage/PluginHDR.cpp  view on Meta::CPAN

			return rgbe_Error(rgbe_write_error, NULL);
		}
		for(unsigned x = 0; x < scanline_width; x++) {
			rgbe_FloatToRGBE(rgbe, data);
			buffer[x] = rgbe[0];
			buffer[x+scanline_width] = rgbe[1];
			buffer[x+2*scanline_width] = rgbe[2];
			buffer[x+3*scanline_width] = rgbe[3];
			data ++;
		}
		// write out each of the four channels separately run length encoded
		// first red, then green, then blue, then exponent
		for(int i = 0; i < 4; i++) {
			BOOL bOK = rgbe_WriteBytes_RLE(io, handle, &buffer[i*scanline_width], scanline_width);
			if(!bOK) {
				free(buffer);
				return bOK;
			}
		}
	}
	free(buffer);

src/Source/FreeImage/PluginIFF.cpp  view on Meta::CPAN

						}
#endif
					}

					free(src);

					return dib;
				}
			}

			// Every odd-length chunk is followed by a 0 pad byte.  This pad
			//  byte is not counted in ch_size.
			if (ch_size & 1) {
				ch_size++;
				ch_end++;
			}

			io->seek_proc(handle, ch_end - io->tell_proc(handle), SEEK_CUR);

			size -= ch_size + 8;
		}

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

// ----------------------------------------------------------

#define INPUT_BUF_SIZE  4096	// choose an efficiently fread'able size 
#define OUTPUT_BUF_SIZE 4096    // choose an efficiently fwrite'able size

#define EXIF_MARKER		(JPEG_APP0+1)	// EXIF marker / Adobe XMP marker
#define ICC_MARKER		(JPEG_APP0+2)	// ICC profile marker
#define IPTC_MARKER		(JPEG_APP0+13)	// IPTC marker / BIM marker 

#define ICC_HEADER_SIZE 14				// size of non-profile data in APP2
#define MAX_BYTES_IN_MARKER 65533L		// maximum data length of a JPEG marker
#define MAX_DATA_BYTES_IN_MARKER 65519L	// maximum data length of a JPEG APP2 marker

#define MAX_JFXX_THUMB_SIZE (MAX_BYTES_IN_MARKER - 5 - 1)

#define JFXX_TYPE_JPEG 	0x10	// JFIF extension marker: JPEG-compressed thumbnail image
#define JFXX_TYPE_8bit 	0x11	// JFIF extension marker: palette thumbnail image
#define JFXX_TYPE_24bit	0x13	// JFIF extension marker: RGB thumbnail image

// ----------------------------------------------------------
//   Typedef declarations
// ----------------------------------------------------------

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
				  OUTPUT_BUF_SIZE * sizeof(JOCTET));

	dest->pub.next_output_byte = dest->buffer;
	dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}

/**
	This is called whenever the buffer has filled (free_in_buffer
	reaches zero). In typical applications, it should write out the
	*entire* buffer (use the saved start address and buffer length;
	ignore the current state of next_output_byte and free_in_buffer).
	Then reset the pointer & count to the start of the buffer, and
	return TRUE indicating that the buffer has been dumped.
	free_in_buffer must be set to a positive value when TRUE is
	returned.  A FALSE return should only be used when I/O suspension is
	desired.
*/
METHODDEF(boolean)
empty_output_buffer (j_compress_ptr cinfo) {
	freeimage_dst_ptr dest = (freeimage_dst_ptr) cinfo->dest;

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN


// ----------------------------------------------------------
//   Special markers read functions
// ----------------------------------------------------------

/**
	Read JPEG_COM marker (comment)
*/
static BOOL 
jpeg_read_comment(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
	size_t length = datalen;
	BYTE *profile = (BYTE*)dataptr;

	// read the comment
	char *value = (char*)malloc((length + 1) * sizeof(char));
	if(value == NULL) return FALSE;
	memcpy(value, profile, length);
	value[length] = '\0';

	// create a tag
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		unsigned int count = (unsigned int)length + 1;	// includes the null value

		FreeImage_SetTagID(tag, JPEG_COM);
		FreeImage_SetTagKey(tag, "Comment");
		FreeImage_SetTagLength(tag, count);
		FreeImage_SetTagCount(tag, count);
		FreeImage_SetTagType(tag, FIDT_ASCII);
		FreeImage_SetTagValue(tag, value);
		
		// store the tag
		FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

/**
Handy subroutine to test whether a saved marker is an ICC profile marker.
*/
static BOOL 
marker_is_icc(jpeg_saved_marker_ptr marker) {
    // marker identifying string "ICC_PROFILE" (null-terminated)
	const BYTE icc_signature[12] = { 0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, 0x00 };

	if(marker->marker == ICC_MARKER) {
		// verify the identifying string
		if(marker->data_length >= ICC_HEADER_SIZE) {
			if(memcmp(icc_signature, marker->data, sizeof(icc_signature)) == 0) {
				return TRUE;
			}
		}
	}

	return FALSE;
}

/**
  See if there was an ICC profile in the JPEG file being read;
  if so, reassemble and return the profile data.

  TRUE is returned if an ICC profile was found, FALSE if not.
  If TRUE is returned, *icc_data_ptr is set to point to the
  returned data, and *icc_data_len is set to its length.
  
  IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
  and must be freed by the caller with free() when the caller no longer
  needs it.  (Alternatively, we could write this routine to use the
  IJG library's memory allocator, so that the data would be freed implicitly
  at jpeg_finish_decompress() time.  But it seems likely that many apps
  will prefer to have the data stick around after decompression finishes.)
  
  NOTE: if the file contains invalid ICC APP2 markers, we just silently
  return FALSE.  You might want to issue an error message instead.
*/
static BOOL 
jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned *icc_data_len) {
	jpeg_saved_marker_ptr marker;
	int num_markers = 0;
	int seq_no;
	JOCTET *icc_data;
	unsigned total_length;

	const int MAX_SEQ_NO = 255;			// sufficient since marker numbers are bytes
	BYTE marker_present[MAX_SEQ_NO+1];	// 1 if marker found
	unsigned data_length[MAX_SEQ_NO+1];	// size of profile data in marker
	unsigned data_offset[MAX_SEQ_NO+1];	// offset for data in marker
	
	*icc_data_ptr = NULL;		// avoid confusion if FALSE return
	*icc_data_len = 0;
	
	/**
	this first pass over the saved markers discovers whether there are
	any ICC markers and verifies the consistency of the marker numbering.
	*/
	

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

			}
			// sequence number
			seq_no = GETJOCTET(marker->data[12]);
			if (seq_no <= 0 || seq_no > num_markers) {
				return FALSE;		// bogus sequence number 
			}
			if (marker_present[seq_no]) {
				return FALSE;		// duplicate sequence numbers 
			}
			marker_present[seq_no] = 1;
			data_length[seq_no] = marker->data_length - ICC_HEADER_SIZE;
		}
	}
	
	if (num_markers == 0)
		return FALSE;
		
	/**
	check for missing markers, count total space needed,
	compute offset of each marker's part of the data.
	*/
	
	total_length = 0;
	for(seq_no = 1; seq_no <= num_markers; seq_no++) {
		if (marker_present[seq_no] == 0) {
			return FALSE;		// missing sequence number
		}
		data_offset[seq_no] = total_length;
		total_length += data_length[seq_no];
	}
	
	if (total_length <= 0)
		return FALSE;		// found only empty markers ?
	
	// allocate space for assembled data 
	icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
	if (icc_data == NULL)
		return FALSE;		// out of memory
	
	// and fill it in
	for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) {
		if (marker_is_icc(marker)) {
			JOCTET FAR *src_ptr;
			JOCTET *dst_ptr;
			unsigned length;
			seq_no = GETJOCTET(marker->data[12]);
			dst_ptr = icc_data + data_offset[seq_no];
			src_ptr = marker->data + ICC_HEADER_SIZE;
			length = data_length[seq_no];
			while (length--) {
				*dst_ptr++ = *src_ptr++;
			}
		}
	}
	
	*icc_data_ptr = icc_data;
	*icc_data_len = total_length;
	
	return TRUE;
}

/**
	Read JPEG_APPD marker (IPTC or Adobe Photoshop profile)
*/
static BOOL 
jpeg_read_iptc_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
	return read_iptc_profile(dib, dataptr, datalen);
}

/**
	Read JPEG_APP1 marker (XMP profile)
	@param dib Input FIBITMAP
	@param dataptr Pointer to the APP1 marker
	@param datalen APP1 marker length
	@return Returns TRUE if successful, FALSE otherwise
*/
static BOOL  
jpeg_read_xmp_profile(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
	// marker identifying string for XMP (null terminated)
	const char *xmp_signature = "http://ns.adobe.com/xap/1.0/";
	// XMP signature is 29 bytes long
	const size_t xmp_signature_size = strlen(xmp_signature) + 1;

	size_t length = datalen;
	BYTE *profile = (BYTE*)dataptr;

	if(length <= xmp_signature_size) {
		// avoid reading corrupted or empty data 
		return FALSE;
	}

	// verify the identifying string

	if(memcmp(xmp_signature, profile, strlen(xmp_signature)) == 0) {
		// XMP profile

		profile += xmp_signature_size;
		length  -= xmp_signature_size;

		// create a tag
		FITAG *tag = FreeImage_CreateTag();
		if(tag) {
			FreeImage_SetTagID(tag, JPEG_APP0+1);	// 0xFFE1
			FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
			FreeImage_SetTagLength(tag, (DWORD)length);
			FreeImage_SetTagCount(tag, (DWORD)length);
			FreeImage_SetTagType(tag, FIDT_ASCII);
			FreeImage_SetTagValue(tag, profile);
			
			// store the tag
			FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);

			// destroy the tag
			FreeImage_DeleteTag(tag);
		}

		return TRUE;
	}

	return FALSE;
}

/**
	Read JFIF "JFXX" extension APP0 marker
	@param dib Input FIBITMAP
	@param dataptr Pointer to the APP0 marker
	@param datalen APP0 marker length
	@return Returns TRUE if successful, FALSE otherwise
*/
static BOOL 
jpeg_read_jfxx(FIBITMAP *dib, const BYTE *dataptr, unsigned int datalen) {
	if(datalen < 6) {
		return FALSE;
	}
	
	const int id_length = 5;
	const BYTE *data = dataptr + id_length;
	unsigned remaining = datalen - id_length;
		
	const BYTE type = *data;
	++data, --remaining;

	switch(type) {
		case JFXX_TYPE_JPEG:
		{
			// load the thumbnail
			FIMEMORY* hmem = FreeImage_OpenMemory(const_cast<BYTE*>(data), remaining);
			FIBITMAP* thumbnail = FreeImage_LoadFromMemory(FIF_JPEG, hmem);

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

		switch(marker->marker) {
			case JPEG_APP0:
				// JFIF is handled by libjpeg already, handle JFXX
				if(memcmp(marker->data, "JFIF" , 5) == 0) {
					continue;
				}
				if(memcmp(marker->data, "JFXX" , 5) == 0) {
					if(!cinfo->saw_JFIF_marker || cinfo->JFIF_minor_version < 2) {
						FreeImage_OutputMessageProc(s_format_id, "Warning: non-standard JFXX segment");
					}					
					jpeg_read_jfxx(dib, marker->data, marker->data_length);
				}
				// other values such as 'Picasa' : ignore safely unknown APP0 marker
				break;
			case JPEG_COM:
				// JPEG comment
				jpeg_read_comment(dib, marker->data, marker->data_length);
				break;
			case EXIF_MARKER:
				// Exif or Adobe XMP profile
				jpeg_read_exif_profile(dib, marker->data, marker->data_length);
				jpeg_read_xmp_profile(dib, marker->data, marker->data_length);
				jpeg_read_exif_profile_raw(dib, marker->data, marker->data_length);
				break;
			case IPTC_MARKER:
				// IPTC/NAA or Adobe Photoshop profile
				jpeg_read_iptc_profile(dib, marker->data, marker->data_length);
				break;
		}
	}

	// ICC profile
	BYTE *icc_profile = NULL;
	unsigned icc_length = 0;

	if( jpeg_read_icc_profile(cinfo, &icc_profile, &icc_length) ) {
		// copy ICC profile data
		FreeImage_CreateICCProfile(dib, icc_profile, icc_length);
		// clean up
		free(icc_profile);
	}

	return TRUE;
}

// ----------------------------------------------------------
//   Special markers write functions
// ----------------------------------------------------------

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

	FIICCPROFILE *iccProfile = FreeImage_GetICCProfile(dib);

	if (iccProfile->size && iccProfile->data) {
		// ICC_HEADER_SIZE: ICC signature is 'ICC_PROFILE' + 2 bytes

		BYTE *profile = (BYTE*)malloc((iccProfile->size + ICC_HEADER_SIZE) * sizeof(BYTE));
		if(profile == NULL) return FALSE;
		memcpy(profile, icc_signature, 12);

		for(long i = 0; i < (long)iccProfile->size; i += MAX_DATA_BYTES_IN_MARKER) {
			unsigned length = MIN((long)(iccProfile->size - i), MAX_DATA_BYTES_IN_MARKER);
			// sequence number
			profile[12] = (BYTE) ((i / MAX_DATA_BYTES_IN_MARKER) + 1);
			// number of markers
			profile[13] = (BYTE) (iccProfile->size / MAX_DATA_BYTES_IN_MARKER + 1);

			memcpy(profile + ICC_HEADER_SIZE, (BYTE*)iccProfile->data + i, length);
			jpeg_write_marker(cinfo, ICC_MARKER, profile, (length + ICC_HEADER_SIZE));
        }

		free(profile);

		return TRUE;		
	}
	
	return FALSE;
}

/** 
	Write JPEG_APPD marker (IPTC or Adobe Photoshop profile)
	@return Returns TRUE if successful, FALSE otherwise
*/
static BOOL  
jpeg_write_iptc_profile(j_compress_ptr cinfo, FIBITMAP *dib) {
	//const char *ps_header = "Photoshop 3.0\x08BIM\x04\x04\x0\x0\x0\x0";
	const unsigned tag_length = 26;

	if(FreeImage_GetMetadataCount(FIMD_IPTC, dib)) {
		BYTE *profile = NULL;
		unsigned profile_size = 0;

		// create a binary profile
		if(write_iptc_profile(dib, &profile, &profile_size)) {

			// write the profile
			for(long i = 0; i < (long)profile_size; i += 65517L) {
				unsigned length = MIN((long)profile_size - i, 65517L);
				unsigned roundup = length & 0x01;	// needed for Photoshop
				BYTE *iptc_profile = (BYTE*)malloc(length + roundup + tag_length);
				if(iptc_profile == NULL) break;
				// Photoshop identification string
				memcpy(&iptc_profile[0], "Photoshop 3.0\x0", 14);
				// 8BIM segment type
				memcpy(&iptc_profile[14], "8BIM\x04\x04\x0\x0\x0\x0", 10);
				// segment size
				iptc_profile[24] = (BYTE)(length >> 8);
				iptc_profile[25] = (BYTE)(length & 0xFF);
				// segment data
				memcpy(&iptc_profile[tag_length], &profile[i], length);
				if(roundup)
					iptc_profile[length + tag_length] = 0;
				jpeg_write_marker(cinfo, IPTC_MARKER, iptc_profile, length + roundup + tag_length);
				free(iptc_profile);
			}

			// release profile
			free(profile);

			return TRUE;
		}
	}

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

	FITAG *tag_xmp = NULL;
	FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag_xmp);

	if(tag_xmp) {
		const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag_xmp);

		if(NULL != tag_value) {
			// XMP signature is 29 bytes long
			unsigned int xmp_header_size = (unsigned int)strlen(xmp_signature) + 1;

			DWORD tag_length = FreeImage_GetTagLength(tag_xmp);

			BYTE *profile = (BYTE*)malloc((tag_length + xmp_header_size) * sizeof(BYTE));
			if(profile == NULL) return FALSE;
			memcpy(profile, xmp_signature, xmp_header_size);

			for(DWORD i = 0; i < tag_length; i += 65504L) {
				unsigned length = MIN((long)(tag_length - i), 65504L);
				
				memcpy(profile + xmp_header_size, tag_value + i, length);
				jpeg_write_marker(cinfo, EXIF_MARKER, profile, (length + xmp_header_size));
			}

			free(profile);

			return TRUE;	
		}
	}

	return FALSE;
}

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

	if(tag_exif) {
		const BYTE *tag_value = (BYTE*)FreeImage_GetTagValue(tag_exif);
		
		// verify the identifying string
		if(memcmp(exif_signature, tag_value, sizeof(exif_signature)) != 0) {
			// not an Exif profile
			return FALSE;
		}

		if(NULL != tag_value) {
			DWORD tag_length = FreeImage_GetTagLength(tag_exif);

			BYTE *profile = (BYTE*)malloc(tag_length * sizeof(BYTE));
			if(profile == NULL) return FALSE;

			for(DWORD i = 0; i < tag_length; i += 65504L) {
				unsigned length = MIN((long)(tag_length - i), 65504L);
				
				memcpy(profile, tag_value + i, length);
				jpeg_write_marker(cinfo, EXIF_MARKER, profile, length);
			}

			free(profile);

			return TRUE;	
		}
	}

	return FALSE;
}

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN

	} else {
		FreeImage_CloseMemory(stream);
		return FALSE;
	}

	BYTE* thData = NULL;
	DWORD thSize = 0;
	
	FreeImage_AcquireMemory(stream, &thData, &thSize);	
	
	BYTE id_length = 5; //< "JFXX"
	BYTE type = JFXX_TYPE_JPEG;
	
	DWORD totalsize = id_length + sizeof(type) + thSize;
	jpeg_write_m_header(cinfo, JPEG_APP0, totalsize);
	
	jpeg_write_m_byte(cinfo, 'J');
	jpeg_write_m_byte(cinfo, 'F');
	jpeg_write_m_byte(cinfo, 'X');
	jpeg_write_m_byte(cinfo, 'X');
	jpeg_write_m_byte(cinfo, '\0');
	
	jpeg_write_m_byte(cinfo, type);
	

src/Source/FreeImage/PluginJPEG.cpp  view on Meta::CPAN


// ------------------------------------------------------------
//   Keep original size info when using scale option on loading
// ------------------------------------------------------------
static void 
store_size_info(FIBITMAP *dib, JDIMENSION width, JDIMENSION height) {
	char buffer[256];
	// create a tag
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		size_t length = 0;
		// set the original width
		sprintf(buffer, "%d", (int)width);
		length = strlen(buffer) + 1;	// include the NULL/0 value
		FreeImage_SetTagKey(tag, "OriginalJPEGWidth");
		FreeImage_SetTagLength(tag, (DWORD)length);
		FreeImage_SetTagCount(tag, (DWORD)length);
		FreeImage_SetTagType(tag, FIDT_ASCII);
		FreeImage_SetTagValue(tag, buffer);
		FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);
		// set the original height
		sprintf(buffer, "%d", (int)height);
		length = strlen(buffer) + 1;	// include the NULL/0 value
		FreeImage_SetTagKey(tag, "OriginalJPEGHeight");
		FreeImage_SetTagLength(tag, (DWORD)length);
		FreeImage_SetTagCount(tag, (DWORD)length);
		FreeImage_SetTagType(tag, FIDT_ASCII);
		FreeImage_SetTagValue(tag, buffer);
		FreeImage_SetMetadata(FIMD_COMMENTS, dib, FreeImage_GetTagKey(tag), tag);
		// destroy the tag
		FreeImage_DeleteTag(tag);
	}
}

// ==========================================================
// Plugin Implementation

src/Source/FreeImage/PluginJXR.cpp  view on Meta::CPAN

	const char *key = s.getTagFieldName(TagLib::EXIF_MAIN, tag_id, NULL);
	if(!key) {
		return FALSE;
	}

	// create a tag
	FITAG *tag = FreeImage_CreateTag();
	if(tag) {
		// set tag ID
		FreeImage_SetTagID(tag, tag_id);
		// set tag type, count, length and value
		switch (varSrc.vt) {
			case DPKVT_LPSTR:
				FreeImage_SetTagType(tag, FIDT_ASCII);
				dwSize = (DWORD)strlen(varSrc.VT.pszVal) + 1;
				FreeImage_SetTagCount(tag, dwSize);
				FreeImage_SetTagLength(tag, dwSize);
				FreeImage_SetTagValue(tag, varSrc.VT.pszVal);
				break;
			
			case DPKVT_LPWSTR:

src/Source/FreeImage/PluginPCX.cpp  view on Meta::CPAN

					return TRUE;
				}
			}
		}
	}

	return FALSE;
}

static unsigned
readline(FreeImageIO &io, fi_handle handle, BYTE *buffer, unsigned length, BOOL rle, BYTE * ReadBuf, int * ReadPos) {
	// -----------------------------------------------------------//
	// Read either run-length encoded or normal image data        //
	//                                                            //
	//       THIS IS HOW RUNTIME LENGTH ENCODING WORKS IN PCX:    //
	//                                                            //
	//  1) If the upper 2 bits of a byte are set,                 //
	//     the lower 6 bits specify the count for the next byte   //
	//                                                            //
	//  2) If the upper 2 bits of the byte are clear,             //
	//     the byte is actual data with a count of 1              //
	//                                                            //
	//  Note that a scanline always has an even number of bytes   //
	// -------------------------------------------------------------

	BYTE count = 0, value = 0;
	unsigned written = 0;

	if (rle) {
		// run-length encoded read

		while (length--) {
			if (count == 0) {
				if (*ReadPos >= IO_BUF_SIZE - 1 ) {
					if (*ReadPos == IO_BUF_SIZE - 1) {
						// we still have one BYTE, copy it to the start pos

						*ReadBuf = ReadBuf[IO_BUF_SIZE - 1];

						io.read_proc(ReadBuf + 1, 1, IO_BUF_SIZE - 1, handle);
					} else {
						// read the complete buffer

src/Source/FreeImage/PluginPCX.cpp  view on Meta::CPAN

			}

			count--;

			*(buffer + written++) = value;
		}

	} else {
		// normal read

		written = io.read_proc(buffer, length, 1, handle);
	}

	return written;
}

#ifdef FREEIMAGE_BIGENDIAN
static void
SwapHeader(PCXHEADER *header) {
	SwapShort(&header->window[0]);
	SwapShort(&header->window[1]);

src/Source/FreeImage/PluginPCX.cpp  view on Meta::CPAN

	block of data allocated by the Open function.
*/

static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	FIBITMAP *dib = NULL;
	BYTE *bits;			  // Pointer to dib data
	RGBQUAD *pal;		  // Pointer to dib palette
	BYTE *line = NULL;	  // PCX raster line
	BYTE *ReadBuf = NULL; // buffer;
	BOOL bIsRLE;		  // True if the file is run-length encoded

	if(!handle) {
		return NULL;
	}

	BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;

	try {
		// check PCX identifier

src/Source/FreeImage/PluginPCX.cpp  view on Meta::CPAN

				io->seek_proc(handle, (long)sizeof(PCXHEADER), SEEK_SET);
			}
			break;
		}

		if(header_only) {
			// header only mode
			return dib;
		}

		// calculate the line length for the PCX and the DIB

		// length of raster line in bytes
		unsigned linelength = header.bytes_per_line * header.planes;
		// length of DIB line (rounded to DWORD) in bytes
		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++) {
				written = readline(*io, handle, bits, linelength, bIsRLE, ReadBuf, &ReadPos);

				// skip trailing garbage at the end of the scanline

				for (unsigned count = written; count < linelength; count++) {
					if (ReadPos < IO_BUF_SIZE) {
						ReadPos++;
					} else {
						io->read_proc(&skip, sizeof(BYTE), 1, handle);
					}
				}

				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);

					for (x = 0; x < width; x++) {
						index = (unsigned)((x / 8) + plane * header.bytes_per_line);

src/Source/FreeImage/PluginPCX.cpp  view on Meta::CPAN

				}

				// then write the DIB row

				for (x = 0; x < width / 2; x++) {
					bits[x] = (buffer[2*x] << 4) | buffer[2*x+1];
				}

				// skip trailing garbage at the end of the scanline

				for (unsigned count = written; count < linelength; count++) {
					if (ReadPos < IO_BUF_SIZE) {
						ReadPos++;
					} else {
						io->read_proc(&skip, sizeof(BYTE), 1, handle);
					}
				}

				bits -= pitch;
			}

			free(buffer);

		} else if((header.planes == 3) && (header.bpp == 8)) {
			BYTE *pline;

			for (unsigned y = 0; y < height; y++) {
				readline(*io, handle, line, linelength, bIsRLE, ReadBuf, &ReadPos);

				// convert the plane stream to BGR (RRRRGGGGBBBB -> BGRBGRBGRBGR)
				// well, now with the FI_RGBA_x macros, on BIGENDIAN we convert to RGB

				pline = line;
				unsigned x;

				for (x = 0; x < width; x++) {
					bits[x * 3 + FI_RGBA_RED] = pline[x];						
				}

src/Source/FreeImage/PluginPFM.cpp  view on Meta::CPAN

	dj[0] = j[3];						\
	dj[1] = j[2];						\
	dj[2] = j[1];						\
	dj[3] = j[0];						\
}

/**
Get a line from a ASCII io stream
*/
static BOOL 
pfm_get_line(FreeImageIO *io, fi_handle handle, char *buffer, int length) {
	int i;
	memset(buffer, 0, length);
	for(i = 0; i < length; i++) {
		if(!io->read_proc(&buffer[i], 1, 1, handle))
			return FALSE;
		if(buffer[i] == 0x0A)
			break;
	}
	
	return (i < length) ? TRUE : FALSE;
}

/**
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;

src/Source/FreeImage/PluginPICT.cpp  view on Meta::CPAN

// ----------------------------------------------------------

struct OpDef
{
	const char * name;
	int    len;
	const char * description;
};

// for reserved opcodes
#define res(length) { "reserved", (length), "reserved for Apple use" }
#define RGB_LEN 6
#define WORD_LEN -1
#define NA 0

static OpDef optable[] =
{
/* 0x00 */  { "NOP",               0, "nop" },
/* 0x01 */  { "Clip",             NA, "clip" },
/* 0x02 */  { "BkPat",             8, "background pattern" },
/* 0x03 */  { "TxFont",            2, "text font (word)" },

src/Source/FreeImage/PluginPICT.cpp  view on Meta::CPAN

		pixwidth *= 2;
	}
	if (rowBytes == 0) {
		rowBytes = pixwidth;
	}
	if (rowBytes < 8) {
		io->seek_proc( handle, rowBytes*height, SEEK_CUR );
	}
	else {
		for (i = 0; i < height; i++) {
			int lineLen;            // length of source line in bytes.
			if (rowBytes > 250) {
				lineLen = Read16( io, handle );
			} else {
				lineLen = Read8( io, handle );
			}
			io->seek_proc( handle, lineLen, SEEK_CUR );
		}
	}
}

src/Source/FreeImage/PluginPICT.cpp  view on Meta::CPAN

	
	if (rowBytes == 0) {
		rowBytes = (WORD)( width * 4 );
	}
	
	BYTE* pLineBuf = (BYTE*)malloc( rowBytes ); // Let's allocate enough for 4 bit planes
	if ( pLineBuf )	{
		try	{
			for ( int i = 0; i < height; i++ ) { 
				// for each line do...
				int linelen;            // length of source line in bytes.
				if (rowBytes > 250) {
					linelen = Read16( io, handle );
				} else {
					linelen = Read8( io, handle);
				}
				
				BYTE* pBuf = UnpackPictRow( io, handle, pLineBuf, width, rowBytes, linelen );
				
				// Convert plane-oriented data into pixel-oriented data &
				// copy into destination bitmap.

src/Source/FreeImage/PluginPICT.cpp  view on Meta::CPAN

	int width = bounds->right - bounds->left;
	
	// High bit of rowBytes is flag.
	rowBytes &= 0x7fff;
	
	if (rowBytes == 0) {
		rowBytes = (WORD)width;
	}
	
	for ( int i = 0; i < height; i++ ) {
		int linelen;            // length of source line in bytes.
		if (rowBytes > 250) {
			linelen = Read16( io, handle );
		} else {
			linelen = Read8( io, handle );
		}
		BYTE* dst = (BYTE*)FreeImage_GetScanLine( dib, height - 1 - i);				
		dst = UnpackPictRow( io, handle, dst, width, rowBytes, linelen );
	}
}

src/Source/FreeImage/PluginPICT.cpp  view on Meta::CPAN

				if (pixelSize == 16) {
					expandBuf( io, handle, width, pixelSize, dst );
				} else {
					expandBuf8( io, handle, width, pixelSize, dst );
				}
			}
		}
		else {
			for ( int i = 0; i < height; i++ ) { 
				// For each line do...
				int    linelen;            // length of source line in bytes.
				if (rowBytes > 250) {
					linelen = Read16( io, handle );
				} else {
					linelen = Read8( io, handle );
				}
				
				BYTE* dst = (BYTE*)FreeImage_GetScanLine( dib, height - 1 - i);
				BYTE FlagCounter;
				
				// Unpack RLE. The data is packed bytewise - except for

src/Source/FreeImage/PluginPNG.cpp  view on Meta::CPAN

	png_timep mod_time = NULL;
	int num_text = 0;

	// iTXt/tEXt/zTXt chuncks
	if(png_get_text(png_ptr, info_ptr, &text_ptr, &num_text) > 0) {
		for(int i = 0; i < num_text; i++) {
			// create a tag
			tag = FreeImage_CreateTag();
			if(!tag) return FALSE;

			DWORD tag_length = (DWORD) MAX(text_ptr[i].text_length, text_ptr[i].itxt_length);

			FreeImage_SetTagLength(tag, tag_length);
			FreeImage_SetTagCount(tag, tag_length);
			FreeImage_SetTagType(tag, FIDT_ASCII);
			FreeImage_SetTagValue(tag, text_ptr[i].text);

			if(strcmp(text_ptr[i].key, g_png_xmp_keyword) == 0) {
				// store the tag as XMP
				FreeImage_SetTagKey(tag, g_TagLib_XMPFieldName);
				FreeImage_SetMetadata(FIMD_XMP, dib, FreeImage_GetTagKey(tag), tag);
			} else {
				// store the tag as a comment
				FreeImage_SetTagKey(tag, text_ptr[i].key);

src/Source/FreeImage/PluginPNG.cpp  view on Meta::CPAN

	// timestamp chunk
	if(png_get_tIME(png_ptr, info_ptr, &mod_time)) {
		char timestamp[32];
		// create a tag
		tag = FreeImage_CreateTag();
		if(!tag) return FALSE;

		// convert as 'yyyy:MM:dd hh:mm:ss'
		sprintf(timestamp, "%4d:%02d:%02d %2d:%02d:%02d", mod_time->year, mod_time->month, mod_time->day, mod_time->hour, mod_time->minute, mod_time->second);

		DWORD tag_length = (DWORD)strlen(timestamp) + 1;
		FreeImage_SetTagLength(tag, tag_length);
		FreeImage_SetTagCount(tag, tag_length);
		FreeImage_SetTagType(tag, FIDT_ASCII);
		FreeImage_SetTagID(tag, TAG_DATETIME);
		FreeImage_SetTagValue(tag, timestamp);

		// store the tag as Exif-TIFF
		FreeImage_SetTagKey(tag, "DateTime");
		FreeImage_SetMetadata(FIMD_EXIF_MAIN, dib, FreeImage_GetTagKey(tag), tag);

		// destroy the tag
		FreeImage_DeleteTag(tag);

src/Source/FreeImage/PluginPNG.cpp  view on Meta::CPAN

	// set the 'Comments' metadata as iTXt chuncks

	mdhandle = FreeImage_FindFirstMetadata(FIMD_COMMENTS, dib, &tag);

	if(mdhandle) {
		do {
			memset(&text_metadata, 0, sizeof(png_text));
			text_metadata.compression = 1;							// iTXt, none
			text_metadata.key = (char*)FreeImage_GetTagKey(tag);	// keyword, 1-79 character description of "text"
			text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
			text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
			text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
			text_metadata.lang = 0;		 // language code, 0-79 characters or a NULL pointer
			text_metadata.lang_key = 0;	 // keyword translated UTF-8 string, 0 or more chars or a NULL pointer

			// set the tag 
			png_set_text(png_ptr, info_ptr, &text_metadata, 1);

		} while(FreeImage_FindNextMetadata(mdhandle, &tag));

		FreeImage_FindCloseMetadata(mdhandle);
		bResult &= TRUE;
	}

	// set the 'XMP' metadata as iTXt chuncks
	tag = NULL;
	FreeImage_GetMetadata(FIMD_XMP, dib, g_TagLib_XMPFieldName, &tag);
	if(tag && FreeImage_GetTagLength(tag)) {
		memset(&text_metadata, 0, sizeof(png_text));
		text_metadata.compression = 1;							// iTXt, none
		text_metadata.key = (char*)g_png_xmp_keyword;			// keyword, 1-79 character description of "text"
		text_metadata.text = (char*)FreeImage_GetTagValue(tag);	// comment, may be an empty string (ie "")
		text_metadata.text_length = FreeImage_GetTagLength(tag);// length of the text string
		text_metadata.itxt_length = FreeImage_GetTagLength(tag);// length of the itxt string
		text_metadata.lang = 0;		 // language code, 0-79 characters or a NULL pointer
		text_metadata.lang_key = 0;	 // keyword translated UTF-8 string, 0 or more chars or a NULL pointer

		// set the tag 
		png_set_text(png_ptr, info_ptr, &text_metadata, 1);
		bResult &= TRUE;
	}

	// set the Exif-TIFF 'DateTime' metadata as a tIME chunk
	tag = NULL;

src/Source/FreeImage/PluginPNG.cpp  view on Meta::CPAN

					FreeImage_SetDotsPerMeterX(dib, res_x);
					FreeImage_SetDotsPerMeterY(dib, res_y);
				}
			}

			// get possible ICC profile

			if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
				png_charp profile_name = NULL;
				png_bytep profile_data = NULL;
				png_uint_32 profile_length = 0;
				int  compression_type;

				png_get_iCCP(png_ptr, info_ptr, &profile_name, &compression_type, &profile_data, &profile_length);

				// copy ICC profile data (must be done after FreeImage_AllocateHeader)

				FreeImage_CreateICCProfile(dib, profile_data, profile_length);
			}

			// --- header only mode => clean-up and return

			if (header_only) {
				// get possible metadata (it can be located both before and after the image data)
				ReadMetadata(png_ptr, info_ptr, dib);
				if (png_ptr) {
					// clean up after the read, and free any memory allocated - REQUIRED
					png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);

src/Source/FreeImage/PluginPNM.cpp  view on Meta::CPAN


						for (x = 0; x < width; x++) {
							io->write_proc(&bits[FI_RGBA_RED], 1, 1, handle);	// R
							io->write_proc(&bits[FI_RGBA_GREEN], 1, 1, handle);	// G
							io->write_proc(&bits[FI_RGBA_BLUE], 1, 1, handle);	// B

							bits += 3;
						}
					}
				} else {
					int length = 0;

					for (y = 0; y < height; y++) {
						// write the scanline to disc
						BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);
						
						for (x = 0; x < width; x++) {
							sprintf(buffer, "%3d %3d %3d ", bits[FI_RGBA_RED], bits[FI_RGBA_GREEN], bits[FI_RGBA_BLUE]);

							io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);

							length += 12;

							if(length > 58) {
								// No line should be longer than 70 characters
								sprintf(buffer, "\n");
								io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);
								length = 0;
							}

							bits += 3;
						}					
					}

				}
			}
			break;

src/Source/FreeImage/PluginPNM.cpp  view on Meta::CPAN

				if (flags == PNM_SAVE_RAW)  {
					for (y = 0; y < height; y++) {
						// write the scanline to disc
						BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);

						for (x = 0; x < width; x++) {
							io->write_proc(&bits[x], 1, 1, handle);
						}
					}
				} else {
					int length = 0;

					for (y = 0; y < height; y++) {
						// write the scanline to disc
						BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);

						for (x = 0; x < width; x++) {
							sprintf(buffer, "%3d ", bits[x]);

							io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);

							length += 4;

							if (length > 66) {
								// No line should be longer than 70 characters
								sprintf(buffer, "\n");
								io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);
								length = 0;
							}
						}
					}
				}
			}
			break;

			case 1:		// 1-bit B & W
			{
				int color;

				if (flags == PNM_SAVE_RAW)  {
					for(y = 0; y < height; y++) {
						// write the scanline to disc
						BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);

						for(x = 0; x < (int)FreeImage_GetLine(dib); x++)
							io->write_proc(&bits[x], 1, 1, handle);
					}
				} else  {
					int length = 0;

					for (y = 0; y < height; y++) {
						// write the scanline to disc
						BYTE *bits = FreeImage_GetScanLine(dib, height - 1 - y);

						for (x = 0; x < (int)FreeImage_GetLine(dib) * 8; x++)	{
							color = (bits[x>>3] & (0x80 >> (x & 0x07))) != 0;

							sprintf(buffer, "%c ", color ? '1':'0');

							io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);

							length += 2;

							if (length > 68) {
								// No line should be longer than 70 characters
								sprintf(buffer, "\n");
								io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);
								length = 0;
							}
						}
					}
				}
			}
			
			break;
		}
	} // if(FIT_BITMAP)

src/Source/FreeImage/PluginPNM.cpp  view on Meta::CPAN

		if (flags == PNM_SAVE_RAW)  {
			for (y = 0; y < height; y++) {
				// write the scanline to disc
				WORD *bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);

				for (x = 0; x < width; x++) {
					WriteWord(io, handle, bits[x]);
				}
			}
		} else {
			int length = 0;

			for (y = 0; y < height; y++) {
				// write the scanline to disc
				WORD *bits = (WORD*)FreeImage_GetScanLine(dib, height - 1 - y);

				for (x = 0; x < width; x++) {
					sprintf(buffer, "%5d ", bits[x]);

					io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);

					length += 6;

					if (length > 64) {
						// No line should be longer than 70 characters
						sprintf(buffer, "\n");
						io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);
						length = 0;
					}
				}
			}
		}
	}

	else if(image_type == FIT_RGB16) {		// 48-bit RGB
		if (flags == PNM_SAVE_RAW)  {
			for (y = 0; y < height; y++) {
				// write the scanline to disc
				FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);

				for (x = 0; x < width; x++) {
					WriteWord(io, handle, bits[x].red);		// R
					WriteWord(io, handle, bits[x].green);	// G
					WriteWord(io, handle, bits[x].blue);	// B
				}
			}
		} else {
			int length = 0;

			for (y = 0; y < height; y++) {
				// write the scanline to disc
				FIRGB16 *bits = (FIRGB16*)FreeImage_GetScanLine(dib, height - 1 - y);
				
				for (x = 0; x < width; x++) {
					sprintf(buffer, "%5d %5d %5d ", bits[x].red, bits[x].green, bits[x].blue);

					io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);

					length += 18;

					if(length > 52) {
						// No line should be longer than 70 characters
						sprintf(buffer, "\n");
						io->write_proc(&buffer, (unsigned int)strlen(buffer), 1, handle);
						length = 0;
					}
				}					
			}

		}
	}

	return TRUE;
}

src/Source/FreeImage/PluginRAS.cpp  view on Meta::CPAN

#pragma pack(push, 1)
#else
#pragma pack(1)
#endif

typedef struct tagSUNHEADER {
	DWORD magic;		// Magic number
	DWORD width;		// Image width in pixels
	DWORD height;		// Image height in pixels
	DWORD depth;		// Depth (1, 8, 24 or 32 bits) of each pixel
	DWORD length;		// Image length (in bytes)
	DWORD type;			// Format of file (see RT_* below)
	DWORD maptype;		// Type of colormap (see RMT_* below)
	DWORD maplength;	// Length of colormap (in bytes)
} SUNHEADER;

#ifdef _WIN32
#pragma pack(pop)
#else
#pragma pack()
#endif

// ----------------------------------------------------------

// Following the header is the colormap, for maplength bytes (unless maplength is zero),
// then the image. Each row of the image is rounded to 2 bytes.

#define RAS_MAGIC 0x59A66A95 // Magic number for Sun rasterfiles

// Sun supported type's

#define RT_OLD			0	// Old format (raw image in 68000 byte order)
#define RT_STANDARD		1	// Raw image in 68000 byte order
#define RT_BYTE_ENCODED	2	// Run-length encoding of bytes 
#define RT_FORMAT_RGB	3	// XRGB or RGB instead of XBGR or BGR
#define RT_FORMAT_TIFF	4	// TIFF <-> standard rasterfile
#define RT_FORMAT_IFF	5	// IFF (TAAC format) <-> standard rasterfile

#define RT_EXPERIMENTAL 0xffff	// Reserved for testing

// These are the possible colormap types.
// if it's in RGB format, the map is made up of three byte arrays
// (red, green, then blue) that are each 1/3 of the colormap length.

#define RMT_NONE		0	// maplength is expected to be 0
#define RMT_EQUAL_RGB	1	// red[maplength/3], green[maplength/3], blue[maplength/3]
#define RMT_RAW			2	// Raw colormap
#define RESC			128 // Run-length encoding escape character

// ----- NOTES -----
// Each line of the image is rounded out to a multiple of 16 bits.
// This corresponds to the rounding convention used by the memory pixrect
// package (/usr/include/pixrect/memvar.h) of the SunWindows system.
// The ras_encoding field (always set to 0 by Sun's supported software)
// was renamed to ras_length in release 2.0.  As a result, rasterfiles
// of type 0 generated by the old software claim to have 0 length; for
// compatibility, code reading rasterfiles must be prepared to compute the
// TRUE length from the width, height, and depth fields.

// ==========================================================
// Internal functions
// ==========================================================

static void
ReadData(FreeImageIO *io, fi_handle handle, BYTE *buf, DWORD length, BOOL rle) {
	// Read either Run-Length Encoded or normal image data

	static BYTE repchar, remaining= 0;

	if (rle) {
		// Run-length encoded read

		while(length--) {
			if (remaining) {
				remaining--;
				*(buf++)= repchar;
			} else {
				io->read_proc(&repchar, 1, 1, handle);

				if (repchar == RESC) {
					io->read_proc(&remaining, 1, 1, handle);

					if (remaining == 0) {

src/Source/FreeImage/PluginRAS.cpp  view on Meta::CPAN

						*(buf++)= repchar;
					}
				} else {
					*(buf++)= repchar;
				}
			}
		}
	} else {
		// Normal read
	
		io->read_proc(buf, length, 1, handle);
	}
}

// ==========================================================
// Plugin Interface
// ==========================================================

static int s_format_id;

// ==========================================================

src/Source/FreeImage/PluginRAS.cpp  view on Meta::CPAN

static BOOL DLL_CALLCONV
SupportsNoPixels() {
	return TRUE;
}

// ----------------------------------------------------------

static FIBITMAP * DLL_CALLCONV
Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
	SUNHEADER header;	// Sun file header
	WORD linelength;	// Length of raster line in bytes
	WORD fill;			// Number of fill bytes per raster line
	BOOL rle;			// TRUE if RLE file
	BOOL isRGB;			// TRUE if file type is RT_FORMAT_RGB
	BYTE fillchar;

	FIBITMAP *dib = NULL;
	BYTE *bits;			// Pointer to dib data
	WORD x, y;

	if(!handle) {

src/Source/FreeImage/PluginRAS.cpp  view on Meta::CPAN


		io->read_proc(&header, sizeof(SUNHEADER), 1, handle);

#ifndef FREEIMAGE_BIGENDIAN
		// SUN rasterfiles are big endian only

		SwapLong(&header.magic);
		SwapLong(&header.width);
		SwapLong(&header.height);
		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

src/Source/FreeImage/PluginRAS.cpp  view on Meta::CPAN

				break;
			}

			case RMT_EQUAL_RGB:
			{
				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);

src/Source/FreeImage/PluginRAS.cpp  view on Meta::CPAN

				free(r);
				break;
			}

			case RMT_RAW:
			{
				BYTE *colormap;

				// Read (skip) SUN raster colormap.

				colormap = (BYTE *)malloc(header.maplength * sizeof(BYTE));

				io->read_proc(colormap, header.maplength, 1, handle);

				free(colormap);
				break;
			}
		}

		if(header_only) {
			// header only mode
			return dib;
		}

		// Calculate the line + pitch
		// Each row is multiple of 16 bits (2 bytes).

		if (header.depth == 1) {
			linelength = (WORD)((header.width / 8) + (header.width % 8 ? 1 : 0));
		} else {
			linelength = (WORD)header.width;
		}

		fill = (linelength % 2) ? 1 : 0;

		unsigned pitch = FreeImage_GetPitch(dib);

		// Read the image data
		
		switch(header.depth) {
			case 1:
			case 8:
			{
				bits = FreeImage_GetBits(dib) + (header.height - 1) * pitch;

				for (y = 0; y < header.height; y++) {
					ReadData(io, handle, bits, linelength, rle);

					bits -= pitch;

					if (fill) {
						ReadData(io, handle, &fillchar, fill, rle);
					}
				}

				break;
			}

src/Source/FreeImage/PluginRAW.cpp  view on Meta::CPAN

		return _fsize;
	}

    int get_char() { 
		int c = 0;
		if(substream) return substream->get_char();
		if(!_io->read_proc(&c, 1, 1, _handle)) return -1;
		return c;
   }
	
	char* gets(char *buffer, int length) { 
		if (substream) return substream->gets(buffer, length);
		memset(buffer, 0, length);
		for(int i = 0; i < length; i++) {
			if(!_io->read_proc(&buffer[i], 1, 1, _handle))
				return NULL;
			if(buffer[i] == 0x0A)
				break;
		}
		return buffer;
	}

	int scanf_one(const char *fmt, void* val) {
		std::string buffer;

src/Source/FreeImage/PluginRAW.cpp  view on Meta::CPAN

			// load raw data as 8-bit/sample (i.e. RGB 24-bit)
			dib = libraw_LoadRawData(RawProcessor, 8);
		} 
		else {
			// default: load raw data as linear 16-bit/sample (i.e. RGB 48-bit)
			dib = libraw_LoadRawData(RawProcessor, 16);
		}

		// save ICC profile if present
		if(dib && (NULL != RawProcessor->imgdata.color.profile)) {
			FreeImage_CreateICCProfile(dib, RawProcessor->imgdata.color.profile, RawProcessor->imgdata.color.profile_length);
		}

		// try to get JPEG embedded Exif metadata
		if(dib && !((flags & RAW_PREVIEW) == RAW_PREVIEW)) {
			FIBITMAP *metadata_dib = libraw_LoadEmbeddedPreview(RawProcessor, FIF_LOAD_NOPIXELS);
			if(metadata_dib) {
				FreeImage_CloneMetadata(dib, metadata_dib);
				FreeImage_Unload(metadata_dib);
			}
		}

src/Source/FreeImage/PluginSGI.cpp  view on Meta::CPAN


#ifdef _WIN32
#pragma pack(pop)
#else
#pragma pack()
#endif

static const char *SGI_LESS_THAN_HEADER_LENGTH = "Incorrect header size";
static const char *SGI_16_BIT_COMPONENTS_NOT_SUPPORTED = "No 16 bit support";
static const char *SGI_COLORMAPS_NOT_SUPPORTED = "No colormap support";
static const char *SGI_EOF_IN_RLE_INDEX = "EOF in run length encoding";
static const char *SGI_EOF_IN_IMAGE_DATA = "EOF in image data";
static const char *SGI_INVALID_CHANNEL_COUNT = "Invalid channel count";

// ==========================================================
// Plugin Interface
// ==========================================================

static int s_format_id;

// ==========================================================

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN

//   Constants + headers
// ----------------------------------------------------------

#ifdef _WIN32
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif

typedef struct tagTGAHEADER {
	BYTE id_length;				//! length of the image ID field
	BYTE color_map_type;		//! whether a color map is included
	BYTE image_type;			//! compression and color types

	WORD cm_first_entry;		//! first entry index (offset into the color map table)
	WORD cm_length;				//! color map length (number of entries)
	BYTE cm_size;				//! color map entry size, in bits (number of bits per pixel)

	WORD is_xorigin;			//! X-origin of image (absolute coordinate of lower-left corner for displays where origin is at the lower left)
	WORD is_yorigin;			//! Y-origin of image (as for X-origin)
	WORD is_width;				//! image width
	WORD is_height;				//! image height
	BYTE is_pixel_depth;		//! bits per pixel
	BYTE is_image_descriptor;	//! image descriptor, bits 3-0 give the alpha channel depth, bits 5-4 give direction
} TGAHEADER;

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN


static const char *FI_MSG_ERROR_CORRUPTED = "Image data corrupted";

// ----------------------------------------------------------
// Image type
//
#define TGA_NULL		0	// no image data included
#define TGA_CMAP		1	// uncompressed, color-mapped image
#define TGA_RGB			2	// uncompressed, true-color image
#define TGA_MONO		3	// uncompressed, black-and-white image
#define TGA_RLECMAP		9	// run-length encoded, color-mapped image
#define TGA_RLERGB		10	// run-length encoded, true-color image
#define TGA_RLEMONO		11	// run-length encoded, black-and-white image
#define TGA_CMPCMAP		32	// compressed (Huffman/Delta/RLE) color-mapped image (e.g., VDA/D) - Obsolete
#define TGA_CMPCMAP4	33	// compressed (Huffman/Delta/RLE) color-mapped four pass image (e.g., VDA/D) - Obsolete

// ==========================================================
// Thumbnail functions
// ==========================================================

class TargaThumbnail
{
public:

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN

	BYTE *_end;
	const size_t _size;
	const FreeImageIO *_io;	
	const fi_handle _handle;	
};

#ifdef FREEIMAGE_BIGENDIAN
static void
SwapHeader(TGAHEADER *header) {
	SwapShort(&header->cm_first_entry);
	SwapShort(&header->cm_length);
	SwapShort(&header->is_xorigin);
	SwapShort(&header->is_yorigin);
	SwapShort(&header->is_width);
	SwapShort(&header->is_height);
}

static void
SwapExtensionArea(TGAEXTENSIONAREA *ex) {
	SwapShort(&ex->extension_size);
	SwapShort(&ex->datetime_stamp[0]);

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN

		// rewind
		io->seek_proc(handle, start_offset, SEEK_SET);

		// the color map type should be a 0 or a 1...
		if(header.color_map_type != 0 && header.color_map_type != 1) {
			return FALSE;
		}
		// if the color map type is 1 then we validate the map entry information...
		if(header.color_map_type > 0) {
			// it doesn't make any sense if the first entry is larger than the color map table
			if(header.cm_first_entry >= header.cm_length) {
				return FALSE;
			}
			// check header.cm_size, don't allow 0 or anything bigger than 32
			if(header.cm_size == 0 || header.cm_size > 32) {
				return FALSE;
			}
		}
		// the width/height shouldn't be 0, right ?
		if(header.is_width == 0 || header.is_height == 0) {
			return FALSE;

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN

		thumbnail.setDepth(header.is_pixel_depth);
			
		const int line = CalculateLine(header.is_width, header.is_pixel_depth);
		const int pixel_bits = header.is_pixel_depth;
		const int pixel_size = pixel_bits/8;

		int fliphoriz = (header.is_image_descriptor & 0x10) ? 1 : 0;
		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);

							for (count = start; count < stop; count++) {
								palette[count].rgbRed   = (BYTE)((((*rgb555 & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
								palette[count].rgbGreen = (BYTE)((((*rgb555 & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
								palette[count].rgbBlue  = (BYTE)((((*rgb555 & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
								rgb555++;
							}
						}
						break;

						case 24: {
							FILE_BGR *bgr = (FILE_BGR*)&cmap[0];
							unsigned start = (unsigned)header.cm_first_entry;
							unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);

							for (count = start; count < stop; count++) {
								palette[count].rgbBlue  = bgr->b;
								palette[count].rgbGreen = bgr->g;
								palette[count].rgbRed   = bgr->r;
								bgr++;
							}
						}
						break;

						case 32: {
							BYTE trns[256];

							// clear the transparency table
							memset(trns, 0xFF, 256);

							FILE_BGRA *bgra = (FILE_BGRA*)&cmap[0];
							unsigned start = (unsigned)header.cm_first_entry;
							unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);

							for (count = start; count < stop; count++) {
								palette[count].rgbBlue  = bgra->b;
								palette[count].rgbGreen = bgra->g;
								palette[count].rgbRed   = bgra->r;
								// alpha
								trns[count] = bgra->a;
								bgra++;
							}

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN


				const unsigned pixel_size = unsigned(pixel_bits) / 8;
				const unsigned src_pixel_size = sizeof(WORD);

				// note header.cm_size is a misleading name, it should be seen as header.cm_bits
				// ignore current position in file and set filepointer explicitly from the beginning of the file

				int garblen = 0;

				if (header.color_map_type != 0) {
					garblen = (int)((header.cm_size + 7) / 8) * header.cm_length; /* should byte align */

				} else {
					garblen = 0;
				}

				io->seek_proc(handle, start_offset, SEEK_SET);
				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;

src/Source/FreeImage/PluginTARGA.cpp  view on Meta::CPAN

		return FALSE;
	}

	RGBQUAD *palette = FreeImage_GetPalette(dib);
	const unsigned bpp = FreeImage_GetBPP(dib);

	// write the file header

	TGAHEADER header;

	header.id_length = 0;
	header.cm_first_entry = 0;
	header.is_xorigin = 0;
	header.is_yorigin = 0;
	header.is_width = (WORD)FreeImage_GetWidth(dib);
	header.is_height = (WORD)FreeImage_GetHeight(dib);
	header.is_pixel_depth = (BYTE)bpp;
	header.is_image_descriptor = (bpp == 32 ? 8 : 0);

	if (palette) {
		header.color_map_type = 1;
		header.image_type = (TARGA_SAVE_RLE & flags) ? TGA_RLECMAP : TGA_CMAP;
		header.cm_length = (WORD)(1 << bpp);

		if (FreeImage_IsTransparent(dib)) {
			header.cm_size = 32;
		} else {
			header.cm_size = 24;
		}

	} else {
		header.color_map_type = 0;
		header.image_type = (TARGA_SAVE_RLE & flags) ? TGA_RLERGB : TGA_RGB;
		header.cm_length = 0;
		header.cm_size = 0;
	}

	// write the header

#ifdef FREEIMAGE_BIGENDIAN
	SwapHeader(&header);
#endif

	io->write_proc(&header, sizeof(header), 1, handle);

#ifdef FREEIMAGE_BIGENDIAN
	SwapHeader(&header);
#endif

	// write the palette

	if (palette) {
		if (FreeImage_IsTransparent(dib)) {
			FILE_BGRA *bgra_pal = (FILE_BGRA*)malloc(header.cm_length * sizeof(FILE_BGRA));

			// get the transparency table
			BYTE *trns = FreeImage_GetTransparencyTable(dib);

			for (unsigned i = 0; i < header.cm_length; i++) {
				bgra_pal[i].b = palette[i].rgbBlue;
				bgra_pal[i].g = palette[i].rgbGreen;
				bgra_pal[i].r = palette[i].rgbRed;
				bgra_pal[i].a = trns[i];
			}

			io->write_proc(bgra_pal, sizeof(FILE_BGRA), header.cm_length, handle);

			free(bgra_pal);

		} else {
			FILE_BGR *bgr_pal = (FILE_BGR*)malloc(header.cm_length * sizeof(FILE_BGR));

			for (unsigned i = 0; i < header.cm_length; i++) {
				bgr_pal[i].b = palette[i].rgbBlue;
				bgr_pal[i].g = palette[i].rgbGreen;
				bgr_pal[i].r = palette[i].rgbRed;
			}

			io->write_proc(bgr_pal, sizeof(FILE_BGR), header.cm_length, handle);

			free(bgr_pal);
		}
	}

	// write the data bits 


	if (TARGA_SAVE_RLE & flags) {
		

src/Source/FreeImage/PluginTIFF.cpp  view on Meta::CPAN

			BYTE *iptc_profile = (BYTE*)malloc(iptc_size);
			if(!iptc_profile) {
				free(profile);
				return FALSE;
			}
			memset(iptc_profile, 0, iptc_size);
			memcpy(iptc_profile, profile, profile_size);
			if (TIFFIsByteSwapped(tiff)) {
				TIFFSwabArrayOfLong((uint32 *) iptc_profile, (unsigned long)iptc_size/4);
			}
			// Tag is type TIFF_LONG so byte length is divided by four
			TIFFSetField(tiff, TIFFTAG_RICHTIFFIPTC, iptc_size/4, iptc_profile);
			// release the profile data
			free(iptc_profile);
			free(profile);

			return TRUE;
		}
	}

	return FALSE;

src/Source/FreeImage/PluginTIFF.cpp  view on Meta::CPAN

	uint32 height = 0; 
	uint32 width = 0; 
	uint16 bitspersample = 1;
	uint16 samplesperpixel = 1;
	uint32 rowsperstrip = (uint32)-1;  
	uint16 photometric = PHOTOMETRIC_MINISWHITE;
	uint16 compression = (uint16)-1;
	uint16 planar_config;

	FIBITMAP *dib = NULL;
	uint32 iccSize = 0;		// ICC profile length
	void *iccBuf = NULL;	// ICC profile data		

	const BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
	
	try {	
		fi_TIFFIO *fio = (fi_TIFFIO*)data;
		tif = fio->tif;

		if (page != -1) {
			if (!tif || !TIFFSetDirectory(tif, (uint16)page)) {

src/Source/FreeImage/PluginWBMP.cpp  view on Meta::CPAN


// WBMP Header

#ifdef _WIN32
#pragma pack(push, 1)
#else
#pragma pack(1)
#endif

typedef struct tagWBMPHEADER {
	WORD TypeField;			// Image type identifier of multi-byte length
	BYTE FixHeaderField;	// Octet of general header information
	BYTE ExtHeaderFields;	// Zero or more extension header fields
	WORD Width;				// Multi-byte width field
	WORD Height;			// Multi-byte height field
} WBMPHEADER;

#ifdef _WIN32
#pragma pack(pop)
#else
#pragma pack()

src/Source/FreeImage/PluginWBMP.cpp  view on Meta::CPAN


// The extension headers may be of type binary 00 through binary 11, defined as follows.

// - Type 00 indicates a multi-byte bitfield used to specify additional header information.
// The first bit is set if a type 00, extension header is set if more data follows.
//  The other bits are reserved for future use.
// - Type 01 - reserved for future use.
// - Type 10 - reserved for future use.
// - Type 11 indicates a sequence of parameter/value pairs. These can be used for 
// optimisations and special purpose extensions, eg, animation image formats.
// The parameter size tells the length (1-8 bytes) of the following parameter name.
// The value size gives the length (1-16 bytes) of the following parameter value.
// The concatenation flag indicates whether another parameter/value pair will follow
// after reading the specified bytes of data.

// ==========================================================
// Internal functions
// ==========================================================

static DWORD
multiByteRead(FreeImageIO *io, fi_handle handle) {
	// Multi-byte encoding / decoding

src/Source/FreeImage/PluginWBMP.cpp  view on Meta::CPAN


			multiByteWrite(io, handle, header.TypeField);
			
			io->write_proc(&header.FixHeaderField, 1, 1, handle);

			multiByteWrite(io, handle, header.Width);
			multiByteWrite(io, handle, header.Height);

			// write the bitmap data

			WORD linelength = (WORD)FreeImage_GetLine(dib);

			for (WORD y = 0; y < header.Height; y++) {
				bits = FreeImage_GetScanLine(dib, header.Height - 1 - y);

				io->write_proc(&bits[0], linelength, 1, handle);
			}

			return TRUE;

		} catch (const char* text) {
			FreeImage_OutputMessageProc(s_format_id, text);
		}
	}

	return FALSE;

src/Source/FreeImage/PluginWebP.cpp  view on Meta::CPAN

Read the whole file into memory
*/
static BOOL
ReadFileToWebPData(FreeImageIO *io, fi_handle handle, WebPData * const bitstream) {
  uint8_t *raw_data = NULL;

  try {
	  // Read the input file and put it in memory
	  long start_pos = io->tell_proc(handle);
	  io->seek_proc(handle, 0, SEEK_END);
	  size_t file_length = (size_t)(io->tell_proc(handle) - start_pos);
	  io->seek_proc(handle, start_pos, SEEK_SET);
	  raw_data = (uint8_t*)malloc(file_length * sizeof(uint8_t));
	  if(!raw_data) {
		  throw FI_MSG_ERROR_MEMORY;
	  }
	  if(io->read_proc(raw_data, 1, (unsigned)file_length, handle) != file_length) {
		  throw "Error while reading input stream";
	  }
	  
	  // copy pointers (must be released later using free)
	  bitstream->bytes = raw_data;
	  bitstream->size = file_length;

	  return TRUE;

  } catch(const char *text) {
	  if(raw_data) {
		  free(raw_data);
	  }
	  memset(bitstream, 0, sizeof(WebPData));
	  if(NULL != text) {
		  FreeImage_OutputMessageProc(s_format_id, text);

src/Source/FreeImage/PluginXBM.cpp  view on Meta::CPAN

@param heightP (return value) Pointer to the bitmap height
@param dataP (return value) Pointer to the bitmap buffer
@return Returns NULL if OK, returns an error message otherwise
*/
static const char* 
readXBMFile(FreeImageIO *io, fi_handle handle, int *widthP, int *heightP, char **dataP) {
	char line[MAX_LINE], name_and_type[MAX_LINE];
	char* ptr;
	char* t;
	int version = 0;
	int raster_length, v;
	int bytes, bytes_per_line, padding;
	int c1, c2, value1, value2;
	int hex_table[256];
	BOOL found_declaration;
	/* in scanning through the bitmap file, we have found the first
	 line of the C declaration of the array (the "static char ..."
	 or whatever line)
	 */
	BOOL eof;	// we've encountered end of file while searching file

src/Source/FreeImage/PluginXBM.cpp  view on Meta::CPAN

		return( ERR_XBM_WIDTH );
	if( *heightP == -1 )
		return( ERR_XBM_HEIGHT );

	padding = 0;
	if ( ((*widthP % 16) >= 1) && ((*widthP % 16) <= 8) && (version == 10) )
		padding = 1;

	bytes_per_line = (*widthP + 7) / 8 + padding;

	raster_length =  bytes_per_line * *heightP;
	*dataP = (char*) malloc( raster_length );
	if ( *dataP == (char*) 0 )
		return( ERR_XBM_MEMORY );

	// initialize hex_table
	for ( c1 = 0; c1 < 256; c1++ ) {
		hex_table[c1] = 256;
	}
	hex_table['0'] = 0;
	hex_table['1'] = 1;
	hex_table['2'] = 2;

src/Source/FreeImage/PluginXBM.cpp  view on Meta::CPAN

	hex_table['E'] = 14;
	hex_table['F'] = 15;
	hex_table['a'] = 10;
	hex_table['b'] = 11;
	hex_table['c'] = 12;
	hex_table['d'] = 13;
	hex_table['e'] = 14;
	hex_table['f'] = 15;

	if(version == 10) {
		for( bytes = 0, ptr = *dataP; bytes < raster_length; bytes += 2 ) {
			while( ( c1 = readChar(io, handle) ) != 'x' ) {
				if ( c1 == EOF )
					return( ERR_XBM_EOFREAD );
			}

			c1 = readChar(io, handle);
			c2 = readChar(io, handle);
			if( c1 == EOF || c2 == EOF )
				return( ERR_XBM_EOFREAD );
			value1 = ( hex_table[c1] << 4 ) + hex_table[c2];

src/Source/FreeImage/PluginXBM.cpp  view on Meta::CPAN

				return( ERR_XBM_EOFREAD );
			value2 = ( hex_table[c1] << 4 ) + hex_table[c2];
			if ( value2 >= 256 )
				return( ERR_XBM_SYNTAX );
			*ptr++ = (char)value2;
			if ( ( ! padding ) || ( ( bytes + 2 ) % bytes_per_line ) )
				*ptr++ = (char)value1;
		}
	}
	else {
		for(bytes = 0, ptr = *dataP; bytes < raster_length; bytes++ ) {
			/*
			** skip until digit is found
			*/
			for( ; ; ) {
				c1 = readChar(io, handle);
				if ( c1 == EOF )
					return( ERR_XBM_EOFREAD );
				value1 = hex_table[c1];
				if ( value1 != 256 )
					break;



( run in 1.271 second using v1.01-cache-2.11-cpan-49f99fa48dc )