/** ************************************************************************* */ | |
/* * 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 * */ | |
/* ************************************************************************** */ | |