Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
if(key.size() == 0) {
key = (char*)buffer;
pos = 0;
memset(buffer, 0, mLength * sizeof(BYTE));
} else {
break;
}
}
}
value = (char*)buffer;
free(buffer);
key_value_pair[key] = value;
return TRUE;
}
// --------------------------------------------------------------------------
/**
Load a FIBITMAP from a MNG or a JNG stream
@param format_id ID of the caller
@param io Stream i/o functions
@param handle Stream handle
@param Offset Start of the first chunk
@param flags Loading flags
@return Returns a dib if successful, returns NULL otherwise
*/
FIBITMAP*
mng_ReadChunks(int format_id, FreeImageIO *io, fi_handle handle, long Offset, int flags = 0) {
DWORD mLength = 0;
BYTE mChunkName[5];
BYTE *mChunk = NULL;
DWORD crc_file;
long LastOffset;
long mOrigPos;
BYTE *PLTE_file_chunk = NULL; // whole PLTE chunk (lentgh, name, array, crc)
DWORD PLTE_file_size = 0; // size of PLTE chunk
BOOL m_HasGlobalPalette = FALSE; // may turn to TRUE in PLTE chunk
unsigned m_TotalBytesOfChunks = 0;
FIBITMAP *dib = NULL;
FIBITMAP *dib_alpha = NULL;
FIMEMORY *hJpegMemory = NULL;
FIMEMORY *hPngMemory = NULL;
FIMEMORY *hIDATMemory = NULL;
// ---
DWORD jng_width = 0;
DWORD jng_height = 0;
BYTE jng_color_type = 0;
BYTE jng_image_sample_depth = 0;
BYTE jng_image_compression_method = 0;
BYTE jng_alpha_sample_depth = 0;
BYTE jng_alpha_compression_method = 0;
BYTE jng_alpha_filter_method = 0;
BYTE jng_alpha_interlace_method = 0;
DWORD mng_frame_width = 0;
DWORD mng_frame_height = 0;
DWORD mng_ticks_per_second = 0;
DWORD mng_nominal_layer_count = 0;
DWORD mng_nominal_frame_count = 0;
DWORD mng_nominal_play_time = 0;
DWORD mng_simplicity_profile = 0;
DWORD res_x = 2835; // 72 dpi
DWORD res_y = 2835; // 72 dpi
RGBQUAD rgbBkColor = {0, 0, 0, 0};
WORD bk_red, bk_green, bk_blue;
BOOL hasBkColor = FALSE;
BOOL mHasIDAT = FALSE;
tEXtMAP key_value_pair;
// ---
BOOL header_only = (flags & FIF_LOAD_NOPIXELS) == FIF_LOAD_NOPIXELS;
// get the file size
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) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
throw (const char*)NULL;
}
Offset = io->tell_proc(handle);
if(Offset + (long)mLength > mLOF) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: unexpected end of file", mChunkName);
throw (const char*)NULL;
}
// read chunk
io->read_proc(mChunk, 1, mLength, handle);
}
// read crc
io->read_proc(&crc_file, 1, sizeof(crc_file), handle);
mng_SwapLong(&crc_file);
// check crc
DWORD crc_check = FreeImage_ZLibCRC32(0, &mChunkName[0], 4);
crc_check = FreeImage_ZLibCRC32(crc_check, mChunk, mLength);
if(crc_check != crc_file) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: bad CRC", mChunkName);
throw (const char*)NULL;
}
switch( mng_GetChunckType(mChunkName) ) {
case MHDR:
// The MHDR chunk is always first in all MNG datastreams except for those
// that consist of a single PNG or JNG datastream with a PNG or JNG signature.
if(mLength == 28) {
memcpy(&mng_frame_width, &mChunk[0], 4);
memcpy(&mng_frame_height, &mChunk[4], 4);
memcpy(&mng_ticks_per_second, &mChunk[8], 4);
memcpy(&mng_nominal_layer_count, &mChunk[12], 4);
memcpy(&mng_nominal_frame_count, &mChunk[16], 4);
memcpy(&mng_nominal_play_time, &mChunk[20], 4);
memcpy(&mng_simplicity_profile, &mChunk[24], 4);
mng_SwapLong(&mng_frame_width);
mng_SwapLong(&mng_frame_height);
mng_SwapLong(&mng_ticks_per_second);
mng_SwapLong(&mng_nominal_layer_count);
mng_SwapLong(&mng_nominal_frame_count);
mng_SwapLong(&mng_nominal_play_time);
mng_SwapLong(&mng_simplicity_profile);
} else {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: size is %d instead of 28", mChunkName, mLength);
}
break;
case MEND:
mEnd = TRUE;
break;
case LOOP:
case ENDL:
break;
case DEFI:
break;
case SAVE:
case SEEK:
case TERM:
break;
case BACK:
break;
// Global "PLTE" and "tRNS" (if any). PNG "PLTE" will be of 0 byte, as it uses global data.
case PLTE: // Global
m_HasGlobalPalette = TRUE;
PLTE_file_size = mLength + 12; // (lentgh, name, array, crc) = (4, 4, mLength, 4)
PLTE_file_chunk = (BYTE*)realloc(PLTE_file_chunk, PLTE_file_size);
if(!PLTE_file_chunk) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
throw (const char*)NULL;
} else {
mOrigPos = io->tell_proc(handle);
// seek to the start of the chunk
io->seek_proc(handle, LastOffset, SEEK_SET);
// load the whole chunk
io->read_proc(PLTE_file_chunk, 1, PLTE_file_size, handle);
// go to the start of the next chunk
io->seek_proc(handle, mOrigPos, SEEK_SET);
}
break;
case tRNS: // Global
break;
case IHDR:
Offset = LastOffset;
// parse the PNG file and get its file size
if(mng_CountPNGChunks(io, handle, Offset, &m_TotalBytesOfChunks) == FALSE) {
// reach an unexpected end of file
mEnd = TRUE;
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: unexpected end of PNG file", mChunkName);
break;
}
// wrap the { IHDR, ..., IEND } chunks as a PNG stream
if(hPngMemory == NULL) {
hPngMemory = FreeImage_OpenMemory();
}
( run in 0.978 second using v1.01-cache-2.11-cpan-df04353d9ac )