PageRenderTime 88ms CodeModel.GetById 2ms app.highlight 76ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/LibMNG/libmng_chunk_io.c

https://bitbucket.org/cabalistic/ogredeps/
C | 1459 lines | 942 code | 174 blank | 343 comment | 352 complexity | 7923962c84af202d068737fdfbf91ecd MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/** ************************************************************************* */
   2/* *             For conditions of distribution and use,                    * */
   3/* *                see copyright notice in libmng.h                        * */
   4/* ************************************************************************** */
   5/* *                                                                        * */
   6/* * project   : libmng                                                     * */
   7/* * file      : libmng_chunk_io.c         copyright (c) 2000-2007 G.Juyn   * */
   8/* * version   : 1.0.10                                                     * */
   9/* *                                                                        * */
  10/* * purpose   : Chunk I/O routines (implementation)                        * */
  11/* *                                                                        * */
  12/* * author    : G.Juyn                                                     * */
  13/* *                                                                        * */
  14/* * comment   : implementation of chunk input/output routines              * */
  15/* *                                                                        * */
  16/* * changes   : 0.5.1 - 05/01/2000 - G.Juyn                                * */
  17/* *             - cleaned up left-over teststuff in the BACK chunk routine * */
  18/* *             0.5.1 - 05/04/2000 - G.Juyn                                * */
  19/* *             - changed CRC initialization to use dynamic structure      * */
  20/* *               (wasn't thread-safe the old way !)                       * */
  21/* *             0.5.1 - 05/06/2000 - G.Juyn                                * */
  22/* *             - filled in many missing sequence&length checks            * */
  23/* *             - filled in many missing chunk-store snippets              * */
  24/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
  25/* *             - added checks for running animations                      * */
  26/* *             - filled some write routines                               * */
  27/* *             - changed strict-ANSI stuff                                * */
  28/* *             0.5.1 - 05/10/2000 - G.Juyn                                * */
  29/* *             - filled some more write routines                          * */
  30/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
  31/* *             - filled remaining write routines                          * */
  32/* *             - fixed read_pplt with regard to deltatype                 * */
  33/* *             - added callback error-reporting support                   * */
  34/* *             - added pre-draft48 support (short MHDR, frame_mode, LOOP) * */
  35/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
  36/* *             - changed trace to macro for callback error-reporting      * */
  37/* *             - fixed chunk-storage bit in several routines              * */
  38/* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
  39/* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
  40/* *             - added TERM animation object pointer (easier reference)   * */
  41/* *             - supplemented the SAVE & SEEK display processing          * */
  42/* *                                                                        * */
  43/* *             0.5.2 - 05/18/2000 - G.Juyn                                * */
  44/* *             - B004 - fixed problem with MNG_SUPPORT_WRITE not defined  * */
  45/* *               also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG       * */
  46/* *             0.5.2 - 05/19/2000 - G.Juyn                                * */
  47/* *             - cleaned up some code regarding mixed support             * */
  48/* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
  49/* *             - implemented JNG support                                  * */
  50/* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
  51/* *             - added support for global color-chunks in animation       * */
  52/* *             - added support for global PLTE,tRNS,bKGD in animation     * */
  53/* *             - added support for SAVE & SEEK in animation               * */
  54/* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
  55/* *             - changed ani_create calls not returning object pointer    * */
  56/* *             - create ani objects always (not just inside TERM/LOOP)    * */
  57/* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
  58/* *             - added support for delta-image processing                 * */
  59/* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
  60/* *             - fixed up punctuation (contributed by Tim Rowley)         * */
  61/* *             0.5.2 - 06/02/2000 - G.Juyn                                * */
  62/* *             - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED               * */
  63/* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
  64/* *             - fixed makeup for Linux gcc compile                       * */
  65/* *                                                                        * */
  66/* *             0.5.3 - 06/12/2000 - G.Juyn                                * */
  67/* *             - added processing of color-info on delta-image            * */
  68/* *             0.5.3 - 06/13/2000 - G.Juyn                                * */
  69/* *             - fixed handling of empty SAVE chunk                       * */
  70/* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
  71/* *             - changed to support delta-images                          * */
  72/* *             - added extra checks for delta-images                      * */
  73/* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
  74/* *             - fixed possible trouble if IEND display-process got       * */
  75/* *               broken up                                                * */
  76/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
  77/* *             - added processing of PLTE & tRNS for delta-images         * */
  78/* *             - added administration of imagelevel parameter             * */
  79/* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
  80/* *             - implemented support for PPLT chunk                       * */
  81/* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
  82/* *             - added precaution against faulty iCCP chunks from PS      * */
  83/* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
  84/* *             - fixed some 64-bit warnings                               * */
  85/* *                                                                        * */
  86/* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
  87/* *             - changed pre-draft48 frame_mode=3 to frame_mode=1         * */
  88/* *             0.9.1 - 07/16/2000 - G.Juyn                                * */
  89/* *             - fixed storage of images during mng_read()                * */
  90/* *             - fixed support for mng_display() after mng_read()         * */
  91/* *             0.9.1 - 07/19/2000 - G.Juyn                                * */
  92/* *             - fixed several chunk-writing routines                     * */
  93/* *             0.9.1 - 07/24/2000 - G.Juyn                                * */
  94/* *             - fixed reading of still-images                            * */
  95/* *                                                                        * */
  96/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
  97/* *             - changed file-prefixes                                    * */
  98/* *                                                                        * */
  99/* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
 100/* *             - B111300 - fixup for improved portability                 * */
 101/* *             0.9.3 - 08/08/2000 - G.Juyn                                * */
 102/* *             - fixed compiler-warnings from Mozilla                     * */
 103/* *             0.9.3 - 08/09/2000 - G.Juyn                                * */
 104/* *             - added check for simplicity-bits in MHDR                  * */
 105/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
 106/* *             - fixed check for simplicity-bits in MHDR (JNG)            * */
 107/* *             0.9.3 - 08/12/2000 - G.Juyn                                * */
 108/* *             - added workaround for faulty PhotoShop iCCP chunk         * */
 109/* *             0.9.3 - 08/22/2000 - G.Juyn                                * */
 110/* *             - fixed write-code for zTXt & iTXt                         * */
 111/* *             - fixed read-code for iTXt                                 * */
 112/* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
 113/* *             - added MAGN chunk                                         * */
 114/* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
 115/* *             - added support for new filter_types                       * */
 116/* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
 117/* *             - fixed DEFI behavior                                      * */
 118/* *             0.9.3 - 10/02/2000 - G.Juyn                                * */
 119/* *             - fixed simplicity-check in compliance with draft 81/0.98a * */
 120/* *             0.9.3 - 10/10/2000 - G.Juyn                                * */
 121/* *             - added support for alpha-depth prediction                 * */
 122/* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
 123/* *             - added support for nEED                                   * */
 124/* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
 125/* *             - added support for JDAA                                   * */
 126/* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
 127/* *             - fixed support for MAGN                                   * */
 128/* *             - implemented nEED "xxxx" (where "xxxx" is a chunkid)      * */
 129/* *             - added callback to process non-critical unknown chunks    * */
 130/* *             - fixed support for bKGD                                   * */
 131/* *             0.9.3 - 10/23/2000 - G.Juyn                                * */
 132/* *             - fixed bug in empty PLTE handling                         * */
 133/* *                                                                        * */
 134/* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
 135/* *             - changed IHDR filter_method check for PNGs                * */
 136/* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
 137/* *             - added errorchecking for MAGN methods                     * */
 138/* *             - removed test filter-methods 1 & 65                       * */
 139/* *                                                                        * */
 140/* *             0.9.5 -  1/25/2001 - G.Juyn                                * */
 141/* *             - fixed some small compiler warnings (thanks Nikki)        * */
 142/* *                                                                        * */
 143/* *             1.0.2 - 05/05/2000 - G.Juyn                                * */
 144/* *             - B421427 - writes wrong format in bKGD and tRNS           * */
 145/* *             1.0.2 - 06/20/2000 - G.Juyn                                * */
 146/* *             - B434583 - compiler-warning if MNG_STORE_CHUNKS undefined * */
 147/* *                                                                        * */
 148/* *             1.0.5 - 07/08/2002 - G.Juyn                                * */
 149/* *             - B578572 - removed eMNGma hack (thanks Dimitri!)          * */
 150/* *             1.0.5 - 08/07/2002 - G.Juyn                                * */
 151/* *             - added test-option for PNG filter method 193 (=no filter) * */
 152/* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
 153/* *             - completed PROM support                                   * */
 154/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
 155/* *             - B597134 - libmng pollutes the linker namespace           * */
 156/* *             1.0.5 - 09/07/2002 - G.Juyn                                * */
 157/* *             - fixed reading of FRAM with just frame_mode and name      * */
 158/* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
 159/* *             - fixed read/write of MAGN chunk                           * */
 160/* *             1.0.5 - 09/14/2002 - G.Juyn                                * */
 161/* *             - added event handling for dynamic MNG                     * */
 162/* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
 163/* *             - fixed LOOP iteration=0 special case                      * */
 164/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
 165/* *             - misplaced TERM is now treated as warning                 * */
 166/* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
 167/* *             - added support for PAST                                   * */
 168/* *             1.0.5 - 10/03/2002 - G.Juyn                                * */
 169/* *             - fixed chunk-storage for evNT chunk                       * */
 170/* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
 171/* *             - fixed DISC support                                       * */
 172/* *             - added another fix for misplaced TERM chunk               * */
 173/* *             1.0.5 - 10/17/2002 - G.Juyn                                * */
 174/* *             - fixed initializtion of pIds in dISC read routine         * */
 175/* *             1.0.5 - 11/06/2002 - G.Juyn                                * */
 176/* *             - added support for nEED "MNG 1.1"                         * */
 177/* *             - added support for nEED "CACHEOFF"                        * */
 178/* *                                                                        * */
 179/* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
 180/* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
 181/* *             1.0.6 - 06/02/2003 - G.R-P                                 * */
 182/* *             - removed some redundant checks for iRawlen==0             * */
 183/* *             1.0.6 - 06/22/2003 - G.R-P                                 * */
 184/* *             - added MNG_NO_16BIT_SUPPORT, MNG_NO_DELTA_PNG reductions  * */
 185/* *             - optionally use zlib's crc32 function instead of          * */
 186/* *               local mng_update_crc                                     * */
 187/* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
 188/* *             - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional          * */
 189/* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
 190/* *             - added conditionals around PAST chunk support             * */
 191/* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
 192/* *             - added conditionals around non-VLC chunk support          * */
 193/* *                                                                        * */
 194/* *             1.0.7 - 10/29/2003 - G.R-P                                 * */
 195/* *             - revised JDAA and JDAT readers to avoid compiler bug      * */
 196/* *             1.0.7 - 01/25/2004 - J.S                                   * */
 197/* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
 198/* *             1.0.7 - 01/27/2004 - J.S                                   * */
 199/* *             - fixed inclusion of IJNG chunk for non-JNG use            * */
 200/* *             1.0.7 - 02/26/2004 - G.Juyn                                * */
 201/* *             - fixed bug in chunk-storage of SHOW chunk (from == to)    * */
 202/* *                                                                        * */
 203/* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
 204/* *             - added CRC existence & checking flags                     * */
 205/* *             1.0.8 - 07/07/2004 - G.R-P                                 * */
 206/* *             - change worst-case iAlphadepth to 1 for standalone PNGs   * */
 207/* *                                                                        * */
 208/* *             1.0.9 - 09/28/2004 - G.R-P                                 * */
 209/* *             - improved handling of cheap transparency when 16-bit      * */
 210/* *               support is disabled                                      * */
 211/* *             1.0.9 - 10/04/2004 - G.Juyn                                * */
 212/* *             - fixed bug in writing sBIT for indexed color              * */
 213/* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
 214/* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
 215/* *             1.0.9 - 12/05/2004 - G.Juyn                                * */
 216/* *             - added conditional MNG_OPTIMIZE_CHUNKINITFREE             * */
 217/* *             1.0.9 - 12/06/2004 - G.Juyn                                * */
 218/* *             - added conditional MNG_OPTIMIZE_CHUNKASSIGN               * */
 219/* *             1.0.9 - 12/07/2004 - G.Juyn                                * */
 220/* *             - added conditional MNG_OPTIMIZE_CHUNKREADER               * */
 221/* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
 222/* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
 223/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
 224/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
 225/* *             1.0.9 - 01/17/2005 - G.Juyn                                * */
 226/* *             - fixed problem with global PLTE/tRNS                      * */
 227/* *                                                                        * */
 228/* *             1.0.10 - 02/07/2005 - G.Juyn                               * */
 229/* *             - fixed display routines called twice for FULL_MNG         * */
 230/* *               support in mozlibmngconf.h                               * */
 231/* *             1.0.10 - 12/04/2005 - G.R-P.                               * */
 232/* *             - #ifdef out use of mng_inflate_buffer when it is not      * */
 233/* *               available.                                               * */
 234/* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
 235/* *             - added support for mPNG proposal                          * */
 236/* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
 237/* *             - added support for ANG proposal                           * */
 238/* *             1.0.10 - 05/02/2007 - G.Juyn                               * */
 239/* *             - fixed inflate_buffer for extreme compression ratios      * */
 240/* *                                                                        * */
 241/* ************************************************************************** */
 242
 243#include "libmng.h"
 244#include "libmng_data.h"
 245#include "libmng_error.h"
 246#include "libmng_trace.h"
 247#ifdef __BORLANDC__
 248#pragma hdrstop
 249#endif
 250#include "libmng_objects.h"
 251#include "libmng_object_prc.h"
 252#include "libmng_chunks.h"
 253#ifdef MNG_CHECK_BAD_ICCP
 254#include "libmng_chunk_prc.h"
 255#endif
 256#include "libmng_memory.h"
 257#include "libmng_display.h"
 258#include "libmng_zlib.h"
 259#include "libmng_pixels.h"
 260#include "libmng_chunk_io.h"
 261
 262#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
 263#pragma option -A                      /* force ANSI-C */
 264#endif
 265
 266/* ************************************************************************** */
 267/* *                                                                        * */
 268/* * CRC - Cyclic Redundancy Check                                          * */
 269/* *                                                                        * */
 270/* * The code below is taken directly from the sample provided with the     * */
 271/* * PNG specification.                                                     * */
 272/* * (it is only adapted to the library's internal data-definitions)        * */
 273/* *                                                                        * */
 274/* ************************************************************************** */
 275/* Make the table for a fast CRC. */
 276#ifndef MNG_USE_ZLIB_CRC
 277MNG_LOCAL void make_crc_table (mng_datap pData)
 278{
 279  mng_uint32 iC;
 280  mng_int32  iN, iK;
 281
 282  for (iN = 0; iN < 256; iN++)
 283  {
 284    iC = (mng_uint32) iN;
 285
 286    for (iK = 0; iK < 8; iK++)
 287    {
 288      if (iC & 1)
 289        iC = 0xedb88320U ^ (iC >> 1);
 290      else
 291        iC = iC >> 1;
 292    }
 293
 294    pData->aCRCtable [iN] = iC;
 295  }
 296
 297  pData->bCRCcomputed = MNG_TRUE;
 298}
 299#endif
 300
 301/* Update a running CRC with the bytes buf[0..len-1]--the CRC
 302   should be initialized to all 1's, and the transmitted value
 303   is the 1's complement of the final running CRC (see the
 304   crc() routine below). */
 305
 306MNG_LOCAL mng_uint32 update_crc (mng_datap  pData,
 307                                 mng_uint32 iCrc,
 308                                 mng_uint8p pBuf,
 309                                 mng_int32  iLen)
 310{
 311#ifdef MNG_USE_ZLIB_CRC
 312  return crc32 (iCrc, pBuf, iLen);
 313#else
 314  mng_uint32 iC = iCrc;
 315  mng_int32 iN;
 316
 317  if (!pData->bCRCcomputed)
 318    make_crc_table (pData);
 319
 320  for (iN = 0; iN < iLen; iN++)
 321    iC = pData->aCRCtable [(iC ^ pBuf [iN]) & 0xff] ^ (iC >> 8);
 322
 323  return iC;
 324#endif
 325}
 326
 327/* Return the CRC of the bytes buf[0..len-1]. */
 328mng_uint32 mng_crc (mng_datap  pData,
 329                    mng_uint8p pBuf,
 330                    mng_int32  iLen)
 331{
 332#ifdef MNG_USE_ZLIB_CRC
 333  return update_crc (pData, 0, pBuf, iLen);
 334#else
 335  return update_crc (pData, 0xffffffffU, pBuf, iLen) ^ 0xffffffffU;
 336#endif
 337}
 338
 339/* ************************************************************************** */
 340/* *                                                                        * */
 341/* * Routines for swapping byte-order from and to graphic files             * */
 342/* * (This code is adapted from the libpng package)                         * */
 343/* *                                                                        * */
 344/* ************************************************************************** */
 345
 346#ifndef MNG_BIGENDIAN_SUPPORTED
 347
 348/* ************************************************************************** */
 349
 350mng_uint32 mng_get_uint32 (mng_uint8p pBuf)
 351{
 352   mng_uint32 i = ((mng_uint32)(*pBuf)       << 24) +
 353                  ((mng_uint32)(*(pBuf + 1)) << 16) +
 354                  ((mng_uint32)(*(pBuf + 2)) <<  8) +
 355                   (mng_uint32)(*(pBuf + 3));
 356   return (i);
 357}
 358
 359/* ************************************************************************** */
 360
 361mng_int32 mng_get_int32 (mng_uint8p pBuf)
 362{
 363   mng_int32 i = ((mng_int32)(*pBuf)       << 24) +
 364                 ((mng_int32)(*(pBuf + 1)) << 16) +
 365                 ((mng_int32)(*(pBuf + 2)) <<  8) +
 366                  (mng_int32)(*(pBuf + 3));
 367   return (i);
 368}
 369
 370/* ************************************************************************** */
 371
 372mng_uint16 mng_get_uint16 (mng_uint8p pBuf)
 373{
 374   mng_uint16 i = (mng_uint16)(((mng_uint16)(*pBuf) << 8) +
 375                                (mng_uint16)(*(pBuf + 1)));
 376   return (i);
 377}
 378
 379/* ************************************************************************** */
 380
 381void mng_put_uint32 (mng_uint8p pBuf,
 382                     mng_uint32 i)
 383{
 384   *pBuf     = (mng_uint8)((i >> 24) & 0xff);
 385   *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
 386   *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
 387   *(pBuf+3) = (mng_uint8)(i & 0xff);
 388}
 389
 390/* ************************************************************************** */
 391
 392void mng_put_int32 (mng_uint8p pBuf,
 393                    mng_int32  i)
 394{
 395   *pBuf     = (mng_uint8)((i >> 24) & 0xff);
 396   *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
 397   *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
 398   *(pBuf+3) = (mng_uint8)(i & 0xff);
 399}
 400
 401/* ************************************************************************** */
 402
 403void mng_put_uint16 (mng_uint8p pBuf,
 404                     mng_uint16 i)
 405{
 406   *pBuf     = (mng_uint8)((i >> 8) & 0xff);
 407   *(pBuf+1) = (mng_uint8)(i & 0xff);
 408}
 409
 410/* ************************************************************************** */
 411
 412#endif /* !MNG_BIGENDIAN_SUPPORTED */
 413
 414/* ************************************************************************** */
 415/* *                                                                        * */
 416/* * Helper routines to simplify chunk-data extraction                      * */
 417/* *                                                                        * */
 418/* ************************************************************************** */
 419
 420#ifdef MNG_INCLUDE_READ_PROCS
 421
 422/* ************************************************************************** */
 423
 424#ifndef MNG_OPTIMIZE_CHUNKREADER
 425MNG_LOCAL mng_uint8p find_null (mng_uint8p pIn)
 426{
 427  mng_uint8p pOut = pIn;
 428  while (*pOut)                        /* the read_graphic routine has made sure there's */
 429    pOut++;                            /* always at least 1 zero-byte in the buffer */
 430  return pOut;
 431}
 432#endif
 433
 434/* ************************************************************************** */
 435
 436#if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \
 437    !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \
 438    defined(MNG_INCLUDE_ANG_PROPOSAL)
 439mng_retcode mng_inflate_buffer (mng_datap  pData,
 440                                mng_uint8p pInbuf,
 441                                mng_uint32 iInsize,
 442                                mng_uint8p *pOutbuf,
 443                                mng_uint32 *iOutsize,
 444                                mng_uint32 *iRealsize)
 445{
 446  mng_retcode iRetcode = MNG_NOERROR;
 447
 448#ifdef MNG_SUPPORT_TRACE
 449  MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_START);
 450#endif
 451
 452  if (iInsize)                         /* anything to do ? */
 453  {
 454    *iOutsize = iInsize * 3;           /* estimate uncompressed size */
 455                                       /* and allocate a temporary buffer */
 456    MNG_ALLOC (pData, *pOutbuf, *iOutsize);
 457
 458    do
 459    {
 460      mngzlib_inflateinit (pData);     /* initialize zlib */
 461                                       /* let zlib know where to store the output */
 462      pData->sZlib.next_out  = *pOutbuf;
 463                                       /* "size - 1" so we've got space for the
 464                                          zero-termination of a possible string */
 465      pData->sZlib.avail_out = *iOutsize - 1;
 466                                       /* ok; let's inflate... */
 467      iRetcode = mngzlib_inflatedata (pData, iInsize, pInbuf);
 468                                       /* determine actual output size */
 469      *iRealsize = (mng_uint32)pData->sZlib.total_out;
 470
 471      mngzlib_inflatefree (pData);     /* zlib's done */
 472
 473      if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
 474      {                                /* then get some more */
 475        MNG_FREEX (pData, *pOutbuf, *iOutsize);
 476        *iOutsize = *iOutsize + *iOutsize;
 477        MNG_ALLOC (pData, *pOutbuf, *iOutsize);
 478      }
 479    }                                  /* repeat if we didn't have enough space */
 480    while ((iRetcode == MNG_BUFOVERFLOW) &&
 481           (*iOutsize < 200 * iInsize));
 482
 483    if (!iRetcode)                     /* if oke ? */
 484      *((*pOutbuf) + *iRealsize) = 0;  /* then put terminator zero */
 485
 486  }
 487  else
 488  {
 489    *pOutbuf   = 0;                    /* nothing to do; then there's no output */
 490    *iOutsize  = 0;
 491    *iRealsize = 0;
 492  }
 493
 494#ifdef MNG_SUPPORT_TRACE
 495  MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_END);
 496#endif
 497
 498  return iRetcode;
 499}
 500#endif
 501
 502/* ************************************************************************** */
 503
 504#endif /* MNG_INCLUDE_READ_PROCS */
 505
 506/* ************************************************************************** */
 507/* *                                                                        * */
 508/* * Helper routines to simplify chunk writing                              * */
 509/* *                                                                        * */
 510/* ************************************************************************** */
 511#ifdef MNG_INCLUDE_WRITE_PROCS
 512/* ************************************************************************** */
 513
 514#if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || !defined(MNG_SKIPCHUNK_iTXt)
 515MNG_LOCAL mng_retcode deflate_buffer (mng_datap  pData,
 516                                      mng_uint8p pInbuf,
 517                                      mng_uint32 iInsize,
 518                                      mng_uint8p *pOutbuf,
 519                                      mng_uint32 *iOutsize,
 520                                      mng_uint32 *iRealsize)
 521{
 522  mng_retcode iRetcode = MNG_NOERROR;
 523
 524#ifdef MNG_SUPPORT_TRACE
 525  MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_START);
 526#endif
 527
 528  if (iInsize)                         /* anything to do ? */
 529  {
 530    *iOutsize = (iInsize * 5) >> 2;    /* estimate compressed size */
 531                                       /* and allocate a temporary buffer */
 532    MNG_ALLOC (pData, *pOutbuf, *iOutsize);
 533
 534    do
 535    {
 536      mngzlib_deflateinit (pData);     /* initialize zlib */
 537                                       /* let zlib know where to store the output */
 538      pData->sZlib.next_out  = *pOutbuf;
 539      pData->sZlib.avail_out = *iOutsize;
 540                                       /* ok; let's deflate... */
 541      iRetcode = mngzlib_deflatedata (pData, iInsize, pInbuf);
 542                                       /* determine actual output size */
 543      *iRealsize = pData->sZlib.total_out;
 544
 545      mngzlib_deflatefree (pData);     /* zlib's done */
 546
 547      if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
 548      {                                /* then get some more */
 549        MNG_FREEX (pData, *pOutbuf, *iOutsize);
 550        *iOutsize = *iOutsize + (iInsize >> 1);
 551        MNG_ALLOC (pData, *pOutbuf, *iOutsize);
 552      }
 553    }                                  /* repeat if we didn't have enough space */
 554    while (iRetcode == MNG_BUFOVERFLOW);
 555  }
 556  else
 557  {
 558    *pOutbuf   = 0;                    /* nothing to do; then there's no output */
 559    *iOutsize  = 0;
 560    *iRealsize = 0;
 561  }
 562
 563#ifdef MNG_SUPPORT_TRACE
 564  MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_END);
 565#endif
 566
 567  return iRetcode;
 568}
 569#endif
 570
 571/* ************************************************************************** */
 572
 573MNG_LOCAL mng_retcode write_raw_chunk (mng_datap   pData,
 574                                       mng_chunkid iChunkname,
 575                                       mng_uint32  iRawlen,
 576                                       mng_uint8p  pRawdata)
 577{
 578  mng_uint32 iCrc;
 579  mng_uint32 iWritten;
 580
 581#ifdef MNG_SUPPORT_TRACE
 582  MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_START);
 583#endif
 584                                       /* temporary buffer ? */
 585  if ((pRawdata != 0) && (pRawdata != pData->pWritebuf+8))
 586  {                                    /* store length & chunktype in default buffer */
 587    mng_put_uint32 (pData->pWritebuf,   iRawlen);
 588    mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
 589
 590    if (pData->iCrcmode & MNG_CRC_OUTPUT)
 591    {
 592      if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE)
 593      {                                /* calculate the crc */
 594        iCrc = update_crc (pData, 0xffffffffL, pData->pWritebuf+4, 4);
 595        iCrc = update_crc (pData, iCrc, pRawdata, iRawlen) ^ 0xffffffffL;
 596      } else {
 597        iCrc = 0;                      /* dummy crc */
 598      }                                /* store in default buffer */
 599      mng_put_uint32 (pData->pWritebuf+8, iCrc);
 600    }
 601                                       /* write the length & chunktype */
 602    if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
 603      MNG_ERROR (pData, MNG_APPIOERROR);
 604
 605    if (iWritten != 8)                 /* disk full ? */
 606      MNG_ERROR (pData, MNG_OUTPUTERROR);
 607                                       /* write the temporary buffer */
 608    if (!pData->fWritedata ((mng_handle)pData, pRawdata, iRawlen, &iWritten))
 609      MNG_ERROR (pData, MNG_APPIOERROR);
 610
 611    if (iWritten != iRawlen)           /* disk full ? */
 612      MNG_ERROR (pData, MNG_OUTPUTERROR);
 613
 614    if (pData->iCrcmode & MNG_CRC_OUTPUT)
 615    {                                  /* write the crc */
 616      if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf+8, 4, &iWritten))
 617        MNG_ERROR (pData, MNG_APPIOERROR);
 618
 619      if (iWritten != 4)               /* disk full ? */
 620        MNG_ERROR (pData, MNG_OUTPUTERROR);
 621    }
 622  }
 623  else
 624  {                                    /* prefix with length & chunktype */
 625    mng_put_uint32 (pData->pWritebuf,   iRawlen);
 626    mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
 627
 628    if (pData->iCrcmode & MNG_CRC_OUTPUT)
 629    {
 630      if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE)
 631                                       /* calculate the crc */
 632        iCrc = mng_crc (pData, pData->pWritebuf+4, iRawlen + 4);
 633      else
 634        iCrc = 0;                      /* dummy crc */
 635                                       /* add it to the buffer */
 636      mng_put_uint32 (pData->pWritebuf + iRawlen + 8, iCrc);
 637                                       /* write it in a single pass */
 638      if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 12, &iWritten))
 639        MNG_ERROR (pData, MNG_APPIOERROR);
 640
 641      if (iWritten != iRawlen + 12)    /* disk full ? */
 642        MNG_ERROR (pData, MNG_OUTPUTERROR);
 643    } else {
 644      if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 8, &iWritten))
 645        MNG_ERROR (pData, MNG_APPIOERROR);
 646
 647      if (iWritten != iRawlen + 8)     /* disk full ? */
 648        MNG_ERROR (pData, MNG_OUTPUTERROR);
 649    }
 650  }
 651
 652#ifdef MNG_SUPPORT_TRACE
 653  MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_END);
 654#endif
 655
 656  return MNG_NOERROR;
 657}
 658
 659/* ************************************************************************** */
 660/* B004 */
 661#endif /* MNG_INCLUDE_WRITE_PROCS */
 662/* B004 */
 663/* ************************************************************************** */
 664/* *                                                                        * */
 665/* * chunk read functions                                                   * */
 666/* *                                                                        * */
 667/* ************************************************************************** */
 668
 669#ifdef MNG_INCLUDE_READ_PROCS
 670
 671/* ************************************************************************** */
 672
 673#ifdef MNG_OPTIMIZE_CHUNKREADER
 674
 675/* ************************************************************************** */
 676
 677MNG_LOCAL mng_retcode create_chunk_storage (mng_datap       pData,
 678                                            mng_chunkp      pHeader,
 679                                            mng_uint32      iRawlen,
 680                                            mng_uint8p      pRawdata,
 681                                            mng_field_descp pField,
 682                                            mng_uint16      iFields,
 683                                            mng_chunkp*     ppChunk,
 684                                            mng_bool        bWorkcopy)
 685{
 686  mng_field_descp pTempfield  = pField;
 687  mng_uint16      iFieldcount = iFields;
 688  mng_uint8p      pTempdata   = pRawdata;
 689  mng_uint32      iTemplen    = iRawlen;
 690  mng_uint16      iLastgroup  = 0;
 691  mng_uint8p      pChunkdata;
 692  mng_uint32      iDatalen;
 693  mng_uint8       iColortype;
 694  mng_bool        bProcess;
 695                                       /* initialize storage */
 696  mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
 697  if (iRetcode)                        /* on error bail out */
 698    return iRetcode;
 699
 700  if (((mng_chunk_headerp)(*ppChunk))->iChunkname == MNG_UINT_HUH)
 701    ((mng_chunk_headerp)(*ppChunk))->iChunkname = pData->iChunkname;
 702
 703  if ((!bWorkcopy) ||
 704      ((((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_IDAT) &&
 705       (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAT) &&
 706       (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAA)   ))
 707  {
 708    pChunkdata = (mng_uint8p)(*ppChunk);
 709
 710#ifdef MNG_INCLUDE_JNG                 /* determine current colortype */
 711    if (pData->bHasJHDR)
 712      iColortype = (mng_uint8)(pData->iJHDRcolortype - 8);
 713    else
 714#endif /* MNG_INCLUDE_JNG */
 715    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
 716      iColortype = pData->iColortype;
 717    else
 718      iColortype = 6;
 719
 720    if (iTemplen)                      /* not empty ? */
 721    {                                  /* then go fill the fields */
 722      while ((iFieldcount) && (iTemplen))
 723      {
 724        if (pTempfield->iOffsetchunk)
 725        {
 726          if (pTempfield->iFlags & MNG_FIELD_PUTIMGTYPE)
 727          {
 728            *(pChunkdata+pTempfield->iOffsetchunk) = iColortype;
 729            bProcess = MNG_FALSE;
 730          }
 731          else
 732          if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES)
 733            bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) ||
 734                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) ||
 735                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) ||
 736                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) ||
 737                                  ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6))   );
 738          else
 739            bProcess = MNG_TRUE;
 740
 741          if (bProcess)
 742          {
 743            iLastgroup = (mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK);
 744                                      /* numeric field ? */
 745            if (pTempfield->iFlags & MNG_FIELD_INT)
 746            {
 747              if (iTemplen < pTempfield->iLengthmax)
 748                MNG_ERROR (pData, MNG_INVALIDLENGTH);
 749
 750              switch (pTempfield->iLengthmax)
 751              {
 752                case 1 : { mng_uint8 iNum = *pTempdata;
 753                           if (((mng_uint16)iNum < pTempfield->iMinvalue) ||
 754                               ((mng_uint16)iNum > pTempfield->iMaxvalue)    )
 755                             MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
 756                           *(pChunkdata+pTempfield->iOffsetchunk) = iNum;
 757                           break; }
 758                case 2 : { mng_uint16 iNum = mng_get_uint16 (pTempdata);
 759                           if ((iNum < pTempfield->iMinvalue) || (iNum > pTempfield->iMaxvalue))
 760                             MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
 761                           *((mng_uint16p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum;
 762                           break; }
 763                case 4 : { mng_uint32 iNum = mng_get_uint32 (pTempdata);
 764                           if ((iNum < pTempfield->iMinvalue) ||
 765                               ((pTempfield->iFlags & MNG_FIELD_NOHIGHBIT) && (iNum & 0x80000000)) )
 766                             MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
 767                           *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum;
 768                           break; }
 769              }
 770
 771              pTempdata += pTempfield->iLengthmax;
 772              iTemplen  -= pTempfield->iLengthmax;
 773
 774            } else {                   /* not numeric so it's a bunch of bytes */
 775
 776              if (!pTempfield->iOffsetchunklen)    /* big fat NONO */
 777                MNG_ERROR (pData, MNG_INTERNALERROR);
 778                                       /* with terminating 0 ? */
 779              if (pTempfield->iFlags & MNG_FIELD_TERMINATOR)
 780              {
 781                mng_uint8p pWork = pTempdata;
 782                while (*pWork)         /* find the zero */
 783                  pWork++;
 784                iDatalen = (mng_uint32)(pWork - pTempdata);
 785              } else {                 /* no terminator, so everything that's left ! */
 786                iDatalen = iTemplen;
 787              }
 788
 789              if ((pTempfield->iLengthmax) && (iDatalen > pTempfield->iLengthmax))
 790                MNG_ERROR (pData, MNG_INVALIDLENGTH);
 791#if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \
 792    !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \
 793    defined(MNG_INCLUDE_ANG_PROPOSAL)
 794                                       /* needs decompression ? */
 795              if (pTempfield->iFlags & MNG_FIELD_DEFLATED)
 796              {
 797                mng_uint8p pBuf = 0;
 798                mng_uint32 iBufsize = 0;
 799                mng_uint32 iRealsize;
 800                mng_ptr    pWork;
 801
 802                iRetcode = mng_inflate_buffer (pData, pTempdata, iDatalen,
 803                                               &pBuf, &iBufsize, &iRealsize);
 804
 805#ifdef MNG_CHECK_BAD_ICCP              /* Check for bad iCCP chunk */
 806                if ((iRetcode) && (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_iCCP))
 807                {
 808                  *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk))      = MNG_NULL;
 809                  *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen;
 810                }
 811                else
 812#endif
 813                {
 814                  if (iRetcode)
 815                    return iRetcode;
 816
 817#if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
 818                  if ( (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_mpNG) ||
 819                       (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_adAT)    )
 820                  {
 821                    MNG_ALLOC (pData, pWork, iRealsize);
 822                  }
 823                  else
 824                  {
 825#endif
 826                                       /* don't forget to generate null terminator */
 827                    MNG_ALLOC (pData, pWork, iRealsize+1);
 828#if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
 829                  }
 830#endif
 831                  MNG_COPY (pWork, pBuf, iRealsize);
 832
 833                  *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk))      = pWork;
 834                  *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iRealsize;
 835                }
 836
 837                if (pBuf)              /* free the temporary buffer */
 838                  MNG_FREEX (pData, pBuf, iBufsize);
 839
 840              } else
 841#endif
 842                     {                 /* no decompression, so just copy */
 843
 844                mng_ptr pWork;
 845                                       /* don't forget to generate null terminator */
 846                MNG_ALLOC (pData, pWork, iDatalen+1);
 847                MNG_COPY (pWork, pTempdata, iDatalen);
 848
 849                *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk))      = pWork;
 850                *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen;
 851              }
 852
 853              if (pTempfield->iFlags & MNG_FIELD_TERMINATOR)
 854                iDatalen++;            /* skip the terminating zero as well !!! */
 855
 856              iTemplen  -= iDatalen;
 857              pTempdata += iDatalen;
 858            }
 859                                       /* need to set an indicator ? */
 860            if (pTempfield->iOffsetchunkind)
 861              *((mng_uint8p)(pChunkdata+pTempfield->iOffsetchunkind)) = MNG_TRUE;
 862          }
 863        }
 864
 865        if (pTempfield->pSpecialfunc)  /* special function required ? */
 866        {
 867          iRetcode = pTempfield->pSpecialfunc(pData, *ppChunk, &iTemplen, &pTempdata);
 868          if (iRetcode)                /* on error bail out */
 869            return iRetcode;
 870        }
 871
 872        pTempfield++;                  /* Neeeeeeexxxtt */
 873        iFieldcount--;
 874      }
 875
 876      if (iTemplen)                    /* extra data ??? */
 877        MNG_ERROR (pData, MNG_INVALIDLENGTH);
 878
 879      while (iFieldcount)              /* not enough data ??? */
 880      {
 881        if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES)
 882          bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) ||
 883                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) ||
 884                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) ||
 885                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) ||
 886                                ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6))   );
 887        else
 888          bProcess = MNG_TRUE;
 889
 890        if (bProcess)
 891        {
 892          if (!(pTempfield->iFlags & MNG_FIELD_OPTIONAL))
 893            MNG_ERROR (pData, MNG_INVALIDLENGTH);
 894          if ((pTempfield->iFlags & MNG_FIELD_GROUPMASK) &&
 895              ((mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK) == iLastgroup))
 896            MNG_ERROR (pData, MNG_INVALIDLENGTH);
 897        }
 898
 899        pTempfield++;
 900        iFieldcount--;
 901      }
 902    }
 903  }
 904
 905  return MNG_NOERROR;
 906}
 907
 908/* ************************************************************************** */
 909
 910READ_CHUNK (mng_read_general)
 911{
 912  mng_retcode     iRetcode = MNG_NOERROR;
 913  mng_chunk_descp pDescr   = ((mng_chunk_headerp)pHeader)->pChunkdescr;
 914  mng_field_descp pField;
 915  mng_uint16      iFields;
 916
 917  if (!pDescr)                         /* this is a bad booboo !!! */
 918    MNG_ERROR (pData, MNG_INTERNALERROR);
 919
 920  pField  = pDescr->pFielddesc;
 921  iFields = pDescr->iFielddesc;
 922                                       /* check chunk against signature */
 923  if ((pDescr->eImgtype == mng_it_mng) && (pData->eSigtype != mng_it_mng))
 924    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
 925
 926  if ((pDescr->eImgtype == mng_it_jng) && (pData->eSigtype == mng_it_png))
 927    MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
 928                                       /* empties allowed ? */
 929  if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTY)))
 930    MNG_ERROR (pData, MNG_INVALIDLENGTH);
 931
 932  if ((pData->eImagetype != mng_it_mng) || (!(pDescr->iAllowed & MNG_DESCR_GLOBAL)))
 933  {                                    /* *a* header required ? */
 934    if ((pDescr->iMusthaves & MNG_DESCR_GenHDR) &&
 935#ifdef MNG_INCLUDE_JNG
 936        (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
 937#else
 938        (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
 939#endif
 940      MNG_ERROR (pData, MNG_SEQUENCEERROR);
 941
 942#ifdef MNG_INCLUDE_JNG
 943    if ((pDescr->iMusthaves & MNG_DESCR_JngHDR) &&
 944        (!pData->bHasDHDR) && (!pData->bHasJHDR))
 945      MNG_ERROR (pData, MNG_SEQUENCEERROR);
 946#endif
 947  }
 948                                       /* specific chunk pre-requisite ? */
 949  if (((pDescr->iMusthaves & MNG_DESCR_IHDR) && (!pData->bHasIHDR)) ||
 950#ifdef MNG_INCLUDE_JNG
 951      ((pDescr->iMusthaves & MNG_DESCR_JHDR) && (!pData->bHasJHDR)) ||
 952#endif
 953      ((pDescr->iMusthaves & MNG_DESCR_DHDR) && (!pData->bHasDHDR)) ||
 954      ((pDescr->iMusthaves & MNG_DESCR_LOOP) && (!pData->bHasLOOP)) ||
 955      ((pDescr->iMusthaves & MNG_DESCR_PLTE) && (!pData->bHasPLTE)) ||
 956      ((pDescr->iMusthaves & MNG_DESCR_MHDR) && (!pData->bHasMHDR)) ||
 957      ((pDescr->iMusthaves & MNG_DESCR_SAVE) && (!pData->bHasSAVE))   )
 958    MNG_ERROR (pData, MNG_SEQUENCEERROR);
 959                                       /* specific chunk undesired ? */
 960  if (((pDescr->iMustNOThaves & MNG_DESCR_NOIHDR) && (pData->bHasIHDR)) ||
 961      ((pDescr->iMustNOThaves & MNG_DESCR_NOBASI) && (pData->bHasBASI)) ||
 962      ((pDescr->iMustNOThaves & MNG_DESCR_NODHDR) && (pData->bHasDHDR)) ||
 963      ((pDescr->iMustNOThaves & MNG_DESCR_NOIDAT) && (pData->bHasIDAT)) ||
 964      ((pDescr->iMustNOThaves & MNG_DESCR_NOPLTE) && (pData->bHasPLTE)) ||
 965#ifdef MNG_INCLUDE_JNG
 966      ((pDescr->iMustNOThaves & MNG_DESCR_NOJHDR) && (pData->bHasJHDR)) ||
 967      ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAT) && (pData->bHasJDAT)) ||
 968      ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAA) && (pData->bHasJDAA)) ||
 969      ((pDescr->iMustNOThaves & MNG_DESCR_NOJSEP) && (pData->bHasJSEP)) ||
 970#endif
 971      ((pDescr->iMustNOThaves & MNG_DESCR_NOMHDR) && (pData->bHasMHDR)) ||
 972      ((pDescr->iMustNOThaves & MNG_DESCR_NOLOOP) && (pData->bHasLOOP)) ||
 973      ((pDescr->iMustNOThaves & MNG_DESCR_NOTERM) && (pData->bHasTERM)) ||
 974      ((pDescr->iMustNOThaves & MNG_DESCR_NOSAVE) && (pData->bHasSAVE))   )
 975    MNG_ERROR (pData, MNG_SEQUENCEERROR);
 976
 977  if (pData->eSigtype == mng_it_mng)   /* check global and embedded empty chunks */
 978  {
 979#ifdef MNG_INCLUDE_JNG
 980    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
 981#else
 982    if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
 983#endif
 984    {
 985      if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYEMBED)))
 986        MNG_ERROR (pData, MNG_INVALIDLENGTH);
 987    } else {
 988      if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYGLOBAL)))
 989        MNG_ERROR (pData, MNG_INVALIDLENGTH);
 990    }
 991  }
 992
 993  if (pDescr->pSpecialfunc)            /* need special processing ? */
 994  {
 995    iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata,
 996                                     pField, iFields, ppChunk, MNG_TRUE);
 997    if (iRetcode)                      /* on error bail out */
 998      return iRetcode;
 999                                       /* empty indicator ? */
1000    if ((!iRawlen) && (pDescr->iOffsetempty))
1001      *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE;
1002
1003    iRetcode = pDescr->pSpecialfunc(pData, *ppChunk);
1004    if (iRetcode)                      /* on error bail out */
1005      return iRetcode;
1006
1007    if ((((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT) ||
1008        (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT) ||
1009        (((mng_chunk_headerp)pHeader)->iChunkname == M

Large files files are truncated, but you can click here to view the full file