Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/FreeImage/MNGHelper.cpp view on Meta::CPAN
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();
}
mOrigPos = io->tell_proc(handle);
// write PNG file signature
FreeImage_SeekMemory(hPngMemory, 0, SEEK_SET);
FreeImage_WriteMemory(g_png_signature, 1, 8, hPngMemory);
mChunk = (BYTE*)realloc(mChunk, m_TotalBytesOfChunks);
if(!mChunk) {
FreeImage_OutputMessageProc(format_id, "Error while parsing %s chunk: out of memory", mChunkName);
throw (const char*)NULL;
}
// on calling CountPNGChunks earlier, we were in Offset pos,
// go back there
io->seek_proc(handle, Offset, SEEK_SET);
io->read_proc(mChunk, 1, m_TotalBytesOfChunks, handle);
// Put back to original pos
io->seek_proc(handle, mOrigPos, SEEK_SET);
// write the PNG chunks
FreeImage_WriteMemory(mChunk, 1, m_TotalBytesOfChunks, hPngMemory);
// plug in global PLTE if local PLTE exists
if(m_HasGlobalPalette) {
// ensure we remove some local chunks, so that global
// "PLTE" can be inserted right before "IDAT".
mng_RemoveChunk(hPngMemory, mng_PLTE);
mng_RemoveChunk(hPngMemory, mng_tRNS);
mng_RemoveChunk(hPngMemory, mng_bKGD);
// insert global "PLTE" chunk in its entirety before "IDAT"
mng_InsertChunk(hPngMemory, mng_IDAT, PLTE_file_chunk, PLTE_file_size);
}
if(dib) FreeImage_Unload(dib);
dib = mng_LoadFromMemoryHandle(hPngMemory, flags);
// stop after the first image
mEnd = TRUE;
break;
case JHDR:
if(mLength == 16) {
memcpy(&jng_width, &mChunk[0], 4);
memcpy(&jng_height, &mChunk[4], 4);
mng_SwapLong(&jng_width);
mng_SwapLong(&jng_height);
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);
break;
case IDAT:
if(!header_only && (jng_alpha_compression_method == 0)) {
// PNG grayscale IDAT format
if(hIDATMemory == NULL) {
hIDATMemory = FreeImage_OpenMemory();
mHasIDAT = TRUE;
}
// as there may be several IDAT chunks, concatenate them
FreeImage_WriteMemory(mChunk, 1, mLength, hIDATMemory);
}
break;
case IEND:
if(!hJpegMemory) {
mEnd = TRUE;
break;
}
// load the JPEG
if(dib) {
FreeImage_Unload(dib);
( run in 0.541 second using v1.01-cache-2.11-cpan-0bd6704ced7 )