| /** ************************************************************************* */ |
| /* * For conditions of distribution and use, * */ |
| /* * see copyright notice in libmng.h * */ |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * project : libmng * */ |
| /* * file : libmng_chunk_io.c copyright (c) 2000-2007 G.Juyn * */ |
| /* * version : 1.0.10 * */ |
| /* * * */ |
| /* * purpose : Chunk I/O routines (implementation) * */ |
| /* * * */ |
| /* * author : G.Juyn * */ |
| /* * * */ |
| /* * comment : implementation of chunk input/output routines * */ |
| /* * * */ |
| /* * changes : 0.5.1 - 05/01/2000 - G.Juyn * */ |
| /* * - cleaned up left-over teststuff in the BACK chunk routine * */ |
| /* * 0.5.1 - 05/04/2000 - G.Juyn * */ |
| /* * - changed CRC initialization to use dynamic structure * */ |
| /* * (wasn't thread-safe the old way !) * */ |
| /* * 0.5.1 - 05/06/2000 - G.Juyn * */ |
| /* * - filled in many missing sequence&length checks * */ |
| /* * - filled in many missing chunk-store snippets * */ |
| /* * 0.5.1 - 05/08/2000 - G.Juyn * */ |
| /* * - added checks for running animations * */ |
| /* * - filled some write routines * */ |
| /* * - changed strict-ANSI stuff * */ |
| /* * 0.5.1 - 05/10/2000 - G.Juyn * */ |
| /* * - filled some more write routines * */ |
| /* * 0.5.1 - 05/11/2000 - G.Juyn * */ |
| /* * - filled remaining write routines * */ |
| /* * - fixed read_pplt with regard to deltatype * */ |
| /* * - added callback error-reporting support * */ |
| /* * - added pre-draft48 support (short MHDR, frame_mode, LOOP) * */ |
| /* * 0.5.1 - 05/12/2000 - G.Juyn * */ |
| /* * - changed trace to macro for callback error-reporting * */ |
| /* * - fixed chunk-storage bit in several routines * */ |
| /* * 0.5.1 - 05/13/2000 - G.Juyn * */ |
| /* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */ |
| /* * - added TERM animation object pointer (easier reference) * */ |
| /* * - supplemented the SAVE & SEEK display processing * */ |
| /* * * */ |
| /* * 0.5.2 - 05/18/2000 - G.Juyn * */ |
| /* * - B004 - fixed problem with MNG_SUPPORT_WRITE not defined * */ |
| /* * also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG * */ |
| /* * 0.5.2 - 05/19/2000 - G.Juyn * */ |
| /* * - cleaned up some code regarding mixed support * */ |
| /* * 0.5.2 - 05/20/2000 - G.Juyn * */ |
| /* * - implemented JNG support * */ |
| /* * 0.5.2 - 05/24/2000 - G.Juyn * */ |
| /* * - added support for global color-chunks in animation * */ |
| /* * - added support for global PLTE,tRNS,bKGD in animation * */ |
| /* * - added support for SAVE & SEEK in animation * */ |
| /* * 0.5.2 - 05/29/2000 - G.Juyn * */ |
| /* * - changed ani_create calls not returning object pointer * */ |
| /* * - create ani objects always (not just inside TERM/LOOP) * */ |
| /* * 0.5.2 - 05/30/2000 - G.Juyn * */ |
| /* * - added support for delta-image processing * */ |
| /* * 0.5.2 - 05/31/2000 - G.Juyn * */ |
| /* * - fixed up punctuation (contributed by Tim Rowley) * */ |
| /* * 0.5.2 - 06/02/2000 - G.Juyn * */ |
| /* * - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED * */ |
| /* * 0.5.2 - 06/03/2000 - G.Juyn * */ |
| /* * - fixed makeup for Linux gcc compile * */ |
| /* * * */ |
| /* * 0.5.3 - 06/12/2000 - G.Juyn * */ |
| /* * - added processing of color-info on delta-image * */ |
| /* * 0.5.3 - 06/13/2000 - G.Juyn * */ |
| /* * - fixed handling of empty SAVE chunk * */ |
| /* * 0.5.3 - 06/17/2000 - G.Juyn * */ |
| /* * - changed to support delta-images * */ |
| /* * - added extra checks for delta-images * */ |
| /* * 0.5.3 - 06/20/2000 - G.Juyn * */ |
| /* * - fixed possible trouble if IEND display-process got * */ |
| /* * broken up * */ |
| /* * 0.5.3 - 06/21/2000 - G.Juyn * */ |
| /* * - added processing of PLTE & tRNS for delta-images * */ |
| /* * - added administration of imagelevel parameter * */ |
| /* * 0.5.3 - 06/22/2000 - G.Juyn * */ |
| /* * - implemented support for PPLT chunk * */ |
| /* * 0.5.3 - 06/26/2000 - G.Juyn * */ |
| /* * - added precaution against faulty iCCP chunks from PS * */ |
| /* * 0.5.3 - 06/29/2000 - G.Juyn * */ |
| /* * - fixed some 64-bit warnings * */ |
| /* * * */ |
| /* * 0.9.1 - 07/14/2000 - G.Juyn * */ |
| /* * - changed pre-draft48 frame_mode=3 to frame_mode=1 * */ |
| /* * 0.9.1 - 07/16/2000 - G.Juyn * */ |
| /* * - fixed storage of images during mng_read() * */ |
| /* * - fixed support for mng_display() after mng_read() * */ |
| /* * 0.9.1 - 07/19/2000 - G.Juyn * */ |
| /* * - fixed several chunk-writing routines * */ |
| /* * 0.9.1 - 07/24/2000 - G.Juyn * */ |
| /* * - fixed reading of still-images * */ |
| /* * * */ |
| /* * 0.9.2 - 08/05/2000 - G.Juyn * */ |
| /* * - changed file-prefixes * */ |
| /* * * */ |
| /* * 0.9.3 - 08/07/2000 - G.Juyn * */ |
| /* * - B111300 - fixup for improved portability * */ |
| /* * 0.9.3 - 08/08/2000 - G.Juyn * */ |
| /* * - fixed compiler-warnings from Mozilla * */ |
| /* * 0.9.3 - 08/09/2000 - G.Juyn * */ |
| /* * - added check for simplicity-bits in MHDR * */ |
| /* * 0.9.3 - 08/12/2000 - G.Juyn * */ |
| /* * - fixed check for simplicity-bits in MHDR (JNG) * */ |
| /* * 0.9.3 - 08/12/2000 - G.Juyn * */ |
| /* * - added workaround for faulty PhotoShop iCCP chunk * */ |
| /* * 0.9.3 - 08/22/2000 - G.Juyn * */ |
| /* * - fixed write-code for zTXt & iTXt * */ |
| /* * - fixed read-code for iTXt * */ |
| /* * 0.9.3 - 08/26/2000 - G.Juyn * */ |
| /* * - added MAGN chunk * */ |
| /* * 0.9.3 - 09/07/2000 - G.Juyn * */ |
| /* * - added support for new filter_types * */ |
| /* * 0.9.3 - 09/10/2000 - G.Juyn * */ |
| /* * - fixed DEFI behavior * */ |
| /* * 0.9.3 - 10/02/2000 - G.Juyn * */ |
| /* * - fixed simplicity-check in compliance with draft 81/0.98a * */ |
| /* * 0.9.3 - 10/10/2000 - G.Juyn * */ |
| /* * - added support for alpha-depth prediction * */ |
| /* * 0.9.3 - 10/11/2000 - G.Juyn * */ |
| /* * - added support for nEED * */ |
| /* * 0.9.3 - 10/16/2000 - G.Juyn * */ |
| /* * - added support for JDAA * */ |
| /* * 0.9.3 - 10/17/2000 - G.Juyn * */ |
| /* * - fixed support for MAGN * */ |
| /* * - implemented nEED "xxxx" (where "xxxx" is a chunkid) * */ |
| /* * - added callback to process non-critical unknown chunks * */ |
| /* * - fixed support for bKGD * */ |
| /* * 0.9.3 - 10/23/2000 - G.Juyn * */ |
| /* * - fixed bug in empty PLTE handling * */ |
| /* * * */ |
| /* * 0.9.4 - 11/20/2000 - G.Juyn * */ |
| /* * - changed IHDR filter_method check for PNGs * */ |
| /* * 0.9.4 - 1/18/2001 - G.Juyn * */ |
| /* * - added errorchecking for MAGN methods * */ |
| /* * - removed test filter-methods 1 & 65 * */ |
| /* * * */ |
| /* * 0.9.5 - 1/25/2001 - G.Juyn * */ |
| /* * - fixed some small compiler warnings (thanks Nikki) * */ |
| /* * * */ |
| /* * 1.0.2 - 05/05/2000 - G.Juyn * */ |
| /* * - B421427 - writes wrong format in bKGD and tRNS * */ |
| /* * 1.0.2 - 06/20/2000 - G.Juyn * */ |
| /* * - B434583 - compiler-warning if MNG_STORE_CHUNKS undefined * */ |
| /* * * */ |
| /* * 1.0.5 - 07/08/2002 - G.Juyn * */ |
| /* * - B578572 - removed eMNGma hack (thanks Dimitri!) * */ |
| /* * 1.0.5 - 08/07/2002 - G.Juyn * */ |
| /* * - added test-option for PNG filter method 193 (=no filter) * */ |
| /* * 1.0.5 - 08/15/2002 - G.Juyn * */ |
| /* * - completed PROM support * */ |
| /* * 1.0.5 - 08/19/2002 - G.Juyn * */ |
| /* * - B597134 - libmng pollutes the linker namespace * */ |
| /* * 1.0.5 - 09/07/2002 - G.Juyn * */ |
| /* * - fixed reading of FRAM with just frame_mode and name * */ |
| /* * 1.0.5 - 09/13/2002 - G.Juyn * */ |
| /* * - fixed read/write of MAGN chunk * */ |
| /* * 1.0.5 - 09/14/2002 - G.Juyn * */ |
| /* * - added event handling for dynamic MNG * */ |
| /* * 1.0.5 - 09/15/2002 - G.Juyn * */ |
| /* * - fixed LOOP iteration=0 special case * */ |
| /* * 1.0.5 - 09/19/2002 - G.Juyn * */ |
| /* * - misplaced TERM is now treated as warning * */ |
| /* * 1.0.5 - 09/20/2002 - G.Juyn * */ |
| /* * - added support for PAST * */ |
| /* * 1.0.5 - 10/03/2002 - G.Juyn * */ |
| /* * - fixed chunk-storage for evNT chunk * */ |
| /* * 1.0.5 - 10/07/2002 - G.Juyn * */ |
| /* * - fixed DISC support * */ |
| /* * - added another fix for misplaced TERM chunk * */ |
| /* * 1.0.5 - 10/17/2002 - G.Juyn * */ |
| /* * - fixed initializtion of pIds in dISC read routine * */ |
| /* * 1.0.5 - 11/06/2002 - G.Juyn * */ |
| /* * - added support for nEED "MNG 1.1" * */ |
| /* * - added support for nEED "CACHEOFF" * */ |
| /* * * */ |
| /* * 1.0.6 - 05/25/2003 - G.R-P * */ |
| /* * - added MNG_SKIPCHUNK_cHNK footprint optimizations * */ |
| /* * 1.0.6 - 06/02/2003 - G.R-P * */ |
| /* * - removed some redundant checks for iRawlen==0 * */ |
| /* * 1.0.6 - 06/22/2003 - G.R-P * */ |
| /* * - added MNG_NO_16BIT_SUPPORT, MNG_NO_DELTA_PNG reductions * */ |
| /* * - optionally use zlib's crc32 function instead of * */ |
| /* * local mng_update_crc * */ |
| /* * 1.0.6 - 07/14/2003 - G.R-P * */ |
| /* * - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional * */ |
| /* * 1.0.6 - 07/29/2003 - G.R-P * */ |
| /* * - added conditionals around PAST chunk support * */ |
| /* * 1.0.6 - 08/17/2003 - G.R-P * */ |
| /* * - added conditionals around non-VLC chunk support * */ |
| /* * * */ |
| /* * 1.0.7 - 10/29/2003 - G.R-P * */ |
| /* * - revised JDAA and JDAT readers to avoid compiler bug * */ |
| /* * 1.0.7 - 01/25/2004 - J.S * */ |
| /* * - added premultiplied alpha canvas' for RGBA, ARGB, ABGR * */ |
| /* * 1.0.7 - 01/27/2004 - J.S * */ |
| /* * - fixed inclusion of IJNG chunk for non-JNG use * */ |
| /* * 1.0.7 - 02/26/2004 - G.Juyn * */ |
| /* * - fixed bug in chunk-storage of SHOW chunk (from == to) * */ |
| /* * * */ |
| /* * 1.0.8 - 04/02/2004 - G.Juyn * */ |
| /* * - added CRC existence & checking flags * */ |
| /* * 1.0.8 - 07/07/2004 - G.R-P * */ |
| /* * - change worst-case iAlphadepth to 1 for standalone PNGs * */ |
| /* * * */ |
| /* * 1.0.9 - 09/28/2004 - G.R-P * */ |
| /* * - improved handling of cheap transparency when 16-bit * */ |
| /* * support is disabled * */ |
| /* * 1.0.9 - 10/04/2004 - G.Juyn * */ |
| /* * - fixed bug in writing sBIT for indexed color * */ |
| /* * 1.0.9 - 10/10/2004 - G.R-P. * */ |
| /* * - added MNG_NO_1_2_4BIT_SUPPORT * */ |
| /* * 1.0.9 - 12/05/2004 - G.Juyn * */ |
| /* * - added conditional MNG_OPTIMIZE_CHUNKINITFREE * */ |
| /* * 1.0.9 - 12/06/2004 - G.Juyn * */ |
| /* * - added conditional MNG_OPTIMIZE_CHUNKASSIGN * */ |
| /* * 1.0.9 - 12/07/2004 - G.Juyn * */ |
| /* * - added conditional MNG_OPTIMIZE_CHUNKREADER * */ |
| /* * 1.0.9 - 12/11/2004 - G.Juyn * */ |
| /* * - added conditional MNG_OPTIMIZE_DISPLAYCALLS * */ |
| /* * 1.0.9 - 12/20/2004 - G.Juyn * */ |
| /* * - cleaned up macro-invocations (thanks to D. Airlie) * */ |
| /* * 1.0.9 - 01/17/2005 - G.Juyn * */ |
| /* * - fixed problem with global PLTE/tRNS * */ |
| /* * * */ |
| /* * 1.0.10 - 02/07/2005 - G.Juyn * */ |
| /* * - fixed display routines called twice for FULL_MNG * */ |
| /* * support in mozlibmngconf.h * */ |
| /* * 1.0.10 - 12/04/2005 - G.R-P. * */ |
| /* * - #ifdef out use of mng_inflate_buffer when it is not * */ |
| /* * available. * */ |
| /* * 1.0.10 - 04/08/2007 - G.Juyn * */ |
| /* * - added support for mPNG proposal * */ |
| /* * 1.0.10 - 04/12/2007 - G.Juyn * */ |
| /* * - added support for ANG proposal * */ |
| /* * 1.0.10 - 05/02/2007 - G.Juyn * */ |
| /* * - fixed inflate_buffer for extreme compression ratios * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| #include "libmng.h" |
| #include "libmng_data.h" |
| #include "libmng_error.h" |
| #include "libmng_trace.h" |
| #ifdef __BORLANDC__ |
| #pragma hdrstop |
| #endif |
| #include "libmng_objects.h" |
| #include "libmng_object_prc.h" |
| #include "libmng_chunks.h" |
| #ifdef MNG_CHECK_BAD_ICCP |
| #include "libmng_chunk_prc.h" |
| #endif |
| #include "libmng_memory.h" |
| #include "libmng_display.h" |
| #include "libmng_zlib.h" |
| #include "libmng_pixels.h" |
| #include "libmng_chunk_io.h" |
| |
| #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI) |
| #pragma option -A /* force ANSI-C */ |
| #endif |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * CRC - Cyclic Redundancy Check * */ |
| /* * * */ |
| /* * The code below is taken directly from the sample provided with the * */ |
| /* * PNG specification. * */ |
| /* * (it is only adapted to the library's internal data-definitions) * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| /* Make the table for a fast CRC. */ |
| #ifndef MNG_USE_ZLIB_CRC |
| MNG_LOCAL void make_crc_table (mng_datap pData) |
| { |
| mng_uint32 iC; |
| mng_int32 iN, iK; |
| |
| for (iN = 0; iN < 256; iN++) |
| { |
| iC = (mng_uint32) iN; |
| |
| for (iK = 0; iK < 8; iK++) |
| { |
| if (iC & 1) |
| iC = 0xedb88320U ^ (iC >> 1); |
| else |
| iC = iC >> 1; |
| } |
| |
| pData->aCRCtable [iN] = iC; |
| } |
| |
| pData->bCRCcomputed = MNG_TRUE; |
| } |
| #endif |
| |
| /* Update a running CRC with the bytes buf[0..len-1]--the CRC |
| should be initialized to all 1's, and the transmitted value |
| is the 1's complement of the final running CRC (see the |
| crc() routine below). */ |
| |
| MNG_LOCAL mng_uint32 update_crc (mng_datap pData, |
| mng_uint32 iCrc, |
| mng_uint8p pBuf, |
| mng_int32 iLen) |
| { |
| #ifdef MNG_USE_ZLIB_CRC |
| return crc32 (iCrc, pBuf, iLen); |
| #else |
| mng_uint32 iC = iCrc; |
| mng_int32 iN; |
| |
| if (!pData->bCRCcomputed) |
| make_crc_table (pData); |
| |
| for (iN = 0; iN < iLen; iN++) |
| iC = pData->aCRCtable [(iC ^ pBuf [iN]) & 0xff] ^ (iC >> 8); |
| |
| return iC; |
| #endif |
| } |
| |
| /* Return the CRC of the bytes buf[0..len-1]. */ |
| mng_uint32 mng_crc (mng_datap pData, |
| mng_uint8p pBuf, |
| mng_int32 iLen) |
| { |
| #ifdef MNG_USE_ZLIB_CRC |
| return update_crc (pData, 0, pBuf, iLen); |
| #else |
| return update_crc (pData, 0xffffffffU, pBuf, iLen) ^ 0xffffffffU; |
| #endif |
| } |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Routines for swapping byte-order from and to graphic files * */ |
| /* * (This code is adapted from the libpng package) * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_BIGENDIAN_SUPPORTED |
| |
| /* ************************************************************************** */ |
| |
| mng_uint32 mng_get_uint32 (mng_uint8p pBuf) |
| { |
| mng_uint32 i = ((mng_uint32)(*pBuf) << 24) + |
| ((mng_uint32)(*(pBuf + 1)) << 16) + |
| ((mng_uint32)(*(pBuf + 2)) << 8) + |
| (mng_uint32)(*(pBuf + 3)); |
| return (i); |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_int32 mng_get_int32 (mng_uint8p pBuf) |
| { |
| mng_int32 i = ((mng_int32)(*pBuf) << 24) + |
| ((mng_int32)(*(pBuf + 1)) << 16) + |
| ((mng_int32)(*(pBuf + 2)) << 8) + |
| (mng_int32)(*(pBuf + 3)); |
| return (i); |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_uint16 mng_get_uint16 (mng_uint8p pBuf) |
| { |
| mng_uint16 i = (mng_uint16)(((mng_uint16)(*pBuf) << 8) + |
| (mng_uint16)(*(pBuf + 1))); |
| return (i); |
| } |
| |
| /* ************************************************************************** */ |
| |
| void mng_put_uint32 (mng_uint8p pBuf, |
| mng_uint32 i) |
| { |
| *pBuf = (mng_uint8)((i >> 24) & 0xff); |
| *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff); |
| *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff); |
| *(pBuf+3) = (mng_uint8)(i & 0xff); |
| } |
| |
| /* ************************************************************************** */ |
| |
| void mng_put_int32 (mng_uint8p pBuf, |
| mng_int32 i) |
| { |
| *pBuf = (mng_uint8)((i >> 24) & 0xff); |
| *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff); |
| *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff); |
| *(pBuf+3) = (mng_uint8)(i & 0xff); |
| } |
| |
| /* ************************************************************************** */ |
| |
| void mng_put_uint16 (mng_uint8p pBuf, |
| mng_uint16 i) |
| { |
| *pBuf = (mng_uint8)((i >> 8) & 0xff); |
| *(pBuf+1) = (mng_uint8)(i & 0xff); |
| } |
| |
| /* ************************************************************************** */ |
| |
| #endif /* !MNG_BIGENDIAN_SUPPORTED */ |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Helper routines to simplify chunk-data extraction * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_READ_PROCS |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| MNG_LOCAL mng_uint8p find_null (mng_uint8p pIn) |
| { |
| mng_uint8p pOut = pIn; |
| while (*pOut) /* the read_graphic routine has made sure there's */ |
| pOut++; /* always at least 1 zero-byte in the buffer */ |
| return pOut; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \ |
| !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \ |
| defined(MNG_INCLUDE_ANG_PROPOSAL) |
| mng_retcode mng_inflate_buffer (mng_datap pData, |
| mng_uint8p pInbuf, |
| mng_uint32 iInsize, |
| mng_uint8p *pOutbuf, |
| mng_uint32 *iOutsize, |
| mng_uint32 *iRealsize) |
| { |
| mng_retcode iRetcode = MNG_NOERROR; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_START); |
| #endif |
| |
| if (iInsize) /* anything to do ? */ |
| { |
| *iOutsize = iInsize * 3; /* estimate uncompressed size */ |
| /* and allocate a temporary buffer */ |
| MNG_ALLOC (pData, *pOutbuf, *iOutsize); |
| |
| do |
| { |
| mngzlib_inflateinit (pData); /* initialize zlib */ |
| /* let zlib know where to store the output */ |
| pData->sZlib.next_out = *pOutbuf; |
| /* "size - 1" so we've got space for the |
| zero-termination of a possible string */ |
| pData->sZlib.avail_out = *iOutsize - 1; |
| /* ok; let's inflate... */ |
| iRetcode = mngzlib_inflatedata (pData, iInsize, pInbuf); |
| /* determine actual output size */ |
| *iRealsize = (mng_uint32)pData->sZlib.total_out; |
| |
| mngzlib_inflatefree (pData); /* zlib's done */ |
| |
| if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */ |
| { /* then get some more */ |
| MNG_FREEX (pData, *pOutbuf, *iOutsize); |
| *iOutsize = *iOutsize + *iOutsize; |
| MNG_ALLOC (pData, *pOutbuf, *iOutsize); |
| } |
| } /* repeat if we didn't have enough space */ |
| while ((iRetcode == MNG_BUFOVERFLOW) && |
| (*iOutsize < 200 * iInsize)); |
| |
| if (!iRetcode) /* if oke ? */ |
| *((*pOutbuf) + *iRealsize) = 0; /* then put terminator zero */ |
| |
| } |
| else |
| { |
| *pOutbuf = 0; /* nothing to do; then there's no output */ |
| *iOutsize = 0; |
| *iRealsize = 0; |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #endif /* MNG_INCLUDE_READ_PROCS */ |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Helper routines to simplify chunk writing * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| #ifdef MNG_INCLUDE_WRITE_PROCS |
| /* ************************************************************************** */ |
| |
| #if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || !defined(MNG_SKIPCHUNK_iTXt) |
| MNG_LOCAL mng_retcode deflate_buffer (mng_datap pData, |
| mng_uint8p pInbuf, |
| mng_uint32 iInsize, |
| mng_uint8p *pOutbuf, |
| mng_uint32 *iOutsize, |
| mng_uint32 *iRealsize) |
| { |
| mng_retcode iRetcode = MNG_NOERROR; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_START); |
| #endif |
| |
| if (iInsize) /* anything to do ? */ |
| { |
| *iOutsize = (iInsize * 5) >> 2; /* estimate compressed size */ |
| /* and allocate a temporary buffer */ |
| MNG_ALLOC (pData, *pOutbuf, *iOutsize); |
| |
| do |
| { |
| mngzlib_deflateinit (pData); /* initialize zlib */ |
| /* let zlib know where to store the output */ |
| pData->sZlib.next_out = *pOutbuf; |
| pData->sZlib.avail_out = *iOutsize; |
| /* ok; let's deflate... */ |
| iRetcode = mngzlib_deflatedata (pData, iInsize, pInbuf); |
| /* determine actual output size */ |
| *iRealsize = pData->sZlib.total_out; |
| |
| mngzlib_deflatefree (pData); /* zlib's done */ |
| |
| if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */ |
| { /* then get some more */ |
| MNG_FREEX (pData, *pOutbuf, *iOutsize); |
| *iOutsize = *iOutsize + (iInsize >> 1); |
| MNG_ALLOC (pData, *pOutbuf, *iOutsize); |
| } |
| } /* repeat if we didn't have enough space */ |
| while (iRetcode == MNG_BUFOVERFLOW); |
| } |
| else |
| { |
| *pOutbuf = 0; /* nothing to do; then there's no output */ |
| *iOutsize = 0; |
| *iRealsize = 0; |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| MNG_LOCAL mng_retcode write_raw_chunk (mng_datap pData, |
| mng_chunkid iChunkname, |
| mng_uint32 iRawlen, |
| mng_uint8p pRawdata) |
| { |
| mng_uint32 iCrc; |
| mng_uint32 iWritten; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_START); |
| #endif |
| /* temporary buffer ? */ |
| if ((pRawdata != 0) && (pRawdata != pData->pWritebuf+8)) |
| { /* store length & chunktype in default buffer */ |
| mng_put_uint32 (pData->pWritebuf, iRawlen); |
| mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname); |
| |
| if (pData->iCrcmode & MNG_CRC_OUTPUT) |
| { |
| if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE) |
| { /* calculate the crc */ |
| iCrc = update_crc (pData, 0xffffffffL, pData->pWritebuf+4, 4); |
| iCrc = update_crc (pData, iCrc, pRawdata, iRawlen) ^ 0xffffffffL; |
| } else { |
| iCrc = 0; /* dummy crc */ |
| } /* store in default buffer */ |
| mng_put_uint32 (pData->pWritebuf+8, iCrc); |
| } |
| /* write the length & chunktype */ |
| if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten)) |
| MNG_ERROR (pData, MNG_APPIOERROR); |
| |
| if (iWritten != 8) /* disk full ? */ |
| MNG_ERROR (pData, MNG_OUTPUTERROR); |
| /* write the temporary buffer */ |
| if (!pData->fWritedata ((mng_handle)pData, pRawdata, iRawlen, &iWritten)) |
| MNG_ERROR (pData, MNG_APPIOERROR); |
| |
| if (iWritten != iRawlen) /* disk full ? */ |
| MNG_ERROR (pData, MNG_OUTPUTERROR); |
| |
| if (pData->iCrcmode & MNG_CRC_OUTPUT) |
| { /* write the crc */ |
| if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf+8, 4, &iWritten)) |
| MNG_ERROR (pData, MNG_APPIOERROR); |
| |
| if (iWritten != 4) /* disk full ? */ |
| MNG_ERROR (pData, MNG_OUTPUTERROR); |
| } |
| } |
| else |
| { /* prefix with length & chunktype */ |
| mng_put_uint32 (pData->pWritebuf, iRawlen); |
| mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname); |
| |
| if (pData->iCrcmode & MNG_CRC_OUTPUT) |
| { |
| if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE) |
| /* calculate the crc */ |
| iCrc = mng_crc (pData, pData->pWritebuf+4, iRawlen + 4); |
| else |
| iCrc = 0; /* dummy crc */ |
| /* add it to the buffer */ |
| mng_put_uint32 (pData->pWritebuf + iRawlen + 8, iCrc); |
| /* write it in a single pass */ |
| if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 12, &iWritten)) |
| MNG_ERROR (pData, MNG_APPIOERROR); |
| |
| if (iWritten != iRawlen + 12) /* disk full ? */ |
| MNG_ERROR (pData, MNG_OUTPUTERROR); |
| } else { |
| if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 8, &iWritten)) |
| MNG_ERROR (pData, MNG_APPIOERROR); |
| |
| if (iWritten != iRawlen + 8) /* disk full ? */ |
| MNG_ERROR (pData, MNG_OUTPUTERROR); |
| } |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| /* B004 */ |
| #endif /* MNG_INCLUDE_WRITE_PROCS */ |
| /* B004 */ |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * chunk read functions * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_READ_PROCS |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_OPTIMIZE_CHUNKREADER |
| |
| /* ************************************************************************** */ |
| |
| MNG_LOCAL mng_retcode create_chunk_storage (mng_datap pData, |
| mng_chunkp pHeader, |
| mng_uint32 iRawlen, |
| mng_uint8p pRawdata, |
| mng_field_descp pField, |
| mng_uint16 iFields, |
| mng_chunkp* ppChunk, |
| mng_bool bWorkcopy) |
| { |
| mng_field_descp pTempfield = pField; |
| mng_uint16 iFieldcount = iFields; |
| mng_uint8p pTempdata = pRawdata; |
| mng_uint32 iTemplen = iRawlen; |
| mng_uint16 iLastgroup = 0; |
| mng_uint8p pChunkdata; |
| mng_uint32 iDatalen; |
| mng_uint8 iColortype; |
| mng_bool bProcess; |
| /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| if (((mng_chunk_headerp)(*ppChunk))->iChunkname == MNG_UINT_HUH) |
| ((mng_chunk_headerp)(*ppChunk))->iChunkname = pData->iChunkname; |
| |
| if ((!bWorkcopy) || |
| ((((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_IDAT) && |
| (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAT) && |
| (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAA) )) |
| { |
| pChunkdata = (mng_uint8p)(*ppChunk); |
| |
| #ifdef MNG_INCLUDE_JNG /* determine current colortype */ |
| if (pData->bHasJHDR) |
| iColortype = (mng_uint8)(pData->iJHDRcolortype - 8); |
| else |
| #endif /* MNG_INCLUDE_JNG */ |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| iColortype = pData->iColortype; |
| else |
| iColortype = 6; |
| |
| if (iTemplen) /* not empty ? */ |
| { /* then go fill the fields */ |
| while ((iFieldcount) && (iTemplen)) |
| { |
| if (pTempfield->iOffsetchunk) |
| { |
| if (pTempfield->iFlags & MNG_FIELD_PUTIMGTYPE) |
| { |
| *(pChunkdata+pTempfield->iOffsetchunk) = iColortype; |
| bProcess = MNG_FALSE; |
| } |
| else |
| if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES) |
| bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6)) ); |
| else |
| bProcess = MNG_TRUE; |
| |
| if (bProcess) |
| { |
| iLastgroup = (mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK); |
| /* numeric field ? */ |
| if (pTempfield->iFlags & MNG_FIELD_INT) |
| { |
| if (iTemplen < pTempfield->iLengthmax) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| switch (pTempfield->iLengthmax) |
| { |
| case 1 : { mng_uint8 iNum = *pTempdata; |
| if (((mng_uint16)iNum < pTempfield->iMinvalue) || |
| ((mng_uint16)iNum > pTempfield->iMaxvalue) ) |
| MNG_ERROR (pData, MNG_INVALIDFIELDVAL); |
| *(pChunkdata+pTempfield->iOffsetchunk) = iNum; |
| break; } |
| case 2 : { mng_uint16 iNum = mng_get_uint16 (pTempdata); |
| if ((iNum < pTempfield->iMinvalue) || (iNum > pTempfield->iMaxvalue)) |
| MNG_ERROR (pData, MNG_INVALIDFIELDVAL); |
| *((mng_uint16p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum; |
| break; } |
| case 4 : { mng_uint32 iNum = mng_get_uint32 (pTempdata); |
| if ((iNum < pTempfield->iMinvalue) || |
| ((pTempfield->iFlags & MNG_FIELD_NOHIGHBIT) && (iNum & 0x80000000)) ) |
| MNG_ERROR (pData, MNG_INVALIDFIELDVAL); |
| *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum; |
| break; } |
| } |
| |
| pTempdata += pTempfield->iLengthmax; |
| iTemplen -= pTempfield->iLengthmax; |
| |
| } else { /* not numeric so it's a bunch of bytes */ |
| |
| if (!pTempfield->iOffsetchunklen) /* big fat NONO */ |
| MNG_ERROR (pData, MNG_INTERNALERROR); |
| /* with terminating 0 ? */ |
| if (pTempfield->iFlags & MNG_FIELD_TERMINATOR) |
| { |
| mng_uint8p pWork = pTempdata; |
| while (*pWork) /* find the zero */ |
| pWork++; |
| iDatalen = (mng_uint32)(pWork - pTempdata); |
| } else { /* no terminator, so everything that's left ! */ |
| iDatalen = iTemplen; |
| } |
| |
| if ((pTempfield->iLengthmax) && (iDatalen > pTempfield->iLengthmax)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| #if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \ |
| !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \ |
| defined(MNG_INCLUDE_ANG_PROPOSAL) |
| /* needs decompression ? */ |
| if (pTempfield->iFlags & MNG_FIELD_DEFLATED) |
| { |
| mng_uint8p pBuf = 0; |
| mng_uint32 iBufsize = 0; |
| mng_uint32 iRealsize; |
| mng_ptr pWork; |
| |
| iRetcode = mng_inflate_buffer (pData, pTempdata, iDatalen, |
| &pBuf, &iBufsize, &iRealsize); |
| |
| #ifdef MNG_CHECK_BAD_ICCP /* Check for bad iCCP chunk */ |
| if ((iRetcode) && (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_iCCP)) |
| { |
| *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = MNG_NULL; |
| *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen; |
| } |
| else |
| #endif |
| { |
| if (iRetcode) |
| return iRetcode; |
| |
| #if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL) |
| if ( (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_mpNG) || |
| (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_adAT) ) |
| { |
| MNG_ALLOC (pData, pWork, iRealsize); |
| } |
| else |
| { |
| #endif |
| /* don't forget to generate null terminator */ |
| MNG_ALLOC (pData, pWork, iRealsize+1); |
| #if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL) |
| } |
| #endif |
| MNG_COPY (pWork, pBuf, iRealsize); |
| |
| *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = pWork; |
| *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iRealsize; |
| } |
| |
| if (pBuf) /* free the temporary buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| |
| } else |
| #endif |
| { /* no decompression, so just copy */ |
| |
| mng_ptr pWork; |
| /* don't forget to generate null terminator */ |
| MNG_ALLOC (pData, pWork, iDatalen+1); |
| MNG_COPY (pWork, pTempdata, iDatalen); |
| |
| *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = pWork; |
| *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen; |
| } |
| |
| if (pTempfield->iFlags & MNG_FIELD_TERMINATOR) |
| iDatalen++; /* skip the terminating zero as well !!! */ |
| |
| iTemplen -= iDatalen; |
| pTempdata += iDatalen; |
| } |
| /* need to set an indicator ? */ |
| if (pTempfield->iOffsetchunkind) |
| *((mng_uint8p)(pChunkdata+pTempfield->iOffsetchunkind)) = MNG_TRUE; |
| } |
| } |
| |
| if (pTempfield->pSpecialfunc) /* special function required ? */ |
| { |
| iRetcode = pTempfield->pSpecialfunc(pData, *ppChunk, &iTemplen, &pTempdata); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| |
| pTempfield++; /* Neeeeeeexxxtt */ |
| iFieldcount--; |
| } |
| |
| if (iTemplen) /* extra data ??? */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| while (iFieldcount) /* not enough data ??? */ |
| { |
| if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES) |
| bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) || |
| ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6)) ); |
| else |
| bProcess = MNG_TRUE; |
| |
| if (bProcess) |
| { |
| if (!(pTempfield->iFlags & MNG_FIELD_OPTIONAL)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| if ((pTempfield->iFlags & MNG_FIELD_GROUPMASK) && |
| ((mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK) == iLastgroup)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| pTempfield++; |
| iFieldcount--; |
| } |
| } |
| } |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| READ_CHUNK (mng_read_general) |
| { |
| mng_retcode iRetcode = MNG_NOERROR; |
| mng_chunk_descp pDescr = ((mng_chunk_headerp)pHeader)->pChunkdescr; |
| mng_field_descp pField; |
| mng_uint16 iFields; |
| |
| if (!pDescr) /* this is a bad booboo !!! */ |
| MNG_ERROR (pData, MNG_INTERNALERROR); |
| |
| pField = pDescr->pFielddesc; |
| iFields = pDescr->iFielddesc; |
| /* check chunk against signature */ |
| if ((pDescr->eImgtype == mng_it_mng) && (pData->eSigtype != mng_it_mng)) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| |
| if ((pDescr->eImgtype == mng_it_jng) && (pData->eSigtype == mng_it_png)) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| /* empties allowed ? */ |
| if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTY))) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->eImagetype != mng_it_mng) || (!(pDescr->iAllowed & MNG_DESCR_GLOBAL))) |
| { /* *a* header required ? */ |
| if ((pDescr->iMusthaves & MNG_DESCR_GenHDR) && |
| #ifdef MNG_INCLUDE_JNG |
| (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pDescr->iMusthaves & MNG_DESCR_JngHDR) && |
| (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| #endif |
| } |
| /* specific chunk pre-requisite ? */ |
| if (((pDescr->iMusthaves & MNG_DESCR_IHDR) && (!pData->bHasIHDR)) || |
| #ifdef MNG_INCLUDE_JNG |
| ((pDescr->iMusthaves & MNG_DESCR_JHDR) && (!pData->bHasJHDR)) || |
| #endif |
| ((pDescr->iMusthaves & MNG_DESCR_DHDR) && (!pData->bHasDHDR)) || |
| ((pDescr->iMusthaves & MNG_DESCR_LOOP) && (!pData->bHasLOOP)) || |
| ((pDescr->iMusthaves & MNG_DESCR_PLTE) && (!pData->bHasPLTE)) || |
| ((pDescr->iMusthaves & MNG_DESCR_MHDR) && (!pData->bHasMHDR)) || |
| ((pDescr->iMusthaves & MNG_DESCR_SAVE) && (!pData->bHasSAVE)) ) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* specific chunk undesired ? */ |
| if (((pDescr->iMustNOThaves & MNG_DESCR_NOIHDR) && (pData->bHasIHDR)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOBASI) && (pData->bHasBASI)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NODHDR) && (pData->bHasDHDR)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOIDAT) && (pData->bHasIDAT)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOPLTE) && (pData->bHasPLTE)) || |
| #ifdef MNG_INCLUDE_JNG |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOJHDR) && (pData->bHasJHDR)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAT) && (pData->bHasJDAT)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAA) && (pData->bHasJDAA)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOJSEP) && (pData->bHasJSEP)) || |
| #endif |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOMHDR) && (pData->bHasMHDR)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOLOOP) && (pData->bHasLOOP)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOTERM) && (pData->bHasTERM)) || |
| ((pDescr->iMustNOThaves & MNG_DESCR_NOSAVE) && (pData->bHasSAVE)) ) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (pData->eSigtype == mng_it_mng) /* check global and embedded empty chunks */ |
| { |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { |
| if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYEMBED))) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } else { |
| if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYGLOBAL))) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| } |
| |
| if (pDescr->pSpecialfunc) /* need special processing ? */ |
| { |
| iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata, |
| pField, iFields, ppChunk, MNG_TRUE); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* empty indicator ? */ |
| if ((!iRawlen) && (pDescr->iOffsetempty)) |
| *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE; |
| |
| iRetcode = pDescr->pSpecialfunc(pData, *ppChunk); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| if ((((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT) || |
| (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT) || |
| (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA) ) |
| { |
| iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| *ppChunk = MNG_NULL; |
| } else { |
| #ifdef MNG_STORE_CHUNKS |
| if (!pData->bStorechunks) |
| #endif |
| { |
| iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| *ppChunk = MNG_NULL; |
| } |
| } |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if (iRawlen) |
| { |
| #ifdef MNG_OPTIMIZE_DISPLAYCALLS |
| pData->iRawlen = iRawlen; |
| pData->pRawdata = pRawdata; |
| #endif |
| |
| /* display processing */ |
| #ifndef MNG_OPTIMIZE_DISPLAYCALLS |
| if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT) |
| iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata); |
| #ifdef MNG_INCLUDE_JNG |
| else |
| if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT) |
| iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata); |
| else |
| if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA) |
| iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata); |
| #endif |
| #else |
| if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT) |
| iRetcode = mng_process_display_idat (pData); |
| #ifdef MNG_INCLUDE_JNG |
| else |
| if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT) |
| iRetcode = mng_process_display_jdat (pData); |
| else |
| if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA) |
| iRetcode = mng_process_display_jdaa (pData); |
| #endif |
| #endif |
| |
| if (iRetcode) |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if ((pData->bStorechunks) && (!(*ppChunk))) |
| { |
| iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata, |
| pField, iFields, ppChunk, MNG_FALSE); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* empty indicator ? */ |
| if ((!iRawlen) && (pDescr->iOffsetempty)) |
| *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #endif /* MNG_OPTIMIZE_CHUNKREADER */ |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_ihdr) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_START); |
| #endif |
| |
| if (iRawlen != 13) /* length oke ? */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| /* only allowed inside PNG or MNG */ |
| if ((pData->eSigtype != mng_it_png) && (pData->eSigtype != mng_it_mng)) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| /* sequence checks */ |
| if ((pData->eSigtype == mng_it_png) && (pData->iChunkseq > 1)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| pData->bHasIHDR = MNG_TRUE; /* indicate IHDR is present */ |
| /* and store interesting fields */ |
| if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)) |
| { |
| pData->iDatawidth = mng_get_uint32 (pRawdata); |
| pData->iDataheight = mng_get_uint32 (pRawdata+4); |
| } |
| |
| pData->iBitdepth = *(pRawdata+8); |
| pData->iColortype = *(pRawdata+9); |
| pData->iCompression = *(pRawdata+10); |
| pData->iFilter = *(pRawdata+11); |
| pData->iInterlace = *(pRawdata+12); |
| |
| #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT) |
| pData->iPNGmult = 1; |
| pData->iPNGdepth = pData->iBitdepth; |
| #endif |
| |
| #ifdef MNG_NO_1_2_4BIT_SUPPORT |
| if (pData->iBitdepth < 8) |
| pData->iBitdepth = 8; |
| #endif |
| |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (pData->iBitdepth > 8) |
| { |
| pData->iBitdepth = 8; |
| pData->iPNGmult = 2; |
| } |
| #endif |
| |
| if ((pData->iBitdepth != 8) /* parameter validity checks */ |
| #ifndef MNG_NO_1_2_4BIT_SUPPORT |
| && (pData->iBitdepth != 1) && |
| (pData->iBitdepth != 2) && |
| (pData->iBitdepth != 4) |
| #endif |
| #ifndef MNG_NO_16BIT_SUPPORT |
| && (pData->iBitdepth != 16) |
| #endif |
| ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if ((pData->iColortype != MNG_COLORTYPE_GRAY ) && |
| (pData->iColortype != MNG_COLORTYPE_RGB ) && |
| (pData->iColortype != MNG_COLORTYPE_INDEXED) && |
| (pData->iColortype != MNG_COLORTYPE_GRAYA ) && |
| (pData->iColortype != MNG_COLORTYPE_RGBA ) ) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| |
| if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8)) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if (((pData->iColortype == MNG_COLORTYPE_RGB ) || |
| (pData->iColortype == MNG_COLORTYPE_GRAYA ) || |
| (pData->iColortype == MNG_COLORTYPE_RGBA ) ) && |
| (pData->iBitdepth < 8 ) ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if (pData->iCompression != MNG_COMPRESSION_DEFLATE) |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| #if defined(FILTER192) || defined(FILTER193) |
| if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) && |
| #if defined(FILTER192) && defined(FILTER193) |
| (pData->iFilter != MNG_FILTER_DIFFERING) && |
| (pData->iFilter != MNG_FILTER_NOFILTER ) ) |
| #else |
| #ifdef FILTER192 |
| (pData->iFilter != MNG_FILTER_DIFFERING) ) |
| #else |
| (pData->iFilter != MNG_FILTER_NOFILTER ) ) |
| #endif |
| #endif |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| #else |
| if (pData->iFilter) |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| #endif |
| |
| if ((pData->iInterlace != MNG_INTERLACE_NONE ) && |
| (pData->iInterlace != MNG_INTERLACE_ADAM7) ) |
| MNG_ERROR (pData, MNG_INVALIDINTERLACE); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* check the colortype for delta-images ! */ |
| { |
| mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf; |
| |
| if (pData->iColortype != pBuf->iColortype) |
| { |
| if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) || |
| (pBuf->iColortype == MNG_COLORTYPE_GRAY ) ) && |
| ( (pData->iColortype != MNG_COLORTYPE_GRAY ) || |
| (pBuf->iColortype == MNG_COLORTYPE_INDEXED) ) ) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| } |
| } |
| #endif |
| #endif |
| |
| if (!pData->bHasheader) /* first chunk ? */ |
| { |
| pData->bHasheader = MNG_TRUE; /* we've got a header */ |
| pData->eImagetype = mng_it_png; /* then this must be a PNG */ |
| pData->iWidth = pData->iDatawidth; |
| pData->iHeight = pData->iDataheight; |
| /* predict alpha-depth ! */ |
| if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) || |
| (pData->iColortype == MNG_COLORTYPE_RGBA ) ) |
| pData->iAlphadepth = pData->iBitdepth; |
| else |
| if (pData->iColortype == MNG_COLORTYPE_INDEXED) |
| pData->iAlphadepth = 8; /* worst case scenario */ |
| else |
| pData->iAlphadepth = 1; /* Possible tRNS cheap binary transparency */ |
| /* fits on maximum canvas ? */ |
| if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight)) |
| MNG_WARNING (pData, MNG_IMAGETOOLARGE); |
| |
| #if !defined(MNG_INCLUDE_MPNG_PROPOSAL) || !defined(MNG_SUPPORT_DISPLAY) |
| if (pData->fProcessheader) /* inform the app ? */ |
| if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight)) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| #endif |
| } |
| |
| if (!pData->bHasDHDR) |
| pData->iImagelevel++; /* one level deeper */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode = mng_process_display_ihdr (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* fill the fields */ |
| ((mng_ihdrp)*ppChunk)->iWidth = mng_get_uint32 (pRawdata); |
| ((mng_ihdrp)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4); |
| ((mng_ihdrp)*ppChunk)->iBitdepth = pData->iBitdepth; |
| ((mng_ihdrp)*ppChunk)->iColortype = pData->iColortype; |
| ((mng_ihdrp)*ppChunk)->iCompression = pData->iCompression; |
| ((mng_ihdrp)*ppChunk)->iFilter = pData->iFilter; |
| ((mng_ihdrp)*ppChunk)->iInterlace = pData->iInterlace; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif /* MNG_OPTIMIZE_CHUNKREADER */ |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_plte) |
| { |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| mng_uint32 iX; |
| mng_uint8p pRawdata2; |
| #endif |
| #ifdef MNG_SUPPORT_DISPLAY |
| mng_uint32 iRawlen2; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasJHDR)) |
| #else |
| if (pData->bHasIDAT) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* multiple PLTE only inside BASI */ |
| if ((pData->bHasPLTE) && (!pData->bHasBASI)) |
| MNG_ERROR (pData, MNG_MULTIPLEERROR); |
| /* length must be multiple of 3 */ |
| if (((iRawlen % 3) != 0) || (iRawlen > 768)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { /* only allowed for indexed-color or |
| rgb(a)-color! */ |
| if ((pData->iColortype != 2) && (pData->iColortype != 3) && (pData->iColortype != 6)) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| /* empty only allowed if global present */ |
| if ((iRawlen == 0) && (!pData->bHasglobalPLTE)) |
| MNG_ERROR (pData, MNG_CANNOTBEEMPTY); |
| } |
| else |
| { |
| if (iRawlen == 0) /* cannot be empty as global! */ |
| MNG_ERROR (pData, MNG_CANNOTBEEMPTY); |
| } |
| |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| pData->bHasPLTE = MNG_TRUE; /* got it! */ |
| else |
| pData->bHasglobalPLTE = MNG_TRUE; |
| |
| pData->iPLTEcount = iRawlen / 3; |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { |
| mng_imagep pImage; |
| mng_imagedatap pBuf; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* processing delta-image ? */ |
| { /* store in object 0 !!! */ |
| pImage = (mng_imagep)pData->pObjzero; |
| pBuf = pImage->pImgbuf; |
| pBuf->bHasPLTE = MNG_TRUE; /* it's definitely got a PLTE now */ |
| pBuf->iPLTEcount = iRawlen / 3; /* this is the exact length */ |
| pRawdata2 = pRawdata; /* copy the entries */ |
| |
| for (iX = 0; iX < iRawlen / 3; iX++) |
| { |
| pBuf->aPLTEentries[iX].iRed = *pRawdata2; |
| pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1); |
| pBuf->aPLTEentries[iX].iBlue = *(pRawdata2+2); |
| |
| pRawdata2 += 3; |
| } |
| } |
| else |
| #endif |
| { /* get the current object */ |
| pImage = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pImage) /* no object then dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| pBuf = pImage->pImgbuf; /* address the object buffer */ |
| pBuf->bHasPLTE = MNG_TRUE; /* and tell it it's got a PLTE now */ |
| |
| if (!iRawlen) /* if empty, inherit from global */ |
| { |
| pBuf->iPLTEcount = pData->iGlobalPLTEcount; |
| MNG_COPY (pBuf->aPLTEentries, pData->aGlobalPLTEentries, |
| sizeof (pBuf->aPLTEentries)); |
| |
| if (pData->bHasglobalTRNS) /* also copy global tRNS ? */ |
| { /* indicate tRNS available */ |
| pBuf->bHasTRNS = MNG_TRUE; |
| |
| iRawlen2 = pData->iGlobalTRNSrawlen; |
| pRawdata2 = (mng_uint8p)(pData->aGlobalTRNSrawdata); |
| /* global length oke ? */ |
| if ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount)) |
| MNG_ERROR (pData, MNG_GLOBALLENGTHERR); |
| /* copy it */ |
| pBuf->iTRNScount = iRawlen2; |
| MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2); |
| } |
| } |
| else |
| { /* store fields for future reference */ |
| pBuf->iPLTEcount = iRawlen / 3; |
| pRawdata2 = pRawdata; |
| |
| for (iX = 0; iX < pBuf->iPLTEcount; iX++) |
| { |
| pBuf->aPLTEentries[iX].iRed = *pRawdata2; |
| pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1); |
| pBuf->aPLTEentries[iX].iBlue = *(pRawdata2+2); |
| |
| pRawdata2 += 3; |
| } |
| } |
| } |
| } |
| else /* store as global */ |
| { |
| pData->iGlobalPLTEcount = iRawlen / 3; |
| pRawdata2 = pRawdata; |
| |
| for (iX = 0; iX < pData->iGlobalPLTEcount; iX++) |
| { |
| pData->aGlobalPLTEentries[iX].iRed = *pRawdata2; |
| pData->aGlobalPLTEentries[iX].iGreen = *(pRawdata2+1); |
| pData->aGlobalPLTEentries[iX].iBlue = *(pRawdata2+2); |
| |
| pRawdata2 += 3; |
| } |
| |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_plte (pData, pData->iGlobalPLTEcount, |
| pData->aGlobalPLTEentries); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_pltep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| ((mng_pltep)*ppChunk)->iEntrycount = iRawlen / 3; |
| pRawdata2 = pRawdata; |
| |
| for (iX = 0; iX < ((mng_pltep)*ppChunk)->iEntrycount; iX++) |
| { |
| ((mng_pltep)*ppChunk)->aEntries[iX].iRed = *pRawdata2; |
| ((mng_pltep)*ppChunk)->aEntries[iX].iGreen = *(pRawdata2+1); |
| ((mng_pltep)*ppChunk)->aEntries[iX].iBlue = *(pRawdata2+2); |
| |
| pRawdata2 += 3; |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif /* MNG_OPTIMIZE_CHUNKREADER */ |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_idat) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_START); |
| #endif |
| |
| #ifdef MNG_INCLUDE_JNG /* sequence checks */ |
| if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasJHDR) && |
| (pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (pData->bHasJSEP) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| #endif |
| /* not allowed for deltatype NO_CHANGE */ |
| #ifndef MNG_NO_DELTA_PNG |
| if ((pData->bHasDHDR) && ((pData->iDeltatype == MNG_DELTATYPE_NOCHANGE))) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| #endif |
| /* can only be empty in BASI-block! */ |
| if ((iRawlen == 0) && (!pData->bHasBASI)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| /* indexed-color requires PLTE */ |
| if ((pData->bHasIHDR) && (pData->iColortype == 3) && (!pData->bHasPLTE)) |
| MNG_ERROR (pData, MNG_PLTEMISSING); |
| |
| pData->bHasIDAT = MNG_TRUE; /* got some IDAT now, don't we */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if (iRawlen) |
| { /* display processing */ |
| mng_retcode iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_idatp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| ((mng_idatp)*ppChunk)->iDatasize = iRawlen; |
| |
| if (iRawlen != 0) /* is there any data ? */ |
| { |
| MNG_ALLOC (pData, ((mng_idatp)*ppChunk)->pData, iRawlen); |
| MNG_COPY (((mng_idatp)*ppChunk)->pData, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_iend) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_START); |
| #endif |
| |
| if (iRawlen > 0) /* must not contain data! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_INCLUDE_JNG /* sequence checks */ |
| if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* IHDR-block requires IDAT */ |
| if ((pData->bHasIHDR) && (!pData->bHasIDAT)) |
| MNG_ERROR (pData, MNG_IDATMISSING); |
| |
| pData->iImagelevel--; /* one level up */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_image (pData); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* display processing */ |
| iRetcode = mng_process_display_iend (pData); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if (!pData->bTimerset) /* reset only if not broken !!! */ |
| { |
| #endif |
| /* IEND signals the end for most ... */ |
| pData->bHasIHDR = MNG_FALSE; |
| pData->bHasBASI = MNG_FALSE; |
| pData->bHasDHDR = MNG_FALSE; |
| #ifdef MNG_INCLUDE_JNG |
| pData->bHasJHDR = MNG_FALSE; |
| pData->bHasJSEP = MNG_FALSE; |
| pData->bHasJDAA = MNG_FALSE; |
| pData->bHasJDAT = MNG_FALSE; |
| #endif |
| pData->bHasPLTE = MNG_FALSE; |
| pData->bHasTRNS = MNG_FALSE; |
| pData->bHasGAMA = MNG_FALSE; |
| pData->bHasCHRM = MNG_FALSE; |
| pData->bHasSRGB = MNG_FALSE; |
| pData->bHasICCP = MNG_FALSE; |
| pData->bHasBKGD = MNG_FALSE; |
| pData->bHasIDAT = MNG_FALSE; |
| #ifdef MNG_SUPPORT_DISPLAY |
| } |
| #endif |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_trns) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasJHDR)) |
| #else |
| if (pData->bHasIDAT) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* multiple tRNS only inside BASI */ |
| if ((pData->bHasTRNS) && (!pData->bHasBASI)) |
| MNG_ERROR (pData, MNG_MULTIPLEERROR); |
| |
| if (iRawlen > 256) /* it just can't be bigger than that! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { /* not allowed with full alpha-channel */ |
| if ((pData->iColortype == 4) || (pData->iColortype == 6)) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| |
| if (iRawlen != 0) /* filled ? */ |
| { /* length checks */ |
| if ((pData->iColortype == 0) && (iRawlen != 2)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iColortype == 2) && (iRawlen != 6)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if (pData->iColortype == 3) |
| { |
| mng_imagep pImage = (mng_imagep)pData->pCurrentobj; |
| mng_imagedatap pBuf; |
| |
| if (!pImage) /* no object then check obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| pBuf = pImage->pImgbuf; /* address object buffer */ |
| |
| if (iRawlen > pBuf->iPLTEcount) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| #endif |
| } |
| else /* if empty there must be global stuff! */ |
| { |
| if (!pData->bHasglobalTRNS) |
| MNG_ERROR (pData, MNG_CANNOTBEEMPTY); |
| } |
| } |
| |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| pData->bHasTRNS = MNG_TRUE; /* indicate tRNS available */ |
| else |
| pData->bHasglobalTRNS = MNG_TRUE; |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { |
| mng_imagep pImage; |
| mng_imagedatap pBuf; |
| mng_uint8p pRawdata2; |
| mng_uint32 iRawlen2; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* processing delta-image ? */ |
| { /* store in object 0 !!! */ |
| pImage = (mng_imagep)pData->pObjzero; |
| pBuf = pImage->pImgbuf; /* address object buffer */ |
| |
| switch (pData->iColortype) /* store fields for future reference */ |
| { |
| case 0: { /* gray */ |
| #if defined(MNG_NO_1_2_4BIT_SUPPORT) |
| mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1, |
| 0,0,0,0,0,0,0,1}; |
| #endif |
| pBuf->iTRNSgray = mng_get_uint16 (pRawdata); |
| pBuf->iTRNSred = 0; |
| pBuf->iTRNSgreen = 0; |
| pBuf->iTRNSblue = 0; |
| pBuf->iTRNScount = 0; |
| #if defined(MNG_NO_1_2_4BIT_SUPPORT) |
| pBuf->iTRNSgray *= multiplier[pData->iPNGdepth]; |
| #endif |
| #if defined(MNG_NO_16BIT_SUPPORT) |
| if (pData->iPNGmult == 2) |
| pBuf->iTRNSgray >>= 8; |
| #endif |
| break; |
| } |
| case 2: { /* rgb */ |
| pBuf->iTRNSgray = 0; |
| pBuf->iTRNSred = mng_get_uint16 (pRawdata); |
| pBuf->iTRNSgreen = mng_get_uint16 (pRawdata+2); |
| pBuf->iTRNSblue = mng_get_uint16 (pRawdata+4); |
| pBuf->iTRNScount = 0; |
| #if defined(MNG_NO_16BIT_SUPPORT) |
| if (pData->iPNGmult == 2) |
| { |
| pBuf->iTRNSred >>= 8; |
| pBuf->iTRNSgreen >>= 8; |
| pBuf->iTRNSblue >>= 8; |
| } |
| #endif |
| break; |
| } |
| case 3: { /* indexed */ |
| pBuf->iTRNSgray = 0; |
| pBuf->iTRNSred = 0; |
| pBuf->iTRNSgreen = 0; |
| pBuf->iTRNSblue = 0; |
| pBuf->iTRNScount = iRawlen; |
| MNG_COPY (pBuf->aTRNSentries, pRawdata, iRawlen); |
| break; |
| } |
| } |
| |
| pBuf->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */ |
| } |
| else |
| #endif |
| { /* address current object */ |
| pImage = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pImage) /* no object then dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| pBuf = pImage->pImgbuf; /* address object buffer */ |
| pBuf->bHasTRNS = MNG_TRUE; /* and tell it it's got a tRNS now */ |
| |
| if (iRawlen == 0) /* if empty, inherit from global */ |
| { |
| iRawlen2 = pData->iGlobalTRNSrawlen; |
| pRawdata2 = (mng_ptr)(pData->aGlobalTRNSrawdata); |
| /* global length oke ? */ |
| if ((pData->iColortype == 0) && (iRawlen2 != 2)) |
| MNG_ERROR (pData, MNG_GLOBALLENGTHERR); |
| |
| if ((pData->iColortype == 2) && (iRawlen2 != 6)) |
| MNG_ERROR (pData, MNG_GLOBALLENGTHERR); |
| |
| if ((pData->iColortype == 3) && ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount))) |
| MNG_ERROR (pData, MNG_GLOBALLENGTHERR); |
| } |
| else |
| { |
| iRawlen2 = iRawlen; |
| pRawdata2 = pRawdata; |
| } |
| |
| switch (pData->iColortype) /* store fields for future reference */ |
| { |
| case 0: { /* gray */ |
| pBuf->iTRNSgray = mng_get_uint16 (pRawdata2); |
| pBuf->iTRNSred = 0; |
| pBuf->iTRNSgreen = 0; |
| pBuf->iTRNSblue = 0; |
| pBuf->iTRNScount = 0; |
| #if defined(MNG_NO_16BIT_SUPPORT) |
| if (pData->iPNGmult == 2) |
| pBuf->iTRNSgray >>= 8; |
| #endif |
| break; |
| } |
| case 2: { /* rgb */ |
| pBuf->iTRNSgray = 0; |
| pBuf->iTRNSred = mng_get_uint16 (pRawdata2); |
| pBuf->iTRNSgreen = mng_get_uint16 (pRawdata2+2); |
| pBuf->iTRNSblue = mng_get_uint16 (pRawdata2+4); |
| pBuf->iTRNScount = 0; |
| #if defined(MNG_NO_16BIT_SUPPORT) |
| if (pData->iPNGmult == 2) |
| { |
| pBuf->iTRNSred >>= 8; |
| pBuf->iTRNSgreen >>= 8; |
| pBuf->iTRNSblue >>= 8; |
| } |
| #endif |
| break; |
| } |
| case 3: { /* indexed */ |
| pBuf->iTRNSgray = 0; |
| pBuf->iTRNSred = 0; |
| pBuf->iTRNSgreen = 0; |
| pBuf->iTRNSblue = 0; |
| pBuf->iTRNScount = iRawlen2; |
| MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2); |
| break; |
| } |
| } |
| } |
| } |
| else /* store as global */ |
| { |
| pData->iGlobalTRNSrawlen = iRawlen; |
| MNG_COPY (pData->aGlobalTRNSrawdata, pRawdata, iRawlen); |
| |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_trns (pData, pData->iGlobalTRNSrawlen, |
| pData->aGlobalTRNSrawdata); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { /* not global! */ |
| ((mng_trnsp)*ppChunk)->bGlobal = MNG_FALSE; |
| ((mng_trnsp)*ppChunk)->iType = pData->iColortype; |
| |
| if (iRawlen == 0) /* if empty, indicate so */ |
| ((mng_trnsp)*ppChunk)->bEmpty = MNG_TRUE; |
| else |
| { |
| ((mng_trnsp)*ppChunk)->bEmpty = MNG_FALSE; |
| |
| switch (pData->iColortype) /* store fields */ |
| { |
| case 0: { /* gray */ |
| ((mng_trnsp)*ppChunk)->iGray = mng_get_uint16 (pRawdata); |
| break; |
| } |
| case 2: { /* rgb */ |
| ((mng_trnsp)*ppChunk)->iRed = mng_get_uint16 (pRawdata); |
| ((mng_trnsp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2); |
| ((mng_trnsp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4); |
| break; |
| } |
| case 3: { /* indexed */ |
| ((mng_trnsp)*ppChunk)->iCount = iRawlen; |
| MNG_COPY (((mng_trnsp)*ppChunk)->aEntries, pRawdata, iRawlen); |
| break; |
| } |
| } |
| } |
| } |
| else /* it's global! */ |
| { |
| ((mng_trnsp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| ((mng_trnsp)*ppChunk)->bGlobal = MNG_TRUE; |
| ((mng_trnsp)*ppChunk)->iType = 0; |
| ((mng_trnsp)*ppChunk)->iRawlen = iRawlen; |
| |
| MNG_COPY (((mng_trnsp)*ppChunk)->aRawdata, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_gama) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if ((pData->bHasIDAT) || (pData->bHasPLTE)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { /* length must be exactly 4 */ |
| if (iRawlen != 4) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { /* length must be empty or exactly 4 */ |
| if ((iRawlen != 0) && (iRawlen != 4)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| pData->bHasGAMA = MNG_TRUE; /* indicate we've got it */ |
| else |
| pData->bHasglobalGAMA = (mng_bool)(iRawlen != 0); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { |
| mng_imagep pImage; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* update delta image ? */ |
| { /* store in object 0 ! */ |
| pImage = (mng_imagep)pData->pObjzero; |
| /* store for color-processing routines */ |
| pImage->pImgbuf->iGamma = mng_get_uint32 (pRawdata); |
| pImage->pImgbuf->bHasGAMA = MNG_TRUE; |
| } |
| else |
| #endif |
| { |
| pImage = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pImage) /* no object then dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| /* store for color-processing routines */ |
| pImage->pImgbuf->iGamma = mng_get_uint32 (pRawdata); |
| pImage->pImgbuf->bHasGAMA = MNG_TRUE; |
| } |
| } |
| else |
| { /* store as global */ |
| if (iRawlen != 0) |
| pData->iGlobalGamma = mng_get_uint32 (pRawdata); |
| |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_gama (pData, (mng_bool)(iRawlen == 0), |
| pData->iGlobalGamma); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_gamap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| ((mng_gamap)*ppChunk)->iGamma = mng_get_uint32 (pRawdata); |
| |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_cHRM |
| READ_CHUNK (mng_read_chrm) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if ((pData->bHasIDAT) || (pData->bHasPLTE)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { /* length must be exactly 32 */ |
| if (iRawlen != 32) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { /* length must be empty or exactly 32 */ |
| if ((iRawlen != 0) && (iRawlen != 32)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| pData->bHasCHRM = MNG_TRUE; /* indicate we've got it */ |
| else |
| pData->bHasglobalCHRM = (mng_bool)(iRawlen != 0); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_uint32 iWhitepointx, iWhitepointy; |
| mng_uint32 iPrimaryredx, iPrimaryredy; |
| mng_uint32 iPrimarygreenx, iPrimarygreeny; |
| mng_uint32 iPrimarybluex, iPrimarybluey; |
| |
| iWhitepointx = mng_get_uint32 (pRawdata); |
| iWhitepointy = mng_get_uint32 (pRawdata+4); |
| iPrimaryredx = mng_get_uint32 (pRawdata+8); |
| iPrimaryredy = mng_get_uint32 (pRawdata+12); |
| iPrimarygreenx = mng_get_uint32 (pRawdata+16); |
| iPrimarygreeny = mng_get_uint32 (pRawdata+20); |
| iPrimarybluex = mng_get_uint32 (pRawdata+24); |
| iPrimarybluey = mng_get_uint32 (pRawdata+28); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { |
| mng_imagep pImage; |
| mng_imagedatap pBuf; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* update delta image ? */ |
| { /* store it in object 0 ! */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| pBuf = pImage->pImgbuf; /* address object buffer */ |
| pBuf->bHasCHRM = MNG_TRUE; /* and tell it it's got a CHRM now */ |
| /* store for color-processing routines */ |
| pBuf->iWhitepointx = iWhitepointx; |
| pBuf->iWhitepointy = iWhitepointy; |
| pBuf->iPrimaryredx = iPrimaryredx; |
| pBuf->iPrimaryredy = iPrimaryredy; |
| pBuf->iPrimarygreenx = iPrimarygreenx; |
| pBuf->iPrimarygreeny = iPrimarygreeny; |
| pBuf->iPrimarybluex = iPrimarybluex; |
| pBuf->iPrimarybluey = iPrimarybluey; |
| } |
| else |
| #endif |
| { |
| pImage = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pImage) /* no object then dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| pBuf = pImage->pImgbuf; /* address object buffer */ |
| pBuf->bHasCHRM = MNG_TRUE; /* and tell it it's got a CHRM now */ |
| /* store for color-processing routines */ |
| pBuf->iWhitepointx = iWhitepointx; |
| pBuf->iWhitepointy = iWhitepointy; |
| pBuf->iPrimaryredx = iPrimaryredx; |
| pBuf->iPrimaryredy = iPrimaryredy; |
| pBuf->iPrimarygreenx = iPrimarygreenx; |
| pBuf->iPrimarygreeny = iPrimarygreeny; |
| pBuf->iPrimarybluex = iPrimarybluex; |
| pBuf->iPrimarybluey = iPrimarybluey; |
| } |
| } |
| else |
| { /* store as global */ |
| if (iRawlen != 0) |
| { |
| pData->iGlobalWhitepointx = iWhitepointx; |
| pData->iGlobalWhitepointy = iWhitepointy; |
| pData->iGlobalPrimaryredx = iPrimaryredx; |
| pData->iGlobalPrimaryredy = iPrimaryredy; |
| pData->iGlobalPrimarygreenx = iPrimarygreenx; |
| pData->iGlobalPrimarygreeny = iPrimarygreeny; |
| pData->iGlobalPrimarybluex = iPrimarybluex; |
| pData->iGlobalPrimarybluey = iPrimarybluey; |
| } |
| |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_chrm (pData, (mng_bool)(iRawlen == 0), |
| iWhitepointx, iWhitepointy, |
| iPrimaryredx, iPrimaryredy, |
| iPrimarygreenx, iPrimarygreeny, |
| iPrimarybluex, iPrimarybluey); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_chrmp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| ((mng_chrmp)*ppChunk)->iWhitepointx = mng_get_uint32 (pRawdata); |
| ((mng_chrmp)*ppChunk)->iWhitepointy = mng_get_uint32 (pRawdata+4); |
| ((mng_chrmp)*ppChunk)->iRedx = mng_get_uint32 (pRawdata+8); |
| ((mng_chrmp)*ppChunk)->iRedy = mng_get_uint32 (pRawdata+12); |
| ((mng_chrmp)*ppChunk)->iGreenx = mng_get_uint32 (pRawdata+16); |
| ((mng_chrmp)*ppChunk)->iGreeny = mng_get_uint32 (pRawdata+20); |
| ((mng_chrmp)*ppChunk)->iBluex = mng_get_uint32 (pRawdata+24); |
| ((mng_chrmp)*ppChunk)->iBluey = mng_get_uint32 (pRawdata+28); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_srgb) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if ((pData->bHasIDAT) || (pData->bHasPLTE)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { /* length must be exactly 1 */ |
| if (iRawlen != 1) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { /* length must be empty or exactly 1 */ |
| if ((iRawlen != 0) && (iRawlen != 1)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| pData->bHasSRGB = MNG_TRUE; /* indicate we've got it */ |
| else |
| pData->bHasglobalSRGB = (mng_bool)(iRawlen != 0); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { |
| mng_imagep pImage; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* update delta image ? */ |
| { /* store in object 0 ! */ |
| pImage = (mng_imagep)pData->pObjzero; |
| /* store for color-processing routines */ |
| pImage->pImgbuf->iRenderingintent = *pRawdata; |
| pImage->pImgbuf->bHasSRGB = MNG_TRUE; |
| } |
| else |
| #endif |
| { |
| pImage = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pImage) /* no object then dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| /* store for color-processing routines */ |
| pImage->pImgbuf->iRenderingintent = *pRawdata; |
| pImage->pImgbuf->bHasSRGB = MNG_TRUE; |
| } |
| } |
| else |
| { /* store as global */ |
| if (iRawlen != 0) |
| pData->iGlobalRendintent = *pRawdata; |
| |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_srgb (pData, (mng_bool)(iRawlen == 0), |
| pData->iGlobalRendintent); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_srgbp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| ((mng_srgbp)*ppChunk)->iRenderingintent = *pRawdata; |
| |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_iCCP |
| READ_CHUNK (mng_read_iccp) |
| { |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint32 iCompressedsize; |
| mng_uint32 iProfilesize; |
| mng_uint32 iBufsize = 0; |
| mng_uint8p pBuf = 0; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if ((pData->bHasIDAT) || (pData->bHasPLTE)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { /* length must be at least 2 */ |
| if (iRawlen < 2) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { /* length must be empty or at least 2 */ |
| if ((iRawlen != 0) && (iRawlen < 2)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| pTemp = find_null (pRawdata); /* find null-separator */ |
| /* not found inside input-data ? */ |
| if ((pTemp - pRawdata) > (mng_int32)iRawlen) |
| MNG_ERROR (pData, MNG_NULLNOTFOUND); |
| /* determine size of compressed profile */ |
| iCompressedsize = (mng_uint32)(iRawlen - (pTemp - pRawdata) - 2); |
| /* decompress the profile */ |
| iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize, |
| &pBuf, &iBufsize, &iProfilesize); |
| |
| #ifdef MNG_CHECK_BAD_ICCP /* Check for bad iCCP chunk */ |
| if ((iRetcode) && (!strncmp ((char *)pRawdata, "Photoshop ICC profile", 21))) |
| { |
| if (iRawlen == 2615) /* is it the sRGB profile ? */ |
| { |
| mng_chunk_header chunk_srgb = |
| #ifdef MNG_OPTIMIZE_CHUNKINITFREE |
| {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)}; |
| #else |
| {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0}; |
| #endif |
| /* pretend it's an sRGB chunk then ! */ |
| iRetcode = mng_read_srgb (pData, &chunk_srgb, 1, (mng_ptr)"0", ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| } |
| } |
| else |
| { |
| #endif /* MNG_CHECK_BAD_ICCP */ |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| pData->bHasICCP = MNG_TRUE; /* indicate we've got it */ |
| else |
| pData->bHasglobalICCP = (mng_bool)(iRawlen != 0); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| { |
| mng_imagep pImage; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* update delta image ? */ |
| { /* store in object 0 ! */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| if (pImage->pImgbuf->pProfile) /* profile existed ? */ |
| MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize); |
| /* allocate a buffer & copy it */ |
| MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize); |
| MNG_COPY (pImage->pImgbuf->pProfile, pBuf, iProfilesize); |
| /* store its length as well */ |
| pImage->pImgbuf->iProfilesize = iProfilesize; |
| pImage->pImgbuf->bHasICCP = MNG_TRUE; |
| } |
| else |
| #endif |
| { |
| pImage = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pImage) /* no object then dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| if (pImage->pImgbuf->pProfile) /* profile existed ? */ |
| MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize); |
| /* allocate a buffer & copy it */ |
| MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize); |
| MNG_COPY (pImage->pImgbuf->pProfile, pBuf, iProfilesize); |
| /* store its length as well */ |
| pImage->pImgbuf->iProfilesize = iProfilesize; |
| pImage->pImgbuf->bHasICCP = MNG_TRUE; |
| } |
| } |
| else |
| { /* store as global */ |
| if (iRawlen == 0) /* empty chunk ? */ |
| { |
| if (pData->pGlobalProfile) /* did we have a global profile ? */ |
| MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize); |
| |
| pData->iGlobalProfilesize = 0; /* reset to null */ |
| pData->pGlobalProfile = MNG_NULL; |
| } |
| else |
| { /* allocate a global buffer & copy it */ |
| MNG_ALLOC (pData, pData->pGlobalProfile, iProfilesize); |
| MNG_COPY (pData->pGlobalProfile, pBuf, iProfilesize); |
| /* store its length as well */ |
| pData->iGlobalProfilesize = iProfilesize; |
| } |
| |
| /* create an animation object */ |
| iRetcode = mng_create_ani_iccp (pData, (mng_bool)(iRawlen == 0), |
| pData->iGlobalProfilesize, |
| pData->pGlobalProfile); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| /* store the fields */ |
| ((mng_iccpp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) /* not empty ? */ |
| { |
| if (!pBuf) /* hasn't been unpuzzled it yet ? */ |
| { /* find null-separator */ |
| pTemp = find_null (pRawdata); |
| /* not found inside input-data ? */ |
| if ((pTemp - pRawdata) > (mng_int32)iRawlen) |
| MNG_ERROR (pData, MNG_NULLNOTFOUND); |
| /* determine size of compressed profile */ |
| iCompressedsize = iRawlen - (pTemp - pRawdata) - 2; |
| /* decompress the profile */ |
| iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize, |
| &pBuf, &iBufsize, &iProfilesize); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| } |
| |
| ((mng_iccpp)*ppChunk)->iNamesize = (mng_uint32)(pTemp - pRawdata); |
| |
| if (((mng_iccpp)*ppChunk)->iNamesize) |
| { |
| MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->zName, |
| ((mng_iccpp)*ppChunk)->iNamesize + 1); |
| MNG_COPY (((mng_iccpp)*ppChunk)->zName, pRawdata, |
| ((mng_iccpp)*ppChunk)->iNamesize); |
| } |
| |
| ((mng_iccpp)*ppChunk)->iCompression = *(pTemp+1); |
| ((mng_iccpp)*ppChunk)->iProfilesize = iProfilesize; |
| |
| MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->pProfile, iProfilesize); |
| MNG_COPY (((mng_iccpp)*ppChunk)->pProfile, pBuf, iProfilesize); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| if (pBuf) /* free the temporary buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| |
| #ifdef MNG_CHECK_BAD_ICCP |
| } |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_tEXt |
| READ_CHUNK (mng_read_text) |
| { |
| mng_uint32 iKeywordlen, iTextlen; |
| mng_pchar zKeyword, zText; |
| mng_uint8p pTemp; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 2) /* length must be at least 2 */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pTemp = find_null (pRawdata); /* find the null separator */ |
| /* not found inside input-data ? */ |
| if ((pTemp - pRawdata) > (mng_int32)iRawlen) |
| MNG_ERROR (pData, MNG_NULLNOTFOUND); |
| |
| if (pTemp == pRawdata) /* there must be at least 1 char for keyword */ |
| MNG_ERROR (pData, MNG_KEYWORDNULL); |
| |
| iKeywordlen = (mng_uint32)(pTemp - pRawdata); |
| iTextlen = iRawlen - iKeywordlen - 1; |
| |
| if (pData->fProcesstext) /* inform the application ? */ |
| { |
| mng_bool bOke; |
| |
| MNG_ALLOC (pData, zKeyword, iKeywordlen + 1); |
| MNG_COPY (zKeyword, pRawdata, iKeywordlen); |
| |
| MNG_ALLOCX (pData, zText, iTextlen + 1); |
| |
| if (!zText) /* on error bail out */ |
| { |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| if (iTextlen) |
| MNG_COPY (zText, pTemp+1, iTextlen); |
| |
| bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_TEXT, zKeyword, zText, 0, 0); |
| |
| MNG_FREEX (pData, zText, iTextlen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| |
| if (!bOke) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| |
| } |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_textp)*ppChunk)->iKeywordsize = iKeywordlen; |
| ((mng_textp)*ppChunk)->iTextsize = iTextlen; |
| |
| if (iKeywordlen) |
| { |
| MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zKeyword, iKeywordlen+1); |
| MNG_COPY (((mng_textp)*ppChunk)->zKeyword, pRawdata, iKeywordlen); |
| } |
| |
| if (iTextlen) |
| { |
| MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zText, iTextlen+1); |
| MNG_COPY (((mng_textp)*ppChunk)->zText, pTemp+1, iTextlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_zTXt |
| READ_CHUNK (mng_read_ztxt) |
| { |
| mng_retcode iRetcode; |
| mng_uint32 iKeywordlen, iTextlen; |
| mng_pchar zKeyword; |
| mng_uint8p pTemp; |
| mng_uint32 iCompressedsize; |
| mng_uint32 iBufsize; |
| mng_uint8p pBuf; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 3) /* length must be at least 3 */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pTemp = find_null (pRawdata); /* find the null separator */ |
| /* not found inside input-data ? */ |
| if ((pTemp - pRawdata) > (mng_int32)iRawlen) |
| MNG_ERROR (pData, MNG_NULLNOTFOUND); |
| |
| if (pTemp == pRawdata) /* there must be at least 1 char for keyword */ |
| MNG_ERROR (pData, MNG_KEYWORDNULL); |
| |
| if (*(pTemp+1) != 0) /* only deflate compression-method allowed */ |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| iKeywordlen = (mng_uint32)(pTemp - pRawdata); |
| iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - 2); |
| |
| zKeyword = 0; /* there's no keyword buffer yet */ |
| pBuf = 0; /* or a temporary buffer ! */ |
| |
| if (pData->fProcesstext) /* inform the application ? */ |
| { /* decompress the text */ |
| iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize, |
| &pBuf, &iBufsize, &iTextlen); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| |
| MNG_ALLOCX (pData, zKeyword, iKeywordlen+1); |
| |
| if (!zKeyword) /* on error bail out */ |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (zKeyword, pRawdata, iKeywordlen); |
| |
| if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ZTXT, zKeyword, (mng_pchar)pBuf, 0, 0)) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_FREEX (pData, zKeyword, iKeywordlen+1); |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| } |
| } |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_FREEX (pData, zKeyword, iKeywordlen+1); |
| return iRetcode; |
| } |
| /* store the fields */ |
| ((mng_ztxtp)*ppChunk)->iKeywordsize = iKeywordlen; |
| ((mng_ztxtp)*ppChunk)->iCompression = *(pTemp+1); |
| |
| if ((!pBuf) && (iCompressedsize)) /* did we not get a text-buffer yet ? */ |
| { /* decompress the text */ |
| iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize, |
| &pBuf, &iBufsize, &iTextlen); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_FREEX (pData, zKeyword, iKeywordlen+1); |
| return iRetcode; |
| } |
| } |
| |
| MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zKeyword, iKeywordlen + 1); |
| /* on error bail out */ |
| if (!((mng_ztxtp)*ppChunk)->zKeyword) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_FREEX (pData, zKeyword, iKeywordlen+1); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (((mng_ztxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen); |
| |
| ((mng_ztxtp)*ppChunk)->iTextsize = iTextlen; |
| |
| if (iCompressedsize) |
| { |
| MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zText, iTextlen + 1); |
| /* on error bail out */ |
| if (!((mng_ztxtp)*ppChunk)->zText) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_FREEX (pData, zKeyword, iKeywordlen+1); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (((mng_ztxtp)*ppChunk)->zText, pBuf, iTextlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| MNG_FREEX (pData, pBuf, iBufsize); /* free the temporary buffers */ |
| MNG_FREEX (pData, zKeyword, iKeywordlen+1); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_iTXt |
| READ_CHUNK (mng_read_itxt) |
| { |
| mng_retcode iRetcode; |
| mng_uint32 iKeywordlen, iTextlen, iLanguagelen, iTranslationlen; |
| mng_pchar zKeyword, zLanguage, zTranslation; |
| mng_uint8p pNull1, pNull2, pNull3; |
| mng_uint32 iCompressedsize; |
| mng_uint8 iCompressionflag; |
| mng_uint32 iBufsize; |
| mng_uint8p pBuf; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 6) /* length must be at least 6 */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pNull1 = find_null (pRawdata); /* find the null separators */ |
| pNull2 = find_null (pNull1+3); |
| pNull3 = find_null (pNull2+1); |
| /* not found inside input-data ? */ |
| if (((pNull1 - pRawdata) > (mng_int32)iRawlen) || |
| ((pNull2 - pRawdata) > (mng_int32)iRawlen) || |
| ((pNull3 - pRawdata) > (mng_int32)iRawlen) ) |
| MNG_ERROR (pData, MNG_NULLNOTFOUND); |
| |
| if (pNull1 == pRawdata) /* there must be at least 1 char for keyword */ |
| MNG_ERROR (pData, MNG_KEYWORDNULL); |
| /* compression or not ? */ |
| if ((*(pNull1+1) != 0) && (*(pNull1+1) != 1)) |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| if (*(pNull1+2) != 0) /* only deflate compression-method allowed */ |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| iKeywordlen = (mng_uint32)(pNull1 - pRawdata); |
| iLanguagelen = (mng_uint32)(pNull2 - pNull1 - 3); |
| iTranslationlen = (mng_uint32)(pNull3 - pNull2 - 1); |
| iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - iLanguagelen - iTranslationlen - 5); |
| iCompressionflag = *(pNull1+1); |
| |
| zKeyword = 0; /* no buffers acquired yet */ |
| zLanguage = 0; |
| zTranslation = 0; |
| pBuf = 0; |
| iTextlen = 0; |
| |
| if (pData->fProcesstext) /* inform the application ? */ |
| { |
| if (iCompressionflag) /* decompress the text ? */ |
| { |
| iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize, |
| &pBuf, &iBufsize, &iTextlen); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffer */ |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| } |
| else |
| { |
| iTextlen = iCompressedsize; |
| iBufsize = iTextlen+1; /* plus 1 for terminator byte!!! */ |
| |
| MNG_ALLOC (pData, pBuf, iBufsize); |
| MNG_COPY (pBuf, pNull3+1, iTextlen); |
| } |
| |
| MNG_ALLOCX (pData, zKeyword, iKeywordlen + 1); |
| MNG_ALLOCX (pData, zLanguage, iLanguagelen + 1); |
| MNG_ALLOCX (pData, zTranslation, iTranslationlen + 1); |
| /* on error bail out */ |
| if ((!zKeyword) || (!zLanguage) || (!zTranslation)) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (zKeyword, pRawdata, iKeywordlen); |
| MNG_COPY (zLanguage, pNull1+3, iLanguagelen); |
| MNG_COPY (zTranslation, pNull2+1, iTranslationlen); |
| |
| if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ITXT, zKeyword, (mng_pchar)pBuf, |
| zLanguage, zTranslation)) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| } |
| } |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| /* store the fields */ |
| ((mng_itxtp)*ppChunk)->iKeywordsize = iKeywordlen; |
| ((mng_itxtp)*ppChunk)->iLanguagesize = iLanguagelen; |
| ((mng_itxtp)*ppChunk)->iTranslationsize = iTranslationlen; |
| ((mng_itxtp)*ppChunk)->iCompressionflag = *(pNull1+1); |
| ((mng_itxtp)*ppChunk)->iCompressionmethod = *(pNull1+2); |
| |
| if ((!pBuf) && (iCompressedsize)) /* did we not get a text-buffer yet ? */ |
| { |
| if (iCompressionflag) /* decompress the text ? */ |
| { |
| iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize, |
| &pBuf, &iBufsize, &iTextlen); |
| |
| if (iRetcode) /* on error bail out */ |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| } |
| else |
| { |
| iTextlen = iCompressedsize; |
| iBufsize = iTextlen+1; /* plus 1 for terminator byte!!! */ |
| |
| MNG_ALLOC (pData, pBuf, iBufsize); |
| MNG_COPY (pBuf, pNull3+1, iTextlen); |
| } |
| } |
| |
| MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zKeyword, iKeywordlen + 1); |
| MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zLanguage, iLanguagelen + 1); |
| MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zTranslation, iTranslationlen + 1); |
| /* on error bail out */ |
| if ((!((mng_itxtp)*ppChunk)->zKeyword ) || |
| (!((mng_itxtp)*ppChunk)->zLanguage ) || |
| (!((mng_itxtp)*ppChunk)->zTranslation) ) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (((mng_itxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen); |
| MNG_COPY (((mng_itxtp)*ppChunk)->zLanguage, pNull1+3, iLanguagelen); |
| MNG_COPY (((mng_itxtp)*ppChunk)->zTranslation, pNull2+1, iTranslationlen); |
| |
| ((mng_itxtp)*ppChunk)->iTextsize = iTextlen; |
| |
| if (iTextlen) |
| { |
| MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zText, iTextlen + 1); |
| |
| if (!((mng_itxtp)*ppChunk)->zText) |
| { /* don't forget to drop the temp buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (((mng_itxtp)*ppChunk)->zText, pBuf, iTextlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| /* free the temporary buffers */ |
| MNG_FREEX (pData, zTranslation, iTranslationlen + 1); |
| MNG_FREEX (pData, zLanguage, iLanguagelen + 1); |
| MNG_FREEX (pData, zKeyword, iKeywordlen + 1); |
| MNG_FREEX (pData, pBuf, iBufsize); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_bKGD |
| READ_CHUNK (mng_read_bkgd) |
| { |
| #ifdef MNG_SUPPORT_DISPLAY |
| mng_imagep pImage = (mng_imagep)pData->pCurrentobj; |
| mng_imagedatap pBuf; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if (pData->bHasIDAT) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen > 6) /* it just can't be bigger than that! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_INCLUDE_JNG /* length checks */ |
| if (pData->bHasJHDR) |
| { |
| if (((pData->iJHDRcolortype == 8) || (pData->iJHDRcolortype == 12)) && (iRawlen != 2)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if (((pData->iJHDRcolortype == 10) || (pData->iJHDRcolortype == 14)) && (iRawlen != 6)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| #endif /* MNG_INCLUDE_JNG */ |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { |
| if (((pData->iColortype == 0) || (pData->iColortype == 4)) && (iRawlen != 2)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if (((pData->iColortype == 2) || (pData->iColortype == 6)) && (iRawlen != 6)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iColortype == 3) && (iRawlen != 1)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { |
| if (iRawlen != 6) /* global is always 16-bit RGB ! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| pData->bHasBKGD = MNG_TRUE; /* indicate bKGD available */ |
| else |
| pData->bHasglobalBKGD = (mng_bool)(iRawlen != 0); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| if (!pImage) /* if no object dump it in obj 0 */ |
| pImage = (mng_imagep)pData->pObjzero; |
| |
| pBuf = pImage->pImgbuf; /* address object buffer */ |
| |
| #ifdef MNG_INCLUDE_JNG |
| if (pData->bHasJHDR) |
| { |
| pBuf->bHasBKGD = MNG_TRUE; /* tell the object it's got bKGD now */ |
| |
| switch (pData->iJHDRcolortype) /* store fields for future reference */ |
| { |
| case 8 : ; /* gray */ |
| case 12 : { /* graya */ |
| pBuf->iBKGDgray = mng_get_uint16 (pRawdata); |
| break; |
| } |
| case 10 : ; /* rgb */ |
| case 14 : { /* rgba */ |
| pBuf->iBKGDred = mng_get_uint16 (pRawdata); |
| pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2); |
| pBuf->iBKGDblue = mng_get_uint16 (pRawdata+4); |
| break; |
| } |
| } |
| } |
| else |
| #endif /* MNG_INCLUDE_JNG */ |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { |
| pBuf->bHasBKGD = MNG_TRUE; /* tell the object it's got bKGD now */ |
| |
| switch (pData->iColortype) /* store fields for future reference */ |
| { |
| case 0 : ; /* gray */ |
| case 4 : { /* graya */ |
| pBuf->iBKGDgray = mng_get_uint16 (pRawdata); |
| break; |
| } |
| case 2 : ; /* rgb */ |
| case 6 : { /* rgba */ |
| pBuf->iBKGDred = mng_get_uint16 (pRawdata); |
| pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2); |
| pBuf->iBKGDblue = mng_get_uint16 (pRawdata+4); |
| break; |
| } |
| case 3 : { /* indexed */ |
| pBuf->iBKGDindex = *pRawdata; |
| break; |
| } |
| } |
| } |
| else /* store as global */ |
| { |
| if (iRawlen) |
| { |
| pData->iGlobalBKGDred = mng_get_uint16 (pRawdata); |
| pData->iGlobalBKGDgreen = mng_get_uint16 (pRawdata+2); |
| pData->iGlobalBKGDblue = mng_get_uint16 (pRawdata+4); |
| } |
| |
| { /* create an animation object */ |
| mng_retcode iRetcode = mng_create_ani_bkgd (pData, pData->iGlobalBKGDred, |
| pData->iGlobalBKGDgreen, |
| pData->iGlobalBKGDblue); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_bkgdp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| ((mng_bkgdp)*ppChunk)->iType = pData->iColortype; |
| |
| if (iRawlen) |
| { |
| switch (iRawlen) /* guess from length */ |
| { |
| case 1 : { /* indexed */ |
| ((mng_bkgdp)*ppChunk)->iType = 3; |
| ((mng_bkgdp)*ppChunk)->iIndex = *pRawdata; |
| break; |
| } |
| case 2 : { /* gray */ |
| ((mng_bkgdp)*ppChunk)->iType = 0; |
| ((mng_bkgdp)*ppChunk)->iGray = mng_get_uint16 (pRawdata); |
| break; |
| } |
| case 6 : { /* rgb */ |
| ((mng_bkgdp)*ppChunk)->iType = 2; |
| ((mng_bkgdp)*ppChunk)->iRed = mng_get_uint16 (pRawdata); |
| ((mng_bkgdp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2); |
| ((mng_bkgdp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4); |
| break; |
| } |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_pHYs |
| READ_CHUNK (mng_read_phys) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if (pData->bHasIDAT) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* it's 9 bytes or empty; no more, no less! */ |
| if ((iRawlen != 9) && (iRawlen != 0)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_physp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| ((mng_physp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata); |
| ((mng_physp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4); |
| ((mng_physp)*ppChunk)->iUnit = *(pRawdata+8); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_sBIT |
| READ_CHUNK (mng_read_sbit) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasPLTE) || (pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA)) |
| #else |
| if ((pData->bHasPLTE) || (pData->bHasIDAT)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen > 4) /* it just can't be bigger than that! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_INCLUDE_JNG /* length checks */ |
| if (pData->bHasJHDR) |
| { |
| if ((pData->iJHDRcolortype == 8) && (iRawlen != 1)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iJHDRcolortype == 10) && (iRawlen != 3)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iJHDRcolortype == 12) && (iRawlen != 2)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iJHDRcolortype == 14) && (iRawlen != 4)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| #endif /* MNG_INCLUDE_JNG */ |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| { |
| if ((pData->iColortype == 0) && (iRawlen != 1)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iColortype == 2) && (iRawlen != 3)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iColortype == 3) && (iRawlen != 3)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iColortype == 4) && (iRawlen != 2)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((pData->iColortype == 6) && (iRawlen != 4)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { /* global = empty or RGBA */ |
| if ((iRawlen != 0) && (iRawlen != 4)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_sbitp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| #ifdef MNG_INCLUDE_JNG |
| if (pData->bHasJHDR) |
| ((mng_sbitp)*ppChunk)->iType = pData->iJHDRcolortype; |
| else |
| #endif |
| if (pData->bHasIHDR) |
| ((mng_sbitp)*ppChunk)->iType = pData->iColortype; |
| else /* global ! */ |
| ((mng_sbitp)*ppChunk)->iType = 6; |
| |
| if (iRawlen > 0) |
| ((mng_sbitp)*ppChunk)->aBits [0] = *pRawdata; |
| if (iRawlen > 1) |
| ((mng_sbitp)*ppChunk)->aBits [1] = *(pRawdata+1); |
| if (iRawlen > 2) |
| ((mng_sbitp)*ppChunk)->aBits [2] = *(pRawdata+2); |
| if (iRawlen > 3) |
| ((mng_sbitp)*ppChunk)->aBits [3] = *(pRawdata+3); |
| |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_sPLT |
| READ_CHUNK (mng_read_splt) |
| { |
| mng_uint8p pTemp; |
| mng_uint32 iNamelen; |
| mng_uint8 iSampledepth; |
| mng_uint32 iRemain; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (pData->bHasIDAT) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen) |
| { |
| pTemp = find_null (pRawdata); /* find null-separator */ |
| /* not found inside input-data ? */ |
| if ((pTemp - pRawdata) > (mng_int32)iRawlen) |
| MNG_ERROR (pData, MNG_NULLNOTFOUND); |
| |
| iNamelen = (mng_uint32)(pTemp - pRawdata); |
| iSampledepth = *(pTemp+1); |
| iRemain = (iRawlen - 2 - iNamelen); |
| |
| if ((iSampledepth != 1) && (iSampledepth != 2)) |
| MNG_ERROR (pData, MNG_INVSAMPLEDEPTH); |
| /* check remaining length */ |
| if ( ((iSampledepth == 1) && (iRemain % 6 != 0)) || |
| ((iSampledepth == 2) && (iRemain % 10 != 0)) ) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| } |
| else |
| { |
| pTemp = MNG_NULL; |
| iNamelen = 0; |
| iSampledepth = 0; |
| iRemain = 0; |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_spltp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| ((mng_spltp)*ppChunk)->iNamesize = iNamelen; |
| ((mng_spltp)*ppChunk)->iSampledepth = iSampledepth; |
| |
| if (iSampledepth == 1) |
| ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 6; |
| else |
| ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 10; |
| |
| if (iNamelen) |
| { |
| MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->zName, iNamelen+1); |
| MNG_COPY (((mng_spltp)*ppChunk)->zName, pRawdata, iNamelen); |
| } |
| |
| if (iRemain) |
| { |
| MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->pEntries, iRemain); |
| MNG_COPY (((mng_spltp)*ppChunk)->pEntries, pTemp+2, iRemain); |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_hIST |
| READ_CHUNK (mng_read_hist) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if ((!pData->bHasPLTE) || (pData->bHasIDAT)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* length oke ? */ |
| if ( ((iRawlen & 0x01) != 0) || ((iRawlen >> 1) != pData->iPLTEcount) ) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { |
| mng_uint32 iX; |
| /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_histp)*ppChunk)->iEntrycount = iRawlen >> 1; |
| |
| for (iX = 0; iX < (iRawlen >> 1); iX++) |
| { |
| ((mng_histp)*ppChunk)->aEntries [iX] = mng_get_uint16 (pRawdata); |
| pRawdata += 2; |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_tIME |
| READ_CHUNK (mng_read_time) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 7) /* length must be exactly 7 */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| /* if (pData->fProcesstime) */ /* inform the application ? */ |
| /* { |
| |
| pData->fProcesstime ((mng_handle)pData, ); |
| } */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_timep)*ppChunk)->iYear = mng_get_uint16 (pRawdata); |
| ((mng_timep)*ppChunk)->iMonth = *(pRawdata+2); |
| ((mng_timep)*ppChunk)->iDay = *(pRawdata+3); |
| ((mng_timep)*ppChunk)->iHour = *(pRawdata+4); |
| ((mng_timep)*ppChunk)->iMinute = *(pRawdata+5); |
| ((mng_timep)*ppChunk)->iSecond = *(pRawdata+6); |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_mhdr) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_START); |
| #endif |
| |
| if (pData->eSigtype != mng_it_mng) /* sequence checks */ |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| |
| if (pData->bHasheader) /* can only be the first chunk! */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* correct length ? */ |
| #ifndef MNG_NO_OLD_VERSIONS |
| if ((iRawlen != 28) && (iRawlen != 12)) |
| #else |
| if ((iRawlen != 28)) |
| #endif |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasMHDR = MNG_TRUE; /* oh boy, a real MNG */ |
| pData->bHasheader = MNG_TRUE; /* we've got a header */ |
| pData->eImagetype = mng_it_mng; /* fill header fields */ |
| pData->iWidth = mng_get_uint32 (pRawdata); |
| pData->iHeight = mng_get_uint32 (pRawdata+4); |
| pData->iTicks = mng_get_uint32 (pRawdata+8); |
| |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (iRawlen == 28) /* proper MHDR ? */ |
| { |
| #endif |
| pData->iLayercount = mng_get_uint32 (pRawdata+12); |
| pData->iFramecount = mng_get_uint32 (pRawdata+16); |
| pData->iPlaytime = mng_get_uint32 (pRawdata+20); |
| pData->iSimplicity = mng_get_uint32 (pRawdata+24); |
| |
| #ifndef MNG_NO_OLD_VERSIONS |
| pData->bPreDraft48 = MNG_FALSE; |
| } |
| else /* probably pre-draft48 then */ |
| { |
| pData->iLayercount = 0; |
| pData->iFramecount = 0; |
| pData->iPlaytime = 0; |
| pData->iSimplicity = 0; |
| |
| pData->bPreDraft48 = MNG_TRUE; |
| } |
| #endif |
| /* predict alpha-depth */ |
| if ((pData->iSimplicity & 0x00000001) == 0) |
| #ifndef MNG_NO_16BIT_SUPPORT |
| pData->iAlphadepth = 16; /* no indicators = assume the worst */ |
| #else |
| pData->iAlphadepth = 8; /* anything else = assume the worst */ |
| #endif |
| else |
| if ((pData->iSimplicity & 0x00000008) == 0) |
| pData->iAlphadepth = 0; /* no transparency at all */ |
| else |
| if ((pData->iSimplicity & 0x00000140) == 0x00000040) |
| pData->iAlphadepth = 1; /* no semi-transparency guaranteed */ |
| else |
| #ifndef MNG_NO_16BIT_SUPPORT |
| pData->iAlphadepth = 16; /* anything else = assume the worst */ |
| #else |
| pData->iAlphadepth = 8; /* anything else = assume the worst */ |
| #endif |
| |
| #ifdef MNG_INCLUDE_JNG /* can we handle the complexity ? */ |
| if (pData->iSimplicity & 0x0000FC00) |
| #else |
| if (pData->iSimplicity & 0x0000FC10) |
| #endif |
| MNG_ERROR (pData, MNG_MNGTOOCOMPLEX); |
| /* fits on maximum canvas ? */ |
| if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight)) |
| MNG_WARNING (pData, MNG_IMAGETOOLARGE); |
| |
| if (pData->fProcessheader) /* inform the app ? */ |
| if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight)) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| |
| pData->iImagelevel++; /* one level deeper */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_mhdrp)*ppChunk)->iWidth = pData->iWidth; |
| ((mng_mhdrp)*ppChunk)->iHeight = pData->iHeight; |
| ((mng_mhdrp)*ppChunk)->iTicks = pData->iTicks; |
| ((mng_mhdrp)*ppChunk)->iLayercount = pData->iLayercount; |
| ((mng_mhdrp)*ppChunk)->iFramecount = pData->iFramecount; |
| ((mng_mhdrp)*ppChunk)->iPlaytime = pData->iPlaytime; |
| ((mng_mhdrp)*ppChunk)->iSimplicity = pData->iSimplicity; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_mend) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen > 0) /* must not contain data! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { /* do something */ |
| mng_retcode iRetcode = mng_process_display_mend (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| if (!pData->iTotalframes) /* save totals */ |
| pData->iTotalframes = pData->iFrameseq; |
| if (!pData->iTotallayers) |
| pData->iTotallayers = pData->iLayerseq; |
| if (!pData->iTotalplaytime) |
| pData->iTotalplaytime = pData->iFrametime; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| pData->bHasMHDR = MNG_FALSE; /* end of the line, bro! */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_LOOP |
| READ_CHUNK (mng_read_loop) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (!pData->bCacheplayback) /* must store playback info to work!! */ |
| MNG_ERROR (pData, MNG_LOOPWITHCACHEOFF); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen >= 5) /* length checks */ |
| { |
| if (iRawlen >= 6) |
| { |
| if ((iRawlen - 6) % 4 != 0) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_uint8 iLevel; |
| mng_uint32 iRepeat; |
| mng_uint8 iTermination = 0; |
| mng_uint32 iItermin = 1; |
| mng_uint32 iItermax = 0x7fffffffL; |
| mng_retcode iRetcode; |
| |
| pData->bHasLOOP = MNG_TRUE; /* indicate we're inside a loop */ |
| |
| iLevel = *pRawdata; /* determine the fields for processing */ |
| |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (pData->bPreDraft48) |
| { |
| iTermination = *(pRawdata+1); |
| |
| iRepeat = mng_get_uint32 (pRawdata+2); |
| } |
| else |
| #endif |
| iRepeat = mng_get_uint32 (pRawdata+1); |
| |
| if (iRawlen >= 6) |
| { |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (!pData->bPreDraft48) |
| #endif |
| iTermination = *(pRawdata+5); |
| |
| if (iRawlen >= 10) |
| { |
| iItermin = mng_get_uint32 (pRawdata+6); |
| |
| if (iRawlen >= 14) |
| { |
| iItermax = mng_get_uint32 (pRawdata+10); |
| |
| /* TODO: process signals */ |
| |
| } |
| } |
| } |
| /* create the LOOP ani-object */ |
| iRetcode = mng_create_ani_loop (pData, iLevel, iRepeat, iTermination, |
| iItermin, iItermax, 0, 0); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* skip till matching ENDL if iteration=0 */ |
| if ((!pData->bSkipping) && (iRepeat == 0)) |
| pData->bSkipping = MNG_TRUE; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| if (iRawlen >= 5) /* store the fields */ |
| { |
| ((mng_loopp)*ppChunk)->iLevel = *pRawdata; |
| |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (pData->bPreDraft48) |
| { |
| ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+1); |
| ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+2); |
| } |
| else |
| #endif |
| { |
| ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+1); |
| } |
| |
| if (iRawlen >= 6) |
| { |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (!pData->bPreDraft48) |
| #endif |
| ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+5); |
| |
| if (iRawlen >= 10) |
| { |
| ((mng_loopp)*ppChunk)->iItermin = mng_get_uint32 (pRawdata+6); |
| |
| #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED |
| if (iRawlen >= 14) |
| { |
| ((mng_loopp)*ppChunk)->iItermax = mng_get_uint32 (pRawdata+10); |
| ((mng_loopp)*ppChunk)->iCount = (iRawlen - 14) / 4; |
| |
| if (((mng_loopp)*ppChunk)->iCount) |
| { |
| MNG_ALLOC (pData, ((mng_loopp)*ppChunk)->pSignals, |
| ((mng_loopp)*ppChunk)->iCount << 2); |
| |
| #ifndef MNG_BIGENDIAN_SUPPORTED |
| { |
| mng_uint32 iX; |
| mng_uint8p pIn = pRawdata + 14; |
| mng_uint32p pOut = (mng_uint32p)((mng_loopp)*ppChunk)->pSignals; |
| |
| for (iX = 0; iX < ((mng_loopp)*ppChunk)->iCount; iX++) |
| { |
| *pOut++ = mng_get_uint32 (pIn); |
| pIn += 4; |
| } |
| } |
| #else |
| MNG_COPY (((mng_loopp)*ppChunk)->pSignals, pRawdata + 14, |
| ((mng_loopp)*ppChunk)->iCount << 2); |
| #endif /* !MNG_BIGENDIAN_SUPPORTED */ |
| } |
| } |
| #endif |
| } |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_LOOP |
| READ_CHUNK (mng_read_endl) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 1) /* length must be exactly 1 */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| if (pData->bHasLOOP) /* are we really processing a loop ? */ |
| { |
| mng_uint8 iLevel = *pRawdata; /* get the nest level */ |
| /* create an ENDL animation object */ |
| mng_retcode iRetcode = mng_create_ani_endl (pData, iLevel); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| /* { |
| mng_ani_endlp pENDL = (mng_ani_endlp)pData->pLastaniobj; |
| |
| iRetcode = pENDL->sHeader.fProcess (pData, pENDL); |
| |
| if (iRetcode) |
| return iRetcode; |
| } */ |
| } |
| else |
| MNG_ERROR (pData, MNG_NOMATCHINGLOOP); |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_endlp)*ppChunk)->iLevel = *pRawdata; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_DEFI |
| READ_CHUNK (mng_read_defi) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check the length */ |
| if ((iRawlen != 2) && (iRawlen != 3) && (iRawlen != 4) && |
| (iRawlen != 12) && (iRawlen != 28)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| |
| pData->iDEFIobjectid = mng_get_uint16 (pRawdata); |
| |
| if (iRawlen > 2) |
| { |
| pData->bDEFIhasdonotshow = MNG_TRUE; |
| pData->iDEFIdonotshow = *(pRawdata+2); |
| } |
| else |
| { |
| pData->bDEFIhasdonotshow = MNG_FALSE; |
| pData->iDEFIdonotshow = 0; |
| } |
| |
| if (iRawlen > 3) |
| { |
| pData->bDEFIhasconcrete = MNG_TRUE; |
| pData->iDEFIconcrete = *(pRawdata+3); |
| } |
| else |
| { |
| pData->bDEFIhasconcrete = MNG_FALSE; |
| pData->iDEFIconcrete = 0; |
| } |
| |
| if (iRawlen > 4) |
| { |
| pData->bDEFIhasloca = MNG_TRUE; |
| pData->iDEFIlocax = mng_get_int32 (pRawdata+4); |
| pData->iDEFIlocay = mng_get_int32 (pRawdata+8); |
| } |
| else |
| { |
| pData->bDEFIhasloca = MNG_FALSE; |
| pData->iDEFIlocax = 0; |
| pData->iDEFIlocay = 0; |
| } |
| |
| if (iRawlen > 12) |
| { |
| pData->bDEFIhasclip = MNG_TRUE; |
| pData->iDEFIclipl = mng_get_int32 (pRawdata+12); |
| pData->iDEFIclipr = mng_get_int32 (pRawdata+16); |
| pData->iDEFIclipt = mng_get_int32 (pRawdata+20); |
| pData->iDEFIclipb = mng_get_int32 (pRawdata+24); |
| } |
| else |
| { |
| pData->bDEFIhasclip = MNG_FALSE; |
| pData->iDEFIclipl = 0; |
| pData->iDEFIclipr = 0; |
| pData->iDEFIclipt = 0; |
| pData->iDEFIclipb = 0; |
| } |
| /* create an animation object */ |
| iRetcode = mng_create_ani_defi (pData); |
| |
| if (!iRetcode) /* do display processing */ |
| iRetcode = mng_process_display_defi (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_defip)*ppChunk)->iObjectid = mng_get_uint16 (pRawdata); |
| |
| if (iRawlen > 2) |
| { |
| ((mng_defip)*ppChunk)->bHasdonotshow = MNG_TRUE; |
| ((mng_defip)*ppChunk)->iDonotshow = *(pRawdata+2); |
| } |
| else |
| ((mng_defip)*ppChunk)->bHasdonotshow = MNG_FALSE; |
| |
| if (iRawlen > 3) |
| { |
| ((mng_defip)*ppChunk)->bHasconcrete = MNG_TRUE; |
| ((mng_defip)*ppChunk)->iConcrete = *(pRawdata+3); |
| } |
| else |
| ((mng_defip)*ppChunk)->bHasconcrete = MNG_FALSE; |
| |
| if (iRawlen > 4) |
| { |
| ((mng_defip)*ppChunk)->bHasloca = MNG_TRUE; |
| ((mng_defip)*ppChunk)->iXlocation = mng_get_int32 (pRawdata+4); |
| ((mng_defip)*ppChunk)->iYlocation = mng_get_int32 (pRawdata+8); |
| } |
| else |
| ((mng_defip)*ppChunk)->bHasloca = MNG_FALSE; |
| |
| if (iRawlen > 12) |
| { |
| ((mng_defip)*ppChunk)->bHasclip = MNG_TRUE; |
| ((mng_defip)*ppChunk)->iLeftcb = mng_get_int32 (pRawdata+12); |
| ((mng_defip)*ppChunk)->iRightcb = mng_get_int32 (pRawdata+16); |
| ((mng_defip)*ppChunk)->iTopcb = mng_get_int32 (pRawdata+20); |
| ((mng_defip)*ppChunk)->iBottomcb = mng_get_int32 (pRawdata+24); |
| } |
| else |
| ((mng_defip)*ppChunk)->bHasclip = MNG_FALSE; |
| |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_BASI |
| READ_CHUNK (mng_read_basi) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check the length */ |
| if ((iRawlen != 13) && (iRawlen != 19) && (iRawlen != 21) && (iRawlen != 22)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasBASI = MNG_TRUE; /* inside a BASI-IEND block now */ |
| /* store interesting fields */ |
| pData->iDatawidth = mng_get_uint32 (pRawdata); |
| pData->iDataheight = mng_get_uint32 (pRawdata+4); |
| pData->iBitdepth = *(pRawdata+8); |
| pData->iColortype = *(pRawdata+9); |
| pData->iCompression = *(pRawdata+10); |
| pData->iFilter = *(pRawdata+11); |
| pData->iInterlace = *(pRawdata+12); |
| |
| |
| #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT) |
| pData->iPNGmult = 1; |
| pData->iPNGdepth = pData->iBitdepth; |
| #endif |
| |
| #ifdef MNG_NO_1_2_4BIT_SUPPORT |
| if (pData->iBitdepth < 8) |
| pData->iBitdepth = 8; |
| #endif |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (pData->iBitdepth > 8) |
| { |
| pData->iBitdepth = 8; |
| pData->iPNGmult = 2; |
| } |
| #endif |
| |
| if ((pData->iBitdepth != 8) /* parameter validity checks */ |
| #ifndef MNG_NO_1_2_4BIT_SUPPORT |
| && (pData->iBitdepth != 1) && |
| (pData->iBitdepth != 2) && |
| (pData->iBitdepth != 4) |
| #endif |
| #ifndef MNG_NO_16BIT_SUPPORT |
| && (pData->iBitdepth != 16) |
| #endif |
| ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if ((pData->iColortype != MNG_COLORTYPE_GRAY ) && |
| (pData->iColortype != MNG_COLORTYPE_RGB ) && |
| (pData->iColortype != MNG_COLORTYPE_INDEXED) && |
| (pData->iColortype != MNG_COLORTYPE_GRAYA ) && |
| (pData->iColortype != MNG_COLORTYPE_RGBA ) ) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| |
| if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8)) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if (((pData->iColortype == MNG_COLORTYPE_RGB ) || |
| (pData->iColortype == MNG_COLORTYPE_GRAYA ) || |
| (pData->iColortype == MNG_COLORTYPE_RGBA ) ) && |
| (pData->iBitdepth < 8 ) ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if (pData->iCompression != MNG_COMPRESSION_DEFLATE) |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| #if defined(FILTER192) || defined(FILTER193) |
| if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) && |
| #if defined(FILTER192) && defined(FILTER193) |
| (pData->iFilter != MNG_FILTER_DIFFERING) && |
| (pData->iFilter != MNG_FILTER_NOFILTER ) ) |
| #else |
| #ifdef FILTER192 |
| (pData->iFilter != MNG_FILTER_DIFFERING) ) |
| #else |
| (pData->iFilter != MNG_FILTER_NOFILTER ) ) |
| #endif |
| #endif |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| #else |
| if (pData->iFilter) |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| #endif |
| |
| if ((pData->iInterlace != MNG_INTERLACE_NONE ) && |
| (pData->iInterlace != MNG_INTERLACE_ADAM7) ) |
| MNG_ERROR (pData, MNG_INVALIDINTERLACE); |
| |
| pData->iImagelevel++; /* one level deeper */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_uint16 iRed = 0; |
| mng_uint16 iGreen = 0; |
| mng_uint16 iBlue = 0; |
| mng_bool bHasalpha = MNG_FALSE; |
| mng_uint16 iAlpha = 0xFFFF; |
| mng_uint8 iViewable = 0; |
| mng_retcode iRetcode; |
| |
| if (iRawlen > 13) /* get remaining fields, if any */ |
| { |
| iRed = mng_get_uint16 (pRawdata+13); |
| iGreen = mng_get_uint16 (pRawdata+15); |
| iBlue = mng_get_uint16 (pRawdata+17); |
| } |
| |
| if (iRawlen > 19) |
| { |
| bHasalpha = MNG_TRUE; |
| iAlpha = mng_get_uint16 (pRawdata+19); |
| } |
| |
| if (iRawlen > 21) |
| iViewable = *(pRawdata+21); |
| /* create an animation object */ |
| iRetcode = mng_create_ani_basi (pData, iRed, iGreen, iBlue, |
| bHasalpha, iAlpha, iViewable); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_basi (pData, iRed, iGreen, iBlue, |
| bHasalpha, iAlpha, iViewable); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_basip)*ppChunk)->iWidth = mng_get_uint32 (pRawdata); |
| ((mng_basip)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4); |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (*(pRawdata+8) > 8) |
| ((mng_basip)*ppChunk)->iBitdepth = 8; |
| else |
| #endif |
| ((mng_basip)*ppChunk)->iBitdepth = *(pRawdata+8); |
| ((mng_basip)*ppChunk)->iColortype = *(pRawdata+9); |
| ((mng_basip)*ppChunk)->iCompression = *(pRawdata+10); |
| ((mng_basip)*ppChunk)->iFilter = *(pRawdata+11); |
| ((mng_basip)*ppChunk)->iInterlace = *(pRawdata+12); |
| |
| if (iRawlen > 13) |
| { |
| ((mng_basip)*ppChunk)->iRed = mng_get_uint16 (pRawdata+13); |
| ((mng_basip)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+15); |
| ((mng_basip)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+17); |
| } |
| |
| if (iRawlen > 19) |
| ((mng_basip)*ppChunk)->iAlpha = mng_get_uint16 (pRawdata+19); |
| |
| if (iRawlen > 21) |
| ((mng_basip)*ppChunk)->iViewable = *(pRawdata+21); |
| |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_CLON |
| READ_CHUNK (mng_read_clon) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check the length */ |
| if ((iRawlen != 4) && (iRawlen != 5) && (iRawlen != 6) && |
| (iRawlen != 7) && (iRawlen != 16)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_uint16 iSourceid, iCloneid; |
| mng_uint8 iClonetype = 0; |
| mng_bool bHasdonotshow = MNG_FALSE; |
| mng_uint8 iDonotshow = 0; |
| mng_uint8 iConcrete = 0; |
| mng_bool bHasloca = MNG_FALSE; |
| mng_uint8 iLocationtype = 0; |
| mng_int32 iLocationx = 0; |
| mng_int32 iLocationy = 0; |
| mng_retcode iRetcode; |
| |
| iSourceid = mng_get_uint16 (pRawdata); |
| iCloneid = mng_get_uint16 (pRawdata+2); |
| |
| if (iRawlen > 4) |
| iClonetype = *(pRawdata+4); |
| |
| if (iRawlen > 5) |
| { |
| bHasdonotshow = MNG_TRUE; |
| iDonotshow = *(pRawdata+5); |
| } |
| |
| if (iRawlen > 6) |
| iConcrete = *(pRawdata+6); |
| |
| if (iRawlen > 7) |
| { |
| bHasloca = MNG_TRUE; |
| iLocationtype = *(pRawdata+7); |
| iLocationx = mng_get_int32 (pRawdata+8); |
| iLocationy = mng_get_int32 (pRawdata+12); |
| } |
| |
| iRetcode = mng_create_ani_clon (pData, iSourceid, iCloneid, iClonetype, |
| bHasdonotshow, iDonotshow, iConcrete, |
| bHasloca, iLocationtype, iLocationx, iLocationy); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_clon (pData, iSourceid, iCloneid, iClonetype, |
| bHasdonotshow, iDonotshow, iConcrete, |
| bHasloca, iLocationtype, iLocationx, |
| iLocationy); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_clonp)*ppChunk)->iSourceid = mng_get_uint16 (pRawdata); |
| ((mng_clonp)*ppChunk)->iCloneid = mng_get_uint16 (pRawdata+2); |
| |
| if (iRawlen > 4) |
| ((mng_clonp)*ppChunk)->iClonetype = *(pRawdata+4); |
| |
| if (iRawlen > 5) |
| ((mng_clonp)*ppChunk)->iDonotshow = *(pRawdata+5); |
| |
| if (iRawlen > 6) |
| ((mng_clonp)*ppChunk)->iConcrete = *(pRawdata+6); |
| |
| if (iRawlen > 7) |
| { |
| ((mng_clonp)*ppChunk)->bHasloca = MNG_TRUE; |
| ((mng_clonp)*ppChunk)->iLocationtype = *(pRawdata+7); |
| ((mng_clonp)*ppChunk)->iLocationx = mng_get_int32 (pRawdata+8); |
| ((mng_clonp)*ppChunk)->iLocationy = mng_get_int32 (pRawdata+12); |
| } |
| else |
| { |
| ((mng_clonp)*ppChunk)->bHasloca = MNG_FALSE; |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_PAST |
| READ_CHUNK (mng_read_past) |
| { |
| #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY) |
| mng_retcode iRetcode; |
| mng_uint16 iTargetid; |
| mng_uint8 iTargettype; |
| mng_int32 iTargetx; |
| mng_int32 iTargety; |
| mng_uint32 iCount; |
| mng_uint32 iSize; |
| mng_ptr pSources; |
| mng_uint32 iX; |
| mng_past_sourcep pSource; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| /* check the length */ |
| if ((iRawlen < 41) || (((iRawlen - 11) % 30) != 0)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY) |
| iTargetid = mng_get_uint16 (pRawdata); |
| iTargettype = *(pRawdata+2); |
| iTargetx = mng_get_int32 (pRawdata+3); |
| iTargety = mng_get_int32 (pRawdata+7); |
| iCount = ((iRawlen - 11) / 30); /* how many entries again? */ |
| iSize = iCount * sizeof (mng_past_source); |
| |
| pRawdata += 11; |
| /* get a buffer for all the source blocks */ |
| MNG_ALLOC (pData, pSources, iSize); |
| |
| pSource = (mng_past_sourcep)pSources; |
| |
| for (iX = 0; iX < iCount; iX++) /* now copy the source blocks */ |
| { |
| pSource->iSourceid = mng_get_uint16 (pRawdata); |
| pSource->iComposition = *(pRawdata+2); |
| pSource->iOrientation = *(pRawdata+3); |
| pSource->iOffsettype = *(pRawdata+4); |
| pSource->iOffsetx = mng_get_int32 (pRawdata+5); |
| pSource->iOffsety = mng_get_int32 (pRawdata+9); |
| pSource->iBoundarytype = *(pRawdata+13); |
| pSource->iBoundaryl = mng_get_int32 (pRawdata+14); |
| pSource->iBoundaryr = mng_get_int32 (pRawdata+18); |
| pSource->iBoundaryt = mng_get_int32 (pRawdata+22); |
| pSource->iBoundaryb = mng_get_int32 (pRawdata+26); |
| |
| pSource++; |
| pRawdata += 30; |
| } |
| #endif |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { /* create playback object */ |
| iRetcode = mng_create_ani_past (pData, iTargetid, iTargettype, iTargetx, |
| iTargety, iCount, pSources); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_past (pData, iTargetid, iTargettype, iTargetx, |
| iTargety, iCount, pSources); */ |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pSources, iSize); |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pSources, iSize); |
| return iRetcode; |
| } |
| /* store the fields */ |
| ((mng_pastp)*ppChunk)->iDestid = iTargetid; |
| ((mng_pastp)*ppChunk)->iTargettype = iTargettype; |
| ((mng_pastp)*ppChunk)->iTargetx = iTargetx; |
| ((mng_pastp)*ppChunk)->iTargety = iTargety; |
| ((mng_pastp)*ppChunk)->iCount = iCount; |
| /* get a buffer & copy the source blocks */ |
| MNG_ALLOC (pData, ((mng_pastp)*ppChunk)->pSources, iSize); |
| MNG_COPY (((mng_pastp)*ppChunk)->pSources, pSources, iSize); |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY) |
| /* free the source block buffer */ |
| MNG_FREEX (pData, pSources, iSize); |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_DISC |
| READ_CHUNK (mng_read_disc) |
| { |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| mng_uint32 iCount; |
| mng_uint16p pIds = MNG_NULL; |
| mng_retcode iRetcode; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if ((iRawlen % 2) != 0) /* check the length */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| iCount = (iRawlen / sizeof (mng_uint16)); |
| |
| if (iCount) |
| { |
| MNG_ALLOC (pData, pIds, iRawlen); |
| |
| #ifndef MNG_BIGENDIAN_SUPPORTED |
| { |
| mng_uint32 iX; |
| mng_uint8p pIn = pRawdata; |
| mng_uint16p pOut = pIds; |
| |
| for (iX = 0; iX < iCount; iX++) |
| { |
| *pOut++ = mng_get_uint16 (pIn); |
| pIn += 2; |
| } |
| } |
| #else |
| MNG_COPY (pIds, pRawdata, iRawlen); |
| #endif /* !MNG_BIGENDIAN_SUPPORTED */ |
| } |
| #endif |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { /* create playback object */ |
| iRetcode = mng_create_ani_disc (pData, iCount, pIds); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_disc (pData, iCount, pIds); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_discp)*ppChunk)->iCount = iCount; |
| |
| if (iRawlen) |
| { |
| MNG_ALLOC (pData, ((mng_discp)*ppChunk)->pObjectids, iRawlen); |
| MNG_COPY (((mng_discp)*ppChunk)->pObjectids, pIds, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| if (iRawlen) |
| MNG_FREEX (pData, pIds, iRawlen); |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_BACK |
| READ_CHUNK (mng_read_back) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check the length */ |
| if ((iRawlen != 6) && (iRawlen != 7) && (iRawlen != 9) && (iRawlen != 10)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| /* retrieve the fields */ |
| pData->bHasBACK = MNG_TRUE; |
| pData->iBACKred = mng_get_uint16 (pRawdata); |
| pData->iBACKgreen = mng_get_uint16 (pRawdata+2); |
| pData->iBACKblue = mng_get_uint16 (pRawdata+4); |
| |
| if (iRawlen > 6) |
| pData->iBACKmandatory = *(pRawdata+6); |
| else |
| pData->iBACKmandatory = 0; |
| |
| if (iRawlen > 7) |
| pData->iBACKimageid = mng_get_uint16 (pRawdata+7); |
| else |
| pData->iBACKimageid = 0; |
| |
| if (iRawlen > 9) |
| pData->iBACKtile = *(pRawdata+9); |
| else |
| pData->iBACKtile = 0; |
| |
| iRetcode = mng_create_ani_back (pData, pData->iBACKred, pData->iBACKgreen, |
| pData->iBACKblue, pData->iBACKmandatory, |
| pData->iBACKimageid, pData->iBACKtile); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_backp)*ppChunk)->iRed = mng_get_uint16 (pRawdata); |
| ((mng_backp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2); |
| ((mng_backp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4); |
| |
| if (iRawlen > 6) |
| ((mng_backp)*ppChunk)->iMandatory = *(pRawdata+6); |
| |
| if (iRawlen > 7) |
| ((mng_backp)*ppChunk)->iImageid = mng_get_uint16 (pRawdata+7); |
| |
| if (iRawlen > 9) |
| ((mng_backp)*ppChunk)->iTile = *(pRawdata+9); |
| |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_FRAM |
| READ_CHUNK (mng_read_fram) |
| { |
| mng_uint8p pTemp; |
| #ifdef MNG_STORE_CHUNKS |
| mng_uint32 iNamelen; |
| #endif |
| mng_uint32 iRemain; |
| mng_uint32 iRequired = 0; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen <= 1) /* only framing-mode ? */ |
| { |
| #ifdef MNG_STORE_CHUNKS |
| iNamelen = 0; /* indicate so */ |
| #endif |
| iRemain = 0; |
| pTemp = MNG_NULL; |
| } |
| else |
| { |
| pTemp = find_null (pRawdata+1); /* find null-separator */ |
| /* not found inside input-data ? */ |
| if ((pTemp - pRawdata) > (mng_int32)iRawlen) |
| pTemp = pRawdata + iRawlen; /* than remainder is name */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| iNamelen = (mng_uint32)((pTemp - pRawdata) - 1); |
| #endif |
| iRemain = (mng_uint32)(iRawlen - (pTemp - pRawdata)); |
| |
| if (iRemain) /* if there is remaining data it's less 1 byte */ |
| iRemain--; |
| |
| if ((iRemain) && (iRemain < 4)) /* remains must be empty or at least 4 bytes */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if (iRemain) |
| { |
| iRequired = 4; /* calculate and check required remaining length */ |
| |
| if (*(pTemp+1)) { iRequired += 4; } |
| if (*(pTemp+2)) { iRequired += 4; } |
| if (*(pTemp+3)) { iRequired += 17; } |
| |
| if (*(pTemp+4)) |
| { |
| if ((iRemain - iRequired) % 4 != 0) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| else |
| { |
| if (iRemain != iRequired) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| } |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_uint8p pWork = pTemp; |
| mng_uint8 iFramemode = 0; |
| mng_uint8 iChangedelay = 0; |
| mng_uint32 iDelay = 0; |
| mng_uint8 iChangetimeout = 0; |
| mng_uint32 iTimeout = 0; |
| mng_uint8 iChangeclipping = 0; |
| mng_uint8 iCliptype = 0; |
| mng_int32 iClipl = 0; |
| mng_int32 iClipr = 0; |
| mng_int32 iClipt = 0; |
| mng_int32 iClipb = 0; |
| mng_retcode iRetcode; |
| |
| if (iRawlen) /* any data specified ? */ |
| { |
| if (*(pRawdata)) /* save the new framing mode ? */ |
| { |
| iFramemode = *(pRawdata); |
| |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (pData->bPreDraft48) /* old style input-stream ? */ |
| { |
| switch (iFramemode) |
| { |
| case 0: { break; } |
| case 1: { iFramemode = 3; break; } |
| case 2: { iFramemode = 4; break; } |
| case 3: { iFramemode = 1; break; } |
| case 4: { iFramemode = 1; break; } |
| case 5: { iFramemode = 2; break; } |
| default: { iFramemode = 1; break; } |
| } |
| } |
| #endif |
| } |
| |
| if (iRemain) |
| { |
| iChangedelay = *(pWork+1); |
| iChangetimeout = *(pWork+2); |
| iChangeclipping = *(pWork+3); |
| pWork += 5; |
| |
| if (iChangedelay) /* delay changed ? */ |
| { |
| iDelay = mng_get_uint32 (pWork); |
| pWork += 4; |
| } |
| |
| if (iChangetimeout) /* timeout changed ? */ |
| { |
| iTimeout = mng_get_uint32 (pWork); |
| pWork += 4; |
| } |
| |
| if (iChangeclipping) /* clipping changed ? */ |
| { |
| iCliptype = *pWork; |
| iClipl = mng_get_int32 (pWork+1); |
| iClipr = mng_get_int32 (pWork+5); |
| iClipt = mng_get_int32 (pWork+9); |
| iClipb = mng_get_int32 (pWork+13); |
| } |
| } |
| } |
| |
| iRetcode = mng_create_ani_fram (pData, iFramemode, iChangedelay, iDelay, |
| iChangetimeout, iTimeout, |
| iChangeclipping, iCliptype, |
| iClipl, iClipr, iClipt, iClipb); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_fram (pData, iFramemode, iChangedelay, iDelay, |
| iChangetimeout, iTimeout, |
| iChangeclipping, iCliptype, |
| iClipl, iClipr, iClipt, iClipb); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_framp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| mng_uint8 iFramemode = *(pRawdata); |
| |
| #ifndef MNG_NO_OLD_VERSIONS |
| if (pData->bPreDraft48) /* old style input-stream ? */ |
| { |
| switch (iFramemode) |
| { |
| case 1: { iFramemode = 3; break; } |
| case 2: { iFramemode = 4; break; } |
| case 3: { iFramemode = 5; break; } /* TODO: provision for mode=5 ??? */ |
| case 4: { iFramemode = 1; break; } |
| case 5: { iFramemode = 2; break; } |
| default: { iFramemode = 1; break; } |
| } |
| } |
| #endif |
| |
| ((mng_framp)*ppChunk)->iMode = iFramemode; |
| ((mng_framp)*ppChunk)->iNamesize = iNamelen; |
| |
| if (iNamelen) |
| { |
| MNG_ALLOC (pData, ((mng_framp)*ppChunk)->zName, iNamelen+1); |
| MNG_COPY (((mng_framp)*ppChunk)->zName, pRawdata+1, iNamelen); |
| } |
| |
| if (iRemain) |
| { |
| ((mng_framp)*ppChunk)->iChangedelay = *(pTemp+1); |
| ((mng_framp)*ppChunk)->iChangetimeout = *(pTemp+2); |
| ((mng_framp)*ppChunk)->iChangeclipping = *(pTemp+3); |
| ((mng_framp)*ppChunk)->iChangesyncid = *(pTemp+4); |
| |
| pTemp += 5; |
| |
| if (((mng_framp)*ppChunk)->iChangedelay) |
| { |
| ((mng_framp)*ppChunk)->iDelay = mng_get_uint32 (pTemp); |
| pTemp += 4; |
| } |
| |
| if (((mng_framp)*ppChunk)->iChangetimeout) |
| { |
| ((mng_framp)*ppChunk)->iTimeout = mng_get_uint32 (pTemp); |
| pTemp += 4; |
| } |
| |
| if (((mng_framp)*ppChunk)->iChangeclipping) |
| { |
| ((mng_framp)*ppChunk)->iBoundarytype = *pTemp; |
| ((mng_framp)*ppChunk)->iBoundaryl = mng_get_int32 (pTemp+1); |
| ((mng_framp)*ppChunk)->iBoundaryr = mng_get_int32 (pTemp+5); |
| ((mng_framp)*ppChunk)->iBoundaryt = mng_get_int32 (pTemp+9); |
| ((mng_framp)*ppChunk)->iBoundaryb = mng_get_int32 (pTemp+13); |
| pTemp += 17; |
| } |
| |
| if (((mng_framp)*ppChunk)->iChangesyncid) |
| { |
| ((mng_framp)*ppChunk)->iCount = (iRemain - iRequired) / 4; |
| |
| if (((mng_framp)*ppChunk)->iCount) |
| { |
| MNG_ALLOC (pData, ((mng_framp)*ppChunk)->pSyncids, |
| ((mng_framp)*ppChunk)->iCount * 4); |
| |
| #ifndef MNG_BIGENDIAN_SUPPORTED |
| { |
| mng_uint32 iX; |
| mng_uint32p pOut = ((mng_framp)*ppChunk)->pSyncids; |
| |
| for (iX = 0; iX < ((mng_framp)*ppChunk)->iCount; iX++) |
| { |
| *pOut++ = mng_get_uint32 (pTemp); |
| pTemp += 4; |
| } |
| } |
| #else |
| MNG_COPY (((mng_framp)*ppChunk)->pSyncids, pTemp, |
| ((mng_framp)*ppChunk)->iCount * 4); |
| #endif /* !MNG_BIGENDIAN_SUPPORTED */ |
| } |
| } |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_MOVE |
| READ_CHUNK (mng_read_move) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 13) /* check the length */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| /* create a MOVE animation object */ |
| iRetcode = mng_create_ani_move (pData, mng_get_uint16 (pRawdata), |
| mng_get_uint16 (pRawdata+2), |
| *(pRawdata+4), |
| mng_get_int32 (pRawdata+5), |
| mng_get_int32 (pRawdata+9)); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_move (pData, |
| mng_get_uint16 (pRawdata), |
| mng_get_uint16 (pRawdata+2), |
| *(pRawdata+4), |
| mng_get_int32 (pRawdata+5), |
| mng_get_int32 (pRawdata+9)); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_movep)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata); |
| ((mng_movep)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2); |
| ((mng_movep)*ppChunk)->iMovetype = *(pRawdata+4); |
| ((mng_movep)*ppChunk)->iMovex = mng_get_int32 (pRawdata+5); |
| ((mng_movep)*ppChunk)->iMovey = mng_get_int32 (pRawdata+9); |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_CLIP |
| READ_CHUNK (mng_read_clip) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 21) /* check the length */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| /* create a CLIP animation object */ |
| iRetcode = mng_create_ani_clip (pData, mng_get_uint16 (pRawdata), |
| mng_get_uint16 (pRawdata+2), |
| *(pRawdata+4), |
| mng_get_int32 (pRawdata+5), |
| mng_get_int32 (pRawdata+9), |
| mng_get_int32 (pRawdata+13), |
| mng_get_int32 (pRawdata+17)); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_clip (pData, |
| mng_get_uint16 (pRawdata), |
| mng_get_uint16 (pRawdata+2), |
| *(pRawdata+4), |
| mng_get_int32 (pRawdata+5), |
| mng_get_int32 (pRawdata+9), |
| mng_get_int32 (pRawdata+13), |
| mng_get_int32 (pRawdata+17)); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_clipp)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata); |
| ((mng_clipp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2); |
| ((mng_clipp)*ppChunk)->iCliptype = *(pRawdata+4); |
| ((mng_clipp)*ppChunk)->iClipl = mng_get_int32 (pRawdata+5); |
| ((mng_clipp)*ppChunk)->iClipr = mng_get_int32 (pRawdata+9); |
| ((mng_clipp)*ppChunk)->iClipt = mng_get_int32 (pRawdata+13); |
| ((mng_clipp)*ppChunk)->iClipb = mng_get_int32 (pRawdata+17); |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_SHOW |
| READ_CHUNK (mng_read_show) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check the length */ |
| if ((iRawlen != 0) && (iRawlen != 2) && (iRawlen != 4) && (iRawlen != 5)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| |
| if (iRawlen) /* determine parameters if any */ |
| { |
| pData->iSHOWfromid = mng_get_uint16 (pRawdata); |
| |
| if (iRawlen > 2) |
| pData->iSHOWtoid = mng_get_uint16 (pRawdata+2); |
| else |
| pData->iSHOWtoid = pData->iSHOWfromid; |
| |
| if (iRawlen > 4) |
| pData->iSHOWmode = *(pRawdata+4); |
| else |
| pData->iSHOWmode = 0; |
| } |
| else /* use defaults then */ |
| { |
| pData->iSHOWmode = 2; |
| pData->iSHOWfromid = 1; |
| pData->iSHOWtoid = 65535; |
| } |
| /* create a SHOW animation object */ |
| iRetcode = mng_create_ani_show (pData, pData->iSHOWfromid, |
| pData->iSHOWtoid, pData->iSHOWmode); |
| |
| if (!iRetcode) |
| iRetcode = mng_process_display_show (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_showp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| ((mng_showp)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata); |
| |
| if (iRawlen > 2) |
| ((mng_showp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2); |
| else |
| ((mng_showp)*ppChunk)->iLastid = ((mng_showp)*ppChunk)->iFirstid; |
| |
| if (iRawlen > 4) |
| ((mng_showp)*ppChunk)->iMode = *(pRawdata+4); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_TERM |
| READ_CHUNK (mng_read_term) |
| { |
| mng_uint8 iTermaction; |
| mng_uint8 iIteraction = 0; |
| mng_uint32 iDelay = 0; |
| mng_uint32 iItermax = 0; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| /* should be behind MHDR or SAVE !! */ |
| if ((!pData->bHasSAVE) && (pData->iChunkseq > 2)) |
| { |
| pData->bMisplacedTERM = MNG_TRUE; /* indicate we found a misplaced TERM */ |
| /* and send a warning signal!!! */ |
| MNG_WARNING (pData, MNG_SEQUENCEERROR); |
| } |
| |
| if (pData->bHasLOOP) /* no way, jose! */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (pData->bHasTERM) /* only 1 allowed! */ |
| MNG_ERROR (pData, MNG_MULTIPLEERROR); |
| /* check the length */ |
| if ((iRawlen != 1) && (iRawlen != 10)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasTERM = MNG_TRUE; |
| |
| iTermaction = *pRawdata; /* get the fields */ |
| |
| if (iRawlen > 1) |
| { |
| iIteraction = *(pRawdata+1); |
| iDelay = mng_get_uint32 (pRawdata+2); |
| iItermax = mng_get_uint32 (pRawdata+6); |
| } |
| |
| if (pData->fProcessterm) /* inform the app ? */ |
| if (!pData->fProcessterm (((mng_handle)pData), iTermaction, iIteraction, |
| iDelay, iItermax)) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { /* create the TERM ani-object */ |
| mng_retcode iRetcode = mng_create_ani_term (pData, iTermaction, iIteraction, |
| iDelay, iItermax); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* save for future reference */ |
| pData->pTermaniobj = pData->pLastaniobj; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_termp)*ppChunk)->iTermaction = iTermaction; |
| ((mng_termp)*ppChunk)->iIteraction = iIteraction; |
| ((mng_termp)*ppChunk)->iDelay = iDelay; |
| ((mng_termp)*ppChunk)->iItermax = iItermax; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_SAVE |
| READ_CHUNK (mng_read_save) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (pData->bHasSAVE)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| pData->bHasSAVE = MNG_TRUE; |
| |
| if (pData->fProcesssave) /* inform the application ? */ |
| { |
| mng_bool bOke = pData->fProcesssave ((mng_handle)pData); |
| |
| if (!bOke) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| |
| |
| /* TODO: something with the parameters */ |
| |
| |
| /* create a SAVE animation object */ |
| iRetcode = mng_create_ani_save (pData); |
| |
| if (!iRetcode) |
| iRetcode = mng_process_display_save (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_savep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) /* not empty ? */ |
| { |
| mng_uint8 iOtype = *pRawdata; |
| mng_uint8 iEtype; |
| mng_uint32 iCount = 0; |
| mng_uint8p pTemp; |
| mng_uint8p pNull; |
| mng_uint32 iLen; |
| mng_uint32 iOffset[2]; |
| mng_uint32 iStarttime[2]; |
| mng_uint32 iFramenr; |
| mng_uint32 iLayernr; |
| mng_uint32 iX; |
| mng_save_entryp pEntry = MNG_NULL; |
| mng_uint32 iNamesize; |
| |
| if ((iOtype != 4) && (iOtype != 8)) |
| MNG_ERROR (pData, MNG_INVOFFSETSIZE); |
| |
| ((mng_savep)*ppChunk)->iOffsettype = iOtype; |
| |
| for (iX = 0; iX < 2; iX++) /* do this twice to get the count first ! */ |
| { |
| pTemp = pRawdata + 1; |
| iLen = iRawlen - 1; |
| |
| if (iX) /* second run ? */ |
| { |
| MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_save_entry))); |
| |
| ((mng_savep)*ppChunk)->iCount = iCount; |
| ((mng_savep)*ppChunk)->pEntries = pEntry; |
| } |
| |
| while (iLen) /* anything left ? */ |
| { |
| iEtype = *pTemp; /* entrytype */ |
| |
| if ((iEtype != 0) && (iEtype != 1) && (iEtype != 2) && (iEtype != 3)) |
| MNG_ERROR (pData, MNG_INVENTRYTYPE); |
| |
| pTemp++; |
| |
| if (iEtype > 1) |
| { |
| iOffset [0] = 0; |
| iOffset [1] = 0; |
| iStarttime [0] = 0; |
| iStarttime [1] = 0; |
| iLayernr = 0; |
| iFramenr = 0; |
| } |
| else |
| { |
| if (iOtype == 4) |
| { |
| iOffset [0] = 0; |
| iOffset [1] = mng_get_uint32 (pTemp); |
| |
| pTemp += 4; |
| } |
| else |
| { |
| iOffset [0] = mng_get_uint32 (pTemp); |
| iOffset [1] = mng_get_uint32 (pTemp+4); |
| |
| pTemp += 8; |
| } |
| |
| if (iEtype > 0) |
| { |
| iStarttime [0] = 0; |
| iStarttime [1] = 0; |
| iLayernr = 0; |
| iFramenr = 0; |
| } |
| else |
| { |
| if (iOtype == 4) |
| { |
| iStarttime [0] = 0; |
| iStarttime [1] = mng_get_uint32 (pTemp+0); |
| iLayernr = mng_get_uint32 (pTemp+4); |
| iFramenr = mng_get_uint32 (pTemp+8); |
| |
| pTemp += 12; |
| } |
| else |
| { |
| iStarttime [0] = mng_get_uint32 (pTemp+0); |
| iStarttime [1] = mng_get_uint32 (pTemp+4); |
| iLayernr = mng_get_uint32 (pTemp+8); |
| iFramenr = mng_get_uint32 (pTemp+12); |
| |
| pTemp += 16; |
| } |
| } |
| } |
| |
| pNull = find_null (pTemp); /* get the name length */ |
| |
| if ((pNull - pRawdata) > (mng_int32)iRawlen) |
| { |
| iNamesize = iLen; /* no null found; so end of SAVE */ |
| iLen = 0; |
| } |
| else |
| { |
| iNamesize = pNull - pTemp; /* should be another entry */ |
| iLen -= iNamesize; |
| |
| if (!iLen) /* must not end with a null ! */ |
| MNG_ERROR (pData, MNG_ENDWITHNULL); |
| } |
| |
| if (!pEntry) |
| { |
| iCount++; |
| } |
| else |
| { |
| pEntry->iEntrytype = iEtype; |
| pEntry->iOffset [0] = iOffset [0]; |
| pEntry->iOffset [1] = iOffset [1]; |
| pEntry->iStarttime [0] = iStarttime [0]; |
| pEntry->iStarttime [1] = iStarttime [1]; |
| pEntry->iLayernr = iLayernr; |
| pEntry->iFramenr = iFramenr; |
| pEntry->iNamesize = iNamesize; |
| |
| if (iNamesize) |
| { |
| MNG_ALLOC (pData, pEntry->zName, iNamesize+1); |
| MNG_COPY (pEntry->zName, pTemp, iNamesize); |
| } |
| |
| pEntry++; |
| } |
| |
| pTemp += iNamesize; |
| } |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_SEEK |
| READ_CHUNK (mng_read_seek) |
| { |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasSAVE)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| /* create a SEEK animation object */ |
| iRetcode = mng_create_ani_seek (pData, iRawlen, (mng_pchar)pRawdata); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| if (pData->fProcessseek) /* inform the app ? */ |
| { |
| mng_bool bOke; |
| mng_pchar zName; |
| |
| MNG_ALLOC (pData, zName, iRawlen + 1); |
| |
| if (iRawlen) |
| MNG_COPY (zName, pRawdata, iRawlen); |
| |
| bOke = pData->fProcessseek ((mng_handle)pData, zName); |
| |
| MNG_FREEX (pData, zName, iRawlen + 1); |
| |
| if (!bOke) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| /* do display processing of the SEEK */ |
| iRetcode = mng_process_display_seek (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_seekp)*ppChunk)->iNamesize = iRawlen; |
| |
| if (iRawlen) |
| { |
| MNG_ALLOC (pData, ((mng_seekp)*ppChunk)->zName, iRawlen+1); |
| MNG_COPY (((mng_seekp)*ppChunk)->zName, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_eXPI |
| READ_CHUNK (mng_read_expi) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 3) /* check the length */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_expip)*ppChunk)->iSnapshotid = mng_get_uint16 (pRawdata); |
| ((mng_expip)*ppChunk)->iNamesize = iRawlen - 2; |
| |
| if (((mng_expip)*ppChunk)->iNamesize) |
| { |
| MNG_ALLOC (pData, ((mng_expip)*ppChunk)->zName, |
| ((mng_expip)*ppChunk)->iNamesize + 1); |
| MNG_COPY (((mng_expip)*ppChunk)->zName, pRawdata+2, |
| ((mng_expip)*ppChunk)->iNamesize); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_fPRI |
| READ_CHUNK (mng_read_fpri) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 2) /* must be two bytes long */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_fprip)*ppChunk)->iDeltatype = *pRawdata; |
| ((mng_fprip)*ppChunk)->iPriority = *(pRawdata+1); |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_nEED |
| MNG_LOCAL mng_bool CheckKeyword (mng_datap pData, |
| mng_uint8p pKeyword) |
| { |
| mng_chunkid handled_chunks [] = |
| { |
| MNG_UINT_BACK, /* keep it sorted !!!! */ |
| MNG_UINT_BASI, |
| MNG_UINT_CLIP, |
| MNG_UINT_CLON, |
| #ifndef MNG_NO_DELTA_PNG |
| /* TODO: MNG_UINT_DBYK, */ |
| #endif |
| MNG_UINT_DEFI, |
| #ifndef MNG_NO_DELTA_PNG |
| MNG_UINT_DHDR, |
| #endif |
| MNG_UINT_DISC, |
| #ifndef MNG_NO_DELTA_PNG |
| /* TODO: MNG_UINT_DROP, */ |
| #endif |
| MNG_UINT_ENDL, |
| MNG_UINT_FRAM, |
| MNG_UINT_IDAT, |
| MNG_UINT_IEND, |
| MNG_UINT_IHDR, |
| #ifndef MNG_NO_DELTA_PNG |
| #ifdef MNG_INCLUDE_JNG |
| MNG_UINT_IJNG, |
| #endif |
| MNG_UINT_IPNG, |
| #endif |
| #ifdef MNG_INCLUDE_JNG |
| MNG_UINT_JDAA, |
| MNG_UINT_JDAT, |
| MNG_UINT_JHDR, |
| /* TODO: MNG_UINT_JSEP, */ |
| MNG_UINT_JdAA, |
| #endif |
| MNG_UINT_LOOP, |
| MNG_UINT_MAGN, |
| MNG_UINT_MEND, |
| MNG_UINT_MHDR, |
| MNG_UINT_MOVE, |
| /* TODO: MNG_UINT_ORDR, */ |
| MNG_UINT_PAST, |
| MNG_UINT_PLTE, |
| #ifndef MNG_NO_DELTA_PNG |
| MNG_UINT_PPLT, |
| MNG_UINT_PROM, |
| #endif |
| MNG_UINT_SAVE, |
| MNG_UINT_SEEK, |
| MNG_UINT_SHOW, |
| MNG_UINT_TERM, |
| #ifdef MNG_INCLUDE_ANG_PROPOSAL |
| MNG_UINT_adAT, |
| MNG_UINT_ahDR, |
| #endif |
| MNG_UINT_bKGD, |
| MNG_UINT_cHRM, |
| /* TODO: MNG_UINT_eXPI, */ |
| MNG_UINT_evNT, |
| /* TODO: MNG_UINT_fPRI, */ |
| MNG_UINT_gAMA, |
| /* TODO: MNG_UINT_hIST, */ |
| MNG_UINT_iCCP, |
| MNG_UINT_iTXt, |
| #ifdef MNG_INCLUDE_MPNG_PROPOSAL |
| MNG_UINT_mpNG, |
| #endif |
| MNG_UINT_nEED, |
| /* TODO: MNG_UINT_oFFs, */ |
| /* TODO: MNG_UINT_pCAL, */ |
| /* TODO: MNG_UINT_pHYg, */ |
| /* TODO: MNG_UINT_pHYs, */ |
| /* TODO: MNG_UINT_sBIT, */ |
| /* TODO: MNG_UINT_sCAL, */ |
| /* TODO: MNG_UINT_sPLT, */ |
| MNG_UINT_sRGB, |
| MNG_UINT_tEXt, |
| MNG_UINT_tIME, |
| MNG_UINT_tRNS, |
| MNG_UINT_zTXt, |
| }; |
| |
| mng_bool bOke = MNG_FALSE; |
| |
| if (pData->fProcessneed) /* does the app handle it ? */ |
| bOke = pData->fProcessneed ((mng_handle)pData, (mng_pchar)pKeyword); |
| |
| if (!bOke) |
| { /* find the keyword length */ |
| mng_uint8p pNull = find_null (pKeyword); |
| |
| if (pNull - pKeyword == 4) /* test a chunk ? */ |
| { /* get the chunk-id */ |
| mng_chunkid iChunkid = (*pKeyword << 24) + (*(pKeyword+1) << 16) + |
| (*(pKeyword+2) << 8) + (*(pKeyword+3) ); |
| /* binary search variables */ |
| mng_int32 iTop, iLower, iUpper, iMiddle; |
| /* determine max index of table */ |
| iTop = (sizeof (handled_chunks) / sizeof (handled_chunks [0])) - 1; |
| |
| /* binary search; with 52 chunks, worst-case is 7 comparisons */ |
| iLower = 0; |
| iMiddle = iTop >> 1; |
| iUpper = iTop; |
| |
| do /* the binary search itself */ |
| { |
| if (handled_chunks [iMiddle] < iChunkid) |
| iLower = iMiddle + 1; |
| else if (handled_chunks [iMiddle] > iChunkid) |
| iUpper = iMiddle - 1; |
| else |
| { |
| bOke = MNG_TRUE; |
| break; |
| } |
| |
| iMiddle = (iLower + iUpper) >> 1; |
| } |
| while (iLower <= iUpper); |
| } |
| /* test draft ? */ |
| if ((!bOke) && (pNull - pKeyword == 8) && |
| (*pKeyword == 'd') && (*(pKeyword+1) == 'r') && |
| (*(pKeyword+2) == 'a') && (*(pKeyword+3) == 'f') && |
| (*(pKeyword+4) == 't') && (*(pKeyword+5) == ' ')) |
| { |
| mng_uint32 iDraft; |
| |
| iDraft = (*(pKeyword+6) - '0') * 10 + (*(pKeyword+7) - '0'); |
| bOke = (mng_bool)(iDraft <= MNG_MNG_DRAFT); |
| } |
| /* test MNG 1.0/1.1 ? */ |
| if ((!bOke) && (pNull - pKeyword == 7) && |
| (*pKeyword == 'M') && (*(pKeyword+1) == 'N') && |
| (*(pKeyword+2) == 'G') && (*(pKeyword+3) == '-') && |
| (*(pKeyword+4) == '1') && (*(pKeyword+5) == '.') && |
| ((*(pKeyword+6) == '0') || (*(pKeyword+6) == '1'))) |
| bOke = MNG_TRUE; |
| /* test CACHEOFF ? */ |
| if ((!bOke) && (pNull - pKeyword == 8) && |
| (*pKeyword == 'C') && (*(pKeyword+1) == 'A') && |
| (*(pKeyword+2) == 'C') && (*(pKeyword+3) == 'H') && |
| (*(pKeyword+4) == 'E') && (*(pKeyword+5) == 'O') && |
| (*(pKeyword+6) == 'F') && (*(pKeyword+7) == 'F')) |
| { |
| if (!pData->pFirstaniobj) /* only if caching hasn't started yet ! */ |
| { |
| bOke = MNG_TRUE; |
| pData->bCacheplayback = MNG_FALSE; |
| pData->bStorechunks = MNG_FALSE; |
| } |
| } |
| } |
| |
| return bOke; |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_nEED |
| READ_CHUNK (mng_read_need) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 1) /* check the length */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| { /* let's check it */ |
| mng_bool bOke = MNG_TRUE; |
| mng_pchar zKeywords; |
| mng_uint8p pNull, pTemp; |
| |
| MNG_ALLOC (pData, zKeywords, iRawlen + 1); |
| |
| if (iRawlen) |
| MNG_COPY (zKeywords, pRawdata, iRawlen); |
| |
| pTemp = (mng_uint8p)zKeywords; |
| pNull = find_null (pTemp); |
| |
| while ((bOke) && (pNull < (mng_uint8p)zKeywords + iRawlen)) |
| { |
| bOke = CheckKeyword (pData, pTemp); |
| pTemp = pNull + 1; |
| pNull = find_null (pTemp); |
| } |
| |
| if (bOke) |
| bOke = CheckKeyword (pData, pTemp); |
| |
| MNG_FREEX (pData, zKeywords, iRawlen + 1); |
| |
| if (!bOke) |
| MNG_ERROR (pData, MNG_UNSUPPORTEDNEED); |
| } |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_needp)*ppChunk)->iKeywordssize = iRawlen; |
| |
| if (iRawlen) |
| { |
| MNG_ALLOC (pData, ((mng_needp)*ppChunk)->zKeywords, iRawlen+1); |
| MNG_COPY (((mng_needp)*ppChunk)->zKeywords, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_pHYg |
| READ_CHUNK (mng_read_phyg) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* it's 9 bytes or empty; no more, no less! */ |
| if ((iRawlen != 9) && (iRawlen != 0)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_phygp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| |
| if (iRawlen) |
| { |
| ((mng_phygp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata); |
| ((mng_phygp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4); |
| ((mng_phygp)*ppChunk)->iUnit = *(pRawdata+8); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifdef MNG_INCLUDE_JNG |
| READ_CHUNK (mng_read_jhdr) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((pData->eSigtype != mng_it_jng) && (pData->eSigtype != mng_it_mng)) |
| MNG_ERROR (pData, MNG_CHUNKNOTALLOWED); |
| |
| if ((pData->eSigtype == mng_it_jng) && (pData->iChunkseq > 1)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 16) /* length oke ? */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| /* inside a JHDR-IEND block now */ |
| pData->bHasJHDR = MNG_TRUE; |
| /* and store interesting fields */ |
| pData->iDatawidth = mng_get_uint32 (pRawdata); |
| pData->iDataheight = mng_get_uint32 (pRawdata+4); |
| pData->iJHDRcolortype = *(pRawdata+8); |
| pData->iJHDRimgbitdepth = *(pRawdata+9); |
| pData->iJHDRimgcompression = *(pRawdata+10); |
| pData->iJHDRimginterlace = *(pRawdata+11); |
| pData->iJHDRalphabitdepth = *(pRawdata+12); |
| pData->iJHDRalphacompression = *(pRawdata+13); |
| pData->iJHDRalphafilter = *(pRawdata+14); |
| pData->iJHDRalphainterlace = *(pRawdata+15); |
| |
| |
| #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT) |
| pData->iPNGmult = 1; |
| pData->iPNGdepth = pData->iJHDRalphabitdepth; |
| #endif |
| |
| #ifdef MNG_NO_1_2_4BIT_SUPPORT |
| if (pData->iJHDRalphabitdepth < 8) |
| pData->iJHDRalphabitdepth = 8; |
| #endif |
| |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (pData->iJHDRalphabitdepth > 8) |
| { |
| pData->iPNGmult = 2; |
| pData->iJHDRalphabitdepth = 8; |
| } |
| #endif |
| /* parameter validity checks */ |
| if ((pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAY ) && |
| (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLOR ) && |
| (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAYA ) && |
| (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLORA) ) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| |
| if ((pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8 ) && |
| (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG12 ) && |
| (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8AND12) ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if (pData->iJHDRimgcompression != MNG_COMPRESSION_BASELINEJPEG) |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| if ((pData->iJHDRimginterlace != MNG_INTERLACE_SEQUENTIAL ) && |
| (pData->iJHDRimginterlace != MNG_INTERLACE_PROGRESSIVE) ) |
| MNG_ERROR (pData, MNG_INVALIDINTERLACE); |
| |
| if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) || |
| (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) |
| { |
| if ((pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 ) |
| #ifndef MNG_NO_1_2_4BIT_SUPPORT |
| && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_1 ) && |
| (pData->iJHDRalphabitdepth != MNG_BITDEPTH_2 ) && |
| (pData->iJHDRalphabitdepth != MNG_BITDEPTH_4 ) |
| #endif |
| #ifndef MNG_NO_16BIT_SUPPORT |
| && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_16) |
| #endif |
| ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if ((pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE ) && |
| (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG) ) |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| if ((pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG) && |
| (pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 ) ) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| #if defined(FILTER192) || defined(FILTER193) |
| if ((pData->iJHDRalphafilter != MNG_FILTER_ADAPTIVE ) && |
| #if defined(FILTER192) && defined(FILTER193) |
| (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) && |
| (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER ) ) |
| #else |
| #ifdef FILTER192 |
| (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) ) |
| #else |
| (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER ) ) |
| #endif |
| #endif |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| #else |
| if (pData->iJHDRalphafilter) |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| #endif |
| |
| if ((pData->iJHDRalphainterlace != MNG_INTERLACE_NONE ) && |
| (pData->iJHDRalphainterlace != MNG_INTERLACE_ADAM7) ) |
| MNG_ERROR (pData, MNG_INVALIDINTERLACE); |
| |
| } |
| else |
| { |
| if (pData->iJHDRalphabitdepth) |
| MNG_ERROR (pData, MNG_INVALIDBITDEPTH); |
| |
| if (pData->iJHDRalphacompression) |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| if (pData->iJHDRalphafilter) |
| MNG_ERROR (pData, MNG_INVALIDFILTER); |
| |
| if (pData->iJHDRalphainterlace) |
| MNG_ERROR (pData, MNG_INVALIDINTERLACE); |
| |
| } |
| |
| if (!pData->bHasheader) /* first chunk ? */ |
| { |
| pData->bHasheader = MNG_TRUE; /* we've got a header */ |
| pData->eImagetype = mng_it_jng; /* then this must be a JNG */ |
| pData->iWidth = mng_get_uint32 (pRawdata); |
| pData->iHeight = mng_get_uint32 (pRawdata+4); |
| /* predict alpha-depth ! */ |
| if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) || |
| (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) |
| pData->iAlphadepth = pData->iJHDRalphabitdepth; |
| else |
| pData->iAlphadepth = 0; |
| /* fits on maximum canvas ? */ |
| if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight)) |
| MNG_WARNING (pData, MNG_IMAGETOOLARGE); |
| |
| if (pData->fProcessheader) /* inform the app ? */ |
| if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight)) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| |
| } |
| |
| pData->iColortype = 0; /* fake grayscale for other routines */ |
| pData->iImagelevel++; /* one level deeper */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode = mng_process_display_jhdr (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_jhdrp)*ppChunk)->iWidth = mng_get_uint32 (pRawdata); |
| ((mng_jhdrp)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4); |
| ((mng_jhdrp)*ppChunk)->iColortype = *(pRawdata+8); |
| ((mng_jhdrp)*ppChunk)->iImagesampledepth = *(pRawdata+9); |
| ((mng_jhdrp)*ppChunk)->iImagecompression = *(pRawdata+10); |
| ((mng_jhdrp)*ppChunk)->iImageinterlace = *(pRawdata+11); |
| ((mng_jhdrp)*ppChunk)->iAlphasampledepth = *(pRawdata+12); |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (*(pRawdata+12) > 8) |
| ((mng_jhdrp)*ppChunk)->iAlphasampledepth = 8; |
| #endif |
| ((mng_jhdrp)*ppChunk)->iAlphacompression = *(pRawdata+13); |
| ((mng_jhdrp)*ppChunk)->iAlphafilter = *(pRawdata+14); |
| ((mng_jhdrp)*ppChunk)->iAlphainterlace = *(pRawdata+15); |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #else |
| #define read_jhdr 0 |
| #endif /* MNG_INCLUDE_JNG */ |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifdef MNG_INCLUDE_JNG |
| READ_CHUNK (mng_read_jdaa) |
| { |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| volatile mng_retcode iRetcode; |
| |
| iRetcode=MNG_NOERROR; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasJHDR) && (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (pData->bHasJSEP) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen == 0) /* can never be empty */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasJDAA = MNG_TRUE; /* got some JDAA now, don't we */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_jdaap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| ((mng_jdaap)*ppChunk)->iDatasize = iRawlen; |
| |
| if (iRawlen != 0) /* is there any data ? */ |
| { |
| MNG_ALLOC (pData, ((mng_jdaap)*ppChunk)->pData, iRawlen); |
| MNG_COPY (((mng_jdaap)*ppChunk)->pData, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #else |
| #define read_jdaa 0 |
| #endif /* MNG_INCLUDE_JNG */ |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifdef MNG_INCLUDE_JNG |
| READ_CHUNK (mng_read_jdat) |
| { |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| volatile mng_retcode iRetcode; |
| |
| iRetcode=MNG_NOERROR; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasJHDR) && (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen == 0) /* can never be empty */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasJDAT = MNG_TRUE; /* got some JDAT now, don't we */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_jdatp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0); |
| ((mng_jdatp)*ppChunk)->iDatasize = iRawlen; |
| |
| if (iRawlen != 0) /* is there any data ? */ |
| { |
| MNG_ALLOC (pData, ((mng_jdatp)*ppChunk)->pData, iRawlen); |
| MNG_COPY (((mng_jdatp)*ppChunk)->pData, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #else |
| #define read_jdat 0 |
| #endif /* MNG_INCLUDE_JNG */ |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifdef MNG_INCLUDE_JNG |
| READ_CHUNK (mng_read_jsep) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasJHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 0) /* must be empty ! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasJSEP = MNG_TRUE; /* indicate we've had the 8-/12-bit separator */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #else |
| #define read_jsep 0 |
| #endif /* MNG_INCLUDE_JNG */ |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| READ_CHUNK (mng_read_dhdr) |
| { |
| mng_uint8 iImagetype, iDeltatype; |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_START); |
| #endif |
| |
| if (!pData->bHasMHDR) /* sequence checks */ |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check for valid length */ |
| if ((iRawlen != 4) && (iRawlen != 12) && (iRawlen != 20)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| iImagetype = *(pRawdata+2); /* check fields for validity */ |
| iDeltatype = *(pRawdata+3); |
| |
| if (iImagetype > MNG_IMAGETYPE_JNG) |
| MNG_ERROR (pData, MNG_INVIMAGETYPE); |
| |
| if (iDeltatype > MNG_DELTATYPE_NOCHANGE) |
| MNG_ERROR (pData, MNG_INVDELTATYPE); |
| |
| if ((iDeltatype == MNG_DELTATYPE_REPLACE) && (iRawlen > 12)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((iDeltatype == MNG_DELTATYPE_NOCHANGE) && (iRawlen > 4)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| pData->bHasDHDR = MNG_TRUE; /* inside a DHDR-IEND block now */ |
| pData->iDeltatype = iDeltatype; |
| |
| pData->iImagelevel++; /* one level deeper */ |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_uint16 iObjectid = mng_get_uint16 (pRawdata); |
| mng_uint32 iBlockwidth = 0; |
| mng_uint32 iBlockheight = 0; |
| mng_uint32 iBlockx = 0; |
| mng_uint32 iBlocky = 0; |
| mng_retcode iRetcode; |
| |
| if (iRawlen > 4) |
| { |
| iBlockwidth = mng_get_uint32 (pRawdata+4); |
| iBlockheight = mng_get_uint32 (pRawdata+8); |
| } |
| |
| if (iRawlen > 12) |
| { |
| iBlockx = mng_get_uint32 (pRawdata+12); |
| iBlocky = mng_get_uint32 (pRawdata+16); |
| } |
| |
| iRetcode = mng_create_ani_dhdr (pData, iObjectid, iImagetype, iDeltatype, |
| iBlockwidth, iBlockheight, iBlockx, iBlocky); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_dhdr (pData, iObjectid, iImagetype, iDeltatype, |
| iBlockwidth, iBlockheight, iBlockx, iBlocky); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_dhdrp)*ppChunk)->iObjectid = mng_get_uint16 (pRawdata); |
| ((mng_dhdrp)*ppChunk)->iImagetype = iImagetype; |
| ((mng_dhdrp)*ppChunk)->iDeltatype = iDeltatype; |
| |
| if (iRawlen > 4) |
| { |
| ((mng_dhdrp)*ppChunk)->iBlockwidth = mng_get_uint32 (pRawdata+4); |
| ((mng_dhdrp)*ppChunk)->iBlockheight = mng_get_uint32 (pRawdata+8); |
| } |
| |
| if (iRawlen > 12) |
| { |
| ((mng_dhdrp)*ppChunk)->iBlockx = mng_get_uint32 (pRawdata+12); |
| ((mng_dhdrp)*ppChunk)->iBlocky = mng_get_uint32 (pRawdata+16); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| READ_CHUNK (mng_read_prom) |
| { |
| mng_uint8 iColortype; |
| mng_uint8 iSampledepth; |
| mng_uint8 iFilltype; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 3) /* gotta be exactly 3 bytes */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| iColortype = *pRawdata; /* check fields for validity */ |
| iSampledepth = *(pRawdata+1); |
| iFilltype = *(pRawdata+2); |
| |
| if ((iColortype != MNG_COLORTYPE_GRAY ) && |
| (iColortype != MNG_COLORTYPE_RGB ) && |
| (iColortype != MNG_COLORTYPE_INDEXED) && |
| (iColortype != MNG_COLORTYPE_GRAYA ) && |
| (iColortype != MNG_COLORTYPE_RGBA ) ) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (iSampledepth == MNG_BITDEPTH_16 ) |
| iSampledepth = MNG_BITDEPTH_8; |
| #endif |
| |
| if ((iSampledepth != MNG_BITDEPTH_1 ) && |
| (iSampledepth != MNG_BITDEPTH_2 ) && |
| (iSampledepth != MNG_BITDEPTH_4 ) && |
| (iSampledepth != MNG_BITDEPTH_8 ) |
| #ifndef MNG_NO_16BIT_SUPPORT |
| && (iSampledepth != MNG_BITDEPTH_16) |
| #endif |
| ) |
| MNG_ERROR (pData, MNG_INVSAMPLEDEPTH); |
| |
| if ((iFilltype != MNG_FILLMETHOD_LEFTBITREPLICATE) && |
| (iFilltype != MNG_FILLMETHOD_ZEROFILL ) ) |
| MNG_ERROR (pData, MNG_INVFILLMETHOD); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode = mng_create_ani_prom (pData, iSampledepth, |
| iColortype, iFilltype); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_prom (pData, iSampledepth, |
| iColortype, iFilltype); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_promp)*ppChunk)->iColortype = iColortype; |
| ((mng_promp)*ppChunk)->iSampledepth = iSampledepth; |
| ((mng_promp)*ppChunk)->iFilltype = iFilltype; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| READ_CHUNK (mng_read_ipng) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 0) /* gotta be empty */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode = mng_create_ani_ipng (pData); |
| |
| if (!iRetcode) |
| iRetcode = mng_process_display_ipng (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| READ_CHUNK (mng_read_pplt) |
| { |
| mng_uint8 iDeltatype; |
| mng_uint8p pTemp; |
| mng_uint32 iLen; |
| mng_uint8 iX, iM; |
| mng_uint32 iY; |
| mng_uint32 iMax; |
| mng_rgbpaltab aIndexentries; |
| mng_uint8arr aAlphaentries; |
| mng_uint8arr aUsedentries; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) && (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 1) /* must have at least 1 byte */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| iDeltatype = *pRawdata; |
| /* valid ? */ |
| if (iDeltatype > MNG_DELTATYPE_DELTARGBA) |
| MNG_ERROR (pData, MNG_INVDELTATYPE); |
| /* must be indexed color ! */ |
| if (pData->iColortype != MNG_COLORTYPE_INDEXED) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| |
| pTemp = pRawdata + 1; |
| iLen = iRawlen - 1; |
| iMax = 0; |
| |
| for (iY = 0; iY < 256; iY++) /* reset arrays */ |
| { |
| aIndexentries [iY].iRed = 0; |
| aIndexentries [iY].iGreen = 0; |
| aIndexentries [iY].iBlue = 0; |
| aAlphaentries [iY] = 255; |
| aUsedentries [iY] = 0; |
| } |
| |
| while (iLen) /* as long as there are entries left ... */ |
| { |
| mng_uint32 iDiff; |
| |
| if (iLen < 2) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| iX = *pTemp; /* get start and end index */ |
| iM = *(pTemp+1); |
| |
| if (iM < iX) |
| MNG_ERROR (pData, MNG_INVALIDINDEX); |
| |
| if ((mng_uint32)iM >= iMax) /* determine highest used index */ |
| iMax = (mng_uint32)iM + 1; |
| |
| pTemp += 2; |
| iLen -= 2; |
| iDiff = (iM - iX + 1); |
| if ((iDeltatype == MNG_DELTATYPE_REPLACERGB ) || |
| (iDeltatype == MNG_DELTATYPE_DELTARGB ) ) |
| iDiff = iDiff * 3; |
| else |
| if ((iDeltatype == MNG_DELTATYPE_REPLACERGBA) || |
| (iDeltatype == MNG_DELTATYPE_DELTARGBA ) ) |
| iDiff = iDiff * 4; |
| |
| if (iLen < iDiff) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| if ((iDeltatype == MNG_DELTATYPE_REPLACERGB ) || |
| (iDeltatype == MNG_DELTATYPE_DELTARGB ) ) |
| { |
| for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++) |
| { |
| aIndexentries [iY].iRed = *pTemp; |
| aIndexentries [iY].iGreen = *(pTemp+1); |
| aIndexentries [iY].iBlue = *(pTemp+2); |
| aUsedentries [iY] = 1; |
| |
| pTemp += 3; |
| iLen -= 3; |
| } |
| } |
| else |
| if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) || |
| (iDeltatype == MNG_DELTATYPE_DELTAALPHA ) ) |
| { |
| for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++) |
| { |
| aAlphaentries [iY] = *pTemp; |
| aUsedentries [iY] = 1; |
| |
| pTemp++; |
| iLen--; |
| } |
| } |
| else |
| { |
| for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++) |
| { |
| aIndexentries [iY].iRed = *pTemp; |
| aIndexentries [iY].iGreen = *(pTemp+1); |
| aIndexentries [iY].iBlue = *(pTemp+2); |
| aAlphaentries [iY] = *(pTemp+3); |
| aUsedentries [iY] = 1; |
| |
| pTemp += 4; |
| iLen -= 4; |
| } |
| } |
| } |
| |
| switch (pData->iBitdepth) /* check maximum allowed entries for bitdepth */ |
| { |
| case MNG_BITDEPTH_1 : { |
| if (iMax > 2) |
| MNG_ERROR (pData, MNG_INVALIDINDEX); |
| break; |
| } |
| case MNG_BITDEPTH_2 : { |
| if (iMax > 4) |
| MNG_ERROR (pData, MNG_INVALIDINDEX); |
| break; |
| } |
| case MNG_BITDEPTH_4 : { |
| if (iMax > 16) |
| MNG_ERROR (pData, MNG_INVALIDINDEX); |
| break; |
| } |
| } |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { /* create animation object */ |
| mng_retcode iRetcode = mng_create_ani_pplt (pData, iDeltatype, iMax, |
| aIndexentries, aAlphaentries, |
| aUsedentries); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_pplt (pData, iDeltatype, iMax, aIndexentries, |
| aAlphaentries, aUsedentries); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_ppltp)*ppChunk)->iDeltatype = iDeltatype; |
| ((mng_ppltp)*ppChunk)->iCount = iMax; |
| |
| for (iY = 0; iY < 256; iY++) |
| { |
| ((mng_ppltp)*ppChunk)->aEntries [iY].iRed = aIndexentries [iY].iRed; |
| ((mng_ppltp)*ppChunk)->aEntries [iY].iGreen = aIndexentries [iY].iGreen; |
| ((mng_ppltp)*ppChunk)->aEntries [iY].iBlue = aIndexentries [iY].iBlue; |
| ((mng_ppltp)*ppChunk)->aEntries [iY].iAlpha = aAlphaentries [iY]; |
| ((mng_ppltp)*ppChunk)->aEntries [iY].bUsed = (mng_bool)(aUsedentries [iY]); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| #ifdef MNG_INCLUDE_JNG |
| READ_CHUNK (mng_read_ijng) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen != 0) /* gotta be empty */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode = mng_create_ani_ijng (pData); |
| |
| if (!iRetcode) |
| iRetcode = mng_process_display_ijng (pData); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| READ_CHUNK (mng_read_drop) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check length */ |
| if ((iRawlen < 4) || ((iRawlen % 4) != 0)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_dropp)*ppChunk)->iCount = iRawlen / 4; |
| |
| if (iRawlen) |
| { |
| mng_uint32 iX; |
| mng_uint8p pTemp = pRawdata; |
| mng_uint32p pEntry; |
| |
| MNG_ALLOC (pData, pEntry, iRawlen); |
| |
| ((mng_dropp)*ppChunk)->pChunknames = (mng_ptr)pEntry; |
| |
| for (iX = 0; iX < iRawlen / 4; iX++) |
| { |
| *pEntry = mng_get_uint32 (pTemp); |
| |
| pTemp += 4; |
| pEntry++; |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| #ifndef MNG_SKIPCHUNK_DBYK |
| READ_CHUNK (mng_read_dbyk) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 6) /* must be at least 6 long */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_dbykp)*ppChunk)->iChunkname = mng_get_uint32 (pRawdata); |
| ((mng_dbykp)*ppChunk)->iPolarity = *(pRawdata+4); |
| ((mng_dbykp)*ppChunk)->iKeywordssize = iRawlen - 5; |
| |
| if (iRawlen > 5) |
| { |
| MNG_ALLOC (pData, ((mng_dbykp)*ppChunk)->zKeywords, iRawlen-4); |
| MNG_COPY (((mng_dbykp)*ppChunk)->zKeywords, pRawdata+5, iRawlen-5); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_NO_DELTA_PNG |
| #ifndef MNG_SKIPCHUNK_ORDR |
| READ_CHUNK (mng_read_ordr) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (!pData->bHasDHDR)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check length */ |
| if ((iRawlen < 5) || ((iRawlen % 5) != 0)) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| |
| |
| /* TODO: something !!! */ |
| |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_ordrp)*ppChunk)->iCount = iRawlen / 5; |
| |
| if (iRawlen) |
| { |
| mng_uint32 iX; |
| mng_ordr_entryp pEntry; |
| mng_uint8p pTemp = pRawdata; |
| |
| MNG_ALLOC (pData, pEntry, iRawlen); |
| |
| ((mng_ordrp)*ppChunk)->pEntries = pEntry; |
| |
| for (iX = 0; iX < iRawlen / 5; iX++) |
| { |
| pEntry->iChunkname = mng_get_uint32 (pTemp); |
| pEntry->iOrdertype = *(pTemp+4); |
| |
| pTemp += 5; |
| pEntry++; |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_MAGN |
| READ_CHUNK (mng_read_magn) |
| { |
| mng_uint16 iFirstid, iLastid; |
| mng_uint8 iMethodX, iMethodY; |
| mng_uint16 iMX, iMY, iML, iMR, iMT, iMB; |
| mng_bool bFaulty; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_SUPPORT_JNG |
| if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR) || (pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR)) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* check length */ |
| if (iRawlen > 20) |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| /* following is an ugly hack to allow faulty layout caused by previous |
| versions of libmng and MNGeye, which wrote MAGN with a 16-bit |
| MethodX/MethodY (as opposed to the proper 8-bit as defined in the spec!) */ |
| |
| if ((iRawlen == 6) || (iRawlen == 8) || (iRawlen == 10) || (iRawlen == 12) || |
| (iRawlen == 14) || (iRawlen == 16) || (iRawlen == 20)) |
| bFaulty = MNG_TRUE; /* these lengths are all wrong */ |
| else /* length 18 can be right or wrong !!! */ |
| if ((iRawlen == 18) && (mng_get_uint16 (pRawdata+4) <= 5) && |
| (mng_get_uint16 (pRawdata+6) < 256) && |
| (mng_get_uint16 (pRawdata+8) < 256) && |
| (mng_get_uint16 (pRawdata+10) < 256) && |
| (mng_get_uint16 (pRawdata+12) < 256) && |
| (mng_get_uint16 (pRawdata+14) < 256) && |
| (mng_get_uint16 (pRawdata+16) < 256)) |
| bFaulty = MNG_TRUE; /* this is very likely the wrong layout */ |
| else |
| bFaulty = MNG_FALSE; /* all other cases are handled as right */ |
| |
| if (bFaulty) /* wrong layout ? */ |
| { |
| if (iRawlen > 0) /* get the fields */ |
| iFirstid = mng_get_uint16 (pRawdata); |
| else |
| iFirstid = 0; |
| |
| if (iRawlen > 2) |
| iLastid = mng_get_uint16 (pRawdata+2); |
| else |
| iLastid = iFirstid; |
| |
| if (iRawlen > 4) |
| iMethodX = (mng_uint8)(mng_get_uint16 (pRawdata+4)); |
| else |
| iMethodX = 0; |
| |
| if (iRawlen > 6) |
| iMX = mng_get_uint16 (pRawdata+6); |
| else |
| iMX = 1; |
| |
| if (iRawlen > 8) |
| iMY = mng_get_uint16 (pRawdata+8); |
| else |
| iMY = iMX; |
| |
| if (iRawlen > 10) |
| iML = mng_get_uint16 (pRawdata+10); |
| else |
| iML = iMX; |
| |
| if (iRawlen > 12) |
| iMR = mng_get_uint16 (pRawdata+12); |
| else |
| iMR = iMX; |
| |
| if (iRawlen > 14) |
| iMT = mng_get_uint16 (pRawdata+14); |
| else |
| iMT = iMY; |
| |
| if (iRawlen > 16) |
| iMB = mng_get_uint16 (pRawdata+16); |
| else |
| iMB = iMY; |
| |
| if (iRawlen > 18) |
| iMethodY = (mng_uint8)(mng_get_uint16 (pRawdata+18)); |
| else |
| iMethodY = iMethodX; |
| } |
| else /* proper layout !!!! */ |
| { |
| if (iRawlen > 0) /* get the fields */ |
| iFirstid = mng_get_uint16 (pRawdata); |
| else |
| iFirstid = 0; |
| |
| if (iRawlen > 2) |
| iLastid = mng_get_uint16 (pRawdata+2); |
| else |
| iLastid = iFirstid; |
| |
| if (iRawlen > 4) |
| iMethodX = *(pRawdata+4); |
| else |
| iMethodX = 0; |
| |
| if (iRawlen > 5) |
| iMX = mng_get_uint16 (pRawdata+5); |
| else |
| iMX = 1; |
| |
| if (iRawlen > 7) |
| iMY = mng_get_uint16 (pRawdata+7); |
| else |
| iMY = iMX; |
| |
| if (iRawlen > 9) |
| iML = mng_get_uint16 (pRawdata+9); |
| else |
| iML = iMX; |
| |
| if (iRawlen > 11) |
| iMR = mng_get_uint16 (pRawdata+11); |
| else |
| iMR = iMX; |
| |
| if (iRawlen > 13) |
| iMT = mng_get_uint16 (pRawdata+13); |
| else |
| iMT = iMY; |
| |
| if (iRawlen > 15) |
| iMB = mng_get_uint16 (pRawdata+15); |
| else |
| iMB = iMY; |
| |
| if (iRawlen > 17) |
| iMethodY = *(pRawdata+17); |
| else |
| iMethodY = iMethodX; |
| } |
| /* check field validity */ |
| if ((iMethodX > 5) || (iMethodY > 5)) |
| MNG_ERROR (pData, MNG_INVALIDMETHOD); |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| mng_retcode iRetcode; |
| |
| iRetcode = mng_create_ani_magn (pData, iFirstid, iLastid, iMethodX, |
| iMX, iMY, iML, iMR, iMT, iMB, iMethodY); |
| |
| /* if (!iRetcode) |
| iRetcode = mng_process_display_magn (pData, iFirstid, iLastid, iMethodX, |
| iMX, iMY, iML, iMR, iMT, iMB, iMethodY); */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_magnp)*ppChunk)->iFirstid = iFirstid; |
| ((mng_magnp)*ppChunk)->iLastid = iLastid; |
| ((mng_magnp)*ppChunk)->iMethodX = iMethodX; |
| ((mng_magnp)*ppChunk)->iMX = iMX; |
| ((mng_magnp)*ppChunk)->iMY = iMY; |
| ((mng_magnp)*ppChunk)->iML = iML; |
| ((mng_magnp)*ppChunk)->iMR = iMR; |
| ((mng_magnp)*ppChunk)->iMT = iMT; |
| ((mng_magnp)*ppChunk)->iMB = iMB; |
| ((mng_magnp)*ppChunk)->iMethodY = iMethodY; |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifdef MNG_INCLUDE_MPNG_PROPOSAL |
| READ_CHUNK (mng_read_mpng) |
| { |
| mng_uint32 iFramewidth; |
| mng_uint32 iFrameheight; |
| mng_uint16 iTickspersec; |
| mng_uint32 iFramessize; |
| mng_uint32 iCompressedsize; |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| mng_retcode iRetcode; |
| mng_uint16 iNumplays; |
| mng_uint32 iBufsize; |
| mng_uint8p pBuf = 0; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if (!pData->bHasIHDR) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 41) /* length must be at least 41 */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| iFramewidth = mng_get_int32 (pRawdata); |
| if (iFramewidth == 0) /* frame_width must not be zero */ |
| MNG_ERROR (pData, MNG_INVALIDWIDTH); |
| |
| iFrameheight = mng_get_int32 (pRawdata+4); |
| if (iFrameheight == 0) /* frame_height must not be zero */ |
| MNG_ERROR (pData, MNG_INVALIDHEIGHT); |
| |
| iTickspersec = mng_get_uint16 (pRawdata+10); |
| if (iTickspersec == 0) /* delay_den must not be zero */ |
| MNG_ERROR (pData, MNG_INVALIDFIELDVAL); |
| |
| if (*(pRawdata+12) != 0) /* only deflate compression-method allowed */ |
| MNG_ERROR (pData, MNG_INVALIDCOMPRESS); |
| |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| iNumplays = mng_get_uint16 (pRawdata+8); |
| iCompressedsize = (mng_uint32)(iRawlen - 13); |
| #endif |
| |
| #ifdef MNG_SUPPORT_DISPLAY |
| { |
| iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize, |
| &pBuf, &iBufsize, &iFramessize); |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| |
| if (iFramessize % 26) |
| { |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| |
| iRetcode = mng_create_mpng_obj (pData, iFramewidth, iFrameheight, iNumplays, |
| iTickspersec, iFramessize, pBuf); |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the fields */ |
| ((mng_mpngp)*ppChunk)->iFramewidth = iFramewidth; |
| ((mng_mpngp)*ppChunk)->iFrameheight = iFrameheight; |
| ((mng_mpngp)*ppChunk)->iNumplays = iNumplays; |
| ((mng_mpngp)*ppChunk)->iTickspersec = iTickspersec; |
| ((mng_mpngp)*ppChunk)->iCompressionmethod = *(pRawdata+14); |
| |
| #ifndef MNG_SUPPORT_DISPLAY |
| iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize, |
| &pBuf, &iBufsize, &iFramessize); |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pBuf, iBufsize); |
| return iRetcode; |
| } |
| |
| if (iFramessize % 26) |
| { |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| } |
| #endif |
| |
| if (iFramessize) |
| { |
| MNG_ALLOCX (pData, ((mng_mpngp)*ppChunk)->pFrames, iFramessize); |
| if (((mng_mpngp)*ppChunk)->pFrames == 0) |
| { |
| MNG_FREEX (pData, pBuf, iBufsize); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| ((mng_mpngp)*ppChunk)->iFramessize = iFramessize; |
| MNG_COPY (((mng_mpngp)*ppChunk)->pFrames, pBuf, iFramessize); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS) |
| MNG_FREEX (pData, pBuf, iBufsize); |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| #ifndef MNG_SKIPCHUNK_evNT |
| READ_CHUNK (mng_read_evnt) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| if ((!pData->bHasMHDR) || (pData->bHasSAVE)) |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| |
| if (iRawlen < 2) /* must have at least 1 entry ! */ |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| |
| #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG) |
| { |
| if (iRawlen) /* not empty ? */ |
| { |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint8p pNull; |
| mng_uint32 iLen; |
| mng_uint8 iEventtype; |
| mng_uint8 iMasktype; |
| mng_int32 iLeft; |
| mng_int32 iRight; |
| mng_int32 iTop; |
| mng_int32 iBottom; |
| mng_uint16 iObjectid; |
| mng_uint8 iIndex; |
| mng_uint32 iNamesize; |
| |
| pTemp = pRawdata; |
| iLen = iRawlen; |
| |
| while (iLen) /* anything left ? */ |
| { |
| iEventtype = *pTemp; /* eventtype */ |
| if (iEventtype > 5) |
| MNG_ERROR (pData, MNG_INVALIDEVENT); |
| |
| pTemp++; |
| |
| iMasktype = *pTemp; /* masktype */ |
| if (iMasktype > 5) |
| MNG_ERROR (pData, MNG_INVALIDMASK); |
| |
| pTemp++; |
| iLen -= 2; |
| |
| iLeft = 0; |
| iRight = 0; |
| iTop = 0; |
| iBottom = 0; |
| iObjectid = 0; |
| iIndex = 0; |
| |
| switch (iMasktype) |
| { |
| case 1 : |
| { |
| if (iLen > 16) |
| { |
| iLeft = mng_get_int32 (pTemp); |
| iRight = mng_get_int32 (pTemp+4); |
| iTop = mng_get_int32 (pTemp+8); |
| iBottom = mng_get_int32 (pTemp+12); |
| pTemp += 16; |
| iLen -= 16; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 2 : |
| { |
| if (iLen > 2) |
| { |
| iObjectid = mng_get_uint16 (pTemp); |
| pTemp += 2; |
| iLen -= 2; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 3 : |
| { |
| if (iLen > 3) |
| { |
| iObjectid = mng_get_uint16 (pTemp); |
| iIndex = *(pTemp+2); |
| pTemp += 3; |
| iLen -= 3; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 4 : |
| { |
| if (iLen > 18) |
| { |
| iLeft = mng_get_int32 (pTemp); |
| iRight = mng_get_int32 (pTemp+4); |
| iTop = mng_get_int32 (pTemp+8); |
| iBottom = mng_get_int32 (pTemp+12); |
| iObjectid = mng_get_uint16 (pTemp+16); |
| pTemp += 18; |
| iLen -= 18; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 5 : |
| { |
| if (iLen > 19) |
| { |
| iLeft = mng_get_int32 (pTemp); |
| iRight = mng_get_int32 (pTemp+4); |
| iTop = mng_get_int32 (pTemp+8); |
| iBottom = mng_get_int32 (pTemp+12); |
| iObjectid = mng_get_uint16 (pTemp+16); |
| iIndex = *(pTemp+18); |
| pTemp += 19; |
| iLen -= 19; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| } |
| |
| pNull = find_null (pTemp); /* get the name length */ |
| |
| if ((pNull - pTemp) > (mng_int32)iLen) |
| { |
| iNamesize = iLen; /* no null found; so end of evNT */ |
| iLen = 0; |
| } |
| else |
| { |
| iNamesize = pNull - pTemp; /* should be another entry */ |
| iLen = iLen - iNamesize - 1; |
| |
| if (!iLen) /* must not end with a null ! */ |
| MNG_ERROR (pData, MNG_ENDWITHNULL); |
| } |
| |
| iRetcode = mng_create_event (pData, iEventtype, iMasktype, iLeft, iRight, |
| iTop, iBottom, iObjectid, iIndex, |
| iNamesize, (mng_pchar)pTemp); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| pTemp = pTemp + iNamesize + 1; |
| } |
| } |
| } |
| #endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_DYNAMICMNG */ |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| if (iRawlen) /* not empty ? */ |
| { |
| mng_uint32 iX; |
| mng_uint32 iCount = 0; |
| mng_uint8p pTemp; |
| mng_uint8p pNull; |
| mng_uint32 iLen; |
| mng_uint8 iEventtype; |
| mng_uint8 iMasktype; |
| mng_int32 iLeft; |
| mng_int32 iRight; |
| mng_int32 iTop; |
| mng_int32 iBottom; |
| mng_uint16 iObjectid; |
| mng_uint8 iIndex; |
| mng_uint32 iNamesize; |
| mng_evnt_entryp pEntry = MNG_NULL; |
| |
| for (iX = 0; iX < 2; iX++) /* do this twice to get the count first ! */ |
| { |
| pTemp = pRawdata; |
| iLen = iRawlen; |
| |
| if (iX) /* second run ? */ |
| { |
| MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_evnt_entry))); |
| |
| ((mng_evntp)*ppChunk)->iCount = iCount; |
| ((mng_evntp)*ppChunk)->pEntries = pEntry; |
| } |
| |
| while (iLen) /* anything left ? */ |
| { |
| iEventtype = *pTemp; /* eventtype */ |
| if (iEventtype > 5) |
| MNG_ERROR (pData, MNG_INVALIDEVENT); |
| |
| pTemp++; |
| |
| iMasktype = *pTemp; /* masktype */ |
| if (iMasktype > 5) |
| MNG_ERROR (pData, MNG_INVALIDMASK); |
| |
| pTemp++; |
| iLen -= 2; |
| |
| iLeft = 0; |
| iRight = 0; |
| iTop = 0; |
| iBottom = 0; |
| iObjectid = 0; |
| iIndex = 0; |
| |
| switch (iMasktype) |
| { |
| case 1 : |
| { |
| if (iLen > 16) |
| { |
| iLeft = mng_get_int32 (pTemp); |
| iRight = mng_get_int32 (pTemp+4); |
| iTop = mng_get_int32 (pTemp+8); |
| iBottom = mng_get_int32 (pTemp+12); |
| pTemp += 16; |
| iLen -= 16; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 2 : |
| { |
| if (iLen > 2) |
| { |
| iObjectid = mng_get_uint16 (pTemp); |
| pTemp += 2; |
| iLen -= 2; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 3 : |
| { |
| if (iLen > 3) |
| { |
| iObjectid = mng_get_uint16 (pTemp); |
| iIndex = *(pTemp+2); |
| pTemp += 3; |
| iLen -= 3; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 4 : |
| { |
| if (iLen > 18) |
| { |
| iLeft = mng_get_int32 (pTemp); |
| iRight = mng_get_int32 (pTemp+4); |
| iTop = mng_get_int32 (pTemp+8); |
| iBottom = mng_get_int32 (pTemp+12); |
| iObjectid = mng_get_uint16 (pTemp+16); |
| pTemp += 18; |
| iLen -= 18; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| case 5 : |
| { |
| if (iLen > 19) |
| { |
| iLeft = mng_get_int32 (pTemp); |
| iRight = mng_get_int32 (pTemp+4); |
| iTop = mng_get_int32 (pTemp+8); |
| iBottom = mng_get_int32 (pTemp+12); |
| iObjectid = mng_get_uint16 (pTemp+16); |
| iIndex = *(pTemp+18); |
| pTemp += 19; |
| iLen -= 19; |
| } |
| else |
| MNG_ERROR (pData, MNG_INVALIDLENGTH); |
| break; |
| } |
| } |
| |
| pNull = find_null (pTemp); /* get the name length */ |
| |
| if ((pNull - pTemp) > (mng_int32)iLen) |
| { |
| iNamesize = iLen; /* no null found; so end of evNT */ |
| iLen = 0; |
| } |
| else |
| { |
| iNamesize = pNull - pTemp; /* should be another entry */ |
| iLen = iLen - iNamesize - 1; |
| |
| if (!iLen) /* must not end with a null ! */ |
| MNG_ERROR (pData, MNG_ENDWITHNULL); |
| } |
| |
| if (!iX) |
| { |
| iCount++; |
| } |
| else |
| { |
| pEntry->iEventtype = iEventtype; |
| pEntry->iMasktype = iMasktype; |
| pEntry->iLeft = iLeft; |
| pEntry->iRight = iRight; |
| pEntry->iTop = iTop; |
| pEntry->iBottom = iBottom; |
| pEntry->iObjectid = iObjectid; |
| pEntry->iIndex = iIndex; |
| pEntry->iSegmentnamesize = iNamesize; |
| |
| if (iNamesize) |
| { |
| MNG_ALLOC (pData, pEntry->zSegmentname, iNamesize+1); |
| MNG_COPY (pEntry->zSegmentname, pTemp, iNamesize); |
| } |
| |
| pEntry++; |
| } |
| |
| pTemp = pTemp + iNamesize + 1; |
| } |
| } |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| READ_CHUNK (mng_read_unknown) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_START); |
| #endif |
| /* sequence checks */ |
| #ifdef MNG_INCLUDE_JNG |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR)) |
| #else |
| if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && |
| (!pData->bHasBASI) && (!pData->bHasDHDR) ) |
| #endif |
| MNG_ERROR (pData, MNG_SEQUENCEERROR); |
| /* critical chunk ? */ |
| if ((((mng_uint32)pData->iChunkname & 0x20000000) == 0) |
| #ifdef MNG_SKIPCHUNK_SAVE |
| && (pData->iChunkname != MNG_UINT_SAVE) |
| #endif |
| #ifdef MNG_SKIPCHUNK_SEEK |
| && (pData->iChunkname != MNG_UINT_SEEK) |
| #endif |
| #ifdef MNG_SKIPCHUNK_DBYK |
| && (pData->iChunkname != MNG_UINT_DBYK) |
| #endif |
| #ifdef MNG_SKIPCHUNK_ORDR |
| && (pData->iChunkname != MNG_UINT_ORDR) |
| #endif |
| ) |
| MNG_ERROR (pData, MNG_UNKNOWNCRITICAL); |
| |
| if (pData->fProcessunknown) /* let the app handle it ? */ |
| { |
| mng_bool bOke = pData->fProcessunknown ((mng_handle)pData, pData->iChunkname, |
| iRawlen, (mng_ptr)pRawdata); |
| |
| if (!bOke) |
| MNG_ERROR (pData, MNG_APPMISCERROR); |
| } |
| |
| #ifdef MNG_STORE_CHUNKS |
| if (pData->bStorechunks) |
| { /* initialize storage */ |
| mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| /* store the length */ |
| ((mng_chunk_headerp)*ppChunk)->iChunkname = pData->iChunkname; |
| ((mng_unknown_chunkp)*ppChunk)->iDatasize = iRawlen; |
| |
| if (iRawlen == 0) /* any data at all ? */ |
| ((mng_unknown_chunkp)*ppChunk)->pData = 0; |
| else |
| { /* then store it */ |
| MNG_ALLOC (pData, ((mng_unknown_chunkp)*ppChunk)->pData, iRawlen); |
| MNG_COPY (((mng_unknown_chunkp)*ppChunk)->pData, pRawdata, iRawlen); |
| } |
| } |
| #endif /* MNG_STORE_CHUNKS */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* done */ |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #endif /* MNG_INCLUDE_READ_PROCS */ |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * chunk write functions * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_WRITE_PROCS |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_ihdr) |
| { |
| mng_ihdrp pIHDR; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_START); |
| #endif |
| |
| pIHDR = (mng_ihdrp)pChunk; /* address the proper chunk */ |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 13; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pIHDR->iWidth); |
| mng_put_uint32 (pRawdata+4, pIHDR->iHeight); |
| |
| *(pRawdata+8) = pIHDR->iBitdepth; |
| *(pRawdata+9) = pIHDR->iColortype; |
| *(pRawdata+10) = pIHDR->iCompression; |
| *(pRawdata+11) = pIHDR->iFilter; |
| *(pRawdata+12) = pIHDR->iInterlace; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pIHDR->sHeader.iChunkname, iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_plte) |
| { |
| mng_pltep pPLTE; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint32 iX; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_START); |
| #endif |
| |
| pPLTE = (mng_pltep)pChunk; /* address the proper chunk */ |
| |
| if (pPLTE->bEmpty) /* write empty chunk ? */ |
| iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pPLTE->iEntrycount * 3; |
| /* fill the output buffer */ |
| pTemp = pRawdata; |
| |
| for (iX = 0; iX < pPLTE->iEntrycount; iX++) |
| { |
| *pTemp = pPLTE->aEntries [iX].iRed; |
| *(pTemp+1) = pPLTE->aEntries [iX].iGreen; |
| *(pTemp+2) = pPLTE->aEntries [iX].iBlue; |
| |
| pTemp += 3; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_idat) |
| { |
| mng_idatp pIDAT; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_START); |
| #endif |
| |
| pIDAT = (mng_idatp)pChunk; /* address the proper chunk */ |
| |
| if (pIDAT->bEmpty) /* and write it */ |
| iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname, 0, 0); |
| else |
| iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname, |
| pIDAT->iDatasize, pIDAT->pData); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_iend) |
| { |
| mng_iendp pIEND; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_START); |
| #endif |
| |
| pIEND = (mng_iendp)pChunk; /* address the proper chunk */ |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pIEND->sHeader.iChunkname, 0, 0); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_trns) |
| { |
| mng_trnsp pTRNS; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint32 iX; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_START); |
| #endif |
| |
| pTRNS = (mng_trnsp)pChunk; /* address the proper chunk */ |
| |
| if (pTRNS->bEmpty) /* write empty chunk ? */ |
| iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, 0, 0); |
| else |
| if (pTRNS->bGlobal) /* write global chunk ? */ |
| iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, |
| pTRNS->iRawlen, (mng_uint8p)pTRNS->aRawdata); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer */ |
| iRawlen = 0; /* and default size */ |
| |
| switch (pTRNS->iType) |
| { |
| case 0: { |
| iRawlen = 2; /* fill the size & output buffer */ |
| mng_put_uint16 (pRawdata, pTRNS->iGray); |
| |
| break; |
| } |
| case 2: { |
| iRawlen = 6; /* fill the size & output buffer */ |
| mng_put_uint16 (pRawdata, pTRNS->iRed); |
| mng_put_uint16 (pRawdata+2, pTRNS->iGreen); |
| mng_put_uint16 (pRawdata+4, pTRNS->iBlue); |
| |
| break; |
| } |
| case 3: { /* init output buffer size */ |
| iRawlen = pTRNS->iCount; |
| |
| pTemp = pRawdata; /* fill the output buffer */ |
| |
| for (iX = 0; iX < pTRNS->iCount; iX++) |
| { |
| *pTemp = pTRNS->aEntries[iX]; |
| pTemp++; |
| } |
| |
| break; |
| } |
| } |
| /* write the chunk */ |
| iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_gama) |
| { |
| mng_gamap pGAMA; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_START); |
| #endif |
| |
| pGAMA = (mng_gamap)pChunk; /* address the proper chunk */ |
| |
| if (pGAMA->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 4; |
| /* fill the buffer */ |
| mng_put_uint32 (pRawdata, pGAMA->iGamma); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_cHRM |
| WRITE_CHUNK (mng_write_chrm) |
| { |
| mng_chrmp pCHRM; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_START); |
| #endif |
| |
| pCHRM = (mng_chrmp)pChunk; /* address the proper chunk */ |
| |
| if (pCHRM->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 32; |
| /* fill the buffer */ |
| mng_put_uint32 (pRawdata, pCHRM->iWhitepointx); |
| mng_put_uint32 (pRawdata+4, pCHRM->iWhitepointy); |
| mng_put_uint32 (pRawdata+8, pCHRM->iRedx); |
| mng_put_uint32 (pRawdata+12, pCHRM->iRedy); |
| mng_put_uint32 (pRawdata+16, pCHRM->iGreenx); |
| mng_put_uint32 (pRawdata+20, pCHRM->iGreeny); |
| mng_put_uint32 (pRawdata+24, pCHRM->iBluex); |
| mng_put_uint32 (pRawdata+28, pCHRM->iBluey); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_srgb) |
| { |
| mng_srgbp pSRGB; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_START); |
| #endif |
| |
| pSRGB = (mng_srgbp)pChunk; /* address the proper chunk */ |
| |
| if (pSRGB->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 1; |
| /* fill the buffer */ |
| *pRawdata = pSRGB->iRenderingintent; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| WRITE_CHUNK (mng_write_iccp) |
| { |
| mng_iccpp pICCP; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint8p pBuf = 0; |
| mng_uint32 iBuflen; |
| mng_uint32 iReallen; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_START); |
| #endif |
| |
| pICCP = (mng_iccpp)pChunk; /* address the proper chunk */ |
| |
| if (pICCP->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname, 0, 0); |
| else |
| { /* compress the profile */ |
| iRetcode = deflate_buffer (pData, pICCP->pProfile, pICCP->iProfilesize, |
| &pBuf, &iBuflen, &iReallen); |
| |
| if (!iRetcode) /* still oke ? */ |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pICCP->iNamesize + 2 + iReallen; |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| |
| pTemp = pRawdata; /* fill the buffer */ |
| |
| if (pICCP->iNamesize) |
| { |
| MNG_COPY (pTemp, pICCP->zName, pICCP->iNamesize); |
| pTemp += pICCP->iNamesize; |
| } |
| |
| *pTemp = 0; |
| *(pTemp+1) = pICCP->iCompression; |
| pTemp += 2; |
| |
| if (iReallen) |
| MNG_COPY (pTemp, pBuf, iReallen); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| /* drop the temp buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| |
| } |
| |
| MNG_FREEX (pData, pBuf, iBuflen); /* always drop the extra buffer */ |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_tEXt |
| WRITE_CHUNK (mng_write_text) |
| { |
| mng_textp pTEXT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_START); |
| #endif |
| |
| pTEXT = (mng_textp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pTEXT->iKeywordsize + 1 + pTEXT->iTextsize; |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| |
| pTemp = pRawdata; /* fill the buffer */ |
| |
| if (pTEXT->iKeywordsize) |
| { |
| MNG_COPY (pTemp, pTEXT->zKeyword, pTEXT->iKeywordsize); |
| pTemp += pTEXT->iKeywordsize; |
| } |
| |
| *pTemp = 0; |
| pTemp += 1; |
| |
| if (pTEXT->iTextsize) |
| MNG_COPY (pTemp, pTEXT->zText, pTEXT->iTextsize); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pTEXT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| if (iRawlen > pData->iWritebufsize) /* drop the temp buffer ? */ |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_zTXt |
| WRITE_CHUNK (mng_write_ztxt) |
| { |
| mng_ztxtp pZTXT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint8p pBuf = 0; |
| mng_uint32 iBuflen; |
| mng_uint32 iReallen; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_START); |
| #endif |
| |
| pZTXT = (mng_ztxtp)pChunk; /* address the proper chunk */ |
| /* compress the text */ |
| iRetcode = deflate_buffer (pData, (mng_uint8p)pZTXT->zText, pZTXT->iTextsize, |
| &pBuf, &iBuflen, &iReallen); |
| |
| if (!iRetcode) /* all ok ? */ |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pZTXT->iKeywordsize + 2 + iReallen; |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| |
| pTemp = pRawdata; /* fill the buffer */ |
| |
| if (pZTXT->iKeywordsize) |
| { |
| MNG_COPY (pTemp, pZTXT->zKeyword, pZTXT->iKeywordsize); |
| pTemp += pZTXT->iKeywordsize; |
| } |
| |
| *pTemp = 0; /* terminator zero */ |
| pTemp++; |
| *pTemp = 0; /* compression type */ |
| pTemp++; |
| |
| if (iReallen) |
| MNG_COPY (pTemp, pBuf, iReallen); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pZTXT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| /* drop the temp buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| |
| } |
| |
| MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_iTXt |
| WRITE_CHUNK (mng_write_itxt) |
| { |
| mng_itxtp pITXT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint8p pBuf = 0; |
| mng_uint32 iBuflen; |
| mng_uint32 iReallen; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_START); |
| #endif |
| |
| pITXT = (mng_itxtp)pChunk; /* address the proper chunk */ |
| |
| if (pITXT->iCompressionflag) /* compress the text */ |
| iRetcode = deflate_buffer (pData, (mng_uint8p)pITXT->zText, pITXT->iTextsize, |
| &pBuf, &iBuflen, &iReallen); |
| else |
| iRetcode = MNG_NOERROR; |
| |
| if (!iRetcode) /* all ok ? */ |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pITXT->iKeywordsize + pITXT->iLanguagesize + |
| pITXT->iTranslationsize + 5; |
| |
| if (pITXT->iCompressionflag) |
| iRawlen = iRawlen + iReallen; |
| else |
| iRawlen = iRawlen + pITXT->iTextsize; |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| |
| pTemp = pRawdata; /* fill the buffer */ |
| |
| if (pITXT->iKeywordsize) |
| { |
| MNG_COPY (pTemp, pITXT->zKeyword, pITXT->iKeywordsize); |
| pTemp += pITXT->iKeywordsize; |
| } |
| |
| *pTemp = 0; |
| pTemp++; |
| *pTemp = pITXT->iCompressionflag; |
| pTemp++; |
| *pTemp = pITXT->iCompressionmethod; |
| pTemp++; |
| |
| if (pITXT->iLanguagesize) |
| { |
| MNG_COPY (pTemp, pITXT->zLanguage, pITXT->iLanguagesize); |
| pTemp += pITXT->iLanguagesize; |
| } |
| |
| *pTemp = 0; |
| pTemp++; |
| |
| if (pITXT->iTranslationsize) |
| { |
| MNG_COPY (pTemp, pITXT->zTranslation, pITXT->iTranslationsize); |
| pTemp += pITXT->iTranslationsize; |
| } |
| |
| *pTemp = 0; |
| pTemp++; |
| |
| if (pITXT->iCompressionflag) |
| { |
| if (iReallen) |
| MNG_COPY (pTemp, pBuf, iReallen); |
| } |
| else |
| { |
| if (pITXT->iTextsize) |
| MNG_COPY (pTemp, pITXT->zText, pITXT->iTextsize); |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pITXT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| /* drop the temp buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| |
| } |
| |
| MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */ |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_bKGD |
| WRITE_CHUNK (mng_write_bkgd) |
| { |
| mng_bkgdp pBKGD; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_START); |
| #endif |
| |
| pBKGD = (mng_bkgdp)pChunk; /* address the proper chunk */ |
| |
| if (pBKGD->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 0; /* and default size */ |
| |
| switch (pBKGD->iType) |
| { |
| case 0: { /* gray */ |
| iRawlen = 2; /* fill the size & output buffer */ |
| mng_put_uint16 (pRawdata, pBKGD->iGray); |
| |
| break; |
| } |
| case 2: { /* rgb */ |
| iRawlen = 6; /* fill the size & output buffer */ |
| mng_put_uint16 (pRawdata, pBKGD->iRed); |
| mng_put_uint16 (pRawdata+2, pBKGD->iGreen); |
| mng_put_uint16 (pRawdata+4, pBKGD->iBlue); |
| |
| break; |
| } |
| case 3: { /* indexed */ |
| iRawlen = 1; /* fill the size & output buffer */ |
| *pRawdata = pBKGD->iIndex; |
| |
| break; |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_pHYs |
| WRITE_CHUNK (mng_write_phys) |
| { |
| mng_physp pPHYS; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_START); |
| #endif |
| |
| pPHYS = (mng_physp)pChunk; /* address the proper chunk */ |
| |
| if (pPHYS->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 9; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pPHYS->iSizex); |
| mng_put_uint32 (pRawdata+4, pPHYS->iSizey); |
| |
| *(pRawdata+8) = pPHYS->iUnit; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_sBIT |
| WRITE_CHUNK (mng_write_sbit) |
| { |
| mng_sbitp pSBIT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_START); |
| #endif |
| |
| pSBIT = (mng_sbitp)pChunk; /* address the proper chunk */ |
| |
| if (pSBIT->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 0; /* and default size */ |
| |
| switch (pSBIT->iType) |
| { |
| case 0: { /* gray */ |
| iRawlen = 1; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| |
| break; |
| } |
| case 2: { /* rgb */ |
| iRawlen = 3; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *(pRawdata+1) = pSBIT->aBits[1]; |
| *(pRawdata+2) = pSBIT->aBits[2]; |
| |
| break; |
| } |
| case 3: { /* indexed */ |
| iRawlen = 3; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *pRawdata = pSBIT->aBits[1]; |
| *pRawdata = pSBIT->aBits[2]; |
| |
| break; |
| } |
| case 4: { /* gray + alpha */ |
| iRawlen = 2; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *(pRawdata+1) = pSBIT->aBits[1]; |
| |
| break; |
| } |
| case 6: { /* rgb + alpha */ |
| iRawlen = 4; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *(pRawdata+1) = pSBIT->aBits[1]; |
| *(pRawdata+2) = pSBIT->aBits[2]; |
| *(pRawdata+3) = pSBIT->aBits[3]; |
| |
| break; |
| } |
| case 10: { /* jpeg gray */ |
| iRawlen = 1; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| |
| break; |
| } |
| case 12: { /* jpeg rgb */ |
| iRawlen = 3; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *(pRawdata+1) = pSBIT->aBits[1]; |
| *(pRawdata+2) = pSBIT->aBits[2]; |
| |
| break; |
| } |
| case 14: { /* jpeg gray + alpha */ |
| iRawlen = 2; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *(pRawdata+1) = pSBIT->aBits[1]; |
| |
| break; |
| } |
| case 16: { /* jpeg rgb + alpha */ |
| iRawlen = 4; /* fill the size & output buffer */ |
| *pRawdata = pSBIT->aBits[0]; |
| *(pRawdata+1) = pSBIT->aBits[1]; |
| *(pRawdata+2) = pSBIT->aBits[2]; |
| *(pRawdata+3) = pSBIT->aBits[3]; |
| |
| break; |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_sPLT |
| WRITE_CHUNK (mng_write_splt) |
| { |
| mng_spltp pSPLT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint32 iEntrieslen; |
| mng_uint8p pTemp; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_START); |
| #endif |
| |
| pSPLT = (mng_spltp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iEntrieslen = ((pSPLT->iSampledepth >> 3) * 4 + 2) * pSPLT->iEntrycount; |
| iRawlen = pSPLT->iNamesize + 2 + iEntrieslen; |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| |
| pTemp = pRawdata; /* fill the buffer */ |
| |
| if (pSPLT->iNamesize) |
| { |
| MNG_COPY (pTemp, pSPLT->zName, pSPLT->iNamesize); |
| pTemp += pSPLT->iNamesize; |
| } |
| |
| *pTemp = 0; |
| *(pTemp+1) = pSPLT->iSampledepth; |
| pTemp += 2; |
| |
| if (pSPLT->iEntrycount) |
| MNG_COPY (pTemp, pSPLT->pEntries, iEntrieslen); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pSPLT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| if (iRawlen > pData->iWritebufsize) /* drop the temp buffer ? */ |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_hIST |
| WRITE_CHUNK (mng_write_hist) |
| { |
| mng_histp pHIST; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint32 iX; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_START); |
| #endif |
| |
| pHIST = (mng_histp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pHIST->iEntrycount << 1; |
| |
| pTemp = pRawdata; /* fill the output buffer */ |
| |
| for (iX = 0; iX < pHIST->iEntrycount; iX++) |
| { |
| mng_put_uint16 (pTemp, pHIST->aEntries [iX]); |
| pTemp += 2; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pHIST->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_tIME |
| WRITE_CHUNK (mng_write_time) |
| { |
| mng_timep pTIME; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_START); |
| #endif |
| |
| pTIME = (mng_timep)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 7; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pTIME->iYear); |
| |
| *(pRawdata+2) = pTIME->iMonth; |
| *(pRawdata+3) = pTIME->iDay; |
| *(pRawdata+4) = pTIME->iHour; |
| *(pRawdata+5) = pTIME->iMinute; |
| *(pRawdata+6) = pTIME->iSecond; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pTIME->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_mhdr) |
| { |
| mng_mhdrp pMHDR; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_START); |
| #endif |
| |
| pMHDR = (mng_mhdrp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 28; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pMHDR->iWidth); |
| mng_put_uint32 (pRawdata+4, pMHDR->iHeight); |
| mng_put_uint32 (pRawdata+8, pMHDR->iTicks); |
| mng_put_uint32 (pRawdata+12, pMHDR->iLayercount); |
| mng_put_uint32 (pRawdata+16, pMHDR->iFramecount); |
| mng_put_uint32 (pRawdata+20, pMHDR->iPlaytime); |
| mng_put_uint32 (pRawdata+24, pMHDR->iSimplicity); |
| |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pMHDR->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_mend) |
| { |
| mng_mendp pMEND; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_START); |
| #endif |
| |
| pMEND = (mng_mendp)pChunk; /* address the proper chunk */ |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pMEND->sHeader.iChunkname, 0, 0); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_loop) |
| { |
| mng_loopp pLOOP; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED |
| mng_uint8p pTemp1; |
| mng_uint32p pTemp2; |
| mng_uint32 iX; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_START); |
| #endif |
| |
| pLOOP = (mng_loopp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 5; |
| /* fill the output buffer */ |
| *pRawdata = pLOOP->iLevel; |
| mng_put_uint32 (pRawdata+1, pLOOP->iRepeat); |
| |
| if (pLOOP->iTermination) |
| { |
| iRawlen++; |
| *(pRawdata+5) = pLOOP->iTermination; |
| |
| if ((pLOOP->iCount) || |
| (pLOOP->iItermin != 1) || (pLOOP->iItermax != 0x7FFFFFFFL)) |
| { |
| iRawlen += 8; |
| |
| mng_put_uint32 (pRawdata+6, pLOOP->iItermin); |
| mng_put_uint32 (pRawdata+10, pLOOP->iItermax); |
| |
| #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED |
| if (pLOOP->iCount) |
| { |
| iRawlen += pLOOP->iCount * 4; |
| |
| pTemp1 = pRawdata+14; |
| pTemp2 = pLOOP->pSignals; |
| |
| for (iX = 0; iX < pLOOP->iCount; iX++) |
| { |
| mng_put_uint32 (pTemp1, *pTemp2); |
| |
| pTemp1 += 4; |
| pTemp2++; |
| } |
| } |
| #endif |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pLOOP->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_endl) |
| { |
| mng_endlp pENDL; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_START); |
| #endif |
| |
| pENDL = (mng_endlp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 1; |
| |
| *pRawdata = pENDL->iLevel; /* fill the output buffer */ |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pENDL->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_defi) |
| { |
| mng_defip pDEFI; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_START); |
| #endif |
| |
| pDEFI = (mng_defip)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 2; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pDEFI->iObjectid); |
| |
| if ((pDEFI->iDonotshow) || (pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip)) |
| { |
| iRawlen++; |
| *(pRawdata+2) = pDEFI->iDonotshow; |
| |
| if ((pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip)) |
| { |
| iRawlen++; |
| *(pRawdata+3) = pDEFI->iConcrete; |
| |
| if ((pDEFI->bHasloca) || (pDEFI->bHasclip)) |
| { |
| iRawlen += 8; |
| |
| mng_put_uint32 (pRawdata+4, pDEFI->iXlocation); |
| mng_put_uint32 (pRawdata+8, pDEFI->iYlocation); |
| |
| if (pDEFI->bHasclip) |
| { |
| iRawlen += 16; |
| |
| mng_put_uint32 (pRawdata+12, pDEFI->iLeftcb); |
| mng_put_uint32 (pRawdata+16, pDEFI->iRightcb); |
| mng_put_uint32 (pRawdata+20, pDEFI->iTopcb); |
| mng_put_uint32 (pRawdata+24, pDEFI->iBottomcb); |
| } |
| } |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pDEFI->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_basi) |
| { |
| mng_basip pBASI; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_bool bOpaque; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_START); |
| #endif |
| |
| pBASI = (mng_basip)pChunk; /* address the proper chunk */ |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBASI->iBitdepth <= 8) /* determine opacity alpha-field */ |
| #endif |
| bOpaque = (mng_bool)(pBASI->iAlpha == 0xFF); |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else |
| bOpaque = (mng_bool)(pBASI->iAlpha == 0xFFFF); |
| #endif |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 13; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pBASI->iWidth); |
| mng_put_uint32 (pRawdata+4, pBASI->iHeight); |
| |
| *(pRawdata+8) = pBASI->iBitdepth; |
| *(pRawdata+9) = pBASI->iColortype; |
| *(pRawdata+10) = pBASI->iCompression; |
| *(pRawdata+11) = pBASI->iFilter; |
| *(pRawdata+12) = pBASI->iInterlace; |
| |
| if ((pBASI->iRed) || (pBASI->iGreen) || (pBASI->iBlue) || |
| (!bOpaque) || (pBASI->iViewable)) |
| { |
| iRawlen += 6; |
| mng_put_uint16 (pRawdata+13, pBASI->iRed); |
| mng_put_uint16 (pRawdata+15, pBASI->iGreen); |
| mng_put_uint16 (pRawdata+17, pBASI->iBlue); |
| |
| if ((!bOpaque) || (pBASI->iViewable)) |
| { |
| iRawlen += 2; |
| mng_put_uint16 (pRawdata+19, pBASI->iAlpha); |
| |
| if (pBASI->iViewable) |
| { |
| iRawlen++; |
| *(pRawdata+21) = pBASI->iViewable; |
| } |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pBASI->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_clon) |
| { |
| mng_clonp pCLON; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_START); |
| #endif |
| |
| pCLON = (mng_clonp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 4; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pCLON->iSourceid); |
| mng_put_uint16 (pRawdata+2, pCLON->iCloneid); |
| |
| if ((pCLON->iClonetype) || (pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca)) |
| { |
| iRawlen++; |
| *(pRawdata+4) = pCLON->iClonetype; |
| |
| if ((pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca)) |
| { |
| iRawlen++; |
| *(pRawdata+5) = pCLON->iDonotshow; |
| |
| if ((pCLON->iConcrete) || (pCLON->bHasloca)) |
| { |
| iRawlen++; |
| *(pRawdata+6) = pCLON->iConcrete; |
| |
| if (pCLON->bHasloca) |
| { |
| iRawlen += 9; |
| *(pRawdata+7) = pCLON->iLocationtype; |
| mng_put_int32 (pRawdata+8, pCLON->iLocationx); |
| mng_put_int32 (pRawdata+12, pCLON->iLocationy); |
| } |
| } |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pCLON->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_PAST |
| WRITE_CHUNK (mng_write_past) |
| { |
| mng_pastp pPAST; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_past_sourcep pSource; |
| mng_uint32 iX; |
| mng_uint8p pTemp; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_START); |
| #endif |
| |
| pPAST = (mng_pastp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 11 + (30 * pPAST->iCount); |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pPAST->iDestid); |
| |
| *(pRawdata+2) = pPAST->iTargettype; |
| |
| mng_put_int32 (pRawdata+3, pPAST->iTargetx); |
| mng_put_int32 (pRawdata+7, pPAST->iTargety); |
| |
| pTemp = pRawdata+11; |
| pSource = pPAST->pSources; |
| |
| for (iX = 0; iX < pPAST->iCount; iX++) |
| { |
| mng_put_uint16 (pTemp, pSource->iSourceid); |
| |
| *(pTemp+2) = pSource->iComposition; |
| *(pTemp+3) = pSource->iOrientation; |
| *(pTemp+4) = pSource->iOffsettype; |
| |
| mng_put_int32 (pTemp+5, pSource->iOffsetx); |
| mng_put_int32 (pTemp+9, pSource->iOffsety); |
| |
| *(pTemp+13) = pSource->iBoundarytype; |
| |
| mng_put_int32 (pTemp+14, pSource->iBoundaryl); |
| mng_put_int32 (pTemp+18, pSource->iBoundaryr); |
| mng_put_int32 (pTemp+22, pSource->iBoundaryt); |
| mng_put_int32 (pTemp+26, pSource->iBoundaryb); |
| |
| pSource++; |
| pTemp += 30; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pPAST->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| /* free temporary buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_disc) |
| { |
| mng_discp pDISC; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint32 iX; |
| mng_uint8p pTemp1; |
| mng_uint16p pTemp2; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_START); |
| #endif |
| |
| pDISC = (mng_discp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pDISC->iCount << 1; |
| |
| pTemp1 = pRawdata; /* fill the output buffer */ |
| pTemp2 = pDISC->pObjectids; |
| |
| for (iX = 0; iX < pDISC->iCount; iX++) |
| { |
| mng_put_uint16 (pTemp1, *pTemp2); |
| |
| pTemp2++; |
| pTemp1 += 2; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pDISC->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_back) |
| { |
| mng_backp pBACK; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_START); |
| #endif |
| |
| pBACK = (mng_backp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 6; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pBACK->iRed); |
| mng_put_uint16 (pRawdata+2, pBACK->iGreen); |
| mng_put_uint16 (pRawdata+4, pBACK->iBlue); |
| |
| if ((pBACK->iMandatory) || (pBACK->iImageid) || (pBACK->iTile)) |
| { |
| iRawlen++; |
| *(pRawdata+6) = pBACK->iMandatory; |
| |
| if ((pBACK->iImageid) || (pBACK->iTile)) |
| { |
| iRawlen += 2; |
| mng_put_uint16 (pRawdata+7, pBACK->iImageid); |
| |
| if (pBACK->iTile) |
| { |
| iRawlen++; |
| *(pRawdata+9) = pBACK->iTile; |
| } |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pBACK->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_fram) |
| { |
| mng_framp pFRAM; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_uint32p pTemp2; |
| mng_uint32 iX; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_START); |
| #endif |
| |
| pFRAM = (mng_framp)pChunk; /* address the proper chunk */ |
| |
| if (pFRAM->bEmpty) /* empty ? */ |
| iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 1; |
| /* fill the output buffer */ |
| *pRawdata = pFRAM->iMode; |
| |
| if ((pFRAM->iNamesize ) || |
| (pFRAM->iChangedelay ) || (pFRAM->iChangetimeout) || |
| (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid ) ) |
| { |
| if (pFRAM->iNamesize) |
| MNG_COPY (pRawdata+1, pFRAM->zName, pFRAM->iNamesize); |
| |
| iRawlen += pFRAM->iNamesize; |
| pTemp = pRawdata + pFRAM->iNamesize + 1; |
| |
| if ((pFRAM->iChangedelay ) || (pFRAM->iChangetimeout) || |
| (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid ) ) |
| { |
| *pTemp = 0; |
| *(pTemp+1) = pFRAM->iChangedelay; |
| *(pTemp+2) = pFRAM->iChangetimeout; |
| *(pTemp+3) = pFRAM->iChangeclipping; |
| *(pTemp+4) = pFRAM->iChangesyncid; |
| |
| iRawlen += 5; |
| pTemp += 5; |
| |
| if (pFRAM->iChangedelay) |
| { |
| mng_put_uint32 (pTemp, pFRAM->iDelay); |
| iRawlen += 4; |
| pTemp += 4; |
| } |
| |
| if (pFRAM->iChangetimeout) |
| { |
| mng_put_uint32 (pTemp, pFRAM->iTimeout); |
| iRawlen += 4; |
| pTemp += 4; |
| } |
| |
| if (pFRAM->iChangeclipping) |
| { |
| *pTemp = pFRAM->iBoundarytype; |
| |
| mng_put_uint32 (pTemp+1, pFRAM->iBoundaryl); |
| mng_put_uint32 (pTemp+5, pFRAM->iBoundaryr); |
| mng_put_uint32 (pTemp+9, pFRAM->iBoundaryt); |
| mng_put_uint32 (pTemp+13, pFRAM->iBoundaryb); |
| |
| iRawlen += 17; |
| pTemp += 17; |
| } |
| |
| if (pFRAM->iChangesyncid) |
| { |
| iRawlen += pFRAM->iCount * 4; |
| pTemp2 = pFRAM->pSyncids; |
| |
| for (iX = 0; iX < pFRAM->iCount; iX++) |
| { |
| mng_put_uint32 (pTemp, *pTemp2); |
| |
| pTemp2++; |
| pTemp += 4; |
| } |
| } |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_move) |
| { |
| mng_movep pMOVE; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_START); |
| #endif |
| |
| pMOVE = (mng_movep)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 13; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pMOVE->iFirstid); |
| mng_put_uint16 (pRawdata+2, pMOVE->iLastid); |
| |
| *(pRawdata+4) = pMOVE->iMovetype; |
| |
| mng_put_int32 (pRawdata+5, pMOVE->iMovex); |
| mng_put_int32 (pRawdata+9, pMOVE->iMovey); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pMOVE->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_clip) |
| { |
| mng_clipp pCLIP; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_START); |
| #endif |
| |
| pCLIP = (mng_clipp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 21; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pCLIP->iFirstid); |
| mng_put_uint16 (pRawdata+2, pCLIP->iLastid); |
| |
| *(pRawdata+4) = pCLIP->iCliptype; |
| |
| mng_put_int32 (pRawdata+5, pCLIP->iClipl); |
| mng_put_int32 (pRawdata+9, pCLIP->iClipr); |
| mng_put_int32 (pRawdata+13, pCLIP->iClipt); |
| mng_put_int32 (pRawdata+17, pCLIP->iClipb); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pCLIP->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_show) |
| { |
| mng_showp pSHOW; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_START); |
| #endif |
| |
| pSHOW = (mng_showp)pChunk; /* address the proper chunk */ |
| |
| if (pSHOW->bEmpty) /* empty ? */ |
| iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 2; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pSHOW->iFirstid); |
| |
| if ((pSHOW->iLastid != pSHOW->iFirstid) || (pSHOW->iMode)) |
| { |
| iRawlen += 2; |
| mng_put_uint16 (pRawdata+2, pSHOW->iLastid); |
| |
| if (pSHOW->iMode) |
| { |
| iRawlen++; |
| *(pRawdata+4) = pSHOW->iMode; |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_term) |
| { |
| mng_termp pTERM; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_START); |
| #endif |
| |
| pTERM = (mng_termp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 1; |
| |
| *pRawdata = pTERM->iTermaction; /* fill the output buffer */ |
| |
| if (pTERM->iTermaction == 3) |
| { |
| iRawlen = 10; |
| *(pRawdata+1) = pTERM->iIteraction; |
| |
| mng_put_uint32 (pRawdata+2, pTERM->iDelay); |
| mng_put_uint32 (pRawdata+6, pTERM->iItermax); |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pTERM->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_SAVE |
| WRITE_CHUNK (mng_write_save) |
| { |
| mng_savep pSAVE; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_save_entryp pEntry; |
| mng_uint32 iEntrysize; |
| mng_uint8p pTemp; |
| mng_uint32 iX; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_START); |
| #endif |
| |
| pSAVE = (mng_savep)pChunk; /* address the proper chunk */ |
| |
| if (pSAVE->bEmpty) /* empty ? */ |
| iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 1; |
| |
| *pRawdata = pSAVE->iOffsettype; /* fill the output buffer */ |
| |
| if (pSAVE->iOffsettype == 16) |
| iEntrysize = 25; |
| else |
| iEntrysize = 17; |
| |
| pTemp = pRawdata+1; |
| pEntry = pSAVE->pEntries; |
| |
| for (iX = 0; iX < pSAVE->iCount; iX++) |
| { |
| if (iX) /* put separator null-byte, except the first */ |
| { |
| *pTemp = 0; |
| pTemp++; |
| iRawlen++; |
| } |
| |
| iRawlen += iEntrysize + pEntry->iNamesize; |
| *pTemp = pEntry->iEntrytype; |
| |
| if (pSAVE->iOffsettype == 16) |
| { |
| mng_put_uint32 (pTemp+1, pEntry->iOffset[0]); |
| mng_put_uint32 (pTemp+5, pEntry->iOffset[1]); |
| mng_put_uint32 (pTemp+9, pEntry->iStarttime[0]); |
| mng_put_uint32 (pTemp+13, pEntry->iStarttime[1]); |
| mng_put_uint32 (pTemp+17, pEntry->iLayernr); |
| mng_put_uint32 (pTemp+21, pEntry->iFramenr); |
| |
| pTemp += 25; |
| } |
| else |
| { |
| mng_put_uint32 (pTemp+1, pEntry->iOffset[1]); |
| mng_put_uint32 (pTemp+5, pEntry->iStarttime[1]); |
| mng_put_uint32 (pTemp+9, pEntry->iLayernr); |
| mng_put_uint32 (pTemp+13, pEntry->iFramenr); |
| |
| pTemp += 17; |
| } |
| |
| if (pEntry->iNamesize) |
| { |
| MNG_COPY (pTemp, pEntry->zName, pEntry->iNamesize); |
| pTemp += pEntry->iNamesize; |
| } |
| |
| pEntry++; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_SEEK |
| WRITE_CHUNK (mng_write_seek) |
| { |
| mng_seekp pSEEK; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_START); |
| #endif |
| |
| pSEEK = (mng_seekp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pSEEK->iNamesize; |
| |
| if (iRawlen) /* fill the output buffer */ |
| MNG_COPY (pRawdata, pSEEK->zName, iRawlen); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pSEEK->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_eXPI |
| WRITE_CHUNK (mng_write_expi) |
| { |
| mng_expip pEXPI; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_START); |
| #endif |
| |
| pEXPI = (mng_expip)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 2 + pEXPI->iNamesize; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pEXPI->iSnapshotid); |
| |
| if (pEXPI->iNamesize) |
| MNG_COPY (pRawdata+2, pEXPI->zName, pEXPI->iNamesize); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pEXPI->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_fPRI |
| WRITE_CHUNK (mng_write_fpri) |
| { |
| mng_fprip pFPRI; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_START); |
| #endif |
| |
| pFPRI = (mng_fprip)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 2; |
| |
| *pRawdata = pFPRI->iDeltatype; /* fill the output buffer */ |
| *(pRawdata+1) = pFPRI->iPriority; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pFPRI->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_nEED |
| WRITE_CHUNK (mng_write_need) |
| { |
| mng_needp pNEED; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_START); |
| #endif |
| |
| pNEED = (mng_needp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pNEED->iKeywordssize; |
| /* fill the output buffer */ |
| if (pNEED->iKeywordssize) |
| MNG_COPY (pRawdata, pNEED->zKeywords, pNEED->iKeywordssize); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pNEED->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_pHYg |
| WRITE_CHUNK (mng_write_phyg) |
| { |
| mng_phygp pPHYG; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_START); |
| #endif |
| |
| pPHYG = (mng_phygp)pChunk; /* address the proper chunk */ |
| |
| if (pPHYG->bEmpty) /* write empty ? */ |
| iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 9; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pPHYG->iSizex); |
| mng_put_uint32 (pRawdata+4, pPHYG->iSizey); |
| |
| *(pRawdata+8) = pPHYG->iUnit; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| /* B004 */ |
| #ifdef MNG_INCLUDE_JNG |
| /* B004 */ |
| WRITE_CHUNK (mng_write_jhdr) |
| { |
| mng_jhdrp pJHDR; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_START); |
| #endif |
| |
| pJHDR = (mng_jhdrp)pChunk; /* address the proper chunk */ |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 16; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pJHDR->iWidth); |
| mng_put_uint32 (pRawdata+4, pJHDR->iHeight); |
| |
| *(pRawdata+8) = pJHDR->iColortype; |
| *(pRawdata+9) = pJHDR->iImagesampledepth; |
| *(pRawdata+10) = pJHDR->iImagecompression; |
| *(pRawdata+11) = pJHDR->iImageinterlace; |
| *(pRawdata+12) = pJHDR->iAlphasampledepth; |
| *(pRawdata+13) = pJHDR->iAlphacompression; |
| *(pRawdata+14) = pJHDR->iAlphafilter; |
| *(pRawdata+15) = pJHDR->iAlphainterlace; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pJHDR->sHeader.iChunkname, iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #else |
| #define write_jhdr 0 |
| /* B004 */ |
| #endif /* MNG_INCLUDE_JNG */ |
| /* B004 */ |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_JNG |
| WRITE_CHUNK (mng_write_jdaa) |
| { |
| mng_jdatp pJDAA; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_START); |
| #endif |
| |
| pJDAA = (mng_jdaap)pChunk; /* address the proper chunk */ |
| |
| if (pJDAA->bEmpty) /* and write it */ |
| iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname, 0, 0); |
| else |
| iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname, |
| pJDAA->iDatasize, pJDAA->pData); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #else |
| #define write_jdaa 0 |
| #endif /* MNG_INCLUDE_JNG */ |
| |
| /* ************************************************************************** */ |
| |
| /* B004 */ |
| #ifdef MNG_INCLUDE_JNG |
| /* B004 */ |
| WRITE_CHUNK (mng_write_jdat) |
| { |
| mng_jdatp pJDAT; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_START); |
| #endif |
| |
| pJDAT = (mng_jdatp)pChunk; /* address the proper chunk */ |
| |
| if (pJDAT->bEmpty) /* and write it */ |
| iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname, 0, 0); |
| else |
| iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname, |
| pJDAT->iDatasize, pJDAT->pData); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #else |
| #define write_jdat 0 |
| /* B004 */ |
| #endif /* MNG_INCLUDE_JNG */ |
| /* B004 */ |
| |
| /* ************************************************************************** */ |
| |
| /* B004 */ |
| #ifdef MNG_INCLUDE_JNG |
| /* B004 */ |
| WRITE_CHUNK (mng_write_jsep) |
| { |
| mng_jsepp pJSEP; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_START); |
| #endif |
| |
| pJSEP = (mng_jsepp)pChunk; /* address the proper chunk */ |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pJSEP->sHeader.iChunkname, 0, 0); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #else |
| #define write_jsep 0 |
| /* B004 */ |
| #endif /* MNG_INCLUDE_JNG */ |
| /* B004 */ |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| WRITE_CHUNK (mng_write_dhdr) |
| { |
| mng_dhdrp pDHDR; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_START); |
| #endif |
| |
| pDHDR = (mng_dhdrp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 4; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pDHDR->iObjectid); |
| |
| *(pRawdata+2) = pDHDR->iImagetype; |
| *(pRawdata+3) = pDHDR->iDeltatype; |
| |
| if (pDHDR->iDeltatype != 7) |
| { |
| iRawlen += 8; |
| mng_put_uint32 (pRawdata+4, pDHDR->iBlockwidth); |
| mng_put_uint32 (pRawdata+8, pDHDR->iBlockheight); |
| |
| if (pDHDR->iDeltatype != 0) |
| { |
| iRawlen += 8; |
| mng_put_uint32 (pRawdata+12, pDHDR->iBlockx); |
| mng_put_uint32 (pRawdata+16, pDHDR->iBlocky); |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pDHDR->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| WRITE_CHUNK (mng_write_prom) |
| { |
| mng_promp pPROM; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_START); |
| #endif |
| |
| pPROM = (mng_promp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 3; |
| |
| *pRawdata = pPROM->iColortype; /* fill the output buffer */ |
| *(pRawdata+1) = pPROM->iSampledepth; |
| *(pRawdata+2) = pPROM->iFilltype; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pPROM->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| WRITE_CHUNK (mng_write_ipng) |
| { |
| mng_ipngp pIPNG; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_START); |
| #endif |
| |
| pIPNG = (mng_ipngp)pChunk; /* address the proper chunk */ |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pIPNG->sHeader.iChunkname, 0, 0); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| WRITE_CHUNK (mng_write_pplt) |
| { |
| mng_ppltp pPPLT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_pplt_entryp pEntry; |
| mng_uint8p pTemp; |
| mng_uint32 iX; |
| mng_bool bHasgroup; |
| mng_uint8p pLastid = 0; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_START); |
| #endif |
| |
| pPPLT = (mng_ppltp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 1; |
| |
| *pRawdata = pPPLT->iDeltatype; /* fill the output buffer */ |
| |
| pTemp = pRawdata+1; |
| bHasgroup = MNG_FALSE; |
| |
| for (iX = 0; iX < pPPLT->iCount; iX++) |
| { |
| pEntry = &pPPLT->aEntries[iX]; |
| |
| if (pEntry->bUsed) /* valid entry ? */ |
| { |
| if (!bHasgroup) /* start a new group ? */ |
| { |
| bHasgroup = MNG_TRUE; |
| pLastid = pTemp+1; |
| |
| *pTemp = (mng_uint8)iX; |
| *(pTemp+1) = 0; |
| |
| pTemp += 2; |
| iRawlen += 2; |
| } |
| |
| switch (pPPLT->iDeltatype) /* add group-entry depending on type */ |
| { |
| case 0: ; |
| case 1: { |
| *pTemp = pEntry->iRed; |
| *(pTemp+1) = pEntry->iGreen; |
| *(pTemp+2) = pEntry->iBlue; |
| |
| pTemp += 3; |
| iRawlen += 3; |
| |
| break; |
| } |
| |
| case 2: ; |
| case 3: { |
| *pTemp = pEntry->iAlpha; |
| |
| pTemp++; |
| iRawlen++; |
| |
| break; |
| } |
| |
| case 4: ; |
| case 5: { |
| *pTemp = pEntry->iRed; |
| *(pTemp+1) = pEntry->iGreen; |
| *(pTemp+2) = pEntry->iBlue; |
| *(pTemp+3) = pEntry->iAlpha; |
| |
| pTemp += 4; |
| iRawlen += 4; |
| |
| break; |
| } |
| |
| } |
| } |
| else |
| { |
| if (bHasgroup) /* finish off a group ? */ |
| *pLastid = (mng_uint8)(iX-1); |
| |
| bHasgroup = MNG_FALSE; |
| } |
| } |
| |
| if (bHasgroup) /* last group unfinished ? */ |
| *pLastid = (mng_uint8)(pPPLT->iCount-1); |
| /* write the output buffer */ |
| iRetcode = write_raw_chunk (pData, pPPLT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| #ifdef MNG_INCLUDE_JNG |
| WRITE_CHUNK (mng_write_ijng) |
| { |
| mng_ijngp pIJNG; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_START); |
| #endif |
| |
| pIJNG = (mng_ijngp)pChunk; /* address the proper chunk */ |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pIJNG->sHeader.iChunkname, 0, 0); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| WRITE_CHUNK (mng_write_drop) |
| { |
| mng_dropp pDROP; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint32 iX; |
| mng_uint8p pTemp1; |
| mng_chunkidp pTemp2; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_START); |
| #endif |
| |
| pDROP = (mng_dropp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pDROP->iCount << 2; |
| |
| pTemp1 = pRawdata; /* fill the output buffer */ |
| pTemp2 = pDROP->pChunknames; |
| |
| for (iX = 0; iX < pDROP->iCount; iX++) |
| { |
| mng_put_uint32 (pTemp1, (mng_uint32)*pTemp2); |
| |
| pTemp2++; |
| pTemp1 += 4; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pDROP->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| #ifndef MNG_SKIPCHUNK_DBYK |
| WRITE_CHUNK (mng_write_dbyk) |
| { |
| mng_dbykp pDBYK; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_START); |
| #endif |
| |
| pDBYK = (mng_dbykp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 5 + pDBYK->iKeywordssize; |
| /* fill the output buffer */ |
| mng_put_uint32 (pRawdata, pDBYK->iChunkname); |
| *(pRawdata+4) = pDBYK->iPolarity; |
| |
| if (pDBYK->iKeywordssize) |
| MNG_COPY (pRawdata+5, pDBYK->zKeywords, pDBYK->iKeywordssize); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pDBYK->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_NO_DELTA_PNG |
| #ifndef MNG_SKIPCHUNK_ORDR |
| WRITE_CHUNK (mng_write_ordr) |
| { |
| mng_ordrp pORDR; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pTemp; |
| mng_ordr_entryp pEntry; |
| mng_uint32 iX; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_START); |
| #endif |
| |
| pORDR = (mng_ordrp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = pORDR->iCount * 5; |
| |
| pTemp = pRawdata; /* fill the output buffer */ |
| pEntry = pORDR->pEntries; |
| |
| for (iX = 0; iX < pORDR->iCount; iX++) |
| { |
| mng_put_uint32 (pTemp, pEntry->iChunkname); |
| *(pTemp+4) = pEntry->iOrdertype; |
| pTemp += 5; |
| pEntry++; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pORDR->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_magn) |
| { |
| mng_magnp pMAGN; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_START); |
| #endif |
| |
| pMAGN = (mng_magnp)pChunk; /* address the proper chunk */ |
| |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 18; |
| /* fill the output buffer */ |
| mng_put_uint16 (pRawdata, pMAGN->iFirstid); |
| mng_put_uint16 (pRawdata+2, pMAGN->iLastid); |
| *(pRawdata+4) = pMAGN->iMethodX; |
| mng_put_uint16 (pRawdata+5, pMAGN->iMX); |
| mng_put_uint16 (pRawdata+7, pMAGN->iMY); |
| mng_put_uint16 (pRawdata+9, pMAGN->iML); |
| mng_put_uint16 (pRawdata+11, pMAGN->iMR); |
| mng_put_uint16 (pRawdata+13, pMAGN->iMT); |
| mng_put_uint16 (pRawdata+15, pMAGN->iMB); |
| *(pRawdata+17) = pMAGN->iMethodY; |
| /* optimize length */ |
| if (pMAGN->iMethodY == pMAGN->iMethodX) |
| { |
| iRawlen--; |
| |
| if (pMAGN->iMB == pMAGN->iMY) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iMT == pMAGN->iMY) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iMR == pMAGN->iMX) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iML == pMAGN->iMX) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iMY == pMAGN->iMX) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iMX == 1) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iMethodX == 0) |
| { |
| iRawlen--; |
| |
| if (pMAGN->iLastid == pMAGN->iFirstid) |
| { |
| iRawlen -= 2; |
| |
| if (pMAGN->iFirstid == 0) |
| iRawlen = 0; |
| |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pMAGN->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_MPNG_PROPOSAL |
| WRITE_CHUNK (mng_write_mpng) |
| { |
| mng_mpngp pMPNG; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_uint8p pBuf = 0; |
| mng_uint32 iBuflen; |
| mng_uint32 iReallen; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_START); |
| #endif |
| |
| pMPNG = (mng_mpngp)pChunk; /* address the proper chunk */ |
| /* compress the frame structures */ |
| iRetcode = deflate_buffer (pData, (mng_uint8p)pMPNG->pFrames, pMPNG->iFramessize, |
| &pBuf, &iBuflen, &iReallen); |
| |
| if (!iRetcode) /* all ok ? */ |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 15 + iReallen; |
| /* requires large buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_ALLOC (pData, pRawdata, iRawlen); |
| /* fill the buffer */ |
| mng_put_uint32 (pRawdata, pMPNG->iFramewidth); |
| mng_put_uint32 (pRawdata+4, pMPNG->iFrameheight); |
| mng_put_uint16 (pRawdata+8, pMPNG->iNumplays); |
| mng_put_uint16 (pRawdata+10, pMPNG->iTickspersec); |
| *(pRawdata+12) = pMPNG->iCompressionmethod; |
| |
| if (iReallen) |
| MNG_COPY (pRawdata+13, pBuf, iReallen); |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pMPNG->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| /* drop the temp buffer ? */ |
| if (iRawlen > pData->iWritebufsize) |
| MNG_FREEX (pData, pRawdata, iRawlen); |
| } |
| |
| MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_ANG_PROPOSAL |
| WRITE_CHUNK (mng_write_ahdr) |
| { |
| mng_ahdrp pAHDR; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_START); |
| #endif |
| |
| pAHDR = (mng_ahdrp)pChunk; /* address the proper chunk */ |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 22; |
| /* fill the buffer */ |
| mng_put_uint32 (pRawdata, pAHDR->iNumframes); |
| mng_put_uint32 (pRawdata+4, pAHDR->iTickspersec); |
| mng_put_uint32 (pRawdata+8, pAHDR->iNumplays); |
| mng_put_uint32 (pRawdata+12, pAHDR->iTilewidth); |
| mng_put_uint32 (pRawdata+16, pAHDR->iTileheight); |
| *(pRawdata+20) = pAHDR->iInterlace; |
| *(pRawdata+21) = pAHDR->iStillused; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pAHDR->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_ANG_PROPOSAL |
| WRITE_CHUNK (mng_write_adat) |
| { |
| |
| /* TODO: something */ |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_evNT |
| WRITE_CHUNK (mng_write_evnt) |
| { |
| mng_evntp pEVNT; |
| mng_uint8p pRawdata; |
| mng_uint32 iRawlen; |
| mng_retcode iRetcode; |
| mng_evnt_entryp pEntry; |
| mng_uint8p pTemp; |
| mng_uint32 iX; |
| mng_uint32 iNamesize; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_START); |
| #endif |
| |
| pEVNT = (mng_evntp)pChunk; /* address the proper chunk */ |
| |
| if (!pEVNT->iCount) /* empty ? */ |
| iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname, 0, 0); |
| else |
| { |
| pRawdata = pData->pWritebuf+8; /* init output buffer & size */ |
| iRawlen = 0; |
| pTemp = pRawdata; |
| pEntry = pEVNT->pEntries; |
| |
| for (iX = 0; iX < pEVNT->iCount; iX++) |
| { |
| if (iX) /* put separator null-byte, except the first */ |
| { |
| *pTemp = 0; |
| pTemp++; |
| iRawlen++; |
| } |
| |
| *pTemp = pEntry->iEventtype; |
| *(pTemp+1) = pEntry->iMasktype; |
| pTemp += 2; |
| iRawlen += 2; |
| |
| switch (pEntry->iMasktype) |
| { |
| case 1 : |
| { |
| mng_put_int32 (pTemp, pEntry->iLeft); |
| mng_put_int32 (pTemp+4, pEntry->iRight); |
| mng_put_int32 (pTemp+8, pEntry->iTop); |
| mng_put_int32 (pTemp+12, pEntry->iBottom); |
| pTemp += 16; |
| iRawlen += 16; |
| break; |
| } |
| case 2 : |
| { |
| mng_put_uint16 (pTemp, pEntry->iObjectid); |
| pTemp += 2; |
| iRawlen += 2; |
| break; |
| } |
| case 3 : |
| { |
| mng_put_uint16 (pTemp, pEntry->iObjectid); |
| *(pTemp+2) = pEntry->iIndex; |
| pTemp += 3; |
| iRawlen += 3; |
| break; |
| } |
| case 4 : |
| { |
| mng_put_int32 (pTemp, pEntry->iLeft); |
| mng_put_int32 (pTemp+4, pEntry->iRight); |
| mng_put_int32 (pTemp+8, pEntry->iTop); |
| mng_put_int32 (pTemp+12, pEntry->iBottom); |
| mng_put_uint16 (pTemp+16, pEntry->iObjectid); |
| pTemp += 18; |
| iRawlen += 18; |
| break; |
| } |
| case 5 : |
| { |
| mng_put_int32 (pTemp, pEntry->iLeft); |
| mng_put_int32 (pTemp+4, pEntry->iRight); |
| mng_put_int32 (pTemp+8, pEntry->iTop); |
| mng_put_int32 (pTemp+12, pEntry->iBottom); |
| mng_put_uint16 (pTemp+16, pEntry->iObjectid); |
| *(pTemp+18) = pEntry->iIndex; |
| pTemp += 19; |
| iRawlen += 19; |
| break; |
| } |
| } |
| |
| iNamesize = pEntry->iSegmentnamesize; |
| |
| if (iNamesize) |
| { |
| MNG_COPY (pTemp, pEntry->zSegmentname, iNamesize); |
| pTemp += iNamesize; |
| iRawlen += iNamesize; |
| } |
| |
| pEntry++; |
| } |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname, |
| iRawlen, pRawdata); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| WRITE_CHUNK (mng_write_unknown) |
| { |
| mng_unknown_chunkp pUnknown; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_START); |
| #endif |
| /* address the proper chunk */ |
| pUnknown = (mng_unknown_chunkp)pChunk; |
| /* and write it */ |
| iRetcode = write_raw_chunk (pData, pUnknown->sHeader.iChunkname, |
| pUnknown->iDatasize, pUnknown->pData); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #endif /* MNG_INCLUDE_WRITE_PROCS */ |
| |
| /* ************************************************************************** */ |
| /* * end of file * */ |
| /* ************************************************************************** */ |
| |