diff -r 000000000000 -r 1918ee327afb src/3rdparty/libmng/libmng_chunk_io.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/3rdparty/libmng/libmng_chunk_io.c Mon Jan 11 14:00:40 2010 +0000 @@ -0,0 +1,10740 @@ +/** ************************************************************************* */ +/* * 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 * */ +/* ************************************************************************** */ +