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 )