mirror of
https://github.com/etlegacy/EasyGen.git
synced 2024-11-10 06:42:16 +00:00
10740 lines
340 KiB
C
10740 lines
340 KiB
C
/** ************************************************************************* */
|
|
/* * 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 * */
|
|
/* ************************************************************************** */
|
|
|