src/3rdparty/libmng/libmng_chunk_io.c
changeset 0 1918ee327afb
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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
       
   277 MNG_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 
       
   306 MNG_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]. */
       
   328 mng_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 
       
   350 mng_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 
       
   361 mng_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 
       
   372 mng_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 
       
   381 void 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 
       
   392 void 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 
       
   403 void 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
       
   425 MNG_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)
       
   439 mng_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)
       
   515 MNG_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 
       
   573 MNG_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 
       
   677 MNG_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 
       
   910 READ_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 == MNG_UINT_JDAA)    )
       
  1010     {
       
  1011       iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk);
       
  1012       if (iRetcode)                    /* on error bail out */
       
  1013         return iRetcode;
       
  1014       *ppChunk = MNG_NULL;
       
  1015     } else {
       
  1016 #ifdef MNG_STORE_CHUNKS
       
  1017       if (!pData->bStorechunks)
       
  1018 #endif
       
  1019       {
       
  1020         iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk);
       
  1021         if (iRetcode)                  /* on error bail out */
       
  1022           return iRetcode;
       
  1023         *ppChunk = MNG_NULL;
       
  1024       }
       
  1025     }
       
  1026   }
       
  1027 
       
  1028 #ifdef MNG_SUPPORT_DISPLAY
       
  1029   if (iRawlen)
       
  1030   {
       
  1031 #ifdef MNG_OPTIMIZE_DISPLAYCALLS
       
  1032     pData->iRawlen  = iRawlen;
       
  1033     pData->pRawdata = pRawdata;
       
  1034 #endif
       
  1035 
       
  1036                                        /* display processing */
       
  1037 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
       
  1038     if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT)
       
  1039       iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata);
       
  1040 #ifdef MNG_INCLUDE_JNG
       
  1041     else
       
  1042     if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT)
       
  1043       iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata);
       
  1044     else
       
  1045     if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)
       
  1046       iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata);
       
  1047 #endif
       
  1048 #else
       
  1049     if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT)
       
  1050       iRetcode = mng_process_display_idat (pData);
       
  1051 #ifdef MNG_INCLUDE_JNG
       
  1052     else
       
  1053     if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT)
       
  1054       iRetcode = mng_process_display_jdat (pData);
       
  1055     else
       
  1056     if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)
       
  1057       iRetcode = mng_process_display_jdaa (pData);
       
  1058 #endif
       
  1059 #endif
       
  1060 
       
  1061     if (iRetcode)
       
  1062       return iRetcode;
       
  1063   }
       
  1064 #endif /* MNG_SUPPORT_DISPLAY */
       
  1065 
       
  1066 #ifdef MNG_STORE_CHUNKS
       
  1067   if ((pData->bStorechunks) && (!(*ppChunk)))
       
  1068   {
       
  1069     iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata,
       
  1070                                      pField, iFields, ppChunk, MNG_FALSE);
       
  1071     if (iRetcode)                      /* on error bail out */
       
  1072       return iRetcode;
       
  1073                                        /* empty indicator ? */
       
  1074     if ((!iRawlen) && (pDescr->iOffsetempty))
       
  1075       *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE;
       
  1076   }
       
  1077 #endif /* MNG_STORE_CHUNKS */
       
  1078 
       
  1079   return MNG_NOERROR;
       
  1080 }
       
  1081 
       
  1082 /* ************************************************************************** */
       
  1083 
       
  1084 #endif /* MNG_OPTIMIZE_CHUNKREADER */
       
  1085 
       
  1086 /* ************************************************************************** */
       
  1087 
       
  1088 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  1089 READ_CHUNK (mng_read_ihdr)
       
  1090 {
       
  1091 #ifdef MNG_SUPPORT_TRACE
       
  1092   MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_START);
       
  1093 #endif
       
  1094 
       
  1095   if (iRawlen != 13)                   /* length oke ? */
       
  1096     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1097                                        /* only allowed inside PNG or MNG */
       
  1098   if ((pData->eSigtype != mng_it_png) && (pData->eSigtype != mng_it_mng))
       
  1099     MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
       
  1100                                        /* sequence checks */
       
  1101   if ((pData->eSigtype == mng_it_png) && (pData->iChunkseq > 1))
       
  1102     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1103 
       
  1104 #ifdef MNG_INCLUDE_JNG
       
  1105   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT) || (pData->bHasJHDR))
       
  1106 #else
       
  1107   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT))
       
  1108 #endif
       
  1109     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1110 
       
  1111   pData->bHasIHDR      = MNG_TRUE;     /* indicate IHDR is present */
       
  1112                                        /* and store interesting fields */
       
  1113   if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE))
       
  1114   {
       
  1115     pData->iDatawidth  = mng_get_uint32 (pRawdata);
       
  1116     pData->iDataheight = mng_get_uint32 (pRawdata+4);
       
  1117   }
       
  1118 
       
  1119   pData->iBitdepth     = *(pRawdata+8);
       
  1120   pData->iColortype    = *(pRawdata+9);
       
  1121   pData->iCompression  = *(pRawdata+10);
       
  1122   pData->iFilter       = *(pRawdata+11);
       
  1123   pData->iInterlace    = *(pRawdata+12);
       
  1124 
       
  1125 #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
       
  1126   pData->iPNGmult = 1;
       
  1127   pData->iPNGdepth = pData->iBitdepth;
       
  1128 #endif
       
  1129 
       
  1130 #ifdef MNG_NO_1_2_4BIT_SUPPORT
       
  1131   if (pData->iBitdepth < 8)
       
  1132       pData->iBitdepth = 8;
       
  1133 #endif
       
  1134 
       
  1135 #ifdef MNG_NO_16BIT_SUPPORT
       
  1136   if (pData->iBitdepth > 8)
       
  1137     {
       
  1138       pData->iBitdepth = 8;
       
  1139       pData->iPNGmult = 2;
       
  1140     }
       
  1141 #endif
       
  1142 
       
  1143   if ((pData->iBitdepth !=  8)      /* parameter validity checks */
       
  1144 #ifndef MNG_NO_1_2_4BIT_SUPPORT
       
  1145       && (pData->iBitdepth !=  1) &&
       
  1146       (pData->iBitdepth !=  2) &&
       
  1147       (pData->iBitdepth !=  4)
       
  1148 #endif
       
  1149 #ifndef MNG_NO_16BIT_SUPPORT
       
  1150       && (pData->iBitdepth != 16)   
       
  1151 #endif
       
  1152       )
       
  1153     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  1154 
       
  1155   if ((pData->iColortype != MNG_COLORTYPE_GRAY   ) &&
       
  1156       (pData->iColortype != MNG_COLORTYPE_RGB    ) &&
       
  1157       (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
       
  1158       (pData->iColortype != MNG_COLORTYPE_GRAYA  ) &&
       
  1159       (pData->iColortype != MNG_COLORTYPE_RGBA   )    )
       
  1160     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
       
  1161 
       
  1162   if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
       
  1163     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  1164 
       
  1165   if (((pData->iColortype == MNG_COLORTYPE_RGB    ) ||
       
  1166        (pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
       
  1167        (pData->iColortype == MNG_COLORTYPE_RGBA   )    ) &&
       
  1168       (pData->iBitdepth < 8                            )    )
       
  1169     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  1170 
       
  1171   if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
       
  1172     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  1173 
       
  1174 #if defined(FILTER192) || defined(FILTER193)
       
  1175   if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
       
  1176 #if defined(FILTER192) && defined(FILTER193)
       
  1177       (pData->iFilter != MNG_FILTER_DIFFERING) &&
       
  1178       (pData->iFilter != MNG_FILTER_NOFILTER )    )
       
  1179 #else
       
  1180 #ifdef FILTER192
       
  1181       (pData->iFilter != MNG_FILTER_DIFFERING)    )
       
  1182 #else
       
  1183       (pData->iFilter != MNG_FILTER_NOFILTER )    )
       
  1184 #endif
       
  1185 #endif
       
  1186     MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  1187 #else
       
  1188   if (pData->iFilter)
       
  1189     MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  1190 #endif
       
  1191 
       
  1192   if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
       
  1193       (pData->iInterlace != MNG_INTERLACE_ADAM7)    )
       
  1194     MNG_ERROR (pData, MNG_INVALIDINTERLACE);
       
  1195 
       
  1196 #ifdef MNG_SUPPORT_DISPLAY 
       
  1197 #ifndef MNG_NO_DELTA_PNG
       
  1198   if (pData->bHasDHDR)                 /* check the colortype for delta-images ! */
       
  1199   {
       
  1200     mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
       
  1201 
       
  1202     if (pData->iColortype != pBuf->iColortype)
       
  1203     {
       
  1204       if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) ||
       
  1205              (pBuf->iColortype  == MNG_COLORTYPE_GRAY   )    ) &&
       
  1206            ( (pData->iColortype != MNG_COLORTYPE_GRAY   ) ||
       
  1207              (pBuf->iColortype  == MNG_COLORTYPE_INDEXED)    )    )
       
  1208         MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
       
  1209     }
       
  1210   }
       
  1211 #endif
       
  1212 #endif
       
  1213 
       
  1214   if (!pData->bHasheader)              /* first chunk ? */
       
  1215   {
       
  1216     pData->bHasheader = MNG_TRUE;      /* we've got a header */
       
  1217     pData->eImagetype = mng_it_png;    /* then this must be a PNG */
       
  1218     pData->iWidth     = pData->iDatawidth;
       
  1219     pData->iHeight    = pData->iDataheight;
       
  1220                                        /* predict alpha-depth ! */
       
  1221     if ((pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
       
  1222         (pData->iColortype == MNG_COLORTYPE_RGBA   )    )
       
  1223       pData->iAlphadepth = pData->iBitdepth;
       
  1224     else
       
  1225     if (pData->iColortype == MNG_COLORTYPE_INDEXED)
       
  1226       pData->iAlphadepth = 8;          /* worst case scenario */
       
  1227     else
       
  1228       pData->iAlphadepth = 1;  /* Possible tRNS cheap binary transparency */
       
  1229                                        /* fits on maximum canvas ? */
       
  1230     if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
       
  1231       MNG_WARNING (pData, MNG_IMAGETOOLARGE);
       
  1232 
       
  1233 #if !defined(MNG_INCLUDE_MPNG_PROPOSAL) || !defined(MNG_SUPPORT_DISPLAY)
       
  1234     if (pData->fProcessheader)         /* inform the app ? */
       
  1235       if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
       
  1236         MNG_ERROR (pData, MNG_APPMISCERROR);
       
  1237 #endif        
       
  1238   }
       
  1239 
       
  1240   if (!pData->bHasDHDR)
       
  1241     pData->iImagelevel++;              /* one level deeper */
       
  1242 
       
  1243 #ifdef MNG_SUPPORT_DISPLAY
       
  1244   {
       
  1245     mng_retcode iRetcode = mng_process_display_ihdr (pData);
       
  1246 
       
  1247     if (iRetcode)                      /* on error bail out */
       
  1248       return iRetcode;
       
  1249   }
       
  1250 #endif /* MNG_SUPPORT_DISPLAY */
       
  1251 
       
  1252 #ifdef MNG_STORE_CHUNKS
       
  1253   if (pData->bStorechunks)
       
  1254   {                                    /* initialize storage */
       
  1255     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  1256 
       
  1257     if (iRetcode)                      /* on error bail out */
       
  1258       return iRetcode;
       
  1259                                        /* fill the fields */
       
  1260     ((mng_ihdrp)*ppChunk)->iWidth       = mng_get_uint32 (pRawdata);
       
  1261     ((mng_ihdrp)*ppChunk)->iHeight      = mng_get_uint32 (pRawdata+4);
       
  1262     ((mng_ihdrp)*ppChunk)->iBitdepth    = pData->iBitdepth;
       
  1263     ((mng_ihdrp)*ppChunk)->iColortype   = pData->iColortype;
       
  1264     ((mng_ihdrp)*ppChunk)->iCompression = pData->iCompression;
       
  1265     ((mng_ihdrp)*ppChunk)->iFilter      = pData->iFilter;
       
  1266     ((mng_ihdrp)*ppChunk)->iInterlace   = pData->iInterlace;
       
  1267   }
       
  1268 #endif /* MNG_STORE_CHUNKS */
       
  1269 
       
  1270 #ifdef MNG_SUPPORT_TRACE
       
  1271   MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_END);
       
  1272 #endif
       
  1273 
       
  1274   return MNG_NOERROR;                  /* done */
       
  1275 }
       
  1276 #endif /* MNG_OPTIMIZE_CHUNKREADER */
       
  1277 
       
  1278 /* ************************************************************************** */
       
  1279 
       
  1280 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  1281 READ_CHUNK (mng_read_plte)
       
  1282 {
       
  1283 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  1284   mng_uint32  iX;
       
  1285   mng_uint8p  pRawdata2;
       
  1286 #endif
       
  1287 #ifdef MNG_SUPPORT_DISPLAY
       
  1288   mng_uint32  iRawlen2;
       
  1289 #endif
       
  1290 
       
  1291 #ifdef MNG_SUPPORT_TRACE
       
  1292   MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_START);
       
  1293 #endif
       
  1294                                        /* sequence checks */
       
  1295   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  1296       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  1297     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1298 
       
  1299 #ifdef MNG_INCLUDE_JNG
       
  1300   if ((pData->bHasIDAT) || (pData->bHasJHDR))
       
  1301 #else
       
  1302   if (pData->bHasIDAT)
       
  1303 #endif  
       
  1304     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1305                                        /* multiple PLTE only inside BASI */
       
  1306   if ((pData->bHasPLTE) && (!pData->bHasBASI))
       
  1307     MNG_ERROR (pData, MNG_MULTIPLEERROR);
       
  1308                                        /* length must be multiple of 3 */
       
  1309   if (((iRawlen % 3) != 0) || (iRawlen > 768))
       
  1310     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1311 
       
  1312   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1313   {                                    /* only allowed for indexed-color or
       
  1314                                           rgb(a)-color! */
       
  1315     if ((pData->iColortype != 2) && (pData->iColortype != 3) && (pData->iColortype != 6))
       
  1316       MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
       
  1317                                        /* empty only allowed if global present */
       
  1318     if ((iRawlen == 0) && (!pData->bHasglobalPLTE))
       
  1319         MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
       
  1320   }
       
  1321   else
       
  1322   {
       
  1323     if (iRawlen == 0)                  /* cannot be empty as global! */
       
  1324       MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
       
  1325   }
       
  1326 
       
  1327   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1328     pData->bHasPLTE = MNG_TRUE;        /* got it! */
       
  1329   else
       
  1330     pData->bHasglobalPLTE = MNG_TRUE;
       
  1331 
       
  1332   pData->iPLTEcount = iRawlen / 3;  
       
  1333 
       
  1334 #ifdef MNG_SUPPORT_DISPLAY
       
  1335   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1336   {
       
  1337     mng_imagep     pImage;
       
  1338     mng_imagedatap pBuf;
       
  1339 
       
  1340 #ifndef MNG_NO_DELTA_PNG
       
  1341     if (pData->bHasDHDR)               /* processing delta-image ? */
       
  1342     {                                  /* store in object 0 !!! */
       
  1343       pImage           = (mng_imagep)pData->pObjzero;
       
  1344       pBuf             = pImage->pImgbuf;
       
  1345       pBuf->bHasPLTE   = MNG_TRUE;     /* it's definitely got a PLTE now */
       
  1346       pBuf->iPLTEcount = iRawlen / 3;  /* this is the exact length */
       
  1347       pRawdata2        = pRawdata;     /* copy the entries */
       
  1348 
       
  1349       for (iX = 0; iX < iRawlen / 3; iX++)
       
  1350       {
       
  1351         pBuf->aPLTEentries[iX].iRed   = *pRawdata2;
       
  1352         pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
       
  1353         pBuf->aPLTEentries[iX].iBlue  = *(pRawdata2+2);
       
  1354 
       
  1355         pRawdata2 += 3;
       
  1356       }
       
  1357     }
       
  1358     else
       
  1359 #endif
       
  1360     {                                  /* get the current object */
       
  1361       pImage = (mng_imagep)pData->pCurrentobj;
       
  1362 
       
  1363       if (!pImage)                     /* no object then dump it in obj 0 */
       
  1364         pImage = (mng_imagep)pData->pObjzero;
       
  1365 
       
  1366       pBuf = pImage->pImgbuf;          /* address the object buffer */
       
  1367       pBuf->bHasPLTE = MNG_TRUE;       /* and tell it it's got a PLTE now */
       
  1368 
       
  1369       if (!iRawlen)                    /* if empty, inherit from global */
       
  1370       {
       
  1371         pBuf->iPLTEcount = pData->iGlobalPLTEcount;
       
  1372         MNG_COPY (pBuf->aPLTEentries, pData->aGlobalPLTEentries,
       
  1373                   sizeof (pBuf->aPLTEentries));
       
  1374 
       
  1375         if (pData->bHasglobalTRNS)     /* also copy global tRNS ? */
       
  1376         {                              /* indicate tRNS available */
       
  1377           pBuf->bHasTRNS = MNG_TRUE;
       
  1378 
       
  1379           iRawlen2  = pData->iGlobalTRNSrawlen;
       
  1380           pRawdata2 = (mng_uint8p)(pData->aGlobalTRNSrawdata);
       
  1381                                        /* global length oke ? */
       
  1382           if ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount))
       
  1383             MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
       
  1384                                        /* copy it */
       
  1385           pBuf->iTRNScount = iRawlen2;
       
  1386           MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
       
  1387         }
       
  1388       }
       
  1389       else
       
  1390       {                                /* store fields for future reference */
       
  1391         pBuf->iPLTEcount = iRawlen / 3;
       
  1392         pRawdata2        = pRawdata;
       
  1393 
       
  1394         for (iX = 0; iX < pBuf->iPLTEcount; iX++)
       
  1395         {
       
  1396           pBuf->aPLTEentries[iX].iRed   = *pRawdata2;
       
  1397           pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
       
  1398           pBuf->aPLTEentries[iX].iBlue  = *(pRawdata2+2);
       
  1399 
       
  1400           pRawdata2 += 3;
       
  1401         }
       
  1402       }
       
  1403     }
       
  1404   }
       
  1405   else                                 /* store as global */
       
  1406   {
       
  1407     pData->iGlobalPLTEcount = iRawlen / 3;
       
  1408     pRawdata2               = pRawdata;
       
  1409 
       
  1410     for (iX = 0; iX < pData->iGlobalPLTEcount; iX++)
       
  1411     {
       
  1412       pData->aGlobalPLTEentries[iX].iRed   = *pRawdata2;
       
  1413       pData->aGlobalPLTEentries[iX].iGreen = *(pRawdata2+1);
       
  1414       pData->aGlobalPLTEentries[iX].iBlue  = *(pRawdata2+2);
       
  1415 
       
  1416       pRawdata2 += 3;
       
  1417     }
       
  1418 
       
  1419     {                                  /* create an animation object */
       
  1420       mng_retcode iRetcode = mng_create_ani_plte (pData, pData->iGlobalPLTEcount,
       
  1421                                                   pData->aGlobalPLTEentries);
       
  1422       if (iRetcode)                    /* on error bail out */
       
  1423         return iRetcode;
       
  1424     }
       
  1425   }
       
  1426 #endif /* MNG_SUPPORT_DISPLAY */
       
  1427 
       
  1428 #ifdef MNG_STORE_CHUNKS
       
  1429   if (pData->bStorechunks)
       
  1430   {                                    /* initialize storage */
       
  1431     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  1432 
       
  1433     if (iRetcode)                      /* on error bail out */
       
  1434       return iRetcode;
       
  1435                                        /* store the fields */
       
  1436     ((mng_pltep)*ppChunk)->bEmpty      = (mng_bool)(iRawlen == 0);
       
  1437     ((mng_pltep)*ppChunk)->iEntrycount = iRawlen / 3;
       
  1438     pRawdata2                          = pRawdata;
       
  1439 
       
  1440     for (iX = 0; iX < ((mng_pltep)*ppChunk)->iEntrycount; iX++)
       
  1441     {
       
  1442       ((mng_pltep)*ppChunk)->aEntries[iX].iRed   = *pRawdata2;
       
  1443       ((mng_pltep)*ppChunk)->aEntries[iX].iGreen = *(pRawdata2+1);
       
  1444       ((mng_pltep)*ppChunk)->aEntries[iX].iBlue  = *(pRawdata2+2);
       
  1445 
       
  1446       pRawdata2 += 3;
       
  1447     }
       
  1448   }
       
  1449 #endif /* MNG_STORE_CHUNKS */
       
  1450 
       
  1451 #ifdef MNG_SUPPORT_TRACE
       
  1452   MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_END);
       
  1453 #endif
       
  1454 
       
  1455   return MNG_NOERROR;                  /* done */
       
  1456 }
       
  1457 #endif /* MNG_OPTIMIZE_CHUNKREADER */
       
  1458 
       
  1459 /* ************************************************************************** */
       
  1460 
       
  1461 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  1462 READ_CHUNK (mng_read_idat)
       
  1463 {
       
  1464 #ifdef MNG_SUPPORT_TRACE
       
  1465   MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_START);
       
  1466 #endif
       
  1467 
       
  1468 #ifdef MNG_INCLUDE_JNG                 /* sequence checks */
       
  1469   if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  1470 #else
       
  1471   if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
       
  1472 #endif
       
  1473     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1474 
       
  1475 #ifdef MNG_INCLUDE_JNG
       
  1476   if ((pData->bHasJHDR) &&
       
  1477       (pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE))
       
  1478     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1479 
       
  1480   if (pData->bHasJSEP)
       
  1481     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1482 #endif
       
  1483                                        /* not allowed for deltatype NO_CHANGE */
       
  1484 #ifndef MNG_NO_DELTA_PNG
       
  1485   if ((pData->bHasDHDR) && ((pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)))
       
  1486     MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
       
  1487 #endif
       
  1488                                        /* can only be empty in BASI-block! */
       
  1489   if ((iRawlen == 0) && (!pData->bHasBASI))
       
  1490     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1491                                        /* indexed-color requires PLTE */
       
  1492   if ((pData->bHasIHDR) && (pData->iColortype == 3) && (!pData->bHasPLTE))
       
  1493     MNG_ERROR (pData, MNG_PLTEMISSING);
       
  1494 
       
  1495   pData->bHasIDAT = MNG_TRUE;          /* got some IDAT now, don't we */
       
  1496 
       
  1497 #ifdef MNG_SUPPORT_DISPLAY
       
  1498   if (iRawlen)
       
  1499   {                                    /* display processing */
       
  1500     mng_retcode iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata);
       
  1501 
       
  1502     if (iRetcode)                      /* on error bail out */
       
  1503       return iRetcode;
       
  1504   }
       
  1505 #endif /* MNG_SUPPORT_DISPLAY */
       
  1506 
       
  1507 #ifdef MNG_STORE_CHUNKS
       
  1508   if (pData->bStorechunks)
       
  1509   {                                    /* initialize storage */
       
  1510     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  1511 
       
  1512     if (iRetcode)                      /* on error bail out */
       
  1513       return iRetcode;
       
  1514                                        /* store the fields */
       
  1515     ((mng_idatp)*ppChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
       
  1516     ((mng_idatp)*ppChunk)->iDatasize = iRawlen;
       
  1517 
       
  1518     if (iRawlen != 0)                  /* is there any data ? */
       
  1519     {
       
  1520       MNG_ALLOC (pData, ((mng_idatp)*ppChunk)->pData, iRawlen);
       
  1521       MNG_COPY  (((mng_idatp)*ppChunk)->pData, pRawdata, iRawlen);
       
  1522     }
       
  1523   }
       
  1524 #endif /* MNG_STORE_CHUNKS */
       
  1525 
       
  1526 #ifdef MNG_SUPPORT_TRACE
       
  1527   MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_END);
       
  1528 #endif
       
  1529 
       
  1530   return MNG_NOERROR;                  /* done */
       
  1531 }
       
  1532 #endif
       
  1533 
       
  1534 /* ************************************************************************** */
       
  1535 
       
  1536 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  1537 READ_CHUNK (mng_read_iend)
       
  1538 {
       
  1539 #ifdef MNG_SUPPORT_TRACE
       
  1540   MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_START);
       
  1541 #endif
       
  1542 
       
  1543   if (iRawlen > 0)                     /* must not contain data! */
       
  1544     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1545 
       
  1546 #ifdef MNG_INCLUDE_JNG                 /* sequence checks */
       
  1547   if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  1548 #else
       
  1549   if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
       
  1550 #endif
       
  1551     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1552                                        /* IHDR-block requires IDAT */
       
  1553   if ((pData->bHasIHDR) && (!pData->bHasIDAT))
       
  1554     MNG_ERROR (pData, MNG_IDATMISSING);
       
  1555 
       
  1556   pData->iImagelevel--;                /* one level up */
       
  1557 
       
  1558 #ifdef MNG_SUPPORT_DISPLAY
       
  1559   {                                    /* create an animation object */
       
  1560     mng_retcode iRetcode = mng_create_ani_image (pData);
       
  1561     if (iRetcode)                      /* on error bail out */
       
  1562       return iRetcode;
       
  1563                                        /* display processing */
       
  1564     iRetcode = mng_process_display_iend (pData);
       
  1565     if (iRetcode)                      /* on error bail out */
       
  1566       return iRetcode;
       
  1567   }
       
  1568 #endif /* MNG_SUPPORT_DISPLAY */
       
  1569 
       
  1570 #ifdef MNG_SUPPORT_DISPLAY
       
  1571   if (!pData->bTimerset)               /* reset only if not broken !!! */
       
  1572   {
       
  1573 #endif
       
  1574                                        /* IEND signals the end for most ... */
       
  1575     pData->bHasIHDR         = MNG_FALSE;
       
  1576     pData->bHasBASI         = MNG_FALSE;
       
  1577     pData->bHasDHDR         = MNG_FALSE;
       
  1578 #ifdef MNG_INCLUDE_JNG
       
  1579     pData->bHasJHDR         = MNG_FALSE;
       
  1580     pData->bHasJSEP         = MNG_FALSE;
       
  1581     pData->bHasJDAA         = MNG_FALSE;
       
  1582     pData->bHasJDAT         = MNG_FALSE;
       
  1583 #endif
       
  1584     pData->bHasPLTE         = MNG_FALSE;
       
  1585     pData->bHasTRNS         = MNG_FALSE;
       
  1586     pData->bHasGAMA         = MNG_FALSE;
       
  1587     pData->bHasCHRM         = MNG_FALSE;
       
  1588     pData->bHasSRGB         = MNG_FALSE;
       
  1589     pData->bHasICCP         = MNG_FALSE;
       
  1590     pData->bHasBKGD         = MNG_FALSE;
       
  1591     pData->bHasIDAT         = MNG_FALSE;
       
  1592 #ifdef MNG_SUPPORT_DISPLAY
       
  1593   }
       
  1594 #endif
       
  1595 
       
  1596 #ifdef MNG_STORE_CHUNKS
       
  1597   if (pData->bStorechunks)
       
  1598   {                                    /* initialize storage */
       
  1599     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  1600 
       
  1601     if (iRetcode)                      /* on error bail out */
       
  1602       return iRetcode;
       
  1603   }
       
  1604 #endif /* MNG_STORE_CHUNKS */
       
  1605 
       
  1606 #ifdef MNG_SUPPORT_TRACE
       
  1607   MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_END);
       
  1608 #endif
       
  1609 
       
  1610   return MNG_NOERROR;                  /* done */
       
  1611 }
       
  1612 #endif
       
  1613 
       
  1614 /* ************************************************************************** */
       
  1615 
       
  1616 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  1617 READ_CHUNK (mng_read_trns)
       
  1618 {
       
  1619 #ifdef MNG_SUPPORT_TRACE
       
  1620   MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_START);
       
  1621 #endif
       
  1622                                        /* sequence checks */
       
  1623   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  1624       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  1625     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1626 
       
  1627 #ifdef MNG_INCLUDE_JNG
       
  1628   if ((pData->bHasIDAT) || (pData->bHasJHDR))
       
  1629 #else
       
  1630   if (pData->bHasIDAT)
       
  1631 #endif  
       
  1632     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1633                                        /* multiple tRNS only inside BASI */
       
  1634   if ((pData->bHasTRNS) && (!pData->bHasBASI))
       
  1635     MNG_ERROR (pData, MNG_MULTIPLEERROR);
       
  1636 
       
  1637   if (iRawlen > 256)                   /* it just can't be bigger than that! */
       
  1638     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1639 
       
  1640   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1641   {                                    /* not allowed with full alpha-channel */
       
  1642     if ((pData->iColortype == 4) || (pData->iColortype == 6))
       
  1643       MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
       
  1644 
       
  1645     if (iRawlen != 0)                  /* filled ? */
       
  1646     {                                  /* length checks */
       
  1647       if ((pData->iColortype == 0) && (iRawlen != 2))
       
  1648         MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1649 
       
  1650       if ((pData->iColortype == 2) && (iRawlen != 6))
       
  1651         MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1652 
       
  1653 #ifdef MNG_SUPPORT_DISPLAY
       
  1654       if (pData->iColortype == 3)
       
  1655       {
       
  1656         mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
       
  1657         mng_imagedatap pBuf;
       
  1658 
       
  1659         if (!pImage)                   /* no object then check obj 0 */
       
  1660           pImage = (mng_imagep)pData->pObjzero;
       
  1661 
       
  1662         pBuf = pImage->pImgbuf;        /* address object buffer */
       
  1663 
       
  1664         if (iRawlen > pBuf->iPLTEcount)
       
  1665           MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1666       }
       
  1667 #endif
       
  1668     }
       
  1669     else                               /* if empty there must be global stuff! */
       
  1670     {
       
  1671       if (!pData->bHasglobalTRNS)
       
  1672         MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
       
  1673     }
       
  1674   }
       
  1675 
       
  1676   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1677     pData->bHasTRNS = MNG_TRUE;        /* indicate tRNS available */
       
  1678   else
       
  1679     pData->bHasglobalTRNS = MNG_TRUE;
       
  1680 
       
  1681 #ifdef MNG_SUPPORT_DISPLAY
       
  1682   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1683   {
       
  1684     mng_imagep     pImage;
       
  1685     mng_imagedatap pBuf;
       
  1686     mng_uint8p     pRawdata2;
       
  1687     mng_uint32     iRawlen2;
       
  1688 
       
  1689 #ifndef MNG_NO_DELTA_PNG
       
  1690     if (pData->bHasDHDR)               /* processing delta-image ? */
       
  1691     {                                  /* store in object 0 !!! */
       
  1692       pImage = (mng_imagep)pData->pObjzero;
       
  1693       pBuf   = pImage->pImgbuf;        /* address object buffer */
       
  1694 
       
  1695       switch (pData->iColortype)       /* store fields for future reference */
       
  1696       {
       
  1697         case 0: {                      /* gray */
       
  1698 #if defined(MNG_NO_1_2_4BIT_SUPPORT)
       
  1699                   mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1,
       
  1700                                           0,0,0,0,0,0,0,1};
       
  1701 #endif
       
  1702                   pBuf->iTRNSgray  = mng_get_uint16 (pRawdata);
       
  1703                   pBuf->iTRNSred   = 0;
       
  1704                   pBuf->iTRNSgreen = 0;
       
  1705                   pBuf->iTRNSblue  = 0;
       
  1706                   pBuf->iTRNScount = 0;
       
  1707 #if defined(MNG_NO_1_2_4BIT_SUPPORT)
       
  1708                   pBuf->iTRNSgray *= multiplier[pData->iPNGdepth];
       
  1709 #endif
       
  1710 #if defined(MNG_NO_16BIT_SUPPORT)
       
  1711                   if (pData->iPNGmult == 2)
       
  1712                      pBuf->iTRNSgray >>= 8;
       
  1713 #endif
       
  1714                   break;
       
  1715                 }
       
  1716         case 2: {                      /* rgb */
       
  1717                   pBuf->iTRNSgray  = 0;
       
  1718                   pBuf->iTRNSred   = mng_get_uint16 (pRawdata);
       
  1719                   pBuf->iTRNSgreen = mng_get_uint16 (pRawdata+2);
       
  1720                   pBuf->iTRNSblue  = mng_get_uint16 (pRawdata+4);
       
  1721                   pBuf->iTRNScount = 0;
       
  1722 #if defined(MNG_NO_16BIT_SUPPORT)
       
  1723                   if (pData->iPNGmult == 2)
       
  1724                   {
       
  1725                      pBuf->iTRNSred   >>= 8;
       
  1726                      pBuf->iTRNSgreen >>= 8;
       
  1727                      pBuf->iTRNSblue  >>= 8;
       
  1728                   }
       
  1729 #endif
       
  1730                   break;
       
  1731                 }
       
  1732         case 3: {                      /* indexed */
       
  1733                   pBuf->iTRNSgray  = 0;
       
  1734                   pBuf->iTRNSred   = 0;
       
  1735                   pBuf->iTRNSgreen = 0;
       
  1736                   pBuf->iTRNSblue  = 0;
       
  1737                   pBuf->iTRNScount = iRawlen;
       
  1738                   MNG_COPY (pBuf->aTRNSentries, pRawdata, iRawlen);
       
  1739                   break;
       
  1740                 }
       
  1741       }
       
  1742 
       
  1743       pBuf->bHasTRNS = MNG_TRUE;       /* tell it it's got a tRNS now */
       
  1744     }
       
  1745     else
       
  1746 #endif
       
  1747     {                                  /* address current object */
       
  1748       pImage = (mng_imagep)pData->pCurrentobj;
       
  1749 
       
  1750       if (!pImage)                     /* no object then dump it in obj 0 */
       
  1751         pImage = (mng_imagep)pData->pObjzero;
       
  1752 
       
  1753       pBuf = pImage->pImgbuf;          /* address object buffer */
       
  1754       pBuf->bHasTRNS = MNG_TRUE;       /* and tell it it's got a tRNS now */
       
  1755 
       
  1756       if (iRawlen == 0)                /* if empty, inherit from global */
       
  1757       {
       
  1758         iRawlen2  = pData->iGlobalTRNSrawlen;
       
  1759         pRawdata2 = (mng_ptr)(pData->aGlobalTRNSrawdata);
       
  1760                                          /* global length oke ? */
       
  1761         if ((pData->iColortype == 0) && (iRawlen2 != 2))
       
  1762           MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
       
  1763 
       
  1764         if ((pData->iColortype == 2) && (iRawlen2 != 6))
       
  1765           MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
       
  1766 
       
  1767         if ((pData->iColortype == 3) && ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount)))
       
  1768           MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
       
  1769       }
       
  1770       else
       
  1771       {
       
  1772         iRawlen2  = iRawlen;
       
  1773         pRawdata2 = pRawdata;
       
  1774       }
       
  1775 
       
  1776       switch (pData->iColortype)        /* store fields for future reference */
       
  1777       {
       
  1778         case 0: {                      /* gray */
       
  1779                   pBuf->iTRNSgray  = mng_get_uint16 (pRawdata2);
       
  1780                   pBuf->iTRNSred   = 0;
       
  1781                   pBuf->iTRNSgreen = 0;
       
  1782                   pBuf->iTRNSblue  = 0;
       
  1783                   pBuf->iTRNScount = 0;
       
  1784 #if defined(MNG_NO_16BIT_SUPPORT)
       
  1785                   if (pData->iPNGmult == 2)
       
  1786                      pBuf->iTRNSgray >>= 8;
       
  1787 #endif
       
  1788                   break;
       
  1789                 }
       
  1790         case 2: {                      /* rgb */
       
  1791                   pBuf->iTRNSgray  = 0;
       
  1792                   pBuf->iTRNSred   = mng_get_uint16 (pRawdata2);
       
  1793                   pBuf->iTRNSgreen = mng_get_uint16 (pRawdata2+2);
       
  1794                   pBuf->iTRNSblue  = mng_get_uint16 (pRawdata2+4);
       
  1795                   pBuf->iTRNScount = 0;
       
  1796 #if defined(MNG_NO_16BIT_SUPPORT)
       
  1797                   if (pData->iPNGmult == 2)
       
  1798                   {
       
  1799                      pBuf->iTRNSred   >>= 8;
       
  1800                      pBuf->iTRNSgreen >>= 8;
       
  1801                      pBuf->iTRNSblue  >>= 8;
       
  1802                   }
       
  1803 #endif
       
  1804                   break;
       
  1805                 }
       
  1806         case 3: {                      /* indexed */
       
  1807                   pBuf->iTRNSgray  = 0;
       
  1808                   pBuf->iTRNSred   = 0;
       
  1809                   pBuf->iTRNSgreen = 0;
       
  1810                   pBuf->iTRNSblue  = 0;
       
  1811                   pBuf->iTRNScount = iRawlen2;
       
  1812                   MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
       
  1813                   break;
       
  1814                 }
       
  1815       }
       
  1816     }  
       
  1817   }
       
  1818   else                                 /* store as global */
       
  1819   {
       
  1820     pData->iGlobalTRNSrawlen = iRawlen;
       
  1821     MNG_COPY (pData->aGlobalTRNSrawdata, pRawdata, iRawlen);
       
  1822 
       
  1823     {                                  /* create an animation object */
       
  1824       mng_retcode iRetcode = mng_create_ani_trns (pData, pData->iGlobalTRNSrawlen,
       
  1825                                                   pData->aGlobalTRNSrawdata);
       
  1826 
       
  1827       if (iRetcode)                    /* on error bail out */
       
  1828         return iRetcode;
       
  1829     }
       
  1830   }
       
  1831 #endif /* MNG_SUPPORT_DISPLAY */
       
  1832 
       
  1833 #ifdef MNG_STORE_CHUNKS
       
  1834   if (pData->bStorechunks)
       
  1835   {                                    /* initialize storage */
       
  1836     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  1837 
       
  1838     if (iRetcode)                      /* on error bail out */
       
  1839       return iRetcode;
       
  1840 
       
  1841     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1842     {                                  /* not global! */
       
  1843       ((mng_trnsp)*ppChunk)->bGlobal  = MNG_FALSE;
       
  1844       ((mng_trnsp)*ppChunk)->iType    = pData->iColortype;
       
  1845 
       
  1846       if (iRawlen == 0)                /* if empty, indicate so */
       
  1847         ((mng_trnsp)*ppChunk)->bEmpty = MNG_TRUE;
       
  1848       else
       
  1849       {
       
  1850         ((mng_trnsp)*ppChunk)->bEmpty = MNG_FALSE;
       
  1851 
       
  1852         switch (pData->iColortype)     /* store fields */
       
  1853         {
       
  1854           case 0: {                    /* gray */
       
  1855                     ((mng_trnsp)*ppChunk)->iGray  = mng_get_uint16 (pRawdata);
       
  1856                     break;
       
  1857                   }
       
  1858           case 2: {                    /* rgb */
       
  1859                     ((mng_trnsp)*ppChunk)->iRed   = mng_get_uint16 (pRawdata);
       
  1860                     ((mng_trnsp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
       
  1861                     ((mng_trnsp)*ppChunk)->iBlue  = mng_get_uint16 (pRawdata+4);
       
  1862                     break;
       
  1863                   }
       
  1864           case 3: {                    /* indexed */
       
  1865                     ((mng_trnsp)*ppChunk)->iCount = iRawlen;
       
  1866                     MNG_COPY (((mng_trnsp)*ppChunk)->aEntries, pRawdata, iRawlen);
       
  1867                     break;
       
  1868                   }
       
  1869         }
       
  1870       }
       
  1871     }
       
  1872     else                               /* it's global! */
       
  1873     {
       
  1874       ((mng_trnsp)*ppChunk)->bEmpty  = (mng_bool)(iRawlen == 0);
       
  1875       ((mng_trnsp)*ppChunk)->bGlobal = MNG_TRUE;
       
  1876       ((mng_trnsp)*ppChunk)->iType   = 0;
       
  1877       ((mng_trnsp)*ppChunk)->iRawlen = iRawlen;
       
  1878 
       
  1879       MNG_COPY (((mng_trnsp)*ppChunk)->aRawdata, pRawdata, iRawlen);
       
  1880     }
       
  1881   }
       
  1882 #endif /* MNG_STORE_CHUNKS */
       
  1883 
       
  1884 #ifdef MNG_SUPPORT_TRACE
       
  1885   MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_END);
       
  1886 #endif
       
  1887 
       
  1888   return MNG_NOERROR;                  /* done */
       
  1889 }
       
  1890 #endif
       
  1891 
       
  1892 /* ************************************************************************** */
       
  1893 
       
  1894 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  1895 READ_CHUNK (mng_read_gama)
       
  1896 {
       
  1897 #ifdef MNG_SUPPORT_TRACE
       
  1898   MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_START);
       
  1899 #endif
       
  1900                                        /* sequence checks */
       
  1901 #ifdef MNG_INCLUDE_JNG
       
  1902   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  1903       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  1904 #else
       
  1905   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  1906       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  1907 #endif
       
  1908     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1909 
       
  1910 #ifdef MNG_INCLUDE_JNG
       
  1911   if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  1912 #else
       
  1913   if ((pData->bHasIDAT) || (pData->bHasPLTE))
       
  1914 #endif
       
  1915     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  1916 
       
  1917 #ifdef MNG_INCLUDE_JNG
       
  1918   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  1919 #else
       
  1920   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1921 #endif
       
  1922   {                                    /* length must be exactly 4 */
       
  1923     if (iRawlen != 4)
       
  1924       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1925   }
       
  1926   else
       
  1927   {                                    /* length must be empty or exactly 4 */
       
  1928     if ((iRawlen != 0) && (iRawlen != 4))
       
  1929       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  1930   }
       
  1931 
       
  1932 #ifdef MNG_INCLUDE_JNG
       
  1933   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  1934 #else
       
  1935   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1936 #endif
       
  1937     pData->bHasGAMA = MNG_TRUE;        /* indicate we've got it */
       
  1938   else
       
  1939     pData->bHasglobalGAMA = (mng_bool)(iRawlen != 0);
       
  1940 
       
  1941 #ifdef MNG_SUPPORT_DISPLAY
       
  1942 #ifdef MNG_INCLUDE_JNG
       
  1943   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  1944 #else
       
  1945   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  1946 #endif
       
  1947   {
       
  1948     mng_imagep pImage;
       
  1949 
       
  1950 #ifndef MNG_NO_DELTA_PNG
       
  1951     if (pData->bHasDHDR)               /* update delta image ? */
       
  1952     {                                  /* store in object 0 ! */
       
  1953       pImage = (mng_imagep)pData->pObjzero;
       
  1954                                        /* store for color-processing routines */
       
  1955       pImage->pImgbuf->iGamma   = mng_get_uint32 (pRawdata);
       
  1956       pImage->pImgbuf->bHasGAMA = MNG_TRUE;
       
  1957     }
       
  1958     else
       
  1959 #endif
       
  1960     {
       
  1961       pImage = (mng_imagep)pData->pCurrentobj;
       
  1962 
       
  1963       if (!pImage)                     /* no object then dump it in obj 0 */
       
  1964         pImage = (mng_imagep)pData->pObjzero;
       
  1965                                        /* store for color-processing routines */
       
  1966       pImage->pImgbuf->iGamma   = mng_get_uint32 (pRawdata);
       
  1967       pImage->pImgbuf->bHasGAMA = MNG_TRUE;
       
  1968     }
       
  1969   }
       
  1970   else
       
  1971   {                                    /* store as global */
       
  1972     if (iRawlen != 0)
       
  1973       pData->iGlobalGamma = mng_get_uint32 (pRawdata);
       
  1974 
       
  1975     {                                  /* create an animation object */
       
  1976       mng_retcode iRetcode = mng_create_ani_gama (pData, (mng_bool)(iRawlen == 0),
       
  1977                                                   pData->iGlobalGamma);
       
  1978 
       
  1979       if (iRetcode)                    /* on error bail out */
       
  1980         return iRetcode;
       
  1981     }
       
  1982   }
       
  1983 #endif /* MNG_SUPPORT_DISPLAY */
       
  1984 
       
  1985 #ifdef MNG_STORE_CHUNKS
       
  1986   if (pData->bStorechunks)
       
  1987   {                                    /* initialize storage */
       
  1988     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  1989 
       
  1990     if (iRetcode)                      /* on error bail out */
       
  1991       return iRetcode;
       
  1992                                        /* store the fields */
       
  1993     ((mng_gamap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  1994 
       
  1995     if (iRawlen)
       
  1996       ((mng_gamap)*ppChunk)->iGamma = mng_get_uint32 (pRawdata);
       
  1997 
       
  1998   }
       
  1999 #endif /* MNG_STORE_CHUNKS */
       
  2000 
       
  2001 #ifdef MNG_SUPPORT_TRACE
       
  2002   MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_END);
       
  2003 #endif
       
  2004 
       
  2005   return MNG_NOERROR;                  /* done */
       
  2006 }
       
  2007 #endif
       
  2008 
       
  2009 /* ************************************************************************** */
       
  2010 
       
  2011 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2012 #ifndef MNG_SKIPCHUNK_cHRM
       
  2013 READ_CHUNK (mng_read_chrm)
       
  2014 {
       
  2015 #ifdef MNG_SUPPORT_TRACE
       
  2016   MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_START);
       
  2017 #endif
       
  2018                                        /* sequence checks */
       
  2019 #ifdef MNG_INCLUDE_JNG
       
  2020   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2021       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  2022 #else
       
  2023   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2024       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  2025 #endif
       
  2026     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2027 
       
  2028 #ifdef MNG_INCLUDE_JNG
       
  2029   if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  2030 #else
       
  2031   if ((pData->bHasIDAT) || (pData->bHasPLTE))
       
  2032 #endif
       
  2033     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2034 
       
  2035 #ifdef MNG_INCLUDE_JNG
       
  2036   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2037 #else
       
  2038   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2039 #endif
       
  2040   {                                    /* length must be exactly 32 */
       
  2041     if (iRawlen != 32)
       
  2042       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2043   }
       
  2044   else
       
  2045   {                                    /* length must be empty or exactly 32 */
       
  2046     if ((iRawlen != 0) && (iRawlen != 32))
       
  2047       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2048   }
       
  2049 
       
  2050 #ifdef MNG_INCLUDE_JNG
       
  2051   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2052 #else
       
  2053   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2054 #endif
       
  2055     pData->bHasCHRM = MNG_TRUE;        /* indicate we've got it */
       
  2056   else
       
  2057     pData->bHasglobalCHRM = (mng_bool)(iRawlen != 0);
       
  2058 
       
  2059 #ifdef MNG_SUPPORT_DISPLAY
       
  2060   {
       
  2061     mng_uint32 iWhitepointx,   iWhitepointy;
       
  2062     mng_uint32 iPrimaryredx,   iPrimaryredy;
       
  2063     mng_uint32 iPrimarygreenx, iPrimarygreeny;
       
  2064     mng_uint32 iPrimarybluex,  iPrimarybluey;
       
  2065 
       
  2066     iWhitepointx   = mng_get_uint32 (pRawdata);
       
  2067     iWhitepointy   = mng_get_uint32 (pRawdata+4);
       
  2068     iPrimaryredx   = mng_get_uint32 (pRawdata+8);
       
  2069     iPrimaryredy   = mng_get_uint32 (pRawdata+12);
       
  2070     iPrimarygreenx = mng_get_uint32 (pRawdata+16);
       
  2071     iPrimarygreeny = mng_get_uint32 (pRawdata+20);
       
  2072     iPrimarybluex  = mng_get_uint32 (pRawdata+24);
       
  2073     iPrimarybluey  = mng_get_uint32 (pRawdata+28);
       
  2074 
       
  2075 #ifdef MNG_INCLUDE_JNG
       
  2076     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2077 #else
       
  2078     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2079 #endif
       
  2080     {
       
  2081       mng_imagep     pImage;
       
  2082       mng_imagedatap pBuf;
       
  2083 
       
  2084 #ifndef MNG_NO_DELTA_PNG
       
  2085       if (pData->bHasDHDR)             /* update delta image ? */
       
  2086       {                                /* store it in object 0 ! */
       
  2087         pImage = (mng_imagep)pData->pObjzero;
       
  2088 
       
  2089         pBuf = pImage->pImgbuf;        /* address object buffer */
       
  2090         pBuf->bHasCHRM = MNG_TRUE;     /* and tell it it's got a CHRM now */
       
  2091                                        /* store for color-processing routines */
       
  2092         pBuf->iWhitepointx   = iWhitepointx;
       
  2093         pBuf->iWhitepointy   = iWhitepointy;
       
  2094         pBuf->iPrimaryredx   = iPrimaryredx;
       
  2095         pBuf->iPrimaryredy   = iPrimaryredy;
       
  2096         pBuf->iPrimarygreenx = iPrimarygreenx;
       
  2097         pBuf->iPrimarygreeny = iPrimarygreeny;
       
  2098         pBuf->iPrimarybluex  = iPrimarybluex;
       
  2099         pBuf->iPrimarybluey  = iPrimarybluey;
       
  2100       }
       
  2101       else
       
  2102 #endif
       
  2103       {
       
  2104         pImage = (mng_imagep)pData->pCurrentobj;
       
  2105 
       
  2106         if (!pImage)                   /* no object then dump it in obj 0 */
       
  2107           pImage = (mng_imagep)pData->pObjzero;
       
  2108 
       
  2109         pBuf = pImage->pImgbuf;        /* address object buffer */
       
  2110         pBuf->bHasCHRM = MNG_TRUE;     /* and tell it it's got a CHRM now */
       
  2111                                        /* store for color-processing routines */
       
  2112         pBuf->iWhitepointx   = iWhitepointx;
       
  2113         pBuf->iWhitepointy   = iWhitepointy;
       
  2114         pBuf->iPrimaryredx   = iPrimaryredx;
       
  2115         pBuf->iPrimaryredy   = iPrimaryredy;
       
  2116         pBuf->iPrimarygreenx = iPrimarygreenx;
       
  2117         pBuf->iPrimarygreeny = iPrimarygreeny;
       
  2118         pBuf->iPrimarybluex  = iPrimarybluex;
       
  2119         pBuf->iPrimarybluey  = iPrimarybluey;
       
  2120       }
       
  2121     }
       
  2122     else
       
  2123     {                                  /* store as global */
       
  2124       if (iRawlen != 0)
       
  2125       {
       
  2126         pData->iGlobalWhitepointx   = iWhitepointx;
       
  2127         pData->iGlobalWhitepointy   = iWhitepointy;
       
  2128         pData->iGlobalPrimaryredx   = iPrimaryredx;
       
  2129         pData->iGlobalPrimaryredy   = iPrimaryredy;
       
  2130         pData->iGlobalPrimarygreenx = iPrimarygreenx;
       
  2131         pData->iGlobalPrimarygreeny = iPrimarygreeny;
       
  2132         pData->iGlobalPrimarybluex  = iPrimarybluex;
       
  2133         pData->iGlobalPrimarybluey  = iPrimarybluey;
       
  2134       }
       
  2135 
       
  2136       {                                /* create an animation object */
       
  2137         mng_retcode iRetcode = mng_create_ani_chrm (pData, (mng_bool)(iRawlen == 0),
       
  2138                                                     iWhitepointx,   iWhitepointy,
       
  2139                                                     iPrimaryredx,   iPrimaryredy,
       
  2140                                                     iPrimarygreenx, iPrimarygreeny,
       
  2141                                                     iPrimarybluex,  iPrimarybluey);
       
  2142 
       
  2143         if (iRetcode)                  /* on error bail out */
       
  2144           return iRetcode;
       
  2145       }
       
  2146     }
       
  2147   }
       
  2148 #endif /* MNG_SUPPORT_DISPLAY */
       
  2149 
       
  2150 #ifdef MNG_STORE_CHUNKS
       
  2151   if (pData->bStorechunks)
       
  2152   {                                    /* initialize storage */
       
  2153     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  2154 
       
  2155     if (iRetcode)                      /* on error bail out */
       
  2156       return iRetcode;
       
  2157                                        /* store the fields */
       
  2158     ((mng_chrmp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  2159 
       
  2160     if (iRawlen)
       
  2161     {
       
  2162       ((mng_chrmp)*ppChunk)->iWhitepointx = mng_get_uint32 (pRawdata);
       
  2163       ((mng_chrmp)*ppChunk)->iWhitepointy = mng_get_uint32 (pRawdata+4);
       
  2164       ((mng_chrmp)*ppChunk)->iRedx        = mng_get_uint32 (pRawdata+8);
       
  2165       ((mng_chrmp)*ppChunk)->iRedy        = mng_get_uint32 (pRawdata+12);
       
  2166       ((mng_chrmp)*ppChunk)->iGreenx      = mng_get_uint32 (pRawdata+16);
       
  2167       ((mng_chrmp)*ppChunk)->iGreeny      = mng_get_uint32 (pRawdata+20);
       
  2168       ((mng_chrmp)*ppChunk)->iBluex       = mng_get_uint32 (pRawdata+24);
       
  2169       ((mng_chrmp)*ppChunk)->iBluey       = mng_get_uint32 (pRawdata+28);
       
  2170     }
       
  2171   }
       
  2172 #endif /* MNG_STORE_CHUNKS */
       
  2173 
       
  2174 #ifdef MNG_SUPPORT_TRACE
       
  2175   MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_END);
       
  2176 #endif
       
  2177 
       
  2178   return MNG_NOERROR;                  /* done */
       
  2179 }
       
  2180 #endif
       
  2181 #endif
       
  2182 
       
  2183 /* ************************************************************************** */
       
  2184 
       
  2185 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2186 READ_CHUNK (mng_read_srgb)
       
  2187 {
       
  2188 #ifdef MNG_SUPPORT_TRACE
       
  2189   MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_START);
       
  2190 #endif
       
  2191                                        /* sequence checks */
       
  2192 #ifdef MNG_INCLUDE_JNG
       
  2193   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2194       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  2195 #else
       
  2196   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2197       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  2198 #endif
       
  2199     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2200 
       
  2201 #ifdef MNG_INCLUDE_JNG
       
  2202   if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  2203 #else
       
  2204   if ((pData->bHasIDAT) || (pData->bHasPLTE))
       
  2205 #endif
       
  2206     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2207 
       
  2208 #ifdef MNG_INCLUDE_JNG
       
  2209   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2210 #else
       
  2211   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2212 #endif
       
  2213   {                                    /* length must be exactly 1 */
       
  2214     if (iRawlen != 1)
       
  2215       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2216   }
       
  2217   else
       
  2218   {                                    /* length must be empty or exactly 1 */
       
  2219     if ((iRawlen != 0) && (iRawlen != 1))
       
  2220       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2221   }
       
  2222 
       
  2223 #ifdef MNG_INCLUDE_JNG
       
  2224   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2225 #else
       
  2226   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2227 #endif
       
  2228     pData->bHasSRGB = MNG_TRUE;        /* indicate we've got it */
       
  2229   else
       
  2230     pData->bHasglobalSRGB = (mng_bool)(iRawlen != 0);
       
  2231 
       
  2232 #ifdef MNG_SUPPORT_DISPLAY
       
  2233 #ifdef MNG_INCLUDE_JNG
       
  2234   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2235 #else
       
  2236   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2237 #endif
       
  2238   {
       
  2239     mng_imagep pImage;
       
  2240 
       
  2241 #ifndef MNG_NO_DELTA_PNG
       
  2242     if (pData->bHasDHDR)               /* update delta image ? */
       
  2243     {                                  /* store in object 0 ! */
       
  2244       pImage = (mng_imagep)pData->pObjzero;
       
  2245                                        /* store for color-processing routines */
       
  2246       pImage->pImgbuf->iRenderingintent = *pRawdata;
       
  2247       pImage->pImgbuf->bHasSRGB         = MNG_TRUE;
       
  2248     }
       
  2249     else
       
  2250 #endif
       
  2251     {
       
  2252       pImage = (mng_imagep)pData->pCurrentobj;
       
  2253 
       
  2254       if (!pImage)                     /* no object then dump it in obj 0 */
       
  2255         pImage = (mng_imagep)pData->pObjzero;
       
  2256                                        /* store for color-processing routines */
       
  2257       pImage->pImgbuf->iRenderingintent = *pRawdata;
       
  2258       pImage->pImgbuf->bHasSRGB         = MNG_TRUE;
       
  2259     }
       
  2260   }
       
  2261   else
       
  2262   {                                    /* store as global */
       
  2263     if (iRawlen != 0)
       
  2264       pData->iGlobalRendintent = *pRawdata;
       
  2265 
       
  2266     {                                  /* create an animation object */
       
  2267       mng_retcode iRetcode = mng_create_ani_srgb (pData, (mng_bool)(iRawlen == 0),
       
  2268                                                   pData->iGlobalRendintent);
       
  2269 
       
  2270       if (iRetcode)                    /* on error bail out */
       
  2271         return iRetcode;
       
  2272     }
       
  2273   }
       
  2274 #endif /* MNG_SUPPORT_DISPLAY */
       
  2275 
       
  2276 #ifdef MNG_STORE_CHUNKS
       
  2277   if (pData->bStorechunks)
       
  2278   {                                    /* initialize storage */
       
  2279     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  2280 
       
  2281     if (iRetcode)                      /* on error bail out */
       
  2282       return iRetcode;
       
  2283                                        /* store the fields */
       
  2284     ((mng_srgbp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  2285 
       
  2286     if (iRawlen)
       
  2287       ((mng_srgbp)*ppChunk)->iRenderingintent = *pRawdata;
       
  2288 
       
  2289   }
       
  2290 #endif /* MNG_STORE_CHUNKS */
       
  2291 
       
  2292 #ifdef MNG_SUPPORT_TRACE
       
  2293   MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_END);
       
  2294 #endif
       
  2295 
       
  2296   return MNG_NOERROR;                  /* done */
       
  2297 }
       
  2298 #endif
       
  2299 
       
  2300 /* ************************************************************************** */
       
  2301 
       
  2302 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2303 #ifndef MNG_SKIPCHUNK_iCCP
       
  2304 READ_CHUNK (mng_read_iccp)
       
  2305 {
       
  2306   mng_retcode iRetcode;
       
  2307   mng_uint8p  pTemp;
       
  2308   mng_uint32  iCompressedsize;
       
  2309   mng_uint32  iProfilesize;
       
  2310   mng_uint32  iBufsize = 0;
       
  2311   mng_uint8p  pBuf = 0;
       
  2312 
       
  2313 #ifdef MNG_SUPPORT_TRACE
       
  2314   MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_START);
       
  2315 #endif
       
  2316                                        /* sequence checks */
       
  2317 #ifdef MNG_INCLUDE_JNG
       
  2318   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2319       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  2320 #else
       
  2321   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2322       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  2323 #endif
       
  2324     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2325 
       
  2326 #ifdef MNG_INCLUDE_JNG
       
  2327   if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  2328 #else
       
  2329   if ((pData->bHasIDAT) || (pData->bHasPLTE))
       
  2330 #endif
       
  2331     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2332 
       
  2333 #ifdef MNG_INCLUDE_JNG
       
  2334   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2335 #else
       
  2336   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2337 #endif
       
  2338   {                                    /* length must be at least 2 */
       
  2339     if (iRawlen < 2)
       
  2340       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2341   }
       
  2342   else
       
  2343   {                                    /* length must be empty or at least 2 */
       
  2344     if ((iRawlen != 0) && (iRawlen < 2))
       
  2345       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2346   }
       
  2347 
       
  2348   pTemp = find_null (pRawdata);        /* find null-separator */
       
  2349                                        /* not found inside input-data ? */
       
  2350   if ((pTemp - pRawdata) > (mng_int32)iRawlen)
       
  2351     MNG_ERROR (pData, MNG_NULLNOTFOUND);
       
  2352                                        /* determine size of compressed profile */
       
  2353   iCompressedsize = (mng_uint32)(iRawlen - (pTemp - pRawdata) - 2);
       
  2354                                        /* decompress the profile */
       
  2355   iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
       
  2356                                  &pBuf, &iBufsize, &iProfilesize);
       
  2357 
       
  2358 #ifdef MNG_CHECK_BAD_ICCP              /* Check for bad iCCP chunk */
       
  2359   if ((iRetcode) && (!strncmp ((char *)pRawdata, "Photoshop ICC profile", 21)))
       
  2360   {
       
  2361     if (iRawlen == 2615)               /* is it the sRGB profile ? */
       
  2362     {
       
  2363       mng_chunk_header chunk_srgb =
       
  2364 #ifdef MNG_OPTIMIZE_CHUNKINITFREE
       
  2365         {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)};
       
  2366 #else
       
  2367         {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0};
       
  2368 #endif
       
  2369                                        /* pretend it's an sRGB chunk then ! */
       
  2370       iRetcode = mng_read_srgb (pData, &chunk_srgb, 1, (mng_ptr)"0", ppChunk);
       
  2371 
       
  2372       if (iRetcode)                    /* on error bail out */
       
  2373       {                                /* don't forget to drop the temp buffer */
       
  2374         MNG_FREEX (pData, pBuf, iBufsize);
       
  2375         return iRetcode;
       
  2376       }
       
  2377     }
       
  2378   }
       
  2379   else
       
  2380   {
       
  2381 #endif /* MNG_CHECK_BAD_ICCP */
       
  2382 
       
  2383     if (iRetcode)                      /* on error bail out */
       
  2384     {                                  /* don't forget to drop the temp buffer */
       
  2385       MNG_FREEX (pData, pBuf, iBufsize);
       
  2386       return iRetcode;
       
  2387     }
       
  2388 
       
  2389 #ifdef MNG_INCLUDE_JNG
       
  2390     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2391 #else
       
  2392     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2393 #endif
       
  2394       pData->bHasICCP = MNG_TRUE;      /* indicate we've got it */
       
  2395     else
       
  2396       pData->bHasglobalICCP = (mng_bool)(iRawlen != 0);
       
  2397 
       
  2398 #ifdef MNG_SUPPORT_DISPLAY
       
  2399 #ifdef MNG_INCLUDE_JNG
       
  2400     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  2401 #else
       
  2402     if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  2403 #endif
       
  2404     {
       
  2405       mng_imagep pImage;
       
  2406 
       
  2407 #ifndef MNG_NO_DELTA_PNG
       
  2408       if (pData->bHasDHDR)             /* update delta image ? */
       
  2409       {                                /* store in object 0 ! */
       
  2410         pImage = (mng_imagep)pData->pObjzero;
       
  2411 
       
  2412         if (pImage->pImgbuf->pProfile) /* profile existed ? */
       
  2413           MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
       
  2414                                        /* allocate a buffer & copy it */
       
  2415         MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize);
       
  2416         MNG_COPY  (pImage->pImgbuf->pProfile, pBuf, iProfilesize);
       
  2417                                        /* store its length as well */
       
  2418         pImage->pImgbuf->iProfilesize = iProfilesize;
       
  2419         pImage->pImgbuf->bHasICCP     = MNG_TRUE;
       
  2420       }
       
  2421       else
       
  2422 #endif
       
  2423       {
       
  2424         pImage = (mng_imagep)pData->pCurrentobj;
       
  2425 
       
  2426         if (!pImage)                   /* no object then dump it in obj 0 */
       
  2427           pImage = (mng_imagep)pData->pObjzero;
       
  2428 
       
  2429         if (pImage->pImgbuf->pProfile) /* profile existed ? */
       
  2430           MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
       
  2431                                        /* allocate a buffer & copy it */
       
  2432         MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize);
       
  2433         MNG_COPY  (pImage->pImgbuf->pProfile, pBuf, iProfilesize);
       
  2434                                        /* store its length as well */
       
  2435         pImage->pImgbuf->iProfilesize = iProfilesize;
       
  2436         pImage->pImgbuf->bHasICCP     = MNG_TRUE;
       
  2437       }
       
  2438     }
       
  2439     else
       
  2440     {                                  /* store as global */
       
  2441       if (iRawlen == 0)                /* empty chunk ? */
       
  2442       {
       
  2443         if (pData->pGlobalProfile)     /* did we have a global profile ? */
       
  2444           MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
       
  2445 
       
  2446         pData->iGlobalProfilesize = 0; /* reset to null */
       
  2447         pData->pGlobalProfile     = MNG_NULL;
       
  2448       }
       
  2449       else
       
  2450       {                                /* allocate a global buffer & copy it */
       
  2451         MNG_ALLOC (pData, pData->pGlobalProfile, iProfilesize);
       
  2452         MNG_COPY  (pData->pGlobalProfile, pBuf, iProfilesize);
       
  2453                                        /* store its length as well */
       
  2454         pData->iGlobalProfilesize = iProfilesize;
       
  2455       }
       
  2456 
       
  2457                                        /* create an animation object */
       
  2458       iRetcode = mng_create_ani_iccp (pData, (mng_bool)(iRawlen == 0),
       
  2459                                       pData->iGlobalProfilesize,
       
  2460                                       pData->pGlobalProfile);
       
  2461 
       
  2462       if (iRetcode)                    /* on error bail out */
       
  2463         return iRetcode;
       
  2464     }
       
  2465 #endif /* MNG_SUPPORT_DISPLAY */
       
  2466 
       
  2467 #ifdef MNG_STORE_CHUNKS
       
  2468     if (pData->bStorechunks)
       
  2469     {                                  /* initialize storage */
       
  2470       iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  2471 
       
  2472       if (iRetcode)                    /* on error bail out */
       
  2473       {                                /* don't forget to drop the temp buffer */
       
  2474         MNG_FREEX (pData, pBuf, iBufsize);
       
  2475         return iRetcode;
       
  2476       }
       
  2477                                        /* store the fields */
       
  2478       ((mng_iccpp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  2479 
       
  2480       if (iRawlen)                     /* not empty ? */
       
  2481       {
       
  2482         if (!pBuf)                     /* hasn't been unpuzzled it yet ? */
       
  2483         {                              /* find null-separator */
       
  2484           pTemp = find_null (pRawdata);
       
  2485                                        /* not found inside input-data ? */
       
  2486           if ((pTemp - pRawdata) > (mng_int32)iRawlen)
       
  2487             MNG_ERROR (pData, MNG_NULLNOTFOUND);
       
  2488                                        /* determine size of compressed profile */
       
  2489           iCompressedsize = iRawlen - (pTemp - pRawdata) - 2;
       
  2490                                        /* decompress the profile */
       
  2491           iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
       
  2492                                          &pBuf, &iBufsize, &iProfilesize);
       
  2493 
       
  2494           if (iRetcode)                /* on error bail out */
       
  2495           {                            /* don't forget to drop the temp buffer */
       
  2496             MNG_FREEX (pData, pBuf, iBufsize);
       
  2497             return iRetcode;
       
  2498           }
       
  2499         }
       
  2500 
       
  2501         ((mng_iccpp)*ppChunk)->iNamesize = (mng_uint32)(pTemp - pRawdata);
       
  2502 
       
  2503         if (((mng_iccpp)*ppChunk)->iNamesize)
       
  2504         {
       
  2505           MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->zName,
       
  2506                             ((mng_iccpp)*ppChunk)->iNamesize + 1);
       
  2507           MNG_COPY  (((mng_iccpp)*ppChunk)->zName, pRawdata,
       
  2508                      ((mng_iccpp)*ppChunk)->iNamesize);
       
  2509         }
       
  2510 
       
  2511         ((mng_iccpp)*ppChunk)->iCompression = *(pTemp+1);
       
  2512         ((mng_iccpp)*ppChunk)->iProfilesize = iProfilesize;
       
  2513 
       
  2514         MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->pProfile, iProfilesize);
       
  2515         MNG_COPY  (((mng_iccpp)*ppChunk)->pProfile, pBuf, iProfilesize);
       
  2516       }
       
  2517     }
       
  2518 #endif /* MNG_STORE_CHUNKS */
       
  2519 
       
  2520     if (pBuf)                          /* free the temporary buffer */
       
  2521       MNG_FREEX (pData, pBuf, iBufsize);
       
  2522 
       
  2523 #ifdef MNG_CHECK_BAD_ICCP
       
  2524   }
       
  2525 #endif
       
  2526 
       
  2527 #ifdef MNG_SUPPORT_TRACE
       
  2528   MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_END);
       
  2529 #endif
       
  2530 
       
  2531   return MNG_NOERROR;                  /* done */
       
  2532 }
       
  2533 #endif
       
  2534 #endif
       
  2535 
       
  2536 /* ************************************************************************** */
       
  2537 
       
  2538 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2539 #ifndef MNG_SKIPCHUNK_tEXt
       
  2540 READ_CHUNK (mng_read_text)
       
  2541 {
       
  2542   mng_uint32 iKeywordlen, iTextlen;
       
  2543   mng_pchar  zKeyword, zText;
       
  2544   mng_uint8p pTemp;
       
  2545 
       
  2546 #ifdef MNG_SUPPORT_TRACE
       
  2547   MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_START);
       
  2548 #endif
       
  2549                                        /* sequence checks */
       
  2550 #ifdef MNG_INCLUDE_JNG
       
  2551   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2552       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  2553 #else
       
  2554   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2555       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  2556 #endif
       
  2557     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2558 
       
  2559   if (iRawlen < 2)                     /* length must be at least 2 */
       
  2560     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2561 
       
  2562   pTemp = find_null (pRawdata);        /* find the null separator */
       
  2563                                        /* not found inside input-data ? */
       
  2564   if ((pTemp - pRawdata) > (mng_int32)iRawlen)
       
  2565     MNG_ERROR (pData, MNG_NULLNOTFOUND);
       
  2566 
       
  2567   if (pTemp == pRawdata)               /* there must be at least 1 char for keyword */
       
  2568     MNG_ERROR (pData, MNG_KEYWORDNULL);
       
  2569 
       
  2570   iKeywordlen = (mng_uint32)(pTemp - pRawdata);
       
  2571   iTextlen    = iRawlen - iKeywordlen - 1;
       
  2572 
       
  2573   if (pData->fProcesstext)             /* inform the application ? */
       
  2574   {
       
  2575     mng_bool bOke;
       
  2576 
       
  2577     MNG_ALLOC (pData, zKeyword, iKeywordlen + 1);
       
  2578     MNG_COPY  (zKeyword, pRawdata, iKeywordlen);
       
  2579 
       
  2580     MNG_ALLOCX (pData, zText, iTextlen + 1);
       
  2581 
       
  2582     if (!zText)                        /* on error bail out */
       
  2583     {
       
  2584       MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
       
  2585       MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2586     }
       
  2587 
       
  2588     if (iTextlen)
       
  2589       MNG_COPY (zText, pTemp+1, iTextlen);
       
  2590 
       
  2591     bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_TEXT, zKeyword, zText, 0, 0);
       
  2592 
       
  2593     MNG_FREEX (pData, zText, iTextlen + 1);
       
  2594     MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
       
  2595 
       
  2596     if (!bOke)
       
  2597       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  2598 
       
  2599   }
       
  2600 
       
  2601 #ifdef MNG_STORE_CHUNKS
       
  2602   if (pData->bStorechunks)
       
  2603   {                                    /* initialize storage */
       
  2604     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  2605 
       
  2606     if (iRetcode)                      /* on error bail out */
       
  2607       return iRetcode;
       
  2608                                        /* store the fields */
       
  2609     ((mng_textp)*ppChunk)->iKeywordsize = iKeywordlen;
       
  2610     ((mng_textp)*ppChunk)->iTextsize    = iTextlen;
       
  2611 
       
  2612     if (iKeywordlen)
       
  2613     {
       
  2614       MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zKeyword, iKeywordlen+1);
       
  2615       MNG_COPY  (((mng_textp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
       
  2616     }
       
  2617 
       
  2618     if (iTextlen)
       
  2619     {
       
  2620       MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zText, iTextlen+1);
       
  2621       MNG_COPY  (((mng_textp)*ppChunk)->zText, pTemp+1, iTextlen);
       
  2622     }
       
  2623   }
       
  2624 #endif /* MNG_STORE_CHUNKS */
       
  2625 
       
  2626 #ifdef MNG_SUPPORT_TRACE
       
  2627   MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_END);
       
  2628 #endif
       
  2629 
       
  2630   return MNG_NOERROR;                  /* done */
       
  2631 }
       
  2632 #endif
       
  2633 #endif
       
  2634 
       
  2635 /* ************************************************************************** */
       
  2636 
       
  2637 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2638 #ifndef MNG_SKIPCHUNK_zTXt
       
  2639 READ_CHUNK (mng_read_ztxt)
       
  2640 {
       
  2641   mng_retcode iRetcode;
       
  2642   mng_uint32  iKeywordlen, iTextlen;
       
  2643   mng_pchar   zKeyword;
       
  2644   mng_uint8p  pTemp;
       
  2645   mng_uint32  iCompressedsize;
       
  2646   mng_uint32  iBufsize;
       
  2647   mng_uint8p  pBuf;
       
  2648 
       
  2649 #ifdef MNG_SUPPORT_TRACE
       
  2650   MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_START);
       
  2651 #endif
       
  2652                                        /* sequence checks */
       
  2653 #ifdef MNG_INCLUDE_JNG
       
  2654   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2655       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  2656 #else
       
  2657   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2658       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  2659 #endif
       
  2660     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2661 
       
  2662   if (iRawlen < 3)                     /* length must be at least 3 */
       
  2663     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2664 
       
  2665   pTemp = find_null (pRawdata);        /* find the null separator */
       
  2666                                        /* not found inside input-data ? */
       
  2667   if ((pTemp - pRawdata) > (mng_int32)iRawlen)
       
  2668     MNG_ERROR (pData, MNG_NULLNOTFOUND);
       
  2669 
       
  2670   if (pTemp == pRawdata)               /* there must be at least 1 char for keyword */
       
  2671     MNG_ERROR (pData, MNG_KEYWORDNULL);
       
  2672 
       
  2673   if (*(pTemp+1) != 0)                 /* only deflate compression-method allowed */
       
  2674     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  2675 
       
  2676   iKeywordlen     = (mng_uint32)(pTemp - pRawdata);
       
  2677   iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - 2);
       
  2678 
       
  2679   zKeyword        = 0;                 /* there's no keyword buffer yet */
       
  2680   pBuf            = 0;                 /* or a temporary buffer ! */
       
  2681 
       
  2682   if (pData->fProcesstext)             /* inform the application ? */
       
  2683   {                                    /* decompress the text */
       
  2684     iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
       
  2685                                    &pBuf, &iBufsize, &iTextlen);
       
  2686 
       
  2687     if (iRetcode)                      /* on error bail out */
       
  2688     {                                  /* don't forget to drop the temp buffers */
       
  2689       MNG_FREEX (pData, pBuf, iBufsize);
       
  2690       return iRetcode;
       
  2691     }
       
  2692 
       
  2693     MNG_ALLOCX (pData, zKeyword, iKeywordlen+1);
       
  2694 
       
  2695     if (!zKeyword)                     /* on error bail out */
       
  2696     {                                  /* don't forget to drop the temp buffers */
       
  2697       MNG_FREEX (pData, pBuf, iBufsize);
       
  2698       MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2699     }
       
  2700 
       
  2701     MNG_COPY (zKeyword, pRawdata, iKeywordlen);
       
  2702 
       
  2703     if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ZTXT, zKeyword, (mng_pchar)pBuf, 0, 0))
       
  2704     {                                  /* don't forget to drop the temp buffers */
       
  2705       MNG_FREEX (pData, pBuf, iBufsize);
       
  2706       MNG_FREEX (pData, zKeyword, iKeywordlen+1);
       
  2707       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  2708     }
       
  2709   }
       
  2710 
       
  2711 #ifdef MNG_STORE_CHUNKS
       
  2712   if (pData->bStorechunks)
       
  2713   {                                    /* initialize storage */
       
  2714     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  2715 
       
  2716     if (iRetcode)                      /* on error bail out */
       
  2717     {                                  /* don't forget to drop the temp buffers */
       
  2718       MNG_FREEX (pData, pBuf, iBufsize);
       
  2719       MNG_FREEX (pData, zKeyword, iKeywordlen+1);
       
  2720       return iRetcode;
       
  2721     }
       
  2722                                        /* store the fields */
       
  2723     ((mng_ztxtp)*ppChunk)->iKeywordsize = iKeywordlen;
       
  2724     ((mng_ztxtp)*ppChunk)->iCompression = *(pTemp+1);
       
  2725 
       
  2726     if ((!pBuf) && (iCompressedsize))  /* did we not get a text-buffer yet ? */
       
  2727     {                                  /* decompress the text */
       
  2728       iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
       
  2729                                      &pBuf, &iBufsize, &iTextlen);
       
  2730 
       
  2731       if (iRetcode)                    /* on error bail out */
       
  2732       {                                /* don't forget to drop the temp buffers */
       
  2733         MNG_FREEX (pData, pBuf, iBufsize);
       
  2734         MNG_FREEX (pData, zKeyword, iKeywordlen+1);
       
  2735         return iRetcode;
       
  2736       }
       
  2737     }
       
  2738 
       
  2739     MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zKeyword, iKeywordlen + 1);
       
  2740                                        /* on error bail out */
       
  2741     if (!((mng_ztxtp)*ppChunk)->zKeyword)
       
  2742     {                                  /* don't forget to drop the temp buffers */
       
  2743       MNG_FREEX (pData, pBuf, iBufsize);
       
  2744       MNG_FREEX (pData, zKeyword, iKeywordlen+1);
       
  2745       MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2746     }
       
  2747 
       
  2748     MNG_COPY (((mng_ztxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
       
  2749 
       
  2750     ((mng_ztxtp)*ppChunk)->iTextsize = iTextlen;
       
  2751 
       
  2752     if (iCompressedsize)
       
  2753     {
       
  2754       MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zText, iTextlen + 1);
       
  2755                                        /* on error bail out */
       
  2756       if (!((mng_ztxtp)*ppChunk)->zText)
       
  2757       {                                /* don't forget to drop the temp buffers */
       
  2758         MNG_FREEX (pData, pBuf, iBufsize);
       
  2759         MNG_FREEX (pData, zKeyword, iKeywordlen+1);
       
  2760         MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2761       }
       
  2762 
       
  2763       MNG_COPY (((mng_ztxtp)*ppChunk)->zText, pBuf, iTextlen);
       
  2764     }
       
  2765   }
       
  2766 #endif /* MNG_STORE_CHUNKS */
       
  2767 
       
  2768   MNG_FREEX (pData, pBuf, iBufsize);   /* free the temporary buffers */
       
  2769   MNG_FREEX (pData, zKeyword, iKeywordlen+1);
       
  2770 
       
  2771 #ifdef MNG_SUPPORT_TRACE
       
  2772   MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_END);
       
  2773 #endif
       
  2774 
       
  2775   return MNG_NOERROR;                  /* done */
       
  2776 }
       
  2777 #endif
       
  2778 #endif
       
  2779 
       
  2780 /* ************************************************************************** */
       
  2781 
       
  2782 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2783 #ifndef MNG_SKIPCHUNK_iTXt
       
  2784 READ_CHUNK (mng_read_itxt)
       
  2785 {
       
  2786   mng_retcode iRetcode;
       
  2787   mng_uint32  iKeywordlen, iTextlen, iLanguagelen, iTranslationlen;
       
  2788   mng_pchar   zKeyword, zLanguage, zTranslation;
       
  2789   mng_uint8p  pNull1, pNull2, pNull3;
       
  2790   mng_uint32  iCompressedsize;
       
  2791   mng_uint8   iCompressionflag;
       
  2792   mng_uint32  iBufsize;
       
  2793   mng_uint8p  pBuf;
       
  2794 
       
  2795 #ifdef MNG_SUPPORT_TRACE
       
  2796   MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_START);
       
  2797 #endif
       
  2798                                        /* sequence checks */
       
  2799 #ifdef MNG_INCLUDE_JNG
       
  2800   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2801       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  2802 #else
       
  2803   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  2804       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  2805 #endif
       
  2806     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  2807 
       
  2808   if (iRawlen < 6)                     /* length must be at least 6 */
       
  2809     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  2810 
       
  2811   pNull1 = find_null (pRawdata);       /* find the null separators */
       
  2812   pNull2 = find_null (pNull1+3);
       
  2813   pNull3 = find_null (pNull2+1);
       
  2814                                        /* not found inside input-data ? */
       
  2815   if (((pNull1 - pRawdata) > (mng_int32)iRawlen) ||
       
  2816       ((pNull2 - pRawdata) > (mng_int32)iRawlen) ||
       
  2817       ((pNull3 - pRawdata) > (mng_int32)iRawlen)    )
       
  2818     MNG_ERROR (pData, MNG_NULLNOTFOUND);
       
  2819 
       
  2820   if (pNull1 == pRawdata)              /* there must be at least 1 char for keyword */
       
  2821     MNG_ERROR (pData, MNG_KEYWORDNULL);
       
  2822                                        /* compression or not ? */
       
  2823   if ((*(pNull1+1) != 0) && (*(pNull1+1) != 1))
       
  2824     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  2825 
       
  2826   if (*(pNull1+2) != 0)                /* only deflate compression-method allowed */
       
  2827     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  2828 
       
  2829   iKeywordlen      = (mng_uint32)(pNull1 - pRawdata);
       
  2830   iLanguagelen     = (mng_uint32)(pNull2 - pNull1 - 3);
       
  2831   iTranslationlen  = (mng_uint32)(pNull3 - pNull2 - 1);
       
  2832   iCompressedsize  = (mng_uint32)(iRawlen - iKeywordlen - iLanguagelen - iTranslationlen - 5);
       
  2833   iCompressionflag = *(pNull1+1);
       
  2834 
       
  2835   zKeyword     = 0;                    /* no buffers acquired yet */
       
  2836   zLanguage    = 0;
       
  2837   zTranslation = 0;
       
  2838   pBuf         = 0;
       
  2839   iTextlen     = 0;
       
  2840 
       
  2841   if (pData->fProcesstext)             /* inform the application ? */
       
  2842   {
       
  2843     if (iCompressionflag)              /* decompress the text ? */
       
  2844     {
       
  2845       iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize,
       
  2846                                      &pBuf, &iBufsize, &iTextlen);
       
  2847 
       
  2848       if (iRetcode)                    /* on error bail out */
       
  2849       {                                /* don't forget to drop the temp buffer */
       
  2850         MNG_FREEX (pData, pBuf, iBufsize);
       
  2851         return iRetcode;
       
  2852       }
       
  2853     }
       
  2854     else
       
  2855     {
       
  2856       iTextlen = iCompressedsize;
       
  2857       iBufsize = iTextlen+1;           /* plus 1 for terminator byte!!! */
       
  2858 
       
  2859       MNG_ALLOC (pData, pBuf, iBufsize);
       
  2860       MNG_COPY  (pBuf, pNull3+1, iTextlen);
       
  2861     }
       
  2862 
       
  2863     MNG_ALLOCX (pData, zKeyword,     iKeywordlen     + 1);
       
  2864     MNG_ALLOCX (pData, zLanguage,    iLanguagelen    + 1);
       
  2865     MNG_ALLOCX (pData, zTranslation, iTranslationlen + 1);
       
  2866                                        /* on error bail out */
       
  2867     if ((!zKeyword) || (!zLanguage) || (!zTranslation))
       
  2868     {                                  /* don't forget to drop the temp buffers */
       
  2869       MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2870       MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2871       MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2872       MNG_FREEX (pData, pBuf, iBufsize);
       
  2873       MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2874     }
       
  2875 
       
  2876     MNG_COPY (zKeyword,     pRawdata, iKeywordlen);
       
  2877     MNG_COPY (zLanguage,    pNull1+3, iLanguagelen);
       
  2878     MNG_COPY (zTranslation, pNull2+1, iTranslationlen);
       
  2879 
       
  2880     if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ITXT, zKeyword, (mng_pchar)pBuf,
       
  2881                                                                 zLanguage, zTranslation))
       
  2882     {                                  /* don't forget to drop the temp buffers */
       
  2883       MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2884       MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2885       MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2886       MNG_FREEX (pData, pBuf,         iBufsize);
       
  2887 
       
  2888       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  2889     }
       
  2890   }
       
  2891 
       
  2892 #ifdef MNG_STORE_CHUNKS
       
  2893   if (pData->bStorechunks)
       
  2894   {                                    /* initialize storage */
       
  2895     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  2896 
       
  2897     if (iRetcode)                      /* on error bail out */
       
  2898     {                                  /* don't forget to drop the temp buffers */
       
  2899       MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2900       MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2901       MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2902       MNG_FREEX (pData, pBuf,         iBufsize);
       
  2903       return iRetcode;
       
  2904     }
       
  2905                                        /* store the fields */
       
  2906     ((mng_itxtp)*ppChunk)->iKeywordsize       = iKeywordlen;
       
  2907     ((mng_itxtp)*ppChunk)->iLanguagesize      = iLanguagelen;
       
  2908     ((mng_itxtp)*ppChunk)->iTranslationsize   = iTranslationlen;
       
  2909     ((mng_itxtp)*ppChunk)->iCompressionflag   = *(pNull1+1);
       
  2910     ((mng_itxtp)*ppChunk)->iCompressionmethod = *(pNull1+2);
       
  2911 
       
  2912     if ((!pBuf) && (iCompressedsize))  /* did we not get a text-buffer yet ? */
       
  2913     {
       
  2914       if (iCompressionflag)            /* decompress the text ? */
       
  2915       {
       
  2916         iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize,
       
  2917                                        &pBuf, &iBufsize, &iTextlen);
       
  2918 
       
  2919         if (iRetcode)                  /* on error bail out */
       
  2920         {                              /* don't forget to drop the temp buffers */
       
  2921           MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2922           MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2923           MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2924           MNG_FREEX (pData, pBuf,         iBufsize);
       
  2925           return iRetcode;
       
  2926         }
       
  2927       }
       
  2928       else
       
  2929       {
       
  2930         iTextlen = iCompressedsize;
       
  2931         iBufsize = iTextlen+1;         /* plus 1 for terminator byte!!! */
       
  2932 
       
  2933         MNG_ALLOC (pData, pBuf, iBufsize);
       
  2934         MNG_COPY  (pBuf, pNull3+1, iTextlen);
       
  2935       }
       
  2936     }
       
  2937 
       
  2938     MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zKeyword,     iKeywordlen     + 1);
       
  2939     MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zLanguage,    iLanguagelen    + 1);
       
  2940     MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zTranslation, iTranslationlen + 1);
       
  2941                                        /* on error bail out */
       
  2942     if ((!((mng_itxtp)*ppChunk)->zKeyword    ) ||
       
  2943         (!((mng_itxtp)*ppChunk)->zLanguage   ) ||
       
  2944         (!((mng_itxtp)*ppChunk)->zTranslation)    )
       
  2945     {                                  /* don't forget to drop the temp buffers */
       
  2946       MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2947       MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2948       MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2949       MNG_FREEX (pData, pBuf,         iBufsize);
       
  2950       MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2951     }
       
  2952 
       
  2953     MNG_COPY (((mng_itxtp)*ppChunk)->zKeyword,     pRawdata, iKeywordlen);
       
  2954     MNG_COPY (((mng_itxtp)*ppChunk)->zLanguage,    pNull1+3, iLanguagelen);
       
  2955     MNG_COPY (((mng_itxtp)*ppChunk)->zTranslation, pNull2+1, iTranslationlen);
       
  2956 
       
  2957     ((mng_itxtp)*ppChunk)->iTextsize = iTextlen;
       
  2958 
       
  2959     if (iTextlen)
       
  2960     {
       
  2961       MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zText, iTextlen + 1);
       
  2962 
       
  2963       if (!((mng_itxtp)*ppChunk)->zText)
       
  2964       {                                /* don't forget to drop the temp buffers */
       
  2965         MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2966         MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2967         MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2968         MNG_FREEX (pData, pBuf,         iBufsize);
       
  2969         MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  2970       }
       
  2971 
       
  2972       MNG_COPY  (((mng_itxtp)*ppChunk)->zText, pBuf, iTextlen);
       
  2973     }
       
  2974   }
       
  2975 #endif /* MNG_STORE_CHUNKS */
       
  2976                                        /* free the temporary buffers */
       
  2977   MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
       
  2978   MNG_FREEX (pData, zLanguage,    iLanguagelen    + 1);
       
  2979   MNG_FREEX (pData, zKeyword,     iKeywordlen     + 1);
       
  2980   MNG_FREEX (pData, pBuf,         iBufsize);
       
  2981 
       
  2982 #ifdef MNG_SUPPORT_TRACE
       
  2983   MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_END);
       
  2984 #endif
       
  2985 
       
  2986   return MNG_NOERROR;                  /* done */
       
  2987 }
       
  2988 #endif
       
  2989 #endif
       
  2990 
       
  2991 /* ************************************************************************** */
       
  2992 
       
  2993 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  2994 #ifndef MNG_SKIPCHUNK_bKGD
       
  2995 READ_CHUNK (mng_read_bkgd)
       
  2996 {
       
  2997 #ifdef MNG_SUPPORT_DISPLAY
       
  2998   mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
       
  2999   mng_imagedatap pBuf;
       
  3000 #endif
       
  3001 
       
  3002 #ifdef MNG_SUPPORT_TRACE
       
  3003   MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_START);
       
  3004 #endif
       
  3005                                        /* sequence checks */
       
  3006 #ifdef MNG_INCLUDE_JNG
       
  3007   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3008       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  3009 #else
       
  3010   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3011       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  3012 #endif
       
  3013     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3014 
       
  3015 #ifdef MNG_INCLUDE_JNG
       
  3016   if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  3017 #else
       
  3018   if (pData->bHasIDAT)
       
  3019 #endif
       
  3020     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3021 
       
  3022   if (iRawlen > 6)                     /* it just can't be bigger than that! */
       
  3023     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3024 
       
  3025 #ifdef MNG_INCLUDE_JNG                 /* length checks */
       
  3026   if (pData->bHasJHDR)
       
  3027   {
       
  3028     if (((pData->iJHDRcolortype == 8) || (pData->iJHDRcolortype == 12)) && (iRawlen != 2))
       
  3029       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3030 
       
  3031     if (((pData->iJHDRcolortype == 10) || (pData->iJHDRcolortype == 14)) && (iRawlen != 6))
       
  3032       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3033   }
       
  3034   else
       
  3035 #endif /* MNG_INCLUDE_JNG */
       
  3036   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  3037   {
       
  3038     if (((pData->iColortype == 0) || (pData->iColortype == 4)) && (iRawlen != 2))
       
  3039       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3040 
       
  3041     if (((pData->iColortype == 2) || (pData->iColortype == 6)) && (iRawlen != 6))
       
  3042       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3043 
       
  3044     if ((pData->iColortype == 3) && (iRawlen != 1))
       
  3045       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3046   }
       
  3047   else
       
  3048   {
       
  3049     if (iRawlen != 6)                  /* global is always 16-bit RGB ! */
       
  3050       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3051   }
       
  3052 
       
  3053 #ifdef MNG_INCLUDE_JNG
       
  3054   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  3055 #else
       
  3056   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  3057 #endif
       
  3058     pData->bHasBKGD = MNG_TRUE;        /* indicate bKGD available */
       
  3059   else
       
  3060     pData->bHasglobalBKGD = (mng_bool)(iRawlen != 0);
       
  3061 
       
  3062 #ifdef MNG_SUPPORT_DISPLAY
       
  3063   if (!pImage)                         /* if no object dump it in obj 0 */
       
  3064     pImage = (mng_imagep)pData->pObjzero;
       
  3065 
       
  3066   pBuf = pImage->pImgbuf;              /* address object buffer */
       
  3067 
       
  3068 #ifdef MNG_INCLUDE_JNG
       
  3069   if (pData->bHasJHDR)
       
  3070   {
       
  3071     pBuf->bHasBKGD = MNG_TRUE;         /* tell the object it's got bKGD now */
       
  3072 
       
  3073     switch (pData->iJHDRcolortype)     /* store fields for future reference */
       
  3074     {
       
  3075       case  8 : ;                      /* gray */
       
  3076       case 12 : {                      /* graya */
       
  3077                   pBuf->iBKGDgray  = mng_get_uint16 (pRawdata);
       
  3078                   break;
       
  3079                 }
       
  3080       case 10 : ;                      /* rgb */
       
  3081       case 14 : {                      /* rgba */
       
  3082                   pBuf->iBKGDred   = mng_get_uint16 (pRawdata);
       
  3083                   pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
       
  3084                   pBuf->iBKGDblue  = mng_get_uint16 (pRawdata+4);
       
  3085                   break;
       
  3086                 }
       
  3087     }
       
  3088   }
       
  3089   else
       
  3090 #endif /* MNG_INCLUDE_JNG */
       
  3091   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  3092   {
       
  3093     pBuf->bHasBKGD = MNG_TRUE;         /* tell the object it's got bKGD now */
       
  3094 
       
  3095     switch (pData->iColortype)         /* store fields for future reference */
       
  3096     {
       
  3097       case 0 : ;                        /* gray */
       
  3098       case 4 : {                        /* graya */
       
  3099                  pBuf->iBKGDgray  = mng_get_uint16 (pRawdata);
       
  3100                  break;
       
  3101                }
       
  3102       case 2 : ;                        /* rgb */
       
  3103       case 6 : {                        /* rgba */
       
  3104                  pBuf->iBKGDred   = mng_get_uint16 (pRawdata);
       
  3105                  pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
       
  3106                  pBuf->iBKGDblue  = mng_get_uint16 (pRawdata+4);
       
  3107                  break;
       
  3108                }
       
  3109       case 3 : {                        /* indexed */
       
  3110                  pBuf->iBKGDindex = *pRawdata;
       
  3111                  break;
       
  3112                }
       
  3113     }
       
  3114   }
       
  3115   else                                 /* store as global */
       
  3116   {
       
  3117     if (iRawlen)
       
  3118     {
       
  3119       pData->iGlobalBKGDred   = mng_get_uint16 (pRawdata);
       
  3120       pData->iGlobalBKGDgreen = mng_get_uint16 (pRawdata+2);
       
  3121       pData->iGlobalBKGDblue  = mng_get_uint16 (pRawdata+4);
       
  3122     }
       
  3123 
       
  3124     {                                  /* create an animation object */
       
  3125       mng_retcode iRetcode = mng_create_ani_bkgd (pData, pData->iGlobalBKGDred,
       
  3126                                                   pData->iGlobalBKGDgreen,
       
  3127                                                   pData->iGlobalBKGDblue);
       
  3128 
       
  3129       if (iRetcode)                    /* on error bail out */
       
  3130         return iRetcode;
       
  3131     }
       
  3132   }
       
  3133 #endif /* MNG_SUPPORT_DISPLAY */
       
  3134 
       
  3135 #ifdef MNG_STORE_CHUNKS
       
  3136   if (pData->bStorechunks)
       
  3137   {                                    /* initialize storage */
       
  3138     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3139 
       
  3140     if (iRetcode)                      /* on error bail out */
       
  3141       return iRetcode;
       
  3142                                        /* store the fields */
       
  3143     ((mng_bkgdp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  3144     ((mng_bkgdp)*ppChunk)->iType  = pData->iColortype;
       
  3145 
       
  3146     if (iRawlen)
       
  3147     {
       
  3148       switch (iRawlen)                 /* guess from length */
       
  3149       {
       
  3150         case 1 : {                     /* indexed */
       
  3151                    ((mng_bkgdp)*ppChunk)->iType  = 3;
       
  3152                    ((mng_bkgdp)*ppChunk)->iIndex = *pRawdata;
       
  3153                    break;
       
  3154                  }
       
  3155         case 2 : {                     /* gray */
       
  3156                    ((mng_bkgdp)*ppChunk)->iType  = 0;
       
  3157                    ((mng_bkgdp)*ppChunk)->iGray  = mng_get_uint16 (pRawdata);
       
  3158                    break;
       
  3159                  }
       
  3160         case 6 : {                     /* rgb */
       
  3161                    ((mng_bkgdp)*ppChunk)->iType  = 2;
       
  3162                    ((mng_bkgdp)*ppChunk)->iRed   = mng_get_uint16 (pRawdata);
       
  3163                    ((mng_bkgdp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
       
  3164                    ((mng_bkgdp)*ppChunk)->iBlue  = mng_get_uint16 (pRawdata+4);
       
  3165                    break;
       
  3166                  }
       
  3167       }
       
  3168     }
       
  3169   }
       
  3170 #endif /* MNG_STORE_CHUNKS */
       
  3171 
       
  3172 #ifdef MNG_SUPPORT_TRACE
       
  3173   MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_END);
       
  3174 #endif
       
  3175 
       
  3176   return MNG_NOERROR;                  /* done */
       
  3177 }
       
  3178 #endif
       
  3179 #endif
       
  3180 
       
  3181 /* ************************************************************************** */
       
  3182 
       
  3183 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3184 #ifndef MNG_SKIPCHUNK_pHYs
       
  3185 READ_CHUNK (mng_read_phys)
       
  3186 {
       
  3187 #ifdef MNG_SUPPORT_TRACE
       
  3188   MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_START);
       
  3189 #endif
       
  3190                                        /* sequence checks */
       
  3191 #ifdef MNG_INCLUDE_JNG
       
  3192   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3193       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  3194 #else
       
  3195   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3196       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  3197 #endif
       
  3198     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3199 
       
  3200 #ifdef MNG_INCLUDE_JNG
       
  3201   if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  3202 #else
       
  3203   if (pData->bHasIDAT)
       
  3204 #endif
       
  3205     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3206                                        /* it's 9 bytes or empty; no more, no less! */
       
  3207   if ((iRawlen != 9) && (iRawlen != 0))
       
  3208     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3209 
       
  3210 #ifdef MNG_SUPPORT_DISPLAY
       
  3211   {
       
  3212 
       
  3213 
       
  3214     /* TODO: something !!! */
       
  3215 
       
  3216 
       
  3217   }
       
  3218 #endif /* MNG_SUPPORT_DISPLAY */
       
  3219 
       
  3220 #ifdef MNG_STORE_CHUNKS
       
  3221   if (pData->bStorechunks)
       
  3222   {                                    /* initialize storage */
       
  3223     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3224 
       
  3225     if (iRetcode)                      /* on error bail out */
       
  3226       return iRetcode;
       
  3227                                        /* store the fields */
       
  3228     ((mng_physp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  3229 
       
  3230     if (iRawlen)
       
  3231     {
       
  3232       ((mng_physp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
       
  3233       ((mng_physp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
       
  3234       ((mng_physp)*ppChunk)->iUnit  = *(pRawdata+8);
       
  3235     }
       
  3236   }
       
  3237 #endif /* MNG_STORE_CHUNKS */
       
  3238 
       
  3239 #ifdef MNG_SUPPORT_TRACE
       
  3240   MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_END);
       
  3241 #endif
       
  3242 
       
  3243   return MNG_NOERROR;                  /* done */
       
  3244 }
       
  3245 #endif
       
  3246 #endif
       
  3247 
       
  3248 /* ************************************************************************** */
       
  3249 
       
  3250 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3251 #ifndef MNG_SKIPCHUNK_sBIT
       
  3252 READ_CHUNK (mng_read_sbit)
       
  3253 {
       
  3254 #ifdef MNG_SUPPORT_TRACE
       
  3255   MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_START);
       
  3256 #endif
       
  3257                                        /* sequence checks */
       
  3258 #ifdef MNG_INCLUDE_JNG
       
  3259   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3260       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  3261 #else
       
  3262   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3263       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  3264 #endif
       
  3265     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3266 
       
  3267 #ifdef MNG_INCLUDE_JNG
       
  3268   if ((pData->bHasPLTE) || (pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
       
  3269 #else
       
  3270   if ((pData->bHasPLTE) || (pData->bHasIDAT))
       
  3271 #endif
       
  3272     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3273 
       
  3274   if (iRawlen > 4)                     /* it just can't be bigger than that! */
       
  3275     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3276 
       
  3277 #ifdef MNG_INCLUDE_JNG                 /* length checks */
       
  3278   if (pData->bHasJHDR)
       
  3279   {
       
  3280     if ((pData->iJHDRcolortype ==  8) && (iRawlen != 1))
       
  3281       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3282 
       
  3283     if ((pData->iJHDRcolortype == 10) && (iRawlen != 3))
       
  3284       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3285 
       
  3286     if ((pData->iJHDRcolortype == 12) && (iRawlen != 2))
       
  3287       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3288 
       
  3289     if ((pData->iJHDRcolortype == 14) && (iRawlen != 4))
       
  3290       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3291   }
       
  3292   else
       
  3293 #endif /* MNG_INCLUDE_JNG */
       
  3294   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  3295   {
       
  3296     if ((pData->iColortype == 0) && (iRawlen != 1))
       
  3297       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3298 
       
  3299     if ((pData->iColortype == 2) && (iRawlen != 3))
       
  3300       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3301 
       
  3302     if ((pData->iColortype == 3) && (iRawlen != 3))
       
  3303       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3304 
       
  3305     if ((pData->iColortype == 4) && (iRawlen != 2))
       
  3306       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3307 
       
  3308     if ((pData->iColortype == 6) && (iRawlen != 4))
       
  3309       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3310   }
       
  3311   else
       
  3312   {                                    /* global = empty or RGBA */
       
  3313     if ((iRawlen != 0) && (iRawlen != 4))
       
  3314       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3315   }
       
  3316 
       
  3317 #ifdef MNG_SUPPORT_DISPLAY
       
  3318   {
       
  3319 
       
  3320 
       
  3321     /* TODO: something !!! */
       
  3322 
       
  3323 
       
  3324   }
       
  3325 #endif /* MNG_SUPPORT_DISPLAY */
       
  3326 
       
  3327 #ifdef MNG_STORE_CHUNKS
       
  3328   if (pData->bStorechunks)
       
  3329   {                                    /* initialize storage */
       
  3330     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3331 
       
  3332     if (iRetcode)                      /* on error bail out */
       
  3333       return iRetcode;
       
  3334                                        /* store the fields */
       
  3335     ((mng_sbitp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  3336 
       
  3337     if (iRawlen)
       
  3338     {
       
  3339 #ifdef MNG_INCLUDE_JNG
       
  3340       if (pData->bHasJHDR)
       
  3341         ((mng_sbitp)*ppChunk)->iType = pData->iJHDRcolortype;
       
  3342       else
       
  3343 #endif
       
  3344       if (pData->bHasIHDR)
       
  3345         ((mng_sbitp)*ppChunk)->iType = pData->iColortype;
       
  3346       else                             /* global ! */
       
  3347         ((mng_sbitp)*ppChunk)->iType = 6;
       
  3348 
       
  3349       if (iRawlen > 0)
       
  3350         ((mng_sbitp)*ppChunk)->aBits [0] = *pRawdata;
       
  3351       if (iRawlen > 1)
       
  3352         ((mng_sbitp)*ppChunk)->aBits [1] = *(pRawdata+1);
       
  3353       if (iRawlen > 2)
       
  3354         ((mng_sbitp)*ppChunk)->aBits [2] = *(pRawdata+2);
       
  3355       if (iRawlen > 3)
       
  3356         ((mng_sbitp)*ppChunk)->aBits [3] = *(pRawdata+3);
       
  3357 
       
  3358     }
       
  3359   }
       
  3360 #endif /* MNG_STORE_CHUNKS */
       
  3361 
       
  3362 #ifdef MNG_SUPPORT_TRACE
       
  3363   MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_END);
       
  3364 #endif
       
  3365 
       
  3366   return MNG_NOERROR;                  /* done */
       
  3367 }
       
  3368 #endif
       
  3369 #endif
       
  3370 
       
  3371 /* ************************************************************************** */
       
  3372 
       
  3373 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3374 #ifndef MNG_SKIPCHUNK_sPLT
       
  3375 READ_CHUNK (mng_read_splt)
       
  3376 {
       
  3377   mng_uint8p pTemp;
       
  3378   mng_uint32 iNamelen;
       
  3379   mng_uint8  iSampledepth;
       
  3380   mng_uint32 iRemain;
       
  3381 
       
  3382 #ifdef MNG_SUPPORT_TRACE
       
  3383   MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_START);
       
  3384 #endif
       
  3385                                        /* sequence checks */
       
  3386   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3387       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  3388     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3389 
       
  3390   if (pData->bHasIDAT)
       
  3391     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3392 
       
  3393   if (iRawlen)
       
  3394   {
       
  3395     pTemp = find_null (pRawdata);      /* find null-separator */
       
  3396                                        /* not found inside input-data ? */
       
  3397     if ((pTemp - pRawdata) > (mng_int32)iRawlen)
       
  3398       MNG_ERROR (pData, MNG_NULLNOTFOUND);
       
  3399 
       
  3400     iNamelen     = (mng_uint32)(pTemp - pRawdata);
       
  3401     iSampledepth = *(pTemp+1);
       
  3402     iRemain      = (iRawlen - 2 - iNamelen);
       
  3403 
       
  3404     if ((iSampledepth != 1) && (iSampledepth != 2))
       
  3405       MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
       
  3406                                        /* check remaining length */
       
  3407     if ( ((iSampledepth == 1) && (iRemain %  6 != 0)) ||
       
  3408          ((iSampledepth == 2) && (iRemain % 10 != 0))    )
       
  3409       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3410 
       
  3411   }
       
  3412   else
       
  3413   {
       
  3414     pTemp        = MNG_NULL;
       
  3415     iNamelen     = 0;
       
  3416     iSampledepth = 0;
       
  3417     iRemain      = 0;
       
  3418   }
       
  3419 
       
  3420 #ifdef MNG_SUPPORT_DISPLAY
       
  3421   {
       
  3422 
       
  3423 
       
  3424     /* TODO: something !!! */
       
  3425 
       
  3426 
       
  3427   }
       
  3428 #endif /* MNG_SUPPORT_DISPLAY */
       
  3429 
       
  3430 #ifdef MNG_STORE_CHUNKS
       
  3431   if (pData->bStorechunks)
       
  3432   {                                    /* initialize storage */
       
  3433     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3434 
       
  3435     if (iRetcode)                      /* on error bail out */
       
  3436       return iRetcode;
       
  3437                                        /* store the fields */
       
  3438     ((mng_spltp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  3439 
       
  3440     if (iRawlen)
       
  3441     {
       
  3442       ((mng_spltp)*ppChunk)->iNamesize    = iNamelen;
       
  3443       ((mng_spltp)*ppChunk)->iSampledepth = iSampledepth;
       
  3444 
       
  3445       if (iSampledepth == 1)
       
  3446         ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 6;
       
  3447       else
       
  3448         ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 10;
       
  3449 
       
  3450       if (iNamelen)
       
  3451       {
       
  3452         MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->zName, iNamelen+1);
       
  3453         MNG_COPY (((mng_spltp)*ppChunk)->zName, pRawdata, iNamelen);
       
  3454       }
       
  3455 
       
  3456       if (iRemain)
       
  3457       {
       
  3458         MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->pEntries, iRemain);
       
  3459         MNG_COPY (((mng_spltp)*ppChunk)->pEntries, pTemp+2, iRemain);
       
  3460       }
       
  3461     }
       
  3462   }
       
  3463 #endif /* MNG_STORE_CHUNKS */
       
  3464 
       
  3465 #ifdef MNG_SUPPORT_TRACE
       
  3466   MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_END);
       
  3467 #endif
       
  3468 
       
  3469   return MNG_NOERROR;                  /* done */
       
  3470 }
       
  3471 #endif
       
  3472 #endif
       
  3473 
       
  3474 /* ************************************************************************** */
       
  3475 
       
  3476 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3477 #ifndef MNG_SKIPCHUNK_hIST
       
  3478 READ_CHUNK (mng_read_hist)
       
  3479 {
       
  3480 #ifdef MNG_SUPPORT_TRACE
       
  3481   MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_START);
       
  3482 #endif
       
  3483                                        /* sequence checks */
       
  3484   if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  3485     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3486 
       
  3487   if ((!pData->bHasPLTE) || (pData->bHasIDAT))
       
  3488     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3489                                        /* length oke ? */
       
  3490   if ( ((iRawlen & 0x01) != 0) || ((iRawlen >> 1) != pData->iPLTEcount) )
       
  3491     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3492 
       
  3493 #ifdef MNG_SUPPORT_DISPLAY
       
  3494   {
       
  3495 
       
  3496 
       
  3497     /* TODO: something !!! */
       
  3498 
       
  3499 
       
  3500   }
       
  3501 #endif /* MNG_SUPPORT_DISPLAY */
       
  3502 
       
  3503 #ifdef MNG_STORE_CHUNKS
       
  3504   if (pData->bStorechunks)
       
  3505   {
       
  3506     mng_uint32 iX;
       
  3507                                        /* initialize storage */
       
  3508     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3509 
       
  3510     if (iRetcode)                      /* on error bail out */
       
  3511       return iRetcode;
       
  3512                                        /* store the fields */
       
  3513     ((mng_histp)*ppChunk)->iEntrycount = iRawlen >> 1;
       
  3514 
       
  3515     for (iX = 0; iX < (iRawlen >> 1); iX++)
       
  3516     {
       
  3517       ((mng_histp)*ppChunk)->aEntries [iX] = mng_get_uint16 (pRawdata);
       
  3518       pRawdata += 2;
       
  3519     }
       
  3520   }
       
  3521 #endif /* MNG_STORE_CHUNKS */
       
  3522 
       
  3523 #ifdef MNG_SUPPORT_TRACE
       
  3524   MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_END);
       
  3525 #endif
       
  3526 
       
  3527   return MNG_NOERROR;                  /* done */
       
  3528 }
       
  3529 #endif
       
  3530 #endif
       
  3531 
       
  3532 /* ************************************************************************** */
       
  3533 
       
  3534 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3535 #ifndef MNG_SKIPCHUNK_tIME
       
  3536 READ_CHUNK (mng_read_time)
       
  3537 {
       
  3538 #ifdef MNG_SUPPORT_TRACE
       
  3539   MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_START);
       
  3540 #endif
       
  3541                                        /* sequence checks */
       
  3542 #ifdef MNG_INCLUDE_JNG
       
  3543   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3544       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  3545 #else
       
  3546   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  3547       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  3548 #endif
       
  3549     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3550 
       
  3551   if (iRawlen != 7)                    /* length must be exactly 7 */
       
  3552     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3553 
       
  3554 /*  if (pData->fProcesstime) */            /* inform the application ? */
       
  3555 /*  {
       
  3556 
       
  3557     pData->fProcesstime ((mng_handle)pData, );
       
  3558   } */
       
  3559 
       
  3560 #ifdef MNG_STORE_CHUNKS
       
  3561   if (pData->bStorechunks)
       
  3562   {                                    /* initialize storage */
       
  3563     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3564 
       
  3565     if (iRetcode)                      /* on error bail out */
       
  3566       return iRetcode;
       
  3567                                        /* store the fields */
       
  3568     ((mng_timep)*ppChunk)->iYear   = mng_get_uint16 (pRawdata);
       
  3569     ((mng_timep)*ppChunk)->iMonth  = *(pRawdata+2);
       
  3570     ((mng_timep)*ppChunk)->iDay    = *(pRawdata+3);
       
  3571     ((mng_timep)*ppChunk)->iHour   = *(pRawdata+4);
       
  3572     ((mng_timep)*ppChunk)->iMinute = *(pRawdata+5);
       
  3573     ((mng_timep)*ppChunk)->iSecond = *(pRawdata+6);
       
  3574   }
       
  3575 #endif /* MNG_STORE_CHUNKS */
       
  3576 
       
  3577 #ifdef MNG_SUPPORT_TRACE
       
  3578   MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_END);
       
  3579 #endif
       
  3580 
       
  3581   return MNG_NOERROR;                  /* done */
       
  3582 }
       
  3583 #endif
       
  3584 #endif
       
  3585 
       
  3586 /* ************************************************************************** */
       
  3587 
       
  3588 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3589 READ_CHUNK (mng_read_mhdr)
       
  3590 {
       
  3591 #ifdef MNG_SUPPORT_TRACE
       
  3592   MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_START);
       
  3593 #endif
       
  3594 
       
  3595   if (pData->eSigtype != mng_it_mng)   /* sequence checks */
       
  3596     MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
       
  3597 
       
  3598   if (pData->bHasheader)               /* can only be the first chunk! */
       
  3599     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3600                                        /* correct length ? */
       
  3601 #ifndef MNG_NO_OLD_VERSIONS
       
  3602   if ((iRawlen != 28) && (iRawlen != 12))
       
  3603 #else
       
  3604   if ((iRawlen != 28))
       
  3605 #endif
       
  3606     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3607 
       
  3608   pData->bHasMHDR       = MNG_TRUE;    /* oh boy, a real MNG */
       
  3609   pData->bHasheader     = MNG_TRUE;    /* we've got a header */
       
  3610   pData->eImagetype     = mng_it_mng;  /* fill header fields */
       
  3611   pData->iWidth         = mng_get_uint32 (pRawdata);
       
  3612   pData->iHeight        = mng_get_uint32 (pRawdata+4);
       
  3613   pData->iTicks         = mng_get_uint32 (pRawdata+8);
       
  3614 
       
  3615 #ifndef MNG_NO_OLD_VERSIONS
       
  3616   if (iRawlen == 28)                   /* proper MHDR ? */
       
  3617   {
       
  3618 #endif
       
  3619     pData->iLayercount  = mng_get_uint32 (pRawdata+12);
       
  3620     pData->iFramecount  = mng_get_uint32 (pRawdata+16);
       
  3621     pData->iPlaytime    = mng_get_uint32 (pRawdata+20);
       
  3622     pData->iSimplicity  = mng_get_uint32 (pRawdata+24);
       
  3623 
       
  3624 #ifndef MNG_NO_OLD_VERSIONS
       
  3625     pData->bPreDraft48  = MNG_FALSE;
       
  3626   }
       
  3627   else                                 /* probably pre-draft48 then */
       
  3628   {
       
  3629     pData->iLayercount  = 0;
       
  3630     pData->iFramecount  = 0;
       
  3631     pData->iPlaytime    = 0;
       
  3632     pData->iSimplicity  = 0;
       
  3633 
       
  3634     pData->bPreDraft48  = MNG_TRUE;
       
  3635   }
       
  3636 #endif
       
  3637                                        /* predict alpha-depth */
       
  3638   if ((pData->iSimplicity & 0x00000001) == 0)
       
  3639 #ifndef MNG_NO_16BIT_SUPPORT
       
  3640     pData->iAlphadepth = 16;           /* no indicators = assume the worst */
       
  3641 #else
       
  3642     pData->iAlphadepth = 8;            /* anything else = assume the worst */
       
  3643 #endif
       
  3644   else
       
  3645   if ((pData->iSimplicity & 0x00000008) == 0)
       
  3646     pData->iAlphadepth = 0;            /* no transparency at all */
       
  3647   else
       
  3648   if ((pData->iSimplicity & 0x00000140) == 0x00000040)
       
  3649     pData->iAlphadepth = 1;            /* no semi-transparency guaranteed */
       
  3650   else
       
  3651 #ifndef MNG_NO_16BIT_SUPPORT
       
  3652     pData->iAlphadepth = 16;           /* anything else = assume the worst */
       
  3653 #else
       
  3654     pData->iAlphadepth = 8;            /* anything else = assume the worst */
       
  3655 #endif
       
  3656 
       
  3657 #ifdef MNG_INCLUDE_JNG                 /* can we handle the complexity ? */
       
  3658   if (pData->iSimplicity & 0x0000FC00)
       
  3659 #else
       
  3660   if (pData->iSimplicity & 0x0000FC10)
       
  3661 #endif
       
  3662     MNG_ERROR (pData, MNG_MNGTOOCOMPLEX);
       
  3663                                        /* fits on maximum canvas ? */
       
  3664   if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
       
  3665     MNG_WARNING (pData, MNG_IMAGETOOLARGE);
       
  3666 
       
  3667   if (pData->fProcessheader)           /* inform the app ? */
       
  3668     if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
       
  3669       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  3670 
       
  3671   pData->iImagelevel++;                /* one level deeper */
       
  3672 
       
  3673 #ifdef MNG_STORE_CHUNKS
       
  3674   if (pData->bStorechunks)
       
  3675   {                                    /* initialize storage */
       
  3676     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3677 
       
  3678     if (iRetcode)                      /* on error bail out */
       
  3679       return iRetcode;
       
  3680                                        /* store the fields */
       
  3681     ((mng_mhdrp)*ppChunk)->iWidth      = pData->iWidth;
       
  3682     ((mng_mhdrp)*ppChunk)->iHeight     = pData->iHeight;
       
  3683     ((mng_mhdrp)*ppChunk)->iTicks      = pData->iTicks;
       
  3684     ((mng_mhdrp)*ppChunk)->iLayercount = pData->iLayercount;
       
  3685     ((mng_mhdrp)*ppChunk)->iFramecount = pData->iFramecount;
       
  3686     ((mng_mhdrp)*ppChunk)->iPlaytime   = pData->iPlaytime;
       
  3687     ((mng_mhdrp)*ppChunk)->iSimplicity = pData->iSimplicity;
       
  3688   }
       
  3689 #endif /* MNG_STORE_CHUNKS */
       
  3690 
       
  3691 #ifdef MNG_SUPPORT_TRACE
       
  3692   MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_END);
       
  3693 #endif
       
  3694 
       
  3695   return MNG_NOERROR;                  /* done */
       
  3696 }
       
  3697 #endif
       
  3698 
       
  3699 /* ************************************************************************** */
       
  3700 
       
  3701 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3702 READ_CHUNK (mng_read_mend)
       
  3703 {
       
  3704 #ifdef MNG_SUPPORT_TRACE
       
  3705   MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_START);
       
  3706 #endif
       
  3707 
       
  3708   if (!pData->bHasMHDR)                /* sequence checks */
       
  3709     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3710 
       
  3711   if (iRawlen > 0)                     /* must not contain data! */
       
  3712     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3713 
       
  3714 #ifdef MNG_SUPPORT_DISPLAY
       
  3715   {                                    /* do something */
       
  3716     mng_retcode iRetcode = mng_process_display_mend (pData);
       
  3717 
       
  3718     if (iRetcode)                      /* on error bail out */
       
  3719       return iRetcode;
       
  3720 
       
  3721     if (!pData->iTotalframes)          /* save totals */
       
  3722       pData->iTotalframes   = pData->iFrameseq;
       
  3723     if (!pData->iTotallayers)
       
  3724       pData->iTotallayers   = pData->iLayerseq;
       
  3725     if (!pData->iTotalplaytime)
       
  3726       pData->iTotalplaytime = pData->iFrametime;
       
  3727   }
       
  3728 #endif /* MNG_SUPPORT_DISPLAY */
       
  3729 
       
  3730   pData->bHasMHDR = MNG_FALSE;         /* end of the line, bro! */
       
  3731 
       
  3732 #ifdef MNG_STORE_CHUNKS
       
  3733   if (pData->bStorechunks)
       
  3734   {                                    /* initialize storage */
       
  3735     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3736 
       
  3737     if (iRetcode)                      /* on error bail out */
       
  3738       return iRetcode;
       
  3739   }
       
  3740 #endif /* MNG_STORE_CHUNKS */
       
  3741 
       
  3742 #ifdef MNG_SUPPORT_TRACE
       
  3743   MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_END);
       
  3744 #endif
       
  3745 
       
  3746   return MNG_NOERROR;                  /* done */
       
  3747 }
       
  3748 #endif
       
  3749 
       
  3750 /* ************************************************************************** */
       
  3751 
       
  3752 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3753 #ifndef MNG_SKIPCHUNK_LOOP
       
  3754 READ_CHUNK (mng_read_loop)
       
  3755 {
       
  3756 #ifdef MNG_SUPPORT_TRACE
       
  3757   MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_START);
       
  3758 #endif
       
  3759 
       
  3760   if (!pData->bHasMHDR)                /* sequence checks */
       
  3761     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3762 
       
  3763   if (!pData->bCacheplayback)          /* must store playback info to work!! */
       
  3764     MNG_ERROR (pData, MNG_LOOPWITHCACHEOFF);
       
  3765 
       
  3766 #ifdef MNG_INCLUDE_JNG
       
  3767   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  3768 #else
       
  3769   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  3770 #endif
       
  3771     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3772 
       
  3773   if (iRawlen >= 5)                    /* length checks */
       
  3774   {
       
  3775     if (iRawlen >= 6)
       
  3776     {
       
  3777       if ((iRawlen - 6) % 4 != 0)
       
  3778         MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3779     }
       
  3780   }
       
  3781   else
       
  3782     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3783 
       
  3784 #ifdef MNG_SUPPORT_DISPLAY
       
  3785   {
       
  3786     mng_uint8   iLevel;
       
  3787     mng_uint32  iRepeat;
       
  3788     mng_uint8   iTermination = 0;
       
  3789     mng_uint32  iItermin     = 1;
       
  3790     mng_uint32  iItermax     = 0x7fffffffL;
       
  3791     mng_retcode iRetcode;
       
  3792 
       
  3793     pData->bHasLOOP = MNG_TRUE;        /* indicate we're inside a loop */
       
  3794 
       
  3795     iLevel = *pRawdata;                /* determine the fields for processing */
       
  3796 
       
  3797 #ifndef MNG_NO_OLD_VERSIONS
       
  3798     if (pData->bPreDraft48)
       
  3799     {
       
  3800       iTermination = *(pRawdata+1);
       
  3801 
       
  3802       iRepeat = mng_get_uint32 (pRawdata+2);
       
  3803     }
       
  3804     else
       
  3805 #endif
       
  3806       iRepeat = mng_get_uint32 (pRawdata+1);
       
  3807 
       
  3808     if (iRawlen >= 6)
       
  3809     {
       
  3810 #ifndef MNG_NO_OLD_VERSIONS
       
  3811       if (!pData->bPreDraft48)
       
  3812 #endif
       
  3813         iTermination = *(pRawdata+5);
       
  3814 
       
  3815       if (iRawlen >= 10)
       
  3816       {
       
  3817         iItermin = mng_get_uint32 (pRawdata+6);
       
  3818 
       
  3819         if (iRawlen >= 14)
       
  3820         {
       
  3821           iItermax = mng_get_uint32 (pRawdata+10);
       
  3822 
       
  3823           /* TODO: process signals */
       
  3824 
       
  3825         }
       
  3826       }
       
  3827     }
       
  3828                                        /* create the LOOP ani-object */
       
  3829     iRetcode = mng_create_ani_loop (pData, iLevel, iRepeat, iTermination,
       
  3830                                            iItermin, iItermax, 0, 0);
       
  3831 
       
  3832     if (iRetcode)                      /* on error bail out */
       
  3833       return iRetcode;
       
  3834                                        /* skip till matching ENDL if iteration=0 */
       
  3835     if ((!pData->bSkipping) && (iRepeat == 0))
       
  3836       pData->bSkipping = MNG_TRUE;
       
  3837   }
       
  3838 #endif /* MNG_SUPPORT_DISPLAY */
       
  3839 
       
  3840 #ifdef MNG_STORE_CHUNKS
       
  3841   if (pData->bStorechunks)
       
  3842   {                                    /* initialize storage */
       
  3843     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3844 
       
  3845     if (iRetcode)                      /* on error bail out */
       
  3846       return iRetcode;
       
  3847 
       
  3848     if (iRawlen >= 5)                  /* store the fields */
       
  3849     {
       
  3850       ((mng_loopp)*ppChunk)->iLevel  = *pRawdata;
       
  3851 
       
  3852 #ifndef MNG_NO_OLD_VERSIONS
       
  3853       if (pData->bPreDraft48)
       
  3854       {
       
  3855         ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+1);
       
  3856         ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+2);
       
  3857       }
       
  3858       else
       
  3859 #endif
       
  3860       {
       
  3861         ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+1);
       
  3862       }
       
  3863 
       
  3864       if (iRawlen >= 6)
       
  3865       {
       
  3866 #ifndef MNG_NO_OLD_VERSIONS
       
  3867         if (!pData->bPreDraft48)
       
  3868 #endif
       
  3869           ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+5);
       
  3870 
       
  3871         if (iRawlen >= 10)
       
  3872         {
       
  3873           ((mng_loopp)*ppChunk)->iItermin = mng_get_uint32 (pRawdata+6);
       
  3874 
       
  3875 #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
       
  3876           if (iRawlen >= 14)
       
  3877           {
       
  3878             ((mng_loopp)*ppChunk)->iItermax = mng_get_uint32 (pRawdata+10);
       
  3879             ((mng_loopp)*ppChunk)->iCount   = (iRawlen - 14) / 4;
       
  3880 
       
  3881             if (((mng_loopp)*ppChunk)->iCount)
       
  3882             {
       
  3883               MNG_ALLOC (pData, ((mng_loopp)*ppChunk)->pSignals,
       
  3884                                 ((mng_loopp)*ppChunk)->iCount << 2);
       
  3885 
       
  3886 #ifndef MNG_BIGENDIAN_SUPPORTED
       
  3887               {
       
  3888                 mng_uint32  iX;
       
  3889                 mng_uint8p  pIn  = pRawdata + 14;
       
  3890                 mng_uint32p pOut = (mng_uint32p)((mng_loopp)*ppChunk)->pSignals;
       
  3891 
       
  3892                 for (iX = 0; iX < ((mng_loopp)*ppChunk)->iCount; iX++)
       
  3893                 {
       
  3894                   *pOut++ = mng_get_uint32 (pIn);
       
  3895                   pIn += 4;
       
  3896                 }
       
  3897               }
       
  3898 #else
       
  3899               MNG_COPY (((mng_loopp)*ppChunk)->pSignals, pRawdata + 14,
       
  3900                         ((mng_loopp)*ppChunk)->iCount << 2);
       
  3901 #endif /* !MNG_BIGENDIAN_SUPPORTED */
       
  3902             }
       
  3903           }
       
  3904 #endif
       
  3905         }
       
  3906       }
       
  3907     }
       
  3908   }
       
  3909 #endif /* MNG_STORE_CHUNKS */
       
  3910 
       
  3911 #ifdef MNG_SUPPORT_TRACE
       
  3912   MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_END);
       
  3913 #endif
       
  3914 
       
  3915   return MNG_NOERROR;                  /* done */
       
  3916 }
       
  3917 #endif
       
  3918 #endif
       
  3919 
       
  3920 /* ************************************************************************** */
       
  3921 
       
  3922 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3923 #ifndef MNG_SKIPCHUNK_LOOP
       
  3924 READ_CHUNK (mng_read_endl)
       
  3925 {
       
  3926 #ifdef MNG_SUPPORT_TRACE
       
  3927   MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_START);
       
  3928 #endif
       
  3929 
       
  3930   if (!pData->bHasMHDR)                /* sequence checks */
       
  3931     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3932 
       
  3933 #ifdef MNG_INCLUDE_JNG
       
  3934   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  3935 #else
       
  3936   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  3937 #endif
       
  3938     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  3939 
       
  3940   if (iRawlen != 1)                    /* length must be exactly 1 */
       
  3941     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  3942 
       
  3943 #ifdef MNG_SUPPORT_DISPLAY
       
  3944   {
       
  3945     if (pData->bHasLOOP)               /* are we really processing a loop ? */
       
  3946     {
       
  3947       mng_uint8 iLevel = *pRawdata;    /* get the nest level */
       
  3948                                        /* create an ENDL animation object */
       
  3949       mng_retcode iRetcode = mng_create_ani_endl (pData, iLevel);
       
  3950                                  
       
  3951       if (iRetcode)                    /* on error bail out */
       
  3952         return iRetcode;
       
  3953 
       
  3954 /*      {
       
  3955         mng_ani_endlp pENDL = (mng_ani_endlp)pData->pLastaniobj;
       
  3956 
       
  3957         iRetcode = pENDL->sHeader.fProcess (pData, pENDL);
       
  3958 
       
  3959         if (iRetcode)
       
  3960           return iRetcode;
       
  3961       } */
       
  3962     }
       
  3963     else
       
  3964       MNG_ERROR (pData, MNG_NOMATCHINGLOOP);
       
  3965       
       
  3966   }
       
  3967 #endif /* MNG_SUPPORT_DISPLAY */
       
  3968 
       
  3969 #ifdef MNG_STORE_CHUNKS
       
  3970   if (pData->bStorechunks)
       
  3971   {                                    /* initialize storage */
       
  3972     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  3973 
       
  3974     if (iRetcode)                      /* on error bail out */
       
  3975       return iRetcode;
       
  3976                                        /* store the fields */
       
  3977     ((mng_endlp)*ppChunk)->iLevel = *pRawdata;
       
  3978   }
       
  3979 #endif /* MNG_STORE_CHUNKS */
       
  3980 
       
  3981 #ifdef MNG_SUPPORT_TRACE
       
  3982   MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_END);
       
  3983 #endif
       
  3984 
       
  3985   return MNG_NOERROR;                  /* done */
       
  3986 }
       
  3987 #endif
       
  3988 #endif
       
  3989 
       
  3990 /* ************************************************************************** */
       
  3991 
       
  3992 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  3993 #ifndef MNG_SKIPCHUNK_DEFI
       
  3994 READ_CHUNK (mng_read_defi)
       
  3995 {
       
  3996 #ifdef MNG_SUPPORT_TRACE
       
  3997   MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_START);
       
  3998 #endif
       
  3999 
       
  4000   if (!pData->bHasMHDR)                /* sequence checks */
       
  4001     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4002 
       
  4003 #ifdef MNG_INCLUDE_JNG
       
  4004   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4005 #else
       
  4006   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4007 #endif
       
  4008     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4009                                        /* check the length */
       
  4010   if ((iRawlen != 2) && (iRawlen != 3) && (iRawlen != 4) &&
       
  4011       (iRawlen != 12) && (iRawlen != 28))
       
  4012     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4013 
       
  4014 #ifdef MNG_SUPPORT_DISPLAY
       
  4015   {
       
  4016     mng_retcode iRetcode;
       
  4017 
       
  4018     pData->iDEFIobjectid       = mng_get_uint16 (pRawdata);
       
  4019 
       
  4020     if (iRawlen > 2)
       
  4021     {
       
  4022       pData->bDEFIhasdonotshow = MNG_TRUE;
       
  4023       pData->iDEFIdonotshow    = *(pRawdata+2);
       
  4024     }
       
  4025     else
       
  4026     {
       
  4027       pData->bDEFIhasdonotshow = MNG_FALSE;
       
  4028       pData->iDEFIdonotshow    = 0;
       
  4029     }
       
  4030 
       
  4031     if (iRawlen > 3)
       
  4032     {
       
  4033       pData->bDEFIhasconcrete  = MNG_TRUE;
       
  4034       pData->iDEFIconcrete     = *(pRawdata+3);
       
  4035     }
       
  4036     else
       
  4037     {
       
  4038       pData->bDEFIhasconcrete  = MNG_FALSE;
       
  4039       pData->iDEFIconcrete     = 0;
       
  4040     }
       
  4041 
       
  4042     if (iRawlen > 4)
       
  4043     {
       
  4044       pData->bDEFIhasloca      = MNG_TRUE;
       
  4045       pData->iDEFIlocax        = mng_get_int32 (pRawdata+4);
       
  4046       pData->iDEFIlocay        = mng_get_int32 (pRawdata+8);
       
  4047     }
       
  4048     else
       
  4049     {
       
  4050       pData->bDEFIhasloca      = MNG_FALSE;
       
  4051       pData->iDEFIlocax        = 0;
       
  4052       pData->iDEFIlocay        = 0;
       
  4053     }
       
  4054 
       
  4055     if (iRawlen > 12)
       
  4056     {
       
  4057       pData->bDEFIhasclip      = MNG_TRUE;
       
  4058       pData->iDEFIclipl        = mng_get_int32 (pRawdata+12);
       
  4059       pData->iDEFIclipr        = mng_get_int32 (pRawdata+16);
       
  4060       pData->iDEFIclipt        = mng_get_int32 (pRawdata+20);
       
  4061       pData->iDEFIclipb        = mng_get_int32 (pRawdata+24);
       
  4062     }
       
  4063     else
       
  4064     {
       
  4065       pData->bDEFIhasclip      = MNG_FALSE;
       
  4066       pData->iDEFIclipl        = 0;
       
  4067       pData->iDEFIclipr        = 0;
       
  4068       pData->iDEFIclipt        = 0;
       
  4069       pData->iDEFIclipb        = 0;
       
  4070     }
       
  4071                                        /* create an animation object */
       
  4072     iRetcode = mng_create_ani_defi (pData);
       
  4073                    
       
  4074     if (!iRetcode)                     /* do display processing */
       
  4075       iRetcode = mng_process_display_defi (pData);
       
  4076 
       
  4077     if (iRetcode)                      /* on error bail out */
       
  4078       return iRetcode;
       
  4079 
       
  4080   }
       
  4081 #endif /* MNG_SUPPORT_DISPLAY */
       
  4082 
       
  4083 #ifdef MNG_STORE_CHUNKS
       
  4084   if (pData->bStorechunks)
       
  4085   {                                    /* initialize storage */
       
  4086     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4087 
       
  4088     if (iRetcode)                      /* on error bail out */
       
  4089       return iRetcode;
       
  4090                                        /* store the fields */
       
  4091     ((mng_defip)*ppChunk)->iObjectid       = mng_get_uint16 (pRawdata);
       
  4092 
       
  4093     if (iRawlen > 2)
       
  4094     {
       
  4095       ((mng_defip)*ppChunk)->bHasdonotshow = MNG_TRUE;
       
  4096       ((mng_defip)*ppChunk)->iDonotshow    = *(pRawdata+2);
       
  4097     }
       
  4098     else
       
  4099       ((mng_defip)*ppChunk)->bHasdonotshow = MNG_FALSE;
       
  4100 
       
  4101     if (iRawlen > 3)
       
  4102     {
       
  4103       ((mng_defip)*ppChunk)->bHasconcrete  = MNG_TRUE;
       
  4104       ((mng_defip)*ppChunk)->iConcrete     = *(pRawdata+3);
       
  4105     }
       
  4106     else
       
  4107       ((mng_defip)*ppChunk)->bHasconcrete  = MNG_FALSE;
       
  4108 
       
  4109     if (iRawlen > 4)
       
  4110     {
       
  4111       ((mng_defip)*ppChunk)->bHasloca      = MNG_TRUE;
       
  4112       ((mng_defip)*ppChunk)->iXlocation    = mng_get_int32 (pRawdata+4);
       
  4113       ((mng_defip)*ppChunk)->iYlocation    = mng_get_int32 (pRawdata+8);
       
  4114     }
       
  4115     else
       
  4116       ((mng_defip)*ppChunk)->bHasloca      = MNG_FALSE;
       
  4117 
       
  4118     if (iRawlen > 12)
       
  4119     {
       
  4120       ((mng_defip)*ppChunk)->bHasclip      = MNG_TRUE;
       
  4121       ((mng_defip)*ppChunk)->iLeftcb       = mng_get_int32 (pRawdata+12);
       
  4122       ((mng_defip)*ppChunk)->iRightcb      = mng_get_int32 (pRawdata+16);
       
  4123       ((mng_defip)*ppChunk)->iTopcb        = mng_get_int32 (pRawdata+20);
       
  4124       ((mng_defip)*ppChunk)->iBottomcb     = mng_get_int32 (pRawdata+24);
       
  4125     }
       
  4126     else
       
  4127       ((mng_defip)*ppChunk)->bHasclip      = MNG_FALSE;
       
  4128 
       
  4129   }
       
  4130 #endif /* MNG_STORE_CHUNKS */
       
  4131 
       
  4132 #ifdef MNG_SUPPORT_TRACE
       
  4133   MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_END);
       
  4134 #endif
       
  4135 
       
  4136   return MNG_NOERROR;                  /* done */
       
  4137 }
       
  4138 #endif
       
  4139 #endif
       
  4140 
       
  4141 /* ************************************************************************** */
       
  4142 
       
  4143 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  4144 #ifndef MNG_SKIPCHUNK_BASI
       
  4145 READ_CHUNK (mng_read_basi)
       
  4146 {
       
  4147 #ifdef MNG_SUPPORT_TRACE
       
  4148   MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_START);
       
  4149 #endif
       
  4150 
       
  4151   if (!pData->bHasMHDR)                /* sequence checks */
       
  4152     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4153 
       
  4154 #ifdef MNG_INCLUDE_JNG
       
  4155   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4156 #else
       
  4157   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4158 #endif
       
  4159     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4160                                        /* check the length */
       
  4161   if ((iRawlen != 13) && (iRawlen != 19) && (iRawlen != 21) && (iRawlen != 22))
       
  4162     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4163 
       
  4164   pData->bHasBASI     = MNG_TRUE;      /* inside a BASI-IEND block now */
       
  4165                                        /* store interesting fields */
       
  4166   pData->iDatawidth   = mng_get_uint32 (pRawdata);
       
  4167   pData->iDataheight  = mng_get_uint32 (pRawdata+4);
       
  4168   pData->iBitdepth    = *(pRawdata+8);
       
  4169   pData->iColortype   = *(pRawdata+9);
       
  4170   pData->iCompression = *(pRawdata+10);
       
  4171   pData->iFilter      = *(pRawdata+11);
       
  4172   pData->iInterlace   = *(pRawdata+12);
       
  4173 
       
  4174 
       
  4175 #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
       
  4176   pData->iPNGmult = 1;
       
  4177   pData->iPNGdepth = pData->iBitdepth;
       
  4178 #endif
       
  4179 
       
  4180 #ifdef MNG_NO_1_2_4BIT_SUPPORT
       
  4181   if (pData->iBitdepth < 8)
       
  4182     pData->iBitdepth = 8;
       
  4183 #endif
       
  4184 #ifdef MNG_NO_16BIT_SUPPORT
       
  4185   if (pData->iBitdepth > 8)
       
  4186     {
       
  4187       pData->iBitdepth = 8;
       
  4188       pData->iPNGmult = 2;
       
  4189     }
       
  4190 #endif
       
  4191 
       
  4192   if ((pData->iBitdepth !=  8)      /* parameter validity checks */
       
  4193 #ifndef MNG_NO_1_2_4BIT_SUPPORT
       
  4194       && (pData->iBitdepth !=  1) &&
       
  4195       (pData->iBitdepth !=  2) &&
       
  4196       (pData->iBitdepth !=  4)
       
  4197 #endif
       
  4198 #ifndef MNG_NO_16BIT_SUPPORT
       
  4199       && (pData->iBitdepth != 16)
       
  4200 #endif
       
  4201       )
       
  4202     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  4203 
       
  4204   if ((pData->iColortype != MNG_COLORTYPE_GRAY   ) &&
       
  4205       (pData->iColortype != MNG_COLORTYPE_RGB    ) &&
       
  4206       (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
       
  4207       (pData->iColortype != MNG_COLORTYPE_GRAYA  ) &&
       
  4208       (pData->iColortype != MNG_COLORTYPE_RGBA   )    )
       
  4209     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
       
  4210 
       
  4211   if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
       
  4212     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  4213 
       
  4214   if (((pData->iColortype == MNG_COLORTYPE_RGB    ) ||
       
  4215        (pData->iColortype == MNG_COLORTYPE_GRAYA  ) ||
       
  4216        (pData->iColortype == MNG_COLORTYPE_RGBA   )    ) &&
       
  4217       (pData->iBitdepth < 8                            )    )
       
  4218     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  4219 
       
  4220   if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
       
  4221     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  4222 
       
  4223 #if defined(FILTER192) || defined(FILTER193)
       
  4224   if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
       
  4225 #if defined(FILTER192) && defined(FILTER193)
       
  4226       (pData->iFilter != MNG_FILTER_DIFFERING) &&
       
  4227       (pData->iFilter != MNG_FILTER_NOFILTER )    )
       
  4228 #else
       
  4229 #ifdef FILTER192
       
  4230       (pData->iFilter != MNG_FILTER_DIFFERING)    )
       
  4231 #else
       
  4232       (pData->iFilter != MNG_FILTER_NOFILTER )    )
       
  4233 #endif
       
  4234 #endif
       
  4235     MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  4236 #else
       
  4237   if (pData->iFilter)
       
  4238     MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  4239 #endif
       
  4240 
       
  4241   if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
       
  4242       (pData->iInterlace != MNG_INTERLACE_ADAM7)    )
       
  4243     MNG_ERROR (pData, MNG_INVALIDINTERLACE);
       
  4244 
       
  4245   pData->iImagelevel++;                /* one level deeper */
       
  4246 
       
  4247 #ifdef MNG_SUPPORT_DISPLAY
       
  4248   {
       
  4249     mng_uint16  iRed      = 0;
       
  4250     mng_uint16  iGreen    = 0;
       
  4251     mng_uint16  iBlue     = 0;
       
  4252     mng_bool    bHasalpha = MNG_FALSE;
       
  4253     mng_uint16  iAlpha    = 0xFFFF;
       
  4254     mng_uint8   iViewable = 0;
       
  4255     mng_retcode iRetcode;
       
  4256 
       
  4257     if (iRawlen > 13)                  /* get remaining fields, if any */
       
  4258     {
       
  4259       iRed      = mng_get_uint16 (pRawdata+13);
       
  4260       iGreen    = mng_get_uint16 (pRawdata+15);
       
  4261       iBlue     = mng_get_uint16 (pRawdata+17);
       
  4262     }
       
  4263 
       
  4264     if (iRawlen > 19)
       
  4265     {
       
  4266       bHasalpha = MNG_TRUE;
       
  4267       iAlpha    = mng_get_uint16 (pRawdata+19);
       
  4268     }
       
  4269 
       
  4270     if (iRawlen > 21)
       
  4271       iViewable = *(pRawdata+21);
       
  4272                                        /* create an animation object */
       
  4273     iRetcode = mng_create_ani_basi (pData, iRed, iGreen, iBlue,
       
  4274                                     bHasalpha, iAlpha, iViewable);
       
  4275 
       
  4276 /*    if (!iRetcode)
       
  4277       iRetcode = mng_process_display_basi (pData, iRed, iGreen, iBlue,
       
  4278                                            bHasalpha, iAlpha, iViewable); */
       
  4279 
       
  4280     if (iRetcode)                      /* on error bail out */
       
  4281       return iRetcode;
       
  4282 
       
  4283   }
       
  4284 #endif /* MNG_SUPPORT_DISPLAY */
       
  4285 
       
  4286 #ifdef MNG_STORE_CHUNKS
       
  4287   if (pData->bStorechunks)
       
  4288   {                                    /* initialize storage */
       
  4289     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4290 
       
  4291     if (iRetcode)                      /* on error bail out */
       
  4292       return iRetcode;
       
  4293                                        /* store the fields */
       
  4294     ((mng_basip)*ppChunk)->iWidth       = mng_get_uint32 (pRawdata);
       
  4295     ((mng_basip)*ppChunk)->iHeight      = mng_get_uint32 (pRawdata+4);
       
  4296 #ifdef MNG_NO_16BIT_SUPPORT
       
  4297     if (*(pRawdata+8) > 8)
       
  4298       ((mng_basip)*ppChunk)->iBitdepth    = 8;
       
  4299     else
       
  4300 #endif
       
  4301       ((mng_basip)*ppChunk)->iBitdepth    = *(pRawdata+8);
       
  4302     ((mng_basip)*ppChunk)->iColortype   = *(pRawdata+9);
       
  4303     ((mng_basip)*ppChunk)->iCompression = *(pRawdata+10);
       
  4304     ((mng_basip)*ppChunk)->iFilter      = *(pRawdata+11);
       
  4305     ((mng_basip)*ppChunk)->iInterlace   = *(pRawdata+12);
       
  4306 
       
  4307     if (iRawlen > 13)
       
  4308     {
       
  4309       ((mng_basip)*ppChunk)->iRed       = mng_get_uint16 (pRawdata+13);
       
  4310       ((mng_basip)*ppChunk)->iGreen     = mng_get_uint16 (pRawdata+15);
       
  4311       ((mng_basip)*ppChunk)->iBlue      = mng_get_uint16 (pRawdata+17);
       
  4312     }
       
  4313 
       
  4314     if (iRawlen > 19)
       
  4315       ((mng_basip)*ppChunk)->iAlpha     = mng_get_uint16 (pRawdata+19);
       
  4316 
       
  4317     if (iRawlen > 21)
       
  4318       ((mng_basip)*ppChunk)->iViewable  = *(pRawdata+21);
       
  4319 
       
  4320   }
       
  4321 #endif /* MNG_STORE_CHUNKS */
       
  4322 
       
  4323 #ifdef MNG_SUPPORT_TRACE
       
  4324   MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_END);
       
  4325 #endif
       
  4326 
       
  4327   return MNG_NOERROR;                  /* done */
       
  4328 }
       
  4329 #endif
       
  4330 #endif
       
  4331 
       
  4332 /* ************************************************************************** */
       
  4333 
       
  4334 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  4335 #ifndef MNG_SKIPCHUNK_CLON
       
  4336 READ_CHUNK (mng_read_clon)
       
  4337 {
       
  4338 #ifdef MNG_SUPPORT_TRACE
       
  4339   MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_START);
       
  4340 #endif
       
  4341 
       
  4342   if (!pData->bHasMHDR)                /* sequence checks */
       
  4343     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4344 
       
  4345 #ifdef MNG_INCLUDE_JNG
       
  4346   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4347 #else
       
  4348   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4349 #endif
       
  4350     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4351                                        /* check the length */
       
  4352   if ((iRawlen != 4) && (iRawlen != 5) && (iRawlen != 6) &&
       
  4353       (iRawlen != 7) && (iRawlen != 16))
       
  4354     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4355 
       
  4356 #ifdef MNG_SUPPORT_DISPLAY
       
  4357   {
       
  4358     mng_uint16  iSourceid, iCloneid;
       
  4359     mng_uint8   iClonetype    = 0;
       
  4360     mng_bool    bHasdonotshow = MNG_FALSE;
       
  4361     mng_uint8   iDonotshow    = 0;
       
  4362     mng_uint8   iConcrete     = 0;
       
  4363     mng_bool    bHasloca      = MNG_FALSE;
       
  4364     mng_uint8   iLocationtype = 0;
       
  4365     mng_int32   iLocationx    = 0;
       
  4366     mng_int32   iLocationy    = 0;
       
  4367     mng_retcode iRetcode;
       
  4368 
       
  4369     iSourceid       = mng_get_uint16 (pRawdata);
       
  4370     iCloneid        = mng_get_uint16 (pRawdata+2);
       
  4371 
       
  4372     if (iRawlen > 4)
       
  4373       iClonetype    = *(pRawdata+4);
       
  4374 
       
  4375     if (iRawlen > 5)
       
  4376     {
       
  4377       bHasdonotshow = MNG_TRUE;
       
  4378       iDonotshow    = *(pRawdata+5);
       
  4379     }
       
  4380 
       
  4381     if (iRawlen > 6)
       
  4382       iConcrete     = *(pRawdata+6);
       
  4383 
       
  4384     if (iRawlen > 7)
       
  4385     {
       
  4386       bHasloca      = MNG_TRUE;
       
  4387       iLocationtype = *(pRawdata+7);
       
  4388       iLocationx    = mng_get_int32 (pRawdata+8);
       
  4389       iLocationy    = mng_get_int32 (pRawdata+12);
       
  4390     }
       
  4391 
       
  4392     iRetcode = mng_create_ani_clon (pData, iSourceid, iCloneid, iClonetype,
       
  4393                                     bHasdonotshow, iDonotshow, iConcrete,
       
  4394                                     bHasloca, iLocationtype, iLocationx, iLocationy);
       
  4395 
       
  4396 /*    if (!iRetcode)
       
  4397       iRetcode = mng_process_display_clon (pData, iSourceid, iCloneid, iClonetype,
       
  4398                                            bHasdonotshow, iDonotshow, iConcrete,
       
  4399                                            bHasloca, iLocationtype, iLocationx,
       
  4400                                            iLocationy); */
       
  4401 
       
  4402     if (iRetcode)                      /* on error bail out */
       
  4403       return iRetcode;
       
  4404 
       
  4405   }
       
  4406 #endif /* MNG_SUPPORT_DISPLAY */
       
  4407 
       
  4408 #ifdef MNG_STORE_CHUNKS
       
  4409   if (pData->bStorechunks)
       
  4410   {                                    /* initialize storage */
       
  4411     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4412 
       
  4413     if (iRetcode)                      /* on error bail out */
       
  4414       return iRetcode;
       
  4415                                        /* store the fields */
       
  4416     ((mng_clonp)*ppChunk)->iSourceid       = mng_get_uint16 (pRawdata);
       
  4417     ((mng_clonp)*ppChunk)->iCloneid        = mng_get_uint16 (pRawdata+2);
       
  4418 
       
  4419     if (iRawlen > 4)
       
  4420       ((mng_clonp)*ppChunk)->iClonetype    = *(pRawdata+4);
       
  4421 
       
  4422     if (iRawlen > 5)
       
  4423       ((mng_clonp)*ppChunk)->iDonotshow    = *(pRawdata+5);
       
  4424 
       
  4425     if (iRawlen > 6)
       
  4426       ((mng_clonp)*ppChunk)->iConcrete     = *(pRawdata+6);
       
  4427 
       
  4428     if (iRawlen > 7)
       
  4429     {
       
  4430       ((mng_clonp)*ppChunk)->bHasloca      = MNG_TRUE;
       
  4431       ((mng_clonp)*ppChunk)->iLocationtype = *(pRawdata+7);
       
  4432       ((mng_clonp)*ppChunk)->iLocationx    = mng_get_int32 (pRawdata+8);
       
  4433       ((mng_clonp)*ppChunk)->iLocationy    = mng_get_int32 (pRawdata+12);
       
  4434     }
       
  4435     else
       
  4436     {
       
  4437       ((mng_clonp)*ppChunk)->bHasloca      = MNG_FALSE;
       
  4438     }
       
  4439   }
       
  4440 #endif /* MNG_STORE_CHUNKS */
       
  4441 
       
  4442 #ifdef MNG_SUPPORT_TRACE
       
  4443   MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_END);
       
  4444 #endif
       
  4445 
       
  4446   return MNG_NOERROR;                  /* done */
       
  4447 }
       
  4448 #endif
       
  4449 #endif
       
  4450 
       
  4451 /* ************************************************************************** */
       
  4452 
       
  4453 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  4454 #ifndef MNG_SKIPCHUNK_PAST
       
  4455 READ_CHUNK (mng_read_past)
       
  4456 {
       
  4457 #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
       
  4458   mng_retcode      iRetcode;
       
  4459   mng_uint16       iTargetid;
       
  4460   mng_uint8        iTargettype;
       
  4461   mng_int32        iTargetx;
       
  4462   mng_int32        iTargety;
       
  4463   mng_uint32       iCount;
       
  4464   mng_uint32       iSize;
       
  4465   mng_ptr          pSources;
       
  4466   mng_uint32       iX;
       
  4467   mng_past_sourcep pSource;
       
  4468 #endif
       
  4469 
       
  4470 #ifdef MNG_SUPPORT_TRACE
       
  4471   MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_START);
       
  4472 #endif
       
  4473 
       
  4474   if (!pData->bHasMHDR)                /* sequence checks */
       
  4475     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4476 
       
  4477 #ifdef MNG_INCLUDE_JNG
       
  4478   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4479 #else
       
  4480   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4481 #endif
       
  4482     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4483 
       
  4484                                        /* check the length */
       
  4485   if ((iRawlen < 41) || (((iRawlen - 11) % 30) != 0))
       
  4486     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4487 
       
  4488 #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
       
  4489   iTargetid   = mng_get_uint16 (pRawdata);
       
  4490   iTargettype = *(pRawdata+2);
       
  4491   iTargetx    = mng_get_int32  (pRawdata+3);
       
  4492   iTargety    = mng_get_int32  (pRawdata+7);
       
  4493   iCount      = ((iRawlen - 11) / 30); /* how many entries again? */
       
  4494   iSize       = iCount * sizeof (mng_past_source);
       
  4495 
       
  4496   pRawdata += 11;
       
  4497                                        /* get a buffer for all the source blocks */
       
  4498   MNG_ALLOC (pData, pSources, iSize);
       
  4499 
       
  4500   pSource = (mng_past_sourcep)pSources;
       
  4501 
       
  4502   for (iX = 0; iX < iCount; iX++)      /* now copy the source blocks */
       
  4503   {
       
  4504     pSource->iSourceid     = mng_get_uint16 (pRawdata);
       
  4505     pSource->iComposition  = *(pRawdata+2);
       
  4506     pSource->iOrientation  = *(pRawdata+3);
       
  4507     pSource->iOffsettype   = *(pRawdata+4);
       
  4508     pSource->iOffsetx      = mng_get_int32 (pRawdata+5);
       
  4509     pSource->iOffsety      = mng_get_int32 (pRawdata+9);
       
  4510     pSource->iBoundarytype = *(pRawdata+13);
       
  4511     pSource->iBoundaryl    = mng_get_int32 (pRawdata+14);
       
  4512     pSource->iBoundaryr    = mng_get_int32 (pRawdata+18);
       
  4513     pSource->iBoundaryt    = mng_get_int32 (pRawdata+22);
       
  4514     pSource->iBoundaryb    = mng_get_int32 (pRawdata+26);
       
  4515 
       
  4516     pSource++;
       
  4517     pRawdata += 30;
       
  4518   }
       
  4519 #endif
       
  4520 
       
  4521 #ifdef MNG_SUPPORT_DISPLAY
       
  4522   {                                    /* create playback object */
       
  4523     iRetcode = mng_create_ani_past (pData, iTargetid, iTargettype, iTargetx,
       
  4524                                     iTargety, iCount, pSources);
       
  4525 
       
  4526 /*    if (!iRetcode)
       
  4527       iRetcode = mng_process_display_past (pData, iTargetid, iTargettype, iTargetx,
       
  4528                                            iTargety, iCount, pSources); */
       
  4529 
       
  4530     if (iRetcode)                      /* on error bail out */
       
  4531     {
       
  4532       MNG_FREEX (pData, pSources, iSize);
       
  4533       return iRetcode;
       
  4534     }
       
  4535   }
       
  4536 #endif /* MNG_SUPPORT_DISPLAY */
       
  4537 
       
  4538 #ifdef MNG_STORE_CHUNKS
       
  4539   if (pData->bStorechunks)
       
  4540   {                                    /* initialize storage */
       
  4541     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4542 
       
  4543     if (iRetcode)                      /* on error bail out */
       
  4544     {
       
  4545       MNG_FREEX (pData, pSources, iSize);
       
  4546       return iRetcode;
       
  4547     }
       
  4548                                        /* store the fields */
       
  4549     ((mng_pastp)*ppChunk)->iDestid     = iTargetid;
       
  4550     ((mng_pastp)*ppChunk)->iTargettype = iTargettype;
       
  4551     ((mng_pastp)*ppChunk)->iTargetx    = iTargetx;
       
  4552     ((mng_pastp)*ppChunk)->iTargety    = iTargety;
       
  4553     ((mng_pastp)*ppChunk)->iCount      = iCount;
       
  4554                                        /* get a buffer & copy the source blocks */
       
  4555     MNG_ALLOC (pData, ((mng_pastp)*ppChunk)->pSources, iSize);
       
  4556     MNG_COPY (((mng_pastp)*ppChunk)->pSources, pSources, iSize);
       
  4557   }
       
  4558 #endif /* MNG_STORE_CHUNKS */
       
  4559 
       
  4560 #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
       
  4561                                        /* free the source block buffer */
       
  4562   MNG_FREEX (pData, pSources, iSize);
       
  4563 #endif
       
  4564 
       
  4565 #ifdef MNG_SUPPORT_TRACE
       
  4566   MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_END);
       
  4567 #endif
       
  4568 
       
  4569   return MNG_NOERROR;                  /* done */
       
  4570 }
       
  4571 #endif
       
  4572 #endif
       
  4573 
       
  4574 /* ************************************************************************** */
       
  4575 
       
  4576 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  4577 #ifndef MNG_SKIPCHUNK_DISC
       
  4578 READ_CHUNK (mng_read_disc)
       
  4579 {
       
  4580 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  4581   mng_uint32  iCount;
       
  4582   mng_uint16p pIds = MNG_NULL;
       
  4583   mng_retcode iRetcode;
       
  4584 #endif
       
  4585 
       
  4586 #ifdef MNG_SUPPORT_TRACE
       
  4587   MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_START);
       
  4588 #endif
       
  4589 
       
  4590   if (!pData->bHasMHDR)                /* sequence checks */
       
  4591     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4592 
       
  4593 #ifdef MNG_INCLUDE_JNG
       
  4594   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4595 #else
       
  4596   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4597 #endif
       
  4598     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4599 
       
  4600   if ((iRawlen % 2) != 0)              /* check the length */
       
  4601     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4602 
       
  4603 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  4604   iCount = (iRawlen / sizeof (mng_uint16));
       
  4605 
       
  4606   if (iCount)
       
  4607   {
       
  4608     MNG_ALLOC (pData, pIds, iRawlen);
       
  4609 
       
  4610 #ifndef MNG_BIGENDIAN_SUPPORTED
       
  4611     {
       
  4612       mng_uint32  iX;
       
  4613       mng_uint8p  pIn  = pRawdata;
       
  4614       mng_uint16p pOut = pIds;
       
  4615 
       
  4616       for (iX = 0; iX < iCount; iX++)
       
  4617       {
       
  4618         *pOut++ = mng_get_uint16 (pIn);
       
  4619         pIn += 2;
       
  4620       }
       
  4621     }
       
  4622 #else
       
  4623     MNG_COPY (pIds, pRawdata, iRawlen);
       
  4624 #endif /* !MNG_BIGENDIAN_SUPPORTED */
       
  4625   }
       
  4626 #endif
       
  4627 
       
  4628 #ifdef MNG_SUPPORT_DISPLAY
       
  4629   {                                    /* create playback object */
       
  4630     iRetcode = mng_create_ani_disc (pData, iCount, pIds);
       
  4631 
       
  4632 /*    if (!iRetcode)
       
  4633       iRetcode = mng_process_display_disc (pData, iCount, pIds); */
       
  4634 
       
  4635     if (iRetcode)                      /* on error bail out */
       
  4636       return iRetcode;
       
  4637   }
       
  4638 #endif /* MNG_SUPPORT_DISPLAY */
       
  4639 
       
  4640 #ifdef MNG_STORE_CHUNKS
       
  4641   if (pData->bStorechunks)
       
  4642   {                                    /* initialize storage */
       
  4643     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4644 
       
  4645     if (iRetcode)                      /* on error bail out */
       
  4646       return iRetcode;
       
  4647                                        /* store the fields */
       
  4648     ((mng_discp)*ppChunk)->iCount = iCount;
       
  4649 
       
  4650     if (iRawlen)
       
  4651     {
       
  4652       MNG_ALLOC (pData, ((mng_discp)*ppChunk)->pObjectids, iRawlen);
       
  4653       MNG_COPY (((mng_discp)*ppChunk)->pObjectids, pIds, iRawlen);
       
  4654     }
       
  4655   }
       
  4656 #endif /* MNG_STORE_CHUNKS */
       
  4657 
       
  4658 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  4659   if (iRawlen)
       
  4660     MNG_FREEX (pData, pIds, iRawlen);
       
  4661 #endif
       
  4662 
       
  4663 #ifdef MNG_SUPPORT_TRACE
       
  4664   MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_END);
       
  4665 #endif
       
  4666 
       
  4667   return MNG_NOERROR;                  /* done */
       
  4668 }
       
  4669 #endif
       
  4670 #endif
       
  4671 
       
  4672 /* ************************************************************************** */
       
  4673 
       
  4674 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  4675 #ifndef MNG_SKIPCHUNK_BACK
       
  4676 READ_CHUNK (mng_read_back)
       
  4677 {
       
  4678 #ifdef MNG_SUPPORT_TRACE
       
  4679   MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_START);
       
  4680 #endif
       
  4681 
       
  4682   if (!pData->bHasMHDR)                /* sequence checks */
       
  4683     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4684 
       
  4685 #ifdef MNG_INCLUDE_JNG
       
  4686   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4687 #else
       
  4688   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4689 #endif
       
  4690     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4691                                        /* check the length */
       
  4692   if ((iRawlen != 6) && (iRawlen != 7) && (iRawlen != 9) && (iRawlen != 10))
       
  4693     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4694 
       
  4695 #ifdef MNG_SUPPORT_DISPLAY
       
  4696   {
       
  4697     mng_retcode iRetcode;
       
  4698                                        /* retrieve the fields */
       
  4699     pData->bHasBACK         = MNG_TRUE;
       
  4700     pData->iBACKred         = mng_get_uint16 (pRawdata);
       
  4701     pData->iBACKgreen       = mng_get_uint16 (pRawdata+2);
       
  4702     pData->iBACKblue        = mng_get_uint16 (pRawdata+4);
       
  4703 
       
  4704     if (iRawlen > 6)
       
  4705       pData->iBACKmandatory = *(pRawdata+6);
       
  4706     else
       
  4707       pData->iBACKmandatory = 0;
       
  4708 
       
  4709     if (iRawlen > 7)
       
  4710       pData->iBACKimageid   = mng_get_uint16 (pRawdata+7);
       
  4711     else
       
  4712       pData->iBACKimageid   = 0;
       
  4713 
       
  4714     if (iRawlen > 9)
       
  4715       pData->iBACKtile      = *(pRawdata+9);
       
  4716     else
       
  4717       pData->iBACKtile      = 0;
       
  4718 
       
  4719     iRetcode = mng_create_ani_back (pData, pData->iBACKred, pData->iBACKgreen,
       
  4720                                     pData->iBACKblue, pData->iBACKmandatory,
       
  4721                                     pData->iBACKimageid, pData->iBACKtile);
       
  4722 
       
  4723     if (iRetcode)                    /* on error bail out */
       
  4724       return iRetcode;
       
  4725   }
       
  4726 #endif /* MNG_SUPPORT_DISPLAY */
       
  4727 
       
  4728 #ifdef MNG_STORE_CHUNKS
       
  4729   if (pData->bStorechunks)
       
  4730   {                                    /* initialize storage */
       
  4731     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4732 
       
  4733     if (iRetcode)                      /* on error bail out */
       
  4734       return iRetcode;
       
  4735                                        /* store the fields */
       
  4736     ((mng_backp)*ppChunk)->iRed         = mng_get_uint16 (pRawdata);
       
  4737     ((mng_backp)*ppChunk)->iGreen       = mng_get_uint16 (pRawdata+2);
       
  4738     ((mng_backp)*ppChunk)->iBlue        = mng_get_uint16 (pRawdata+4);
       
  4739 
       
  4740     if (iRawlen > 6)
       
  4741       ((mng_backp)*ppChunk)->iMandatory = *(pRawdata+6);
       
  4742 
       
  4743     if (iRawlen > 7)
       
  4744       ((mng_backp)*ppChunk)->iImageid   = mng_get_uint16 (pRawdata+7);
       
  4745 
       
  4746     if (iRawlen > 9)
       
  4747       ((mng_backp)*ppChunk)->iTile      = *(pRawdata+9);
       
  4748 
       
  4749   }
       
  4750 #endif /* MNG_STORE_CHUNKS */
       
  4751 
       
  4752 #ifdef MNG_SUPPORT_TRACE
       
  4753   MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_END);
       
  4754 #endif
       
  4755 
       
  4756   return MNG_NOERROR;                  /* done */
       
  4757 }
       
  4758 #endif
       
  4759 #endif
       
  4760 
       
  4761 /* ************************************************************************** */
       
  4762 
       
  4763 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  4764 #ifndef MNG_SKIPCHUNK_FRAM
       
  4765 READ_CHUNK (mng_read_fram)
       
  4766 {
       
  4767   mng_uint8p pTemp;
       
  4768 #ifdef MNG_STORE_CHUNKS
       
  4769   mng_uint32 iNamelen;
       
  4770 #endif
       
  4771   mng_uint32 iRemain;
       
  4772   mng_uint32 iRequired = 0;
       
  4773 
       
  4774 #ifdef MNG_SUPPORT_TRACE
       
  4775   MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_START);
       
  4776 #endif
       
  4777 
       
  4778   if (!pData->bHasMHDR)                /* sequence checks */
       
  4779     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4780 
       
  4781 #ifdef MNG_INCLUDE_JNG
       
  4782   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  4783 #else
       
  4784   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  4785 #endif
       
  4786     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  4787 
       
  4788   if (iRawlen <= 1)                    /* only framing-mode ? */
       
  4789   {
       
  4790 #ifdef MNG_STORE_CHUNKS
       
  4791     iNamelen = 0;                      /* indicate so */
       
  4792 #endif
       
  4793     iRemain  = 0;
       
  4794     pTemp    = MNG_NULL;
       
  4795   }
       
  4796   else
       
  4797   {
       
  4798     pTemp = find_null (pRawdata+1);    /* find null-separator */
       
  4799                                        /* not found inside input-data ? */
       
  4800     if ((pTemp - pRawdata) > (mng_int32)iRawlen)
       
  4801       pTemp  = pRawdata + iRawlen;     /* than remainder is name */
       
  4802 
       
  4803 #ifdef MNG_STORE_CHUNKS
       
  4804     iNamelen = (mng_uint32)((pTemp - pRawdata) - 1);
       
  4805 #endif
       
  4806     iRemain  = (mng_uint32)(iRawlen - (pTemp - pRawdata));
       
  4807 
       
  4808     if (iRemain)                       /* if there is remaining data it's less 1 byte */
       
  4809       iRemain--;
       
  4810 
       
  4811     if ((iRemain) && (iRemain < 4))    /* remains must be empty or at least 4 bytes */
       
  4812       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4813 
       
  4814     if (iRemain)
       
  4815     {
       
  4816       iRequired = 4;                   /* calculate and check required remaining length */
       
  4817 
       
  4818       if (*(pTemp+1)) { iRequired += 4; }
       
  4819       if (*(pTemp+2)) { iRequired += 4; }
       
  4820       if (*(pTemp+3)) { iRequired += 17; }
       
  4821 
       
  4822       if (*(pTemp+4))
       
  4823       {
       
  4824         if ((iRemain - iRequired) % 4 != 0)
       
  4825           MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4826       }
       
  4827       else
       
  4828       {
       
  4829         if (iRemain != iRequired)
       
  4830           MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  4831       }
       
  4832     }
       
  4833   }
       
  4834 
       
  4835 #ifdef MNG_SUPPORT_DISPLAY
       
  4836   {
       
  4837     mng_uint8p  pWork           = pTemp;
       
  4838     mng_uint8   iFramemode      = 0;
       
  4839     mng_uint8   iChangedelay    = 0;
       
  4840     mng_uint32  iDelay          = 0;
       
  4841     mng_uint8   iChangetimeout  = 0;
       
  4842     mng_uint32  iTimeout        = 0;
       
  4843     mng_uint8   iChangeclipping = 0;
       
  4844     mng_uint8   iCliptype       = 0;
       
  4845     mng_int32   iClipl          = 0;
       
  4846     mng_int32   iClipr          = 0;
       
  4847     mng_int32   iClipt          = 0;
       
  4848     mng_int32   iClipb          = 0;
       
  4849     mng_retcode iRetcode;
       
  4850 
       
  4851     if (iRawlen)                       /* any data specified ? */
       
  4852     {
       
  4853       if (*(pRawdata))                 /* save the new framing mode ? */
       
  4854       {
       
  4855         iFramemode = *(pRawdata);
       
  4856 
       
  4857 #ifndef MNG_NO_OLD_VERSIONS
       
  4858         if (pData->bPreDraft48)        /* old style input-stream ? */
       
  4859         {
       
  4860           switch (iFramemode)
       
  4861           {
       
  4862             case  0: { break; }
       
  4863             case  1: { iFramemode = 3; break; }
       
  4864             case  2: { iFramemode = 4; break; }
       
  4865             case  3: { iFramemode = 1; break; }
       
  4866             case  4: { iFramemode = 1; break; }
       
  4867             case  5: { iFramemode = 2; break; }
       
  4868             default: { iFramemode = 1; break; }
       
  4869           }
       
  4870         }
       
  4871 #endif
       
  4872       }
       
  4873 
       
  4874       if (iRemain)
       
  4875       {
       
  4876         iChangedelay    = *(pWork+1);
       
  4877         iChangetimeout  = *(pWork+2);
       
  4878         iChangeclipping = *(pWork+3);
       
  4879         pWork += 5;
       
  4880 
       
  4881         if (iChangedelay)              /* delay changed ? */
       
  4882         {
       
  4883           iDelay = mng_get_uint32 (pWork);
       
  4884           pWork += 4;
       
  4885         }
       
  4886 
       
  4887         if (iChangetimeout)            /* timeout changed ? */
       
  4888         {
       
  4889           iTimeout = mng_get_uint32 (pWork);
       
  4890           pWork += 4;
       
  4891         }
       
  4892 
       
  4893         if (iChangeclipping)           /* clipping changed ? */
       
  4894         {
       
  4895           iCliptype = *pWork;
       
  4896           iClipl    = mng_get_int32 (pWork+1);
       
  4897           iClipr    = mng_get_int32 (pWork+5);
       
  4898           iClipt    = mng_get_int32 (pWork+9);
       
  4899           iClipb    = mng_get_int32 (pWork+13);
       
  4900         }
       
  4901       }
       
  4902     }
       
  4903 
       
  4904     iRetcode = mng_create_ani_fram (pData, iFramemode, iChangedelay, iDelay,
       
  4905                                     iChangetimeout, iTimeout,
       
  4906                                     iChangeclipping, iCliptype,
       
  4907                                     iClipl, iClipr, iClipt, iClipb);
       
  4908 
       
  4909 /*    if (!iRetcode)
       
  4910       iRetcode = mng_process_display_fram (pData, iFramemode, iChangedelay, iDelay,
       
  4911                                            iChangetimeout, iTimeout,
       
  4912                                            iChangeclipping, iCliptype,
       
  4913                                            iClipl, iClipr, iClipt, iClipb); */
       
  4914 
       
  4915     if (iRetcode)                      /* on error bail out */
       
  4916       return iRetcode;
       
  4917 
       
  4918   }
       
  4919 #endif /* MNG_SUPPORT_DISPLAY */
       
  4920 
       
  4921 #ifdef MNG_STORE_CHUNKS
       
  4922   if (pData->bStorechunks)
       
  4923   {                                    /* initialize storage */
       
  4924     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  4925 
       
  4926     if (iRetcode)                      /* on error bail out */
       
  4927       return iRetcode;
       
  4928                                        /* store the fields */
       
  4929     ((mng_framp)*ppChunk)->bEmpty              = (mng_bool)(iRawlen == 0);
       
  4930 
       
  4931     if (iRawlen)
       
  4932     {
       
  4933       mng_uint8 iFramemode = *(pRawdata);
       
  4934 
       
  4935 #ifndef MNG_NO_OLD_VERSIONS
       
  4936       if (pData->bPreDraft48)          /* old style input-stream ? */
       
  4937       {
       
  4938         switch (iFramemode)
       
  4939         {
       
  4940           case  1: { iFramemode = 3; break; }
       
  4941           case  2: { iFramemode = 4; break; }
       
  4942           case  3: { iFramemode = 5; break; }    /* TODO: provision for mode=5 ??? */
       
  4943           case  4: { iFramemode = 1; break; }
       
  4944           case  5: { iFramemode = 2; break; }
       
  4945           default: { iFramemode = 1; break; }
       
  4946         }
       
  4947       }
       
  4948 #endif
       
  4949 
       
  4950       ((mng_framp)*ppChunk)->iMode             = iFramemode;
       
  4951       ((mng_framp)*ppChunk)->iNamesize         = iNamelen;
       
  4952 
       
  4953       if (iNamelen)
       
  4954       {
       
  4955         MNG_ALLOC (pData, ((mng_framp)*ppChunk)->zName, iNamelen+1);
       
  4956         MNG_COPY (((mng_framp)*ppChunk)->zName, pRawdata+1, iNamelen);
       
  4957       }
       
  4958 
       
  4959       if (iRemain)
       
  4960       {
       
  4961         ((mng_framp)*ppChunk)->iChangedelay    = *(pTemp+1);
       
  4962         ((mng_framp)*ppChunk)->iChangetimeout  = *(pTemp+2);
       
  4963         ((mng_framp)*ppChunk)->iChangeclipping = *(pTemp+3);
       
  4964         ((mng_framp)*ppChunk)->iChangesyncid   = *(pTemp+4);
       
  4965 
       
  4966         pTemp += 5;
       
  4967 
       
  4968         if (((mng_framp)*ppChunk)->iChangedelay)
       
  4969         {
       
  4970           ((mng_framp)*ppChunk)->iDelay        = mng_get_uint32 (pTemp);
       
  4971           pTemp += 4;
       
  4972         }
       
  4973 
       
  4974         if (((mng_framp)*ppChunk)->iChangetimeout)
       
  4975         {
       
  4976           ((mng_framp)*ppChunk)->iTimeout      = mng_get_uint32 (pTemp);
       
  4977           pTemp += 4;
       
  4978         }
       
  4979 
       
  4980         if (((mng_framp)*ppChunk)->iChangeclipping)
       
  4981         {
       
  4982           ((mng_framp)*ppChunk)->iBoundarytype = *pTemp;
       
  4983           ((mng_framp)*ppChunk)->iBoundaryl    = mng_get_int32 (pTemp+1);
       
  4984           ((mng_framp)*ppChunk)->iBoundaryr    = mng_get_int32 (pTemp+5);
       
  4985           ((mng_framp)*ppChunk)->iBoundaryt    = mng_get_int32 (pTemp+9);
       
  4986           ((mng_framp)*ppChunk)->iBoundaryb    = mng_get_int32 (pTemp+13);
       
  4987           pTemp += 17;
       
  4988         }
       
  4989 
       
  4990         if (((mng_framp)*ppChunk)->iChangesyncid)
       
  4991         {
       
  4992           ((mng_framp)*ppChunk)->iCount        = (iRemain - iRequired) / 4;
       
  4993 
       
  4994           if (((mng_framp)*ppChunk)->iCount)
       
  4995           {
       
  4996             MNG_ALLOC (pData, ((mng_framp)*ppChunk)->pSyncids,
       
  4997                               ((mng_framp)*ppChunk)->iCount * 4);
       
  4998 
       
  4999 #ifndef MNG_BIGENDIAN_SUPPORTED
       
  5000             {
       
  5001               mng_uint32 iX;
       
  5002               mng_uint32p pOut = ((mng_framp)*ppChunk)->pSyncids;
       
  5003 
       
  5004               for (iX = 0; iX < ((mng_framp)*ppChunk)->iCount; iX++)
       
  5005               {
       
  5006                 *pOut++ = mng_get_uint32 (pTemp);
       
  5007                 pTemp += 4;
       
  5008               }
       
  5009             }
       
  5010 #else
       
  5011             MNG_COPY (((mng_framp)*ppChunk)->pSyncids, pTemp,
       
  5012                       ((mng_framp)*ppChunk)->iCount * 4);
       
  5013 #endif /* !MNG_BIGENDIAN_SUPPORTED */
       
  5014           }
       
  5015         }
       
  5016       }
       
  5017     }
       
  5018   }
       
  5019 #endif /* MNG_STORE_CHUNKS */
       
  5020 
       
  5021 #ifdef MNG_SUPPORT_TRACE
       
  5022   MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_END);
       
  5023 #endif
       
  5024 
       
  5025   return MNG_NOERROR;                  /* done */
       
  5026 }
       
  5027 #endif
       
  5028 #endif
       
  5029 
       
  5030 /* ************************************************************************** */
       
  5031 
       
  5032 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5033 #ifndef MNG_SKIPCHUNK_MOVE
       
  5034 READ_CHUNK (mng_read_move)
       
  5035 {
       
  5036 #ifdef MNG_SUPPORT_TRACE
       
  5037   MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_START);
       
  5038 #endif
       
  5039 
       
  5040   if (!pData->bHasMHDR)                /* sequence checks */
       
  5041     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5042 
       
  5043 #ifdef MNG_INCLUDE_JNG
       
  5044   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5045 #else
       
  5046   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5047 #endif
       
  5048     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5049 
       
  5050   if (iRawlen != 13)                   /* check the length */
       
  5051     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5052 
       
  5053 #ifdef MNG_SUPPORT_DISPLAY
       
  5054   {
       
  5055     mng_retcode iRetcode;
       
  5056                                        /* create a MOVE animation object */
       
  5057     iRetcode = mng_create_ani_move (pData, mng_get_uint16 (pRawdata),
       
  5058                                            mng_get_uint16 (pRawdata+2),
       
  5059                                            *(pRawdata+4),
       
  5060                                            mng_get_int32 (pRawdata+5),
       
  5061                                            mng_get_int32 (pRawdata+9));
       
  5062 
       
  5063 /*    if (!iRetcode)
       
  5064       iRetcode = mng_process_display_move (pData,
       
  5065                                            mng_get_uint16 (pRawdata),
       
  5066                                            mng_get_uint16 (pRawdata+2),
       
  5067                                            *(pRawdata+4),
       
  5068                                            mng_get_int32 (pRawdata+5),
       
  5069                                            mng_get_int32 (pRawdata+9)); */
       
  5070 
       
  5071     if (iRetcode)                      /* on error bail out */
       
  5072       return iRetcode;
       
  5073 
       
  5074   }
       
  5075 #endif /* MNG_SUPPORT_DISPLAY */
       
  5076 
       
  5077 #ifdef MNG_STORE_CHUNKS
       
  5078   if (pData->bStorechunks)
       
  5079   {                                    /* initialize storage */
       
  5080     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5081 
       
  5082     if (iRetcode)                      /* on error bail out */
       
  5083       return iRetcode;
       
  5084                                        /* store the fields */
       
  5085     ((mng_movep)*ppChunk)->iFirstid  = mng_get_uint16 (pRawdata);
       
  5086     ((mng_movep)*ppChunk)->iLastid   = mng_get_uint16 (pRawdata+2);
       
  5087     ((mng_movep)*ppChunk)->iMovetype = *(pRawdata+4);
       
  5088     ((mng_movep)*ppChunk)->iMovex    = mng_get_int32 (pRawdata+5);
       
  5089     ((mng_movep)*ppChunk)->iMovey    = mng_get_int32 (pRawdata+9);
       
  5090   }
       
  5091 #endif /* MNG_STORE_CHUNKS */
       
  5092 
       
  5093 #ifdef MNG_SUPPORT_TRACE
       
  5094   MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_END);
       
  5095 #endif
       
  5096 
       
  5097   return MNG_NOERROR;                  /* done */
       
  5098 }
       
  5099 #endif
       
  5100 #endif
       
  5101 
       
  5102 /* ************************************************************************** */
       
  5103 
       
  5104 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5105 #ifndef MNG_SKIPCHUNK_CLIP
       
  5106 READ_CHUNK (mng_read_clip)
       
  5107 {
       
  5108 #ifdef MNG_SUPPORT_TRACE
       
  5109   MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_START);
       
  5110 #endif
       
  5111 
       
  5112   if (!pData->bHasMHDR)                /* sequence checks */
       
  5113     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5114 
       
  5115 #ifdef MNG_INCLUDE_JNG
       
  5116   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5117 #else
       
  5118   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5119 #endif
       
  5120     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5121 
       
  5122   if (iRawlen != 21)                   /* check the length */
       
  5123     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5124 
       
  5125 #ifdef MNG_SUPPORT_DISPLAY
       
  5126   {
       
  5127     mng_retcode iRetcode;
       
  5128                                        /* create a CLIP animation object */
       
  5129     iRetcode = mng_create_ani_clip (pData, mng_get_uint16 (pRawdata),
       
  5130                                            mng_get_uint16 (pRawdata+2),
       
  5131                                            *(pRawdata+4),
       
  5132                                            mng_get_int32 (pRawdata+5),
       
  5133                                            mng_get_int32 (pRawdata+9),
       
  5134                                            mng_get_int32 (pRawdata+13),
       
  5135                                            mng_get_int32 (pRawdata+17));
       
  5136 
       
  5137 /*    if (!iRetcode)
       
  5138       iRetcode = mng_process_display_clip (pData,
       
  5139                                            mng_get_uint16 (pRawdata),
       
  5140                                            mng_get_uint16 (pRawdata+2),
       
  5141                                            *(pRawdata+4),
       
  5142                                            mng_get_int32 (pRawdata+5),
       
  5143                                            mng_get_int32 (pRawdata+9),
       
  5144                                            mng_get_int32 (pRawdata+13),
       
  5145                                            mng_get_int32 (pRawdata+17)); */
       
  5146 
       
  5147     if (iRetcode)                      /* on error bail out */
       
  5148       return iRetcode;
       
  5149 
       
  5150   }
       
  5151 #endif /* MNG_SUPPORT_DISPLAY */
       
  5152 
       
  5153 #ifdef MNG_STORE_CHUNKS
       
  5154   if (pData->bStorechunks)
       
  5155   {                                    /* initialize storage */
       
  5156     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5157 
       
  5158     if (iRetcode)                      /* on error bail out */
       
  5159       return iRetcode;
       
  5160                                        /* store the fields */
       
  5161     ((mng_clipp)*ppChunk)->iFirstid  = mng_get_uint16 (pRawdata);
       
  5162     ((mng_clipp)*ppChunk)->iLastid   = mng_get_uint16 (pRawdata+2);
       
  5163     ((mng_clipp)*ppChunk)->iCliptype = *(pRawdata+4);
       
  5164     ((mng_clipp)*ppChunk)->iClipl    = mng_get_int32 (pRawdata+5);
       
  5165     ((mng_clipp)*ppChunk)->iClipr    = mng_get_int32 (pRawdata+9);
       
  5166     ((mng_clipp)*ppChunk)->iClipt    = mng_get_int32 (pRawdata+13);
       
  5167     ((mng_clipp)*ppChunk)->iClipb    = mng_get_int32 (pRawdata+17);
       
  5168   }
       
  5169 #endif /* MNG_STORE_CHUNKS */
       
  5170 
       
  5171 #ifdef MNG_SUPPORT_TRACE
       
  5172   MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_END);
       
  5173 #endif
       
  5174 
       
  5175   return MNG_NOERROR;                  /* done */
       
  5176 }
       
  5177 #endif
       
  5178 #endif
       
  5179 
       
  5180 /* ************************************************************************** */
       
  5181 
       
  5182 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5183 #ifndef MNG_SKIPCHUNK_SHOW
       
  5184 READ_CHUNK (mng_read_show)
       
  5185 {
       
  5186 #ifdef MNG_SUPPORT_TRACE
       
  5187   MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_START);
       
  5188 #endif
       
  5189 
       
  5190   if (!pData->bHasMHDR)                /* sequence checks */
       
  5191     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5192 
       
  5193 #ifdef MNG_INCLUDE_JNG
       
  5194   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5195 #else
       
  5196   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5197 #endif
       
  5198     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5199                                        /* check the length */
       
  5200   if ((iRawlen != 0) && (iRawlen != 2) && (iRawlen != 4) && (iRawlen != 5))
       
  5201     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5202 
       
  5203 #ifdef MNG_SUPPORT_DISPLAY
       
  5204   {
       
  5205     mng_retcode iRetcode;
       
  5206 
       
  5207     if (iRawlen)                       /* determine parameters if any */
       
  5208     {
       
  5209       pData->iSHOWfromid = mng_get_uint16 (pRawdata);
       
  5210 
       
  5211       if (iRawlen > 2)
       
  5212         pData->iSHOWtoid = mng_get_uint16 (pRawdata+2);
       
  5213       else
       
  5214         pData->iSHOWtoid = pData->iSHOWfromid;
       
  5215 
       
  5216       if (iRawlen > 4)
       
  5217         pData->iSHOWmode = *(pRawdata+4);
       
  5218       else
       
  5219         pData->iSHOWmode = 0;
       
  5220     }
       
  5221     else                               /* use defaults then */
       
  5222     {
       
  5223       pData->iSHOWmode   = 2;
       
  5224       pData->iSHOWfromid = 1;
       
  5225       pData->iSHOWtoid   = 65535;
       
  5226     }
       
  5227                                        /* create a SHOW animation object */
       
  5228     iRetcode = mng_create_ani_show (pData, pData->iSHOWfromid,
       
  5229                                     pData->iSHOWtoid, pData->iSHOWmode);
       
  5230 
       
  5231     if (!iRetcode)
       
  5232       iRetcode = mng_process_display_show (pData);
       
  5233 
       
  5234     if (iRetcode)                      /* on error bail out */
       
  5235       return iRetcode;
       
  5236 
       
  5237   }
       
  5238 #endif /* MNG_SUPPORT_DISPLAY */
       
  5239 
       
  5240 #ifdef MNG_STORE_CHUNKS
       
  5241   if (pData->bStorechunks)
       
  5242   {                                    /* initialize storage */
       
  5243     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5244 
       
  5245     if (iRetcode)                      /* on error bail out */
       
  5246       return iRetcode;
       
  5247                                        /* store the fields */
       
  5248     ((mng_showp)*ppChunk)->bEmpty      = (mng_bool)(iRawlen == 0);
       
  5249 
       
  5250     if (iRawlen)
       
  5251     {
       
  5252       ((mng_showp)*ppChunk)->iFirstid  = mng_get_uint16 (pRawdata);
       
  5253 
       
  5254       if (iRawlen > 2)
       
  5255         ((mng_showp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
       
  5256       else
       
  5257         ((mng_showp)*ppChunk)->iLastid = ((mng_showp)*ppChunk)->iFirstid;
       
  5258 
       
  5259       if (iRawlen > 4)
       
  5260         ((mng_showp)*ppChunk)->iMode   = *(pRawdata+4);
       
  5261     }
       
  5262   }
       
  5263 #endif /* MNG_STORE_CHUNKS */
       
  5264 
       
  5265 #ifdef MNG_SUPPORT_TRACE
       
  5266   MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_END);
       
  5267 #endif
       
  5268 
       
  5269   return MNG_NOERROR;                  /* done */
       
  5270 }
       
  5271 #endif
       
  5272 #endif
       
  5273 
       
  5274 /* ************************************************************************** */
       
  5275 
       
  5276 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5277 #ifndef MNG_SKIPCHUNK_TERM
       
  5278 READ_CHUNK (mng_read_term)
       
  5279 {
       
  5280   mng_uint8   iTermaction;
       
  5281   mng_uint8   iIteraction = 0;
       
  5282   mng_uint32  iDelay      = 0;
       
  5283   mng_uint32  iItermax    = 0;
       
  5284 
       
  5285 #ifdef MNG_SUPPORT_TRACE
       
  5286   MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_START);
       
  5287 #endif
       
  5288 
       
  5289   if (!pData->bHasMHDR)                /* sequence checks */
       
  5290     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5291 
       
  5292 #ifdef MNG_INCLUDE_JNG
       
  5293   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5294 #else
       
  5295   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5296 #endif
       
  5297     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5298 
       
  5299                                        /* should be behind MHDR or SAVE !! */
       
  5300   if ((!pData->bHasSAVE) && (pData->iChunkseq > 2))
       
  5301   {
       
  5302     pData->bMisplacedTERM = MNG_TRUE;  /* indicate we found a misplaced TERM */
       
  5303                                        /* and send a warning signal!!! */
       
  5304     MNG_WARNING (pData, MNG_SEQUENCEERROR);
       
  5305   }
       
  5306 
       
  5307   if (pData->bHasLOOP)                 /* no way, jose! */
       
  5308     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5309 
       
  5310   if (pData->bHasTERM)                 /* only 1 allowed! */
       
  5311     MNG_ERROR (pData, MNG_MULTIPLEERROR);
       
  5312                                        /* check the length */
       
  5313   if ((iRawlen != 1) && (iRawlen != 10))
       
  5314     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5315 
       
  5316   pData->bHasTERM = MNG_TRUE;
       
  5317 
       
  5318   iTermaction = *pRawdata;             /* get the fields */
       
  5319 
       
  5320   if (iRawlen > 1)
       
  5321   {
       
  5322     iIteraction = *(pRawdata+1);
       
  5323     iDelay      = mng_get_uint32 (pRawdata+2);
       
  5324     iItermax    = mng_get_uint32 (pRawdata+6);
       
  5325   }
       
  5326 
       
  5327   if (pData->fProcessterm)             /* inform the app ? */
       
  5328     if (!pData->fProcessterm (((mng_handle)pData), iTermaction, iIteraction,
       
  5329                                                    iDelay, iItermax))
       
  5330       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  5331 
       
  5332 #ifdef MNG_SUPPORT_DISPLAY
       
  5333   {                                    /* create the TERM ani-object */
       
  5334     mng_retcode iRetcode = mng_create_ani_term (pData, iTermaction, iIteraction,
       
  5335                                                 iDelay, iItermax);
       
  5336 
       
  5337     if (iRetcode)                      /* on error bail out */
       
  5338       return iRetcode;
       
  5339                                        /* save for future reference */
       
  5340     pData->pTermaniobj = pData->pLastaniobj;
       
  5341   }
       
  5342 #endif /* MNG_SUPPORT_DISPLAY */
       
  5343 
       
  5344 #ifdef MNG_STORE_CHUNKS
       
  5345   if (pData->bStorechunks)
       
  5346   {                                    /* initialize storage */
       
  5347     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5348 
       
  5349     if (iRetcode)                      /* on error bail out */
       
  5350       return iRetcode;
       
  5351                                        /* store the fields */
       
  5352     ((mng_termp)*ppChunk)->iTermaction = iTermaction;
       
  5353     ((mng_termp)*ppChunk)->iIteraction = iIteraction;
       
  5354     ((mng_termp)*ppChunk)->iDelay      = iDelay;
       
  5355     ((mng_termp)*ppChunk)->iItermax    = iItermax;
       
  5356   }
       
  5357 #endif /* MNG_STORE_CHUNKS */
       
  5358 
       
  5359 #ifdef MNG_SUPPORT_TRACE
       
  5360   MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_END);
       
  5361 #endif
       
  5362 
       
  5363   return MNG_NOERROR;                  /* done */
       
  5364 }
       
  5365 #endif
       
  5366 #endif
       
  5367 
       
  5368 /* ************************************************************************** */
       
  5369 
       
  5370 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5371 #ifndef MNG_SKIPCHUNK_SAVE
       
  5372 READ_CHUNK (mng_read_save)
       
  5373 {
       
  5374 #ifdef MNG_SUPPORT_TRACE
       
  5375   MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_START);
       
  5376 #endif
       
  5377                                        /* sequence checks */
       
  5378   if ((!pData->bHasMHDR) || (pData->bHasSAVE))
       
  5379     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5380 
       
  5381 #ifdef MNG_INCLUDE_JNG
       
  5382   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5383 #else
       
  5384   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5385 #endif
       
  5386     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5387 
       
  5388   pData->bHasSAVE = MNG_TRUE;
       
  5389 
       
  5390   if (pData->fProcesssave)             /* inform the application ? */
       
  5391   {
       
  5392     mng_bool bOke = pData->fProcesssave ((mng_handle)pData);
       
  5393 
       
  5394     if (!bOke)
       
  5395       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  5396   }
       
  5397 
       
  5398 #ifdef MNG_SUPPORT_DISPLAY
       
  5399   {
       
  5400     mng_retcode iRetcode;
       
  5401 
       
  5402 
       
  5403     /* TODO: something with the parameters */
       
  5404 
       
  5405 
       
  5406                                        /* create a SAVE animation object */
       
  5407     iRetcode = mng_create_ani_save (pData);
       
  5408 
       
  5409     if (!iRetcode)
       
  5410       iRetcode = mng_process_display_save (pData);
       
  5411 
       
  5412     if (iRetcode)                      /* on error bail out */
       
  5413       return iRetcode;
       
  5414       
       
  5415   }
       
  5416 #endif /* MNG_SUPPORT_DISPLAY */
       
  5417 
       
  5418 #ifdef MNG_STORE_CHUNKS
       
  5419   if (pData->bStorechunks)
       
  5420   {                                    /* initialize storage */
       
  5421     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5422 
       
  5423     if (iRetcode)                      /* on error bail out */
       
  5424       return iRetcode;
       
  5425                                        /* store the fields */
       
  5426     ((mng_savep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  5427 
       
  5428     if (iRawlen)                       /* not empty ? */
       
  5429     {
       
  5430       mng_uint8       iOtype = *pRawdata;
       
  5431       mng_uint8       iEtype;
       
  5432       mng_uint32      iCount = 0;
       
  5433       mng_uint8p      pTemp;
       
  5434       mng_uint8p      pNull;
       
  5435       mng_uint32      iLen;
       
  5436       mng_uint32      iOffset[2];
       
  5437       mng_uint32      iStarttime[2];
       
  5438       mng_uint32      iFramenr;
       
  5439       mng_uint32      iLayernr;
       
  5440       mng_uint32      iX;
       
  5441       mng_save_entryp pEntry = MNG_NULL;
       
  5442       mng_uint32      iNamesize;
       
  5443 
       
  5444       if ((iOtype != 4) && (iOtype != 8))
       
  5445         MNG_ERROR (pData, MNG_INVOFFSETSIZE);
       
  5446 
       
  5447       ((mng_savep)*ppChunk)->iOffsettype = iOtype;
       
  5448 
       
  5449       for (iX = 0; iX < 2; iX++)       /* do this twice to get the count first ! */
       
  5450       {
       
  5451         pTemp = pRawdata + 1;
       
  5452         iLen  = iRawlen  - 1;
       
  5453 
       
  5454         if (iX)                        /* second run ? */
       
  5455         {
       
  5456           MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_save_entry)));
       
  5457 
       
  5458           ((mng_savep)*ppChunk)->iCount   = iCount;
       
  5459           ((mng_savep)*ppChunk)->pEntries = pEntry;
       
  5460         }
       
  5461 
       
  5462         while (iLen)                   /* anything left ? */
       
  5463         {
       
  5464           iEtype = *pTemp;             /* entrytype */
       
  5465 
       
  5466           if ((iEtype != 0) && (iEtype != 1) && (iEtype != 2) && (iEtype != 3))
       
  5467             MNG_ERROR (pData, MNG_INVENTRYTYPE);
       
  5468 
       
  5469           pTemp++;
       
  5470 
       
  5471           if (iEtype > 1)
       
  5472           {
       
  5473             iOffset    [0] = 0;
       
  5474             iOffset    [1] = 0;
       
  5475             iStarttime [0] = 0;
       
  5476             iStarttime [1] = 0;
       
  5477             iLayernr       = 0;
       
  5478             iFramenr       = 0;
       
  5479           }
       
  5480           else
       
  5481           {
       
  5482             if (iOtype == 4)
       
  5483             {
       
  5484               iOffset [0] = 0;
       
  5485               iOffset [1] = mng_get_uint32 (pTemp);
       
  5486 
       
  5487               pTemp += 4;
       
  5488             }
       
  5489             else
       
  5490             {
       
  5491               iOffset [0] = mng_get_uint32 (pTemp);
       
  5492               iOffset [1] = mng_get_uint32 (pTemp+4);
       
  5493 
       
  5494               pTemp += 8;
       
  5495             }
       
  5496 
       
  5497             if (iEtype > 0)
       
  5498             {
       
  5499               iStarttime [0] = 0;
       
  5500               iStarttime [1] = 0;
       
  5501               iLayernr       = 0;
       
  5502               iFramenr       = 0;
       
  5503             }
       
  5504             else
       
  5505             {
       
  5506               if (iOtype == 4)
       
  5507               {
       
  5508                 iStarttime [0] = 0;
       
  5509                 iStarttime [1] = mng_get_uint32 (pTemp+0);
       
  5510                 iLayernr       = mng_get_uint32 (pTemp+4);
       
  5511                 iFramenr       = mng_get_uint32 (pTemp+8);
       
  5512 
       
  5513                 pTemp += 12;
       
  5514               }
       
  5515               else
       
  5516               {
       
  5517                 iStarttime [0] = mng_get_uint32 (pTemp+0);
       
  5518                 iStarttime [1] = mng_get_uint32 (pTemp+4);
       
  5519                 iLayernr       = mng_get_uint32 (pTemp+8);
       
  5520                 iFramenr       = mng_get_uint32 (pTemp+12);
       
  5521 
       
  5522                 pTemp += 16;
       
  5523               }
       
  5524             }
       
  5525           }
       
  5526 
       
  5527           pNull = find_null (pTemp);   /* get the name length */
       
  5528 
       
  5529           if ((pNull - pRawdata) > (mng_int32)iRawlen)
       
  5530           {
       
  5531             iNamesize = iLen;          /* no null found; so end of SAVE */
       
  5532             iLen      = 0;
       
  5533           }
       
  5534           else
       
  5535           {
       
  5536             iNamesize = pNull - pTemp; /* should be another entry */
       
  5537             iLen     -= iNamesize;
       
  5538 
       
  5539             if (!iLen)                 /* must not end with a null ! */
       
  5540               MNG_ERROR (pData, MNG_ENDWITHNULL);
       
  5541           }
       
  5542 
       
  5543           if (!pEntry)
       
  5544           {
       
  5545             iCount++;
       
  5546           }
       
  5547           else
       
  5548           {
       
  5549             pEntry->iEntrytype     = iEtype;
       
  5550             pEntry->iOffset    [0] = iOffset    [0];
       
  5551             pEntry->iOffset    [1] = iOffset    [1];
       
  5552             pEntry->iStarttime [0] = iStarttime [0];
       
  5553             pEntry->iStarttime [1] = iStarttime [1];
       
  5554             pEntry->iLayernr       = iLayernr;
       
  5555             pEntry->iFramenr       = iFramenr;
       
  5556             pEntry->iNamesize      = iNamesize;
       
  5557 
       
  5558             if (iNamesize)
       
  5559             {
       
  5560               MNG_ALLOC (pData, pEntry->zName, iNamesize+1);
       
  5561               MNG_COPY (pEntry->zName, pTemp, iNamesize);
       
  5562             }
       
  5563 
       
  5564             pEntry++;
       
  5565           }
       
  5566 
       
  5567           pTemp += iNamesize;
       
  5568         }
       
  5569       }
       
  5570     }
       
  5571   }
       
  5572 #endif /* MNG_STORE_CHUNKS */
       
  5573 
       
  5574 #ifdef MNG_SUPPORT_TRACE
       
  5575   MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_END);
       
  5576 #endif
       
  5577 
       
  5578   return MNG_NOERROR;                  /* done */
       
  5579 }
       
  5580 #endif
       
  5581 #endif
       
  5582 
       
  5583 /* ************************************************************************** */
       
  5584 
       
  5585 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5586 #ifndef MNG_SKIPCHUNK_SEEK
       
  5587 READ_CHUNK (mng_read_seek)
       
  5588 {
       
  5589   mng_retcode iRetcode;
       
  5590 
       
  5591 #ifdef MNG_SUPPORT_TRACE
       
  5592   MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_START);
       
  5593 #endif
       
  5594                                        /* sequence checks */
       
  5595   if ((!pData->bHasMHDR) || (!pData->bHasSAVE))
       
  5596     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5597 
       
  5598 #ifdef MNG_INCLUDE_JNG
       
  5599   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5600 #else
       
  5601   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5602 #endif
       
  5603     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5604 
       
  5605 #ifdef MNG_SUPPORT_DISPLAY
       
  5606                                        /* create a SEEK animation object */
       
  5607   iRetcode = mng_create_ani_seek (pData, iRawlen, (mng_pchar)pRawdata);
       
  5608 
       
  5609   if (iRetcode)                        /* on error bail out */
       
  5610     return iRetcode;
       
  5611     
       
  5612 #endif /* MNG_SUPPORT_DISPLAY */
       
  5613 
       
  5614   if (pData->fProcessseek)             /* inform the app ? */
       
  5615   {
       
  5616     mng_bool  bOke;
       
  5617     mng_pchar zName;
       
  5618 
       
  5619     MNG_ALLOC (pData, zName, iRawlen + 1);
       
  5620 
       
  5621     if (iRawlen)
       
  5622       MNG_COPY (zName, pRawdata, iRawlen);
       
  5623 
       
  5624     bOke = pData->fProcessseek ((mng_handle)pData, zName);
       
  5625 
       
  5626     MNG_FREEX (pData, zName, iRawlen + 1);
       
  5627 
       
  5628     if (!bOke)
       
  5629       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  5630   }
       
  5631 
       
  5632 #ifdef MNG_SUPPORT_DISPLAY
       
  5633                                        /* do display processing of the SEEK */
       
  5634   iRetcode = mng_process_display_seek (pData);
       
  5635 
       
  5636   if (iRetcode)                        /* on error bail out */
       
  5637     return iRetcode;
       
  5638 #endif /* MNG_SUPPORT_DISPLAY */
       
  5639 
       
  5640 #ifdef MNG_STORE_CHUNKS
       
  5641   if (pData->bStorechunks)
       
  5642   {                                    /* initialize storage */
       
  5643     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5644 
       
  5645     if (iRetcode)                      /* on error bail out */
       
  5646       return iRetcode;
       
  5647                                        /* store the fields */
       
  5648     ((mng_seekp)*ppChunk)->iNamesize = iRawlen;
       
  5649 
       
  5650     if (iRawlen)
       
  5651     {
       
  5652       MNG_ALLOC (pData, ((mng_seekp)*ppChunk)->zName, iRawlen+1);
       
  5653       MNG_COPY (((mng_seekp)*ppChunk)->zName, pRawdata, iRawlen);
       
  5654     }
       
  5655   }
       
  5656 #endif /* MNG_STORE_CHUNKS */
       
  5657 
       
  5658 #ifdef MNG_SUPPORT_TRACE
       
  5659   MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_END);
       
  5660 #endif
       
  5661 
       
  5662   return MNG_NOERROR;                  /* done */
       
  5663 }
       
  5664 #endif
       
  5665 #endif
       
  5666 
       
  5667 /* ************************************************************************** */
       
  5668 
       
  5669 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5670 #ifndef MNG_SKIPCHUNK_eXPI
       
  5671 READ_CHUNK (mng_read_expi)
       
  5672 {
       
  5673 #ifdef MNG_SUPPORT_TRACE
       
  5674   MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_START);
       
  5675 #endif
       
  5676 
       
  5677   if (!pData->bHasMHDR)                /* sequence checks */
       
  5678     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5679 
       
  5680 #ifdef MNG_INCLUDE_JNG
       
  5681   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5682 #else
       
  5683   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5684 #endif
       
  5685     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5686 
       
  5687   if (iRawlen < 3)                     /* check the length */
       
  5688     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5689 
       
  5690 #ifdef MNG_SUPPORT_DISPLAY
       
  5691   {
       
  5692 
       
  5693 
       
  5694     /* TODO: something !!! */
       
  5695 
       
  5696 
       
  5697   }
       
  5698 #endif /* MNG_SUPPORT_DISPLAY */
       
  5699 
       
  5700 #ifdef MNG_STORE_CHUNKS
       
  5701   if (pData->bStorechunks)
       
  5702   {                                    /* initialize storage */
       
  5703     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5704 
       
  5705     if (iRetcode)                      /* on error bail out */
       
  5706       return iRetcode;
       
  5707                                        /* store the fields */
       
  5708     ((mng_expip)*ppChunk)->iSnapshotid = mng_get_uint16 (pRawdata);
       
  5709     ((mng_expip)*ppChunk)->iNamesize   = iRawlen - 2;
       
  5710 
       
  5711     if (((mng_expip)*ppChunk)->iNamesize)
       
  5712     {
       
  5713       MNG_ALLOC (pData, ((mng_expip)*ppChunk)->zName,
       
  5714                         ((mng_expip)*ppChunk)->iNamesize + 1);
       
  5715       MNG_COPY (((mng_expip)*ppChunk)->zName, pRawdata+2,
       
  5716                 ((mng_expip)*ppChunk)->iNamesize);
       
  5717     }
       
  5718   }
       
  5719 #endif /* MNG_STORE_CHUNKS */
       
  5720 
       
  5721 #ifdef MNG_SUPPORT_TRACE
       
  5722   MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_END);
       
  5723 #endif
       
  5724 
       
  5725   return MNG_NOERROR;                  /* done */
       
  5726 }
       
  5727 #endif
       
  5728 #endif
       
  5729 
       
  5730 /* ************************************************************************** */
       
  5731 
       
  5732 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5733 #ifndef MNG_SKIPCHUNK_fPRI
       
  5734 READ_CHUNK (mng_read_fpri)
       
  5735 {
       
  5736 #ifdef MNG_SUPPORT_TRACE
       
  5737   MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_START);
       
  5738 #endif
       
  5739 
       
  5740   if (!pData->bHasMHDR)                /* sequence checks */
       
  5741     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5742 
       
  5743 #ifdef MNG_INCLUDE_JNG
       
  5744   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5745 #else
       
  5746   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5747 #endif
       
  5748     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5749 
       
  5750   if (iRawlen != 2)                    /* must be two bytes long */
       
  5751     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5752 
       
  5753 #ifdef MNG_SUPPORT_DISPLAY
       
  5754   {
       
  5755 
       
  5756 
       
  5757     /* TODO: something !!! */
       
  5758 
       
  5759 
       
  5760   }
       
  5761 #endif /* MNG_SUPPORT_DISPLAY */
       
  5762 
       
  5763 #ifdef MNG_STORE_CHUNKS
       
  5764   if (pData->bStorechunks)
       
  5765   {                                    /* initialize storage */
       
  5766     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  5767 
       
  5768     if (iRetcode)                      /* on error bail out */
       
  5769       return iRetcode;
       
  5770                                        /* store the fields */
       
  5771     ((mng_fprip)*ppChunk)->iDeltatype = *pRawdata;
       
  5772     ((mng_fprip)*ppChunk)->iPriority  = *(pRawdata+1);
       
  5773   }
       
  5774 #endif /* MNG_STORE_CHUNKS */
       
  5775 
       
  5776 #ifdef MNG_SUPPORT_TRACE
       
  5777   MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_END);
       
  5778 #endif
       
  5779 
       
  5780   return MNG_NOERROR;                  /* done */
       
  5781 }
       
  5782 #endif
       
  5783 #endif
       
  5784 
       
  5785 /* ************************************************************************** */
       
  5786 
       
  5787 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5788 #ifndef MNG_SKIPCHUNK_nEED
       
  5789 MNG_LOCAL mng_bool CheckKeyword (mng_datap  pData,
       
  5790                                  mng_uint8p pKeyword)
       
  5791 {
       
  5792   mng_chunkid handled_chunks [] =
       
  5793   {
       
  5794     MNG_UINT_BACK,                     /* keep it sorted !!!! */
       
  5795     MNG_UINT_BASI,
       
  5796     MNG_UINT_CLIP,
       
  5797     MNG_UINT_CLON,
       
  5798 #ifndef MNG_NO_DELTA_PNG
       
  5799 /* TODO:    MNG_UINT_DBYK,  */
       
  5800 #endif
       
  5801     MNG_UINT_DEFI,
       
  5802 #ifndef MNG_NO_DELTA_PNG
       
  5803     MNG_UINT_DHDR,
       
  5804 #endif
       
  5805     MNG_UINT_DISC,
       
  5806 #ifndef MNG_NO_DELTA_PNG
       
  5807 /* TODO:    MNG_UINT_DROP,  */
       
  5808 #endif
       
  5809     MNG_UINT_ENDL,
       
  5810     MNG_UINT_FRAM,
       
  5811     MNG_UINT_IDAT,
       
  5812     MNG_UINT_IEND,
       
  5813     MNG_UINT_IHDR,
       
  5814 #ifndef MNG_NO_DELTA_PNG
       
  5815 #ifdef MNG_INCLUDE_JNG
       
  5816     MNG_UINT_IJNG,
       
  5817 #endif    
       
  5818     MNG_UINT_IPNG,
       
  5819 #endif
       
  5820 #ifdef MNG_INCLUDE_JNG
       
  5821     MNG_UINT_JDAA,
       
  5822     MNG_UINT_JDAT,
       
  5823     MNG_UINT_JHDR,
       
  5824 /* TODO:    MNG_UINT_JSEP,  */
       
  5825     MNG_UINT_JdAA,
       
  5826 #endif
       
  5827     MNG_UINT_LOOP,
       
  5828     MNG_UINT_MAGN,
       
  5829     MNG_UINT_MEND,
       
  5830     MNG_UINT_MHDR,
       
  5831     MNG_UINT_MOVE,
       
  5832 /* TODO:    MNG_UINT_ORDR,  */
       
  5833     MNG_UINT_PAST,
       
  5834     MNG_UINT_PLTE,
       
  5835 #ifndef MNG_NO_DELTA_PNG
       
  5836     MNG_UINT_PPLT,
       
  5837     MNG_UINT_PROM,
       
  5838 #endif
       
  5839     MNG_UINT_SAVE,
       
  5840     MNG_UINT_SEEK,
       
  5841     MNG_UINT_SHOW,
       
  5842     MNG_UINT_TERM,
       
  5843 #ifdef MNG_INCLUDE_ANG_PROPOSAL
       
  5844     MNG_UINT_adAT,
       
  5845     MNG_UINT_ahDR,
       
  5846 #endif
       
  5847     MNG_UINT_bKGD,
       
  5848     MNG_UINT_cHRM,
       
  5849 /* TODO:    MNG_UINT_eXPI,  */
       
  5850     MNG_UINT_evNT,
       
  5851 /* TODO:    MNG_UINT_fPRI,  */
       
  5852     MNG_UINT_gAMA,
       
  5853 /* TODO:    MNG_UINT_hIST,  */
       
  5854     MNG_UINT_iCCP,
       
  5855     MNG_UINT_iTXt,
       
  5856 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
       
  5857     MNG_UINT_mpNG,
       
  5858 #endif
       
  5859     MNG_UINT_nEED,
       
  5860 /* TODO:    MNG_UINT_oFFs,  */
       
  5861 /* TODO:    MNG_UINT_pCAL,  */
       
  5862 /* TODO:    MNG_UINT_pHYg,  */
       
  5863 /* TODO:    MNG_UINT_pHYs,  */
       
  5864 /* TODO:    MNG_UINT_sBIT,  */
       
  5865 /* TODO:    MNG_UINT_sCAL,  */
       
  5866 /* TODO:    MNG_UINT_sPLT,  */
       
  5867     MNG_UINT_sRGB,
       
  5868     MNG_UINT_tEXt,
       
  5869     MNG_UINT_tIME,
       
  5870     MNG_UINT_tRNS,
       
  5871     MNG_UINT_zTXt,
       
  5872   };
       
  5873 
       
  5874   mng_bool bOke = MNG_FALSE;
       
  5875 
       
  5876   if (pData->fProcessneed)             /* does the app handle it ? */
       
  5877     bOke = pData->fProcessneed ((mng_handle)pData, (mng_pchar)pKeyword);
       
  5878 
       
  5879   if (!bOke)
       
  5880   {                                    /* find the keyword length */
       
  5881     mng_uint8p pNull = find_null (pKeyword);
       
  5882 
       
  5883     if (pNull - pKeyword == 4)         /* test a chunk ? */
       
  5884     {                                  /* get the chunk-id */
       
  5885       mng_chunkid iChunkid = (*pKeyword     << 24) + (*(pKeyword+1) << 16) +
       
  5886                              (*(pKeyword+2) <<  8) + (*(pKeyword+3)      );
       
  5887                                        /* binary search variables */
       
  5888       mng_int32   iTop, iLower, iUpper, iMiddle;
       
  5889                                        /* determine max index of table */
       
  5890       iTop = (sizeof (handled_chunks) / sizeof (handled_chunks [0])) - 1;
       
  5891 
       
  5892       /* binary search; with 52 chunks, worst-case is 7 comparisons */
       
  5893       iLower  = 0;
       
  5894       iMiddle = iTop >> 1;
       
  5895       iUpper  = iTop;
       
  5896 
       
  5897       do                                   /* the binary search itself */
       
  5898         {
       
  5899           if (handled_chunks [iMiddle] < iChunkid)
       
  5900             iLower = iMiddle + 1;
       
  5901           else if (handled_chunks [iMiddle] > iChunkid)
       
  5902             iUpper = iMiddle - 1;
       
  5903           else
       
  5904           {
       
  5905             bOke = MNG_TRUE;
       
  5906             break;
       
  5907           }
       
  5908 
       
  5909           iMiddle = (iLower + iUpper) >> 1;
       
  5910         }
       
  5911       while (iLower <= iUpper);
       
  5912     }
       
  5913                                        /* test draft ? */
       
  5914     if ((!bOke) && (pNull - pKeyword == 8) &&
       
  5915         (*pKeyword     == 'd') && (*(pKeyword+1) == 'r') &&
       
  5916         (*(pKeyword+2) == 'a') && (*(pKeyword+3) == 'f') &&
       
  5917         (*(pKeyword+4) == 't') && (*(pKeyword+5) == ' '))
       
  5918     {
       
  5919       mng_uint32 iDraft;
       
  5920 
       
  5921       iDraft = (*(pKeyword+6) - '0') * 10 + (*(pKeyword+7) - '0');
       
  5922       bOke   = (mng_bool)(iDraft <= MNG_MNG_DRAFT);
       
  5923     }
       
  5924                                        /* test MNG 1.0/1.1 ? */
       
  5925     if ((!bOke) && (pNull - pKeyword == 7) &&
       
  5926         (*pKeyword     == 'M') && (*(pKeyword+1) == 'N') &&
       
  5927         (*(pKeyword+2) == 'G') && (*(pKeyword+3) == '-') &&
       
  5928         (*(pKeyword+4) == '1') && (*(pKeyword+5) == '.') &&
       
  5929         ((*(pKeyword+6) == '0') || (*(pKeyword+6) == '1')))
       
  5930       bOke   = MNG_TRUE;
       
  5931                                        /* test CACHEOFF ? */
       
  5932     if ((!bOke) && (pNull - pKeyword == 8) &&
       
  5933         (*pKeyword     == 'C') && (*(pKeyword+1) == 'A') &&
       
  5934         (*(pKeyword+2) == 'C') && (*(pKeyword+3) == 'H') &&
       
  5935         (*(pKeyword+4) == 'E') && (*(pKeyword+5) == 'O') &&
       
  5936         (*(pKeyword+6) == 'F') && (*(pKeyword+7) == 'F'))
       
  5937     {
       
  5938       if (!pData->pFirstaniobj)        /* only if caching hasn't started yet ! */
       
  5939       {
       
  5940         bOke                  = MNG_TRUE;
       
  5941         pData->bCacheplayback = MNG_FALSE;
       
  5942         pData->bStorechunks   = MNG_FALSE;
       
  5943       }
       
  5944     }
       
  5945   }
       
  5946 
       
  5947   return bOke;
       
  5948 }
       
  5949 #endif
       
  5950 #endif
       
  5951 
       
  5952 /* ************************************************************************** */
       
  5953 
       
  5954 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  5955 #ifndef MNG_SKIPCHUNK_nEED
       
  5956 READ_CHUNK (mng_read_need)
       
  5957 {
       
  5958 #ifdef MNG_SUPPORT_TRACE
       
  5959   MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_START);
       
  5960 #endif
       
  5961 
       
  5962   if (!pData->bHasMHDR)                /* sequence checks */
       
  5963     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5964 
       
  5965 #ifdef MNG_INCLUDE_JNG
       
  5966   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  5967 #else
       
  5968   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  5969 #endif
       
  5970     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  5971 
       
  5972   if (iRawlen < 1)                     /* check the length */
       
  5973     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  5974 
       
  5975   {                                    /* let's check it */
       
  5976     mng_bool   bOke = MNG_TRUE;
       
  5977     mng_pchar  zKeywords;
       
  5978     mng_uint8p pNull, pTemp;
       
  5979 
       
  5980     MNG_ALLOC (pData, zKeywords, iRawlen + 1);
       
  5981 
       
  5982     if (iRawlen)
       
  5983       MNG_COPY (zKeywords, pRawdata, iRawlen);
       
  5984 
       
  5985     pTemp = (mng_uint8p)zKeywords;
       
  5986     pNull = find_null (pTemp);
       
  5987 
       
  5988     while ((bOke) && (pNull < (mng_uint8p)zKeywords + iRawlen))
       
  5989     {
       
  5990       bOke  = CheckKeyword (pData, pTemp);
       
  5991       pTemp = pNull + 1;
       
  5992       pNull = find_null (pTemp);
       
  5993     }
       
  5994 
       
  5995     if (bOke)
       
  5996       bOke = CheckKeyword (pData, pTemp);
       
  5997 
       
  5998     MNG_FREEX (pData, zKeywords, iRawlen + 1);
       
  5999 
       
  6000     if (!bOke)
       
  6001       MNG_ERROR (pData, MNG_UNSUPPORTEDNEED);
       
  6002   }
       
  6003 
       
  6004 #ifdef MNG_STORE_CHUNKS
       
  6005   if (pData->bStorechunks)
       
  6006   {                                    /* initialize storage */
       
  6007     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6008 
       
  6009     if (iRetcode)                      /* on error bail out */
       
  6010       return iRetcode;
       
  6011                                        /* store the fields */
       
  6012     ((mng_needp)*ppChunk)->iKeywordssize = iRawlen;
       
  6013 
       
  6014     if (iRawlen)
       
  6015     {
       
  6016       MNG_ALLOC (pData, ((mng_needp)*ppChunk)->zKeywords, iRawlen+1);
       
  6017       MNG_COPY (((mng_needp)*ppChunk)->zKeywords, pRawdata, iRawlen);
       
  6018     }
       
  6019   }
       
  6020 #endif /* MNG_STORE_CHUNKS */
       
  6021 
       
  6022 #ifdef MNG_SUPPORT_TRACE
       
  6023   MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_END);
       
  6024 #endif
       
  6025 
       
  6026   return MNG_NOERROR;                  /* done */
       
  6027 }
       
  6028 #endif
       
  6029 #endif
       
  6030 
       
  6031 /* ************************************************************************** */
       
  6032 
       
  6033 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6034 #ifndef MNG_SKIPCHUNK_pHYg
       
  6035 READ_CHUNK (mng_read_phyg)
       
  6036 {
       
  6037 #ifdef MNG_SUPPORT_TRACE
       
  6038   MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_START);
       
  6039 #endif
       
  6040 
       
  6041   if (!pData->bHasMHDR)                /* sequence checks */
       
  6042     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6043 
       
  6044 #ifdef MNG_INCLUDE_JNG
       
  6045   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  6046 #else
       
  6047   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  6048 #endif
       
  6049     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6050                                        /* it's 9 bytes or empty; no more, no less! */
       
  6051   if ((iRawlen != 9) && (iRawlen != 0))
       
  6052     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6053 
       
  6054 #ifdef MNG_SUPPORT_DISPLAY
       
  6055   {
       
  6056 
       
  6057 
       
  6058     /* TODO: something !!! */
       
  6059 
       
  6060 
       
  6061   }
       
  6062 #endif /* MNG_SUPPORT_DISPLAY */
       
  6063 
       
  6064 #ifdef MNG_STORE_CHUNKS
       
  6065   if (pData->bStorechunks)
       
  6066   {                                    /* initialize storage */
       
  6067     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6068 
       
  6069     if (iRetcode)                      /* on error bail out */
       
  6070       return iRetcode;
       
  6071                                        /* store the fields */
       
  6072     ((mng_phygp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
       
  6073 
       
  6074     if (iRawlen)
       
  6075     {
       
  6076       ((mng_phygp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
       
  6077       ((mng_phygp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
       
  6078       ((mng_phygp)*ppChunk)->iUnit  = *(pRawdata+8);
       
  6079     }
       
  6080   }
       
  6081 #endif /* MNG_STORE_CHUNKS */
       
  6082 
       
  6083 #ifdef MNG_SUPPORT_TRACE
       
  6084   MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_END);
       
  6085 #endif
       
  6086 
       
  6087   return MNG_NOERROR;                  /* done */
       
  6088 }
       
  6089 #endif
       
  6090 #endif
       
  6091 
       
  6092 /* ************************************************************************** */
       
  6093 
       
  6094 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6095 #ifdef MNG_INCLUDE_JNG
       
  6096 READ_CHUNK (mng_read_jhdr)
       
  6097 {
       
  6098 #ifdef MNG_SUPPORT_TRACE
       
  6099   MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_START);
       
  6100 #endif
       
  6101                                        /* sequence checks */
       
  6102   if ((pData->eSigtype != mng_it_jng) && (pData->eSigtype != mng_it_mng))
       
  6103     MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
       
  6104 
       
  6105   if ((pData->eSigtype == mng_it_jng) && (pData->iChunkseq > 1))
       
  6106     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6107 
       
  6108   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  6109     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6110 
       
  6111   if (iRawlen != 16)                   /* length oke ? */
       
  6112     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6113                                        /* inside a JHDR-IEND block now */
       
  6114   pData->bHasJHDR              = MNG_TRUE;
       
  6115                                        /* and store interesting fields */
       
  6116   pData->iDatawidth            = mng_get_uint32 (pRawdata);
       
  6117   pData->iDataheight           = mng_get_uint32 (pRawdata+4);
       
  6118   pData->iJHDRcolortype        = *(pRawdata+8);
       
  6119   pData->iJHDRimgbitdepth      = *(pRawdata+9);
       
  6120   pData->iJHDRimgcompression   = *(pRawdata+10);
       
  6121   pData->iJHDRimginterlace     = *(pRawdata+11);
       
  6122   pData->iJHDRalphabitdepth    = *(pRawdata+12);
       
  6123   pData->iJHDRalphacompression = *(pRawdata+13);
       
  6124   pData->iJHDRalphafilter      = *(pRawdata+14);
       
  6125   pData->iJHDRalphainterlace   = *(pRawdata+15);
       
  6126 
       
  6127 
       
  6128 #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
       
  6129   pData->iPNGmult = 1;
       
  6130   pData->iPNGdepth = pData->iJHDRalphabitdepth;
       
  6131 #endif
       
  6132 
       
  6133 #ifdef MNG_NO_1_2_4BIT_SUPPORT
       
  6134   if (pData->iJHDRalphabitdepth < 8)
       
  6135     pData->iJHDRalphabitdepth = 8;
       
  6136 #endif
       
  6137 
       
  6138 #ifdef MNG_NO_16BIT_SUPPORT
       
  6139   if (pData->iJHDRalphabitdepth > 8)
       
  6140   {
       
  6141     pData->iPNGmult = 2;
       
  6142     pData->iJHDRalphabitdepth = 8;
       
  6143   }
       
  6144 #endif
       
  6145                                        /* parameter validity checks */
       
  6146   if ((pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAY  ) &&
       
  6147       (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
       
  6148       (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
       
  6149       (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLORA)    )
       
  6150     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
       
  6151 
       
  6152   if ((pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8     ) &&
       
  6153       (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG12    ) &&
       
  6154       (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8AND12)    )
       
  6155     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  6156 
       
  6157   if (pData->iJHDRimgcompression != MNG_COMPRESSION_BASELINEJPEG)
       
  6158     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  6159 
       
  6160   if ((pData->iJHDRimginterlace != MNG_INTERLACE_SEQUENTIAL ) &&
       
  6161       (pData->iJHDRimginterlace != MNG_INTERLACE_PROGRESSIVE)    )
       
  6162     MNG_ERROR (pData, MNG_INVALIDINTERLACE);
       
  6163 
       
  6164   if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
       
  6165       (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
       
  6166   {
       
  6167     if ((pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 )
       
  6168 #ifndef MNG_NO_1_2_4BIT_SUPPORT
       
  6169         && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_1 ) &&
       
  6170         (pData->iJHDRalphabitdepth != MNG_BITDEPTH_2 ) &&
       
  6171         (pData->iJHDRalphabitdepth != MNG_BITDEPTH_4 )
       
  6172 #endif
       
  6173 #ifndef MNG_NO_16BIT_SUPPORT
       
  6174         && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_16)
       
  6175 #endif
       
  6176         )
       
  6177       MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  6178 
       
  6179     if ((pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE     ) &&
       
  6180         (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)    )
       
  6181       MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  6182 
       
  6183     if ((pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG) &&
       
  6184         (pData->iJHDRalphabitdepth    !=  MNG_BITDEPTH_8             )    )
       
  6185       MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  6186 
       
  6187 #if defined(FILTER192) || defined(FILTER193)
       
  6188     if ((pData->iJHDRalphafilter != MNG_FILTER_ADAPTIVE ) &&
       
  6189 #if defined(FILTER192) && defined(FILTER193)
       
  6190         (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) &&
       
  6191         (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER )    )
       
  6192 #else
       
  6193 #ifdef FILTER192
       
  6194         (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING)    )
       
  6195 #else
       
  6196         (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER )    )
       
  6197 #endif
       
  6198 #endif
       
  6199       MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  6200 #else
       
  6201     if (pData->iJHDRalphafilter)
       
  6202       MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  6203 #endif
       
  6204 
       
  6205     if ((pData->iJHDRalphainterlace != MNG_INTERLACE_NONE ) &&
       
  6206         (pData->iJHDRalphainterlace != MNG_INTERLACE_ADAM7)    )
       
  6207       MNG_ERROR (pData, MNG_INVALIDINTERLACE);
       
  6208 
       
  6209   }
       
  6210   else
       
  6211   {
       
  6212     if (pData->iJHDRalphabitdepth)
       
  6213       MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
       
  6214 
       
  6215     if (pData->iJHDRalphacompression)
       
  6216       MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  6217 
       
  6218     if (pData->iJHDRalphafilter)
       
  6219       MNG_ERROR (pData, MNG_INVALIDFILTER);
       
  6220 
       
  6221     if (pData->iJHDRalphainterlace)
       
  6222       MNG_ERROR (pData, MNG_INVALIDINTERLACE);
       
  6223 
       
  6224   }
       
  6225 
       
  6226   if (!pData->bHasheader)              /* first chunk ? */
       
  6227   {
       
  6228     pData->bHasheader = MNG_TRUE;      /* we've got a header */
       
  6229     pData->eImagetype = mng_it_jng;    /* then this must be a JNG */
       
  6230     pData->iWidth     = mng_get_uint32 (pRawdata);
       
  6231     pData->iHeight    = mng_get_uint32 (pRawdata+4);
       
  6232                                        /* predict alpha-depth ! */
       
  6233   if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
       
  6234       (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
       
  6235       pData->iAlphadepth = pData->iJHDRalphabitdepth;
       
  6236     else
       
  6237       pData->iAlphadepth = 0;
       
  6238                                        /* fits on maximum canvas ? */
       
  6239     if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
       
  6240       MNG_WARNING (pData, MNG_IMAGETOOLARGE);
       
  6241 
       
  6242     if (pData->fProcessheader)         /* inform the app ? */
       
  6243       if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
       
  6244       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  6245 
       
  6246   }
       
  6247 
       
  6248   pData->iColortype = 0;               /* fake grayscale for other routines */
       
  6249   pData->iImagelevel++;                /* one level deeper */
       
  6250 
       
  6251 #ifdef MNG_SUPPORT_DISPLAY
       
  6252   {
       
  6253     mng_retcode iRetcode = mng_process_display_jhdr (pData);
       
  6254 
       
  6255     if (iRetcode)                      /* on error bail out */
       
  6256       return iRetcode;
       
  6257   }
       
  6258 #endif /* MNG_SUPPORT_DISPLAY */
       
  6259 
       
  6260 #ifdef MNG_STORE_CHUNKS
       
  6261   if (pData->bStorechunks)
       
  6262   {                                    /* initialize storage */
       
  6263     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6264 
       
  6265     if (iRetcode)                      /* on error bail out */
       
  6266       return iRetcode;
       
  6267                                        /* store the fields */
       
  6268     ((mng_jhdrp)*ppChunk)->iWidth            = mng_get_uint32 (pRawdata);
       
  6269     ((mng_jhdrp)*ppChunk)->iHeight           = mng_get_uint32 (pRawdata+4);
       
  6270     ((mng_jhdrp)*ppChunk)->iColortype        = *(pRawdata+8);
       
  6271     ((mng_jhdrp)*ppChunk)->iImagesampledepth = *(pRawdata+9);
       
  6272     ((mng_jhdrp)*ppChunk)->iImagecompression = *(pRawdata+10);
       
  6273     ((mng_jhdrp)*ppChunk)->iImageinterlace   = *(pRawdata+11);
       
  6274     ((mng_jhdrp)*ppChunk)->iAlphasampledepth = *(pRawdata+12);
       
  6275 #ifdef MNG_NO_16BIT_SUPPORT
       
  6276     if (*(pRawdata+12) > 8)
       
  6277         ((mng_jhdrp)*ppChunk)->iAlphasampledepth = 8;
       
  6278 #endif
       
  6279     ((mng_jhdrp)*ppChunk)->iAlphacompression = *(pRawdata+13);
       
  6280     ((mng_jhdrp)*ppChunk)->iAlphafilter      = *(pRawdata+14);
       
  6281     ((mng_jhdrp)*ppChunk)->iAlphainterlace   = *(pRawdata+15);
       
  6282   }
       
  6283 #endif /* MNG_STORE_CHUNKS */
       
  6284 
       
  6285 #ifdef MNG_SUPPORT_TRACE
       
  6286   MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_END);
       
  6287 #endif
       
  6288 
       
  6289   return MNG_NOERROR;                  /* done */
       
  6290 }
       
  6291 #else
       
  6292 #define read_jhdr 0
       
  6293 #endif /* MNG_INCLUDE_JNG */
       
  6294 #endif
       
  6295 
       
  6296 /* ************************************************************************** */
       
  6297 
       
  6298 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6299 #ifdef MNG_INCLUDE_JNG
       
  6300 READ_CHUNK (mng_read_jdaa)
       
  6301 {
       
  6302 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  6303   volatile mng_retcode iRetcode;
       
  6304 
       
  6305   iRetcode=MNG_NOERROR;
       
  6306 #endif
       
  6307 
       
  6308 #ifdef MNG_SUPPORT_TRACE
       
  6309   MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_START);
       
  6310 #endif
       
  6311                                        /* sequence checks */
       
  6312   if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
       
  6313     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6314 
       
  6315   if (pData->bHasJSEP)
       
  6316     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6317     
       
  6318   if (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)
       
  6319     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6320 
       
  6321   if (iRawlen == 0)                    /* can never be empty */
       
  6322     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6323 
       
  6324   pData->bHasJDAA = MNG_TRUE;          /* got some JDAA now, don't we */
       
  6325 
       
  6326 #ifdef MNG_SUPPORT_DISPLAY
       
  6327   iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata);
       
  6328 
       
  6329   if (iRetcode)                      /* on error bail out */
       
  6330     return iRetcode;
       
  6331 #endif /* MNG_SUPPORT_DISPLAY */
       
  6332 
       
  6333 #ifdef MNG_STORE_CHUNKS
       
  6334   if (pData->bStorechunks)
       
  6335   {                                    /* initialize storage */
       
  6336     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6337 
       
  6338     if (iRetcode)                      /* on error bail out */
       
  6339       return iRetcode;
       
  6340                                        /* store the fields */
       
  6341     ((mng_jdaap)*ppChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
       
  6342     ((mng_jdaap)*ppChunk)->iDatasize = iRawlen;
       
  6343 
       
  6344     if (iRawlen != 0)                  /* is there any data ? */
       
  6345     {
       
  6346       MNG_ALLOC (pData, ((mng_jdaap)*ppChunk)->pData, iRawlen);
       
  6347       MNG_COPY  (((mng_jdaap)*ppChunk)->pData, pRawdata, iRawlen);
       
  6348     }
       
  6349   }
       
  6350 #endif /* MNG_STORE_CHUNKS */
       
  6351 
       
  6352 #ifdef MNG_SUPPORT_TRACE
       
  6353   MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_END);
       
  6354 #endif
       
  6355 
       
  6356   return MNG_NOERROR;                  /* done */
       
  6357 }
       
  6358 #else
       
  6359 #define read_jdaa 0
       
  6360 #endif /* MNG_INCLUDE_JNG */
       
  6361 #endif
       
  6362 
       
  6363 /* ************************************************************************** */
       
  6364 
       
  6365 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6366 #ifdef MNG_INCLUDE_JNG
       
  6367 READ_CHUNK (mng_read_jdat)
       
  6368 {
       
  6369 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  6370   volatile mng_retcode iRetcode;
       
  6371 
       
  6372   iRetcode=MNG_NOERROR;
       
  6373 #endif
       
  6374 
       
  6375 #ifdef MNG_SUPPORT_TRACE
       
  6376   MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_START);
       
  6377 #endif
       
  6378                                        /* sequence checks */
       
  6379   if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
       
  6380     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6381 
       
  6382   if (iRawlen == 0)                    /* can never be empty */
       
  6383     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6384 
       
  6385   pData->bHasJDAT = MNG_TRUE;          /* got some JDAT now, don't we */
       
  6386 
       
  6387 #ifdef MNG_SUPPORT_DISPLAY
       
  6388   iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata);
       
  6389 
       
  6390   if (iRetcode)                      /* on error bail out */
       
  6391     return iRetcode;
       
  6392 #endif /* MNG_SUPPORT_DISPLAY */
       
  6393 
       
  6394 #ifdef MNG_STORE_CHUNKS
       
  6395   if (pData->bStorechunks)
       
  6396   {                                    /* initialize storage */
       
  6397     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6398 
       
  6399     if (iRetcode)                      /* on error bail out */
       
  6400       return iRetcode;
       
  6401                                        /* store the fields */
       
  6402     ((mng_jdatp)*ppChunk)->bEmpty    = (mng_bool)(iRawlen == 0);
       
  6403     ((mng_jdatp)*ppChunk)->iDatasize = iRawlen;
       
  6404 
       
  6405     if (iRawlen != 0)                  /* is there any data ? */
       
  6406     {
       
  6407       MNG_ALLOC (pData, ((mng_jdatp)*ppChunk)->pData, iRawlen);
       
  6408       MNG_COPY  (((mng_jdatp)*ppChunk)->pData, pRawdata, iRawlen);
       
  6409     }
       
  6410   }
       
  6411 #endif /* MNG_STORE_CHUNKS */
       
  6412 
       
  6413 #ifdef MNG_SUPPORT_TRACE
       
  6414   MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_END);
       
  6415 #endif
       
  6416 
       
  6417   return MNG_NOERROR;                  /* done */
       
  6418 }
       
  6419 #else
       
  6420 #define read_jdat 0
       
  6421 #endif /* MNG_INCLUDE_JNG */
       
  6422 #endif
       
  6423 
       
  6424 /* ************************************************************************** */
       
  6425 
       
  6426 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6427 #ifdef MNG_INCLUDE_JNG
       
  6428 READ_CHUNK (mng_read_jsep)
       
  6429 {
       
  6430 #ifdef MNG_SUPPORT_TRACE
       
  6431   MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_START);
       
  6432 #endif
       
  6433 
       
  6434   if (!pData->bHasJHDR)                /* sequence checks */
       
  6435     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6436 
       
  6437   if (iRawlen != 0)                    /* must be empty ! */
       
  6438     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6439 
       
  6440   pData->bHasJSEP = MNG_TRUE;          /* indicate we've had the 8-/12-bit separator */
       
  6441 
       
  6442 #ifdef MNG_STORE_CHUNKS
       
  6443   if (pData->bStorechunks)
       
  6444   {                                    /* initialize storage */
       
  6445     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6446 
       
  6447     if (iRetcode)                      /* on error bail out */
       
  6448       return iRetcode;
       
  6449 
       
  6450   }
       
  6451 #endif /* MNG_STORE_CHUNKS */
       
  6452 
       
  6453 #ifdef MNG_SUPPORT_TRACE
       
  6454   MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_END);
       
  6455 #endif
       
  6456 
       
  6457   return MNG_NOERROR;                  /* done */
       
  6458 }
       
  6459 #else
       
  6460 #define read_jsep 0
       
  6461 #endif /* MNG_INCLUDE_JNG */
       
  6462 #endif
       
  6463 
       
  6464 /* ************************************************************************** */
       
  6465 
       
  6466 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6467 #ifndef MNG_NO_DELTA_PNG
       
  6468 READ_CHUNK (mng_read_dhdr)
       
  6469 {
       
  6470   mng_uint8 iImagetype, iDeltatype;
       
  6471 #ifdef MNG_SUPPORT_TRACE
       
  6472   MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_START);
       
  6473 #endif
       
  6474 
       
  6475   if (!pData->bHasMHDR)                /* sequence checks */
       
  6476     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6477 
       
  6478 #ifdef MNG_INCLUDE_JNG
       
  6479   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  6480 #else
       
  6481   if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
       
  6482 #endif
       
  6483     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6484                                        /* check for valid length */
       
  6485   if ((iRawlen != 4) && (iRawlen != 12) && (iRawlen != 20))
       
  6486     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6487 
       
  6488   iImagetype = *(pRawdata+2);          /* check fields for validity */
       
  6489   iDeltatype = *(pRawdata+3);
       
  6490 
       
  6491   if (iImagetype > MNG_IMAGETYPE_JNG)
       
  6492     MNG_ERROR (pData, MNG_INVIMAGETYPE);
       
  6493 
       
  6494   if (iDeltatype > MNG_DELTATYPE_NOCHANGE)
       
  6495     MNG_ERROR (pData, MNG_INVDELTATYPE);
       
  6496 
       
  6497   if ((iDeltatype == MNG_DELTATYPE_REPLACE) && (iRawlen > 12))
       
  6498     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6499 
       
  6500   if ((iDeltatype == MNG_DELTATYPE_NOCHANGE) && (iRawlen > 4))
       
  6501     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6502 
       
  6503   pData->bHasDHDR   = MNG_TRUE;        /* inside a DHDR-IEND block now */
       
  6504   pData->iDeltatype = iDeltatype;
       
  6505 
       
  6506   pData->iImagelevel++;                /* one level deeper */
       
  6507 
       
  6508 #ifdef MNG_SUPPORT_DISPLAY
       
  6509   {
       
  6510     mng_uint16  iObjectid    = mng_get_uint16 (pRawdata);
       
  6511     mng_uint32  iBlockwidth  = 0;
       
  6512     mng_uint32  iBlockheight = 0;
       
  6513     mng_uint32  iBlockx      = 0;
       
  6514     mng_uint32  iBlocky      = 0;
       
  6515     mng_retcode iRetcode;
       
  6516 
       
  6517     if (iRawlen > 4)
       
  6518     {
       
  6519       iBlockwidth  = mng_get_uint32 (pRawdata+4);
       
  6520       iBlockheight = mng_get_uint32 (pRawdata+8);
       
  6521     }
       
  6522 
       
  6523     if (iRawlen > 12)
       
  6524     {
       
  6525       iBlockx      = mng_get_uint32 (pRawdata+12);
       
  6526       iBlocky      = mng_get_uint32 (pRawdata+16);
       
  6527     }
       
  6528 
       
  6529     iRetcode = mng_create_ani_dhdr (pData, iObjectid, iImagetype, iDeltatype,
       
  6530                                     iBlockwidth, iBlockheight, iBlockx, iBlocky);
       
  6531 
       
  6532 /*    if (!iRetcode)
       
  6533       iRetcode = mng_process_display_dhdr (pData, iObjectid, iImagetype, iDeltatype,
       
  6534                                            iBlockwidth, iBlockheight, iBlockx, iBlocky); */
       
  6535 
       
  6536     if (iRetcode)                      /* on error bail out */
       
  6537       return iRetcode;
       
  6538 
       
  6539   }
       
  6540 #endif /* MNG_SUPPORT_DISPLAY */
       
  6541 
       
  6542 #ifdef MNG_STORE_CHUNKS
       
  6543   if (pData->bStorechunks)
       
  6544   {                                    /* initialize storage */
       
  6545     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6546 
       
  6547     if (iRetcode)                      /* on error bail out */
       
  6548       return iRetcode;
       
  6549                                        /* store the fields */
       
  6550     ((mng_dhdrp)*ppChunk)->iObjectid      = mng_get_uint16 (pRawdata);
       
  6551     ((mng_dhdrp)*ppChunk)->iImagetype     = iImagetype;
       
  6552     ((mng_dhdrp)*ppChunk)->iDeltatype     = iDeltatype;
       
  6553 
       
  6554     if (iRawlen > 4)
       
  6555     {
       
  6556       ((mng_dhdrp)*ppChunk)->iBlockwidth  = mng_get_uint32 (pRawdata+4);
       
  6557       ((mng_dhdrp)*ppChunk)->iBlockheight = mng_get_uint32 (pRawdata+8);
       
  6558     }
       
  6559 
       
  6560     if (iRawlen > 12)
       
  6561     {
       
  6562       ((mng_dhdrp)*ppChunk)->iBlockx      = mng_get_uint32 (pRawdata+12);
       
  6563       ((mng_dhdrp)*ppChunk)->iBlocky      = mng_get_uint32 (pRawdata+16);
       
  6564     }
       
  6565   }
       
  6566 #endif /* MNG_STORE_CHUNKS */
       
  6567 
       
  6568 #ifdef MNG_SUPPORT_TRACE
       
  6569   MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_END);
       
  6570 #endif
       
  6571 
       
  6572   return MNG_NOERROR;                  /* done */
       
  6573 }
       
  6574 #endif
       
  6575 #endif
       
  6576 
       
  6577 /* ************************************************************************** */
       
  6578 
       
  6579 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6580 #ifndef MNG_NO_DELTA_PNG
       
  6581 READ_CHUNK (mng_read_prom)
       
  6582 {
       
  6583   mng_uint8 iColortype;
       
  6584   mng_uint8 iSampledepth;
       
  6585   mng_uint8 iFilltype;
       
  6586 
       
  6587 #ifdef MNG_SUPPORT_TRACE
       
  6588   MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_START);
       
  6589 #endif
       
  6590                                        /* sequence checks */
       
  6591   if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
       
  6592     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6593 
       
  6594   if (iRawlen != 3)                    /* gotta be exactly 3 bytes */
       
  6595     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6596 
       
  6597   iColortype   = *pRawdata;            /* check fields for validity */
       
  6598   iSampledepth = *(pRawdata+1);
       
  6599   iFilltype    = *(pRawdata+2);
       
  6600 
       
  6601   if ((iColortype != MNG_COLORTYPE_GRAY   ) &&
       
  6602       (iColortype != MNG_COLORTYPE_RGB    ) &&
       
  6603       (iColortype != MNG_COLORTYPE_INDEXED) &&
       
  6604       (iColortype != MNG_COLORTYPE_GRAYA  ) &&
       
  6605       (iColortype != MNG_COLORTYPE_RGBA   )    )
       
  6606     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
       
  6607 
       
  6608 #ifdef MNG_NO_16BIT_SUPPORT
       
  6609   if (iSampledepth == MNG_BITDEPTH_16 )
       
  6610       iSampledepth = MNG_BITDEPTH_8;
       
  6611 #endif
       
  6612 
       
  6613   if ((iSampledepth != MNG_BITDEPTH_1 ) &&
       
  6614       (iSampledepth != MNG_BITDEPTH_2 ) &&
       
  6615       (iSampledepth != MNG_BITDEPTH_4 ) &&
       
  6616       (iSampledepth != MNG_BITDEPTH_8 )
       
  6617 #ifndef MNG_NO_16BIT_SUPPORT
       
  6618       && (iSampledepth != MNG_BITDEPTH_16)
       
  6619 #endif
       
  6620     )
       
  6621     MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
       
  6622 
       
  6623   if ((iFilltype != MNG_FILLMETHOD_LEFTBITREPLICATE) &&
       
  6624       (iFilltype != MNG_FILLMETHOD_ZEROFILL        )    )
       
  6625     MNG_ERROR (pData, MNG_INVFILLMETHOD);
       
  6626 
       
  6627 #ifdef MNG_SUPPORT_DISPLAY
       
  6628   {
       
  6629     mng_retcode iRetcode = mng_create_ani_prom (pData, iSampledepth,
       
  6630                                                 iColortype, iFilltype);
       
  6631 
       
  6632 /*    if (!iRetcode)
       
  6633       iRetcode = mng_process_display_prom (pData, iSampledepth,
       
  6634                                            iColortype, iFilltype); */
       
  6635                                            
       
  6636     if (iRetcode)                      /* on error bail out */
       
  6637       return iRetcode;
       
  6638   }
       
  6639 #endif /* MNG_SUPPORT_DISPLAY */
       
  6640 
       
  6641 #ifdef MNG_STORE_CHUNKS
       
  6642   if (pData->bStorechunks)
       
  6643   {                                    /* initialize storage */
       
  6644     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6645 
       
  6646     if (iRetcode)                      /* on error bail out */
       
  6647       return iRetcode;
       
  6648                                        /* store the fields */
       
  6649     ((mng_promp)*ppChunk)->iColortype   = iColortype;
       
  6650     ((mng_promp)*ppChunk)->iSampledepth = iSampledepth;
       
  6651     ((mng_promp)*ppChunk)->iFilltype    = iFilltype;
       
  6652   }
       
  6653 #endif /* MNG_STORE_CHUNKS */
       
  6654 
       
  6655 #ifdef MNG_SUPPORT_TRACE
       
  6656   MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_END);
       
  6657 #endif
       
  6658 
       
  6659   return MNG_NOERROR;                  /* done */
       
  6660 }
       
  6661 #endif
       
  6662 #endif
       
  6663 
       
  6664 /* ************************************************************************** */
       
  6665 
       
  6666 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6667 #ifndef MNG_NO_DELTA_PNG
       
  6668 READ_CHUNK (mng_read_ipng)
       
  6669 {
       
  6670 #ifdef MNG_SUPPORT_TRACE
       
  6671   MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_START);
       
  6672 #endif
       
  6673                                        /* sequence checks */
       
  6674   if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
       
  6675     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6676 
       
  6677   if (iRawlen != 0)                    /* gotta be empty */
       
  6678     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6679 
       
  6680 #ifdef MNG_SUPPORT_DISPLAY
       
  6681   {
       
  6682     mng_retcode iRetcode = mng_create_ani_ipng (pData);
       
  6683 
       
  6684     if (!iRetcode)
       
  6685       iRetcode = mng_process_display_ipng (pData);
       
  6686 
       
  6687     if (iRetcode)                      /* on error bail out */
       
  6688       return iRetcode;
       
  6689 
       
  6690   }
       
  6691 #endif /* MNG_SUPPORT_DISPLAY */
       
  6692 
       
  6693 #ifdef MNG_STORE_CHUNKS
       
  6694   if (pData->bStorechunks)
       
  6695   {                                    /* initialize storage */
       
  6696     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6697 
       
  6698     if (iRetcode)                      /* on error bail out */
       
  6699       return iRetcode;
       
  6700   }
       
  6701 #endif /* MNG_STORE_CHUNKS */
       
  6702 
       
  6703 #ifdef MNG_SUPPORT_TRACE
       
  6704   MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_END);
       
  6705 #endif
       
  6706 
       
  6707   return MNG_NOERROR;                  /* done */
       
  6708 }
       
  6709 #endif
       
  6710 #endif
       
  6711 
       
  6712 /* ************************************************************************** */
       
  6713 
       
  6714 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6715 #ifndef MNG_NO_DELTA_PNG
       
  6716 READ_CHUNK (mng_read_pplt)
       
  6717 {
       
  6718   mng_uint8     iDeltatype;
       
  6719   mng_uint8p    pTemp;
       
  6720   mng_uint32    iLen;
       
  6721   mng_uint8     iX, iM;
       
  6722   mng_uint32    iY;
       
  6723   mng_uint32    iMax;
       
  6724   mng_rgbpaltab aIndexentries;
       
  6725   mng_uint8arr  aAlphaentries;
       
  6726   mng_uint8arr  aUsedentries;
       
  6727 
       
  6728 #ifdef MNG_SUPPORT_TRACE
       
  6729   MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_START);
       
  6730 #endif
       
  6731                                        /* sequence checks */
       
  6732   if ((!pData->bHasMHDR) && (!pData->bHasDHDR))
       
  6733     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6734 
       
  6735   if (iRawlen < 1)                     /* must have at least 1 byte */
       
  6736     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6737 
       
  6738   iDeltatype = *pRawdata;
       
  6739                                        /* valid ? */
       
  6740   if (iDeltatype > MNG_DELTATYPE_DELTARGBA)
       
  6741     MNG_ERROR (pData, MNG_INVDELTATYPE);
       
  6742                                        /* must be indexed color ! */
       
  6743   if (pData->iColortype != MNG_COLORTYPE_INDEXED)
       
  6744     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
       
  6745 
       
  6746   pTemp = pRawdata + 1;
       
  6747   iLen  = iRawlen - 1;
       
  6748   iMax  = 0;
       
  6749 
       
  6750   for (iY = 0; iY < 256; iY++)         /* reset arrays */
       
  6751   {
       
  6752     aIndexentries [iY].iRed   = 0;
       
  6753     aIndexentries [iY].iGreen = 0;
       
  6754     aIndexentries [iY].iBlue  = 0;
       
  6755     aAlphaentries [iY]        = 255;
       
  6756     aUsedentries  [iY]        = 0;
       
  6757   }
       
  6758 
       
  6759   while (iLen)                         /* as long as there are entries left ... */
       
  6760   {
       
  6761     mng_uint32 iDiff;
       
  6762 
       
  6763     if (iLen < 2)
       
  6764       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6765 
       
  6766     iX = *pTemp;                       /* get start and end index */
       
  6767     iM = *(pTemp+1);
       
  6768 
       
  6769     if (iM < iX)
       
  6770       MNG_ERROR (pData, MNG_INVALIDINDEX);
       
  6771 
       
  6772     if ((mng_uint32)iM >= iMax)        /* determine highest used index */
       
  6773       iMax = (mng_uint32)iM + 1;
       
  6774 
       
  6775     pTemp += 2;
       
  6776     iLen  -= 2;
       
  6777     iDiff = (iM - iX + 1);
       
  6778     if ((iDeltatype == MNG_DELTATYPE_REPLACERGB  ) ||
       
  6779         (iDeltatype == MNG_DELTATYPE_DELTARGB    )    )
       
  6780       iDiff = iDiff * 3;
       
  6781     else
       
  6782     if ((iDeltatype == MNG_DELTATYPE_REPLACERGBA) ||
       
  6783         (iDeltatype == MNG_DELTATYPE_DELTARGBA  )    )
       
  6784       iDiff = iDiff * 4;
       
  6785 
       
  6786     if (iLen < iDiff)
       
  6787       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6788 
       
  6789     if ((iDeltatype == MNG_DELTATYPE_REPLACERGB  ) ||
       
  6790         (iDeltatype == MNG_DELTATYPE_DELTARGB    )    )
       
  6791     {
       
  6792       for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
       
  6793       {
       
  6794         aIndexentries [iY].iRed   = *pTemp;
       
  6795         aIndexentries [iY].iGreen = *(pTemp+1);
       
  6796         aIndexentries [iY].iBlue  = *(pTemp+2);
       
  6797         aUsedentries  [iY]        = 1;
       
  6798 
       
  6799         pTemp += 3;
       
  6800         iLen  -= 3;
       
  6801       }
       
  6802     }
       
  6803     else
       
  6804     if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) ||
       
  6805         (iDeltatype == MNG_DELTATYPE_DELTAALPHA  )    )
       
  6806     {
       
  6807       for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
       
  6808       {
       
  6809         aAlphaentries [iY]        = *pTemp;
       
  6810         aUsedentries  [iY]        = 1;
       
  6811 
       
  6812         pTemp++;
       
  6813         iLen--;
       
  6814       }
       
  6815     }
       
  6816     else
       
  6817     {
       
  6818       for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
       
  6819       {
       
  6820         aIndexentries [iY].iRed   = *pTemp;
       
  6821         aIndexentries [iY].iGreen = *(pTemp+1);
       
  6822         aIndexentries [iY].iBlue  = *(pTemp+2);
       
  6823         aAlphaentries [iY]        = *(pTemp+3);
       
  6824         aUsedentries  [iY]        = 1;
       
  6825 
       
  6826         pTemp += 4;
       
  6827         iLen  -= 4;
       
  6828       }
       
  6829     }
       
  6830   }
       
  6831 
       
  6832   switch (pData->iBitdepth)            /* check maximum allowed entries for bitdepth */
       
  6833   {
       
  6834     case MNG_BITDEPTH_1 : {
       
  6835                             if (iMax > 2)
       
  6836                               MNG_ERROR (pData, MNG_INVALIDINDEX);
       
  6837                             break;
       
  6838                           }
       
  6839     case MNG_BITDEPTH_2 : {
       
  6840                             if (iMax > 4)
       
  6841                               MNG_ERROR (pData, MNG_INVALIDINDEX);
       
  6842                             break;
       
  6843                           }
       
  6844     case MNG_BITDEPTH_4 : {
       
  6845                             if (iMax > 16)
       
  6846                               MNG_ERROR (pData, MNG_INVALIDINDEX);
       
  6847                             break;
       
  6848                           }
       
  6849   }
       
  6850 
       
  6851 #ifdef MNG_SUPPORT_DISPLAY
       
  6852   {                                    /* create animation object */
       
  6853     mng_retcode iRetcode = mng_create_ani_pplt (pData, iDeltatype, iMax,
       
  6854                                                 aIndexentries, aAlphaentries,
       
  6855                                                 aUsedentries);
       
  6856 
       
  6857 /*    if (!iRetcode)
       
  6858       iRetcode = mng_process_display_pplt (pData, iDeltatype, iMax, aIndexentries,
       
  6859                                            aAlphaentries, aUsedentries); */
       
  6860 
       
  6861     if (iRetcode)                      /* on error bail out */
       
  6862       return iRetcode;
       
  6863 
       
  6864   }
       
  6865 #endif /* MNG_SUPPORT_DISPLAY */
       
  6866 
       
  6867 #ifdef MNG_STORE_CHUNKS
       
  6868   if (pData->bStorechunks)
       
  6869   {                                    /* initialize storage */
       
  6870     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6871 
       
  6872     if (iRetcode)                      /* on error bail out */
       
  6873       return iRetcode;
       
  6874                                        /* store the fields */
       
  6875     ((mng_ppltp)*ppChunk)->iDeltatype = iDeltatype;
       
  6876     ((mng_ppltp)*ppChunk)->iCount     = iMax;
       
  6877 
       
  6878     for (iY = 0; iY < 256; iY++)
       
  6879     {
       
  6880       ((mng_ppltp)*ppChunk)->aEntries [iY].iRed   = aIndexentries [iY].iRed;
       
  6881       ((mng_ppltp)*ppChunk)->aEntries [iY].iGreen = aIndexentries [iY].iGreen;
       
  6882       ((mng_ppltp)*ppChunk)->aEntries [iY].iBlue  = aIndexentries [iY].iBlue;
       
  6883       ((mng_ppltp)*ppChunk)->aEntries [iY].iAlpha = aAlphaentries [iY];
       
  6884       ((mng_ppltp)*ppChunk)->aEntries [iY].bUsed  = (mng_bool)(aUsedentries [iY]);
       
  6885     }
       
  6886   }
       
  6887 #endif /* MNG_STORE_CHUNKS */
       
  6888 
       
  6889 #ifdef MNG_SUPPORT_TRACE
       
  6890   MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_END);
       
  6891 #endif
       
  6892 
       
  6893   return MNG_NOERROR;                  /* done */
       
  6894 }
       
  6895 #endif
       
  6896 #endif
       
  6897 
       
  6898 /* ************************************************************************** */
       
  6899 
       
  6900 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6901 #ifndef MNG_NO_DELTA_PNG
       
  6902 #ifdef MNG_INCLUDE_JNG
       
  6903 READ_CHUNK (mng_read_ijng)
       
  6904 {
       
  6905 #ifdef MNG_SUPPORT_TRACE
       
  6906   MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_START);
       
  6907 #endif
       
  6908                                        /* sequence checks */
       
  6909   if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
       
  6910     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6911 
       
  6912   if (iRawlen != 0)                    /* gotta be empty */
       
  6913     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6914 
       
  6915 #ifdef MNG_SUPPORT_DISPLAY
       
  6916   {
       
  6917     mng_retcode iRetcode = mng_create_ani_ijng (pData);
       
  6918 
       
  6919     if (!iRetcode)
       
  6920       iRetcode = mng_process_display_ijng (pData);
       
  6921 
       
  6922     if (iRetcode)                      /* on error bail out */
       
  6923       return iRetcode;
       
  6924 
       
  6925   }
       
  6926 #endif /* MNG_SUPPORT_DISPLAY */
       
  6927 
       
  6928 #ifdef MNG_STORE_CHUNKS
       
  6929   if (pData->bStorechunks)
       
  6930   {                                    /* initialize storage */
       
  6931     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6932 
       
  6933     if (iRetcode)                      /* on error bail out */
       
  6934       return iRetcode;
       
  6935   }
       
  6936 #endif /* MNG_STORE_CHUNKS */
       
  6937 
       
  6938 #ifdef MNG_SUPPORT_TRACE
       
  6939   MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_END);
       
  6940 #endif
       
  6941 
       
  6942   return MNG_NOERROR;                  /* done */
       
  6943 }
       
  6944 #endif
       
  6945 #endif
       
  6946 #endif
       
  6947 
       
  6948 /* ************************************************************************** */
       
  6949 
       
  6950 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  6951 #ifndef MNG_NO_DELTA_PNG
       
  6952 READ_CHUNK (mng_read_drop)
       
  6953 {
       
  6954 #ifdef MNG_SUPPORT_TRACE
       
  6955   MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_START);
       
  6956 #endif
       
  6957                                        /* sequence checks */
       
  6958   if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
       
  6959     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  6960                                        /* check length */
       
  6961   if ((iRawlen < 4) || ((iRawlen % 4) != 0))
       
  6962     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  6963 
       
  6964 #ifdef MNG_SUPPORT_DISPLAY
       
  6965   {
       
  6966 
       
  6967 
       
  6968     /* TODO: something !!! */
       
  6969 
       
  6970 
       
  6971   }
       
  6972 #endif /* MNG_SUPPORT_DISPLAY */
       
  6973 
       
  6974 #ifdef MNG_STORE_CHUNKS
       
  6975   if (pData->bStorechunks)
       
  6976   {                                    /* initialize storage */
       
  6977     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  6978 
       
  6979     if (iRetcode)                      /* on error bail out */
       
  6980       return iRetcode;
       
  6981                                        /* store the fields */
       
  6982     ((mng_dropp)*ppChunk)->iCount = iRawlen / 4;
       
  6983 
       
  6984     if (iRawlen)
       
  6985     {
       
  6986       mng_uint32      iX;
       
  6987       mng_uint8p      pTemp = pRawdata;
       
  6988       mng_uint32p     pEntry;
       
  6989 
       
  6990       MNG_ALLOC (pData, pEntry, iRawlen);
       
  6991 
       
  6992       ((mng_dropp)*ppChunk)->pChunknames = (mng_ptr)pEntry;
       
  6993 
       
  6994       for (iX = 0; iX < iRawlen / 4; iX++)
       
  6995       {
       
  6996         *pEntry = mng_get_uint32 (pTemp);
       
  6997 
       
  6998         pTemp  += 4;
       
  6999         pEntry++;
       
  7000       }
       
  7001     }
       
  7002   }
       
  7003 #endif /* MNG_STORE_CHUNKS */
       
  7004 
       
  7005 #ifdef MNG_SUPPORT_TRACE
       
  7006   MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_END);
       
  7007 #endif
       
  7008 
       
  7009   return MNG_NOERROR;                  /* done */
       
  7010 }
       
  7011 #endif
       
  7012 #endif
       
  7013 
       
  7014 /* ************************************************************************** */
       
  7015 
       
  7016 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  7017 #ifndef MNG_NO_DELTA_PNG
       
  7018 #ifndef MNG_SKIPCHUNK_DBYK
       
  7019 READ_CHUNK (mng_read_dbyk)
       
  7020 {
       
  7021 #ifdef MNG_SUPPORT_TRACE
       
  7022   MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_START);
       
  7023 #endif
       
  7024                                        /* sequence checks */
       
  7025   if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
       
  7026     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  7027 
       
  7028   if (iRawlen < 6)                     /* must be at least 6 long */
       
  7029     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7030 
       
  7031 #ifdef MNG_SUPPORT_DISPLAY
       
  7032   {
       
  7033 
       
  7034 
       
  7035     /* TODO: something !!! */
       
  7036 
       
  7037 
       
  7038   }
       
  7039 #endif /* MNG_SUPPORT_DISPLAY */
       
  7040 
       
  7041 #ifdef MNG_STORE_CHUNKS
       
  7042   if (pData->bStorechunks)
       
  7043   {                                    /* initialize storage */
       
  7044     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  7045 
       
  7046     if (iRetcode)                      /* on error bail out */
       
  7047       return iRetcode;
       
  7048                                        /* store the fields */
       
  7049     ((mng_dbykp)*ppChunk)->iChunkname    = mng_get_uint32 (pRawdata);
       
  7050     ((mng_dbykp)*ppChunk)->iPolarity     = *(pRawdata+4);
       
  7051     ((mng_dbykp)*ppChunk)->iKeywordssize = iRawlen - 5;
       
  7052 
       
  7053     if (iRawlen > 5)
       
  7054     {
       
  7055       MNG_ALLOC (pData, ((mng_dbykp)*ppChunk)->zKeywords, iRawlen-4);
       
  7056       MNG_COPY (((mng_dbykp)*ppChunk)->zKeywords, pRawdata+5, iRawlen-5);
       
  7057     }
       
  7058   }
       
  7059 #endif /* MNG_STORE_CHUNKS */
       
  7060 
       
  7061 #ifdef MNG_SUPPORT_TRACE
       
  7062   MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_END);
       
  7063 #endif
       
  7064 
       
  7065   return MNG_NOERROR;                  /* done */
       
  7066 }
       
  7067 #endif
       
  7068 #endif
       
  7069 #endif
       
  7070 
       
  7071 /* ************************************************************************** */
       
  7072 
       
  7073 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  7074 #ifndef MNG_NO_DELTA_PNG
       
  7075 #ifndef MNG_SKIPCHUNK_ORDR
       
  7076 READ_CHUNK (mng_read_ordr)
       
  7077 {
       
  7078 #ifdef MNG_SUPPORT_TRACE
       
  7079   MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_START);
       
  7080 #endif
       
  7081                                        /* sequence checks */
       
  7082   if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
       
  7083     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  7084                                        /* check length */
       
  7085   if ((iRawlen < 5) || ((iRawlen % 5) != 0))
       
  7086     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7087 
       
  7088 #ifdef MNG_SUPPORT_DISPLAY
       
  7089   {
       
  7090 
       
  7091 
       
  7092     /* TODO: something !!! */
       
  7093 
       
  7094 
       
  7095   }
       
  7096 #endif /* MNG_SUPPORT_DISPLAY */
       
  7097 
       
  7098 #ifdef MNG_STORE_CHUNKS
       
  7099   if (pData->bStorechunks)
       
  7100   {                                    /* initialize storage */
       
  7101     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  7102 
       
  7103     if (iRetcode)                      /* on error bail out */
       
  7104       return iRetcode;
       
  7105                                        /* store the fields */
       
  7106     ((mng_ordrp)*ppChunk)->iCount = iRawlen / 5;
       
  7107 
       
  7108     if (iRawlen)
       
  7109     {
       
  7110       mng_uint32      iX;
       
  7111       mng_ordr_entryp pEntry;
       
  7112       mng_uint8p      pTemp = pRawdata;
       
  7113       
       
  7114       MNG_ALLOC (pData, pEntry, iRawlen);
       
  7115 
       
  7116       ((mng_ordrp)*ppChunk)->pEntries = pEntry;
       
  7117 
       
  7118       for (iX = 0; iX < iRawlen / 5; iX++)
       
  7119       {
       
  7120         pEntry->iChunkname = mng_get_uint32 (pTemp);
       
  7121         pEntry->iOrdertype = *(pTemp+4);
       
  7122 
       
  7123         pTemp += 5;
       
  7124         pEntry++;
       
  7125       }
       
  7126     }
       
  7127   }
       
  7128 #endif /* MNG_STORE_CHUNKS */
       
  7129 
       
  7130 #ifdef MNG_SUPPORT_TRACE
       
  7131   MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_END);
       
  7132 #endif
       
  7133 
       
  7134   return MNG_NOERROR;                  /* done */
       
  7135 }
       
  7136 #endif
       
  7137 #endif
       
  7138 #endif
       
  7139 
       
  7140 /* ************************************************************************** */
       
  7141 
       
  7142 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  7143 #ifndef MNG_SKIPCHUNK_MAGN
       
  7144 READ_CHUNK (mng_read_magn)
       
  7145 {
       
  7146   mng_uint16 iFirstid, iLastid;
       
  7147   mng_uint8  iMethodX, iMethodY;
       
  7148   mng_uint16 iMX, iMY, iML, iMR, iMT, iMB;
       
  7149   mng_bool   bFaulty;
       
  7150 
       
  7151 #ifdef MNG_SUPPORT_TRACE
       
  7152   MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_START);
       
  7153 #endif
       
  7154                                        /* sequence checks */
       
  7155 #ifdef MNG_SUPPORT_JNG
       
  7156   if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR) || (pData->bHasJHDR))
       
  7157 #else
       
  7158   if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR))
       
  7159 #endif
       
  7160     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  7161                                        /* check length */
       
  7162   if (iRawlen > 20)
       
  7163     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7164 
       
  7165   /* following is an ugly hack to allow faulty layout caused by previous
       
  7166      versions of libmng and MNGeye, which wrote MAGN with a 16-bit
       
  7167      MethodX/MethodY (as opposed to the proper 8-bit as defined in the spec!) */
       
  7168 
       
  7169   if ((iRawlen ==  6) || (iRawlen ==  8) || (iRawlen == 10) || (iRawlen == 12) ||
       
  7170       (iRawlen == 14) || (iRawlen == 16) || (iRawlen == 20))
       
  7171     bFaulty = MNG_TRUE;                /* these lengths are all wrong */
       
  7172   else                                 /* length 18 can be right or wrong !!! */
       
  7173   if ((iRawlen ==  18) && (mng_get_uint16 (pRawdata+4) <= 5) &&
       
  7174       (mng_get_uint16 (pRawdata+6)  < 256) &&
       
  7175       (mng_get_uint16 (pRawdata+8)  < 256) &&
       
  7176       (mng_get_uint16 (pRawdata+10) < 256) &&
       
  7177       (mng_get_uint16 (pRawdata+12) < 256) &&
       
  7178       (mng_get_uint16 (pRawdata+14) < 256) &&
       
  7179       (mng_get_uint16 (pRawdata+16) < 256))
       
  7180     bFaulty = MNG_TRUE;                /* this is very likely the wrong layout */
       
  7181   else
       
  7182     bFaulty = MNG_FALSE;               /* all other cases are handled as right */
       
  7183 
       
  7184   if (bFaulty)                         /* wrong layout ? */
       
  7185   {
       
  7186     if (iRawlen > 0)                   /* get the fields */
       
  7187       iFirstid = mng_get_uint16 (pRawdata);
       
  7188     else
       
  7189       iFirstid = 0;
       
  7190 
       
  7191     if (iRawlen > 2)
       
  7192       iLastid  = mng_get_uint16 (pRawdata+2);
       
  7193     else
       
  7194       iLastid  = iFirstid;
       
  7195 
       
  7196     if (iRawlen > 4)
       
  7197       iMethodX = (mng_uint8)(mng_get_uint16 (pRawdata+4));
       
  7198     else
       
  7199       iMethodX = 0;
       
  7200 
       
  7201     if (iRawlen > 6)
       
  7202       iMX      = mng_get_uint16 (pRawdata+6);
       
  7203     else
       
  7204       iMX      = 1;
       
  7205 
       
  7206     if (iRawlen > 8)
       
  7207       iMY      = mng_get_uint16 (pRawdata+8);
       
  7208     else
       
  7209       iMY      = iMX;
       
  7210 
       
  7211     if (iRawlen > 10)
       
  7212       iML      = mng_get_uint16 (pRawdata+10);
       
  7213     else
       
  7214       iML      = iMX;
       
  7215 
       
  7216     if (iRawlen > 12)
       
  7217       iMR      = mng_get_uint16 (pRawdata+12);
       
  7218     else
       
  7219       iMR      = iMX;
       
  7220 
       
  7221     if (iRawlen > 14)
       
  7222       iMT      = mng_get_uint16 (pRawdata+14);
       
  7223     else
       
  7224       iMT      = iMY;
       
  7225 
       
  7226     if (iRawlen > 16)
       
  7227       iMB      = mng_get_uint16 (pRawdata+16);
       
  7228     else
       
  7229       iMB      = iMY;
       
  7230 
       
  7231     if (iRawlen > 18)
       
  7232       iMethodY = (mng_uint8)(mng_get_uint16 (pRawdata+18));
       
  7233     else
       
  7234       iMethodY = iMethodX;
       
  7235   }
       
  7236   else                                 /* proper layout !!!! */
       
  7237   {
       
  7238     if (iRawlen > 0)                   /* get the fields */
       
  7239       iFirstid = mng_get_uint16 (pRawdata);
       
  7240     else
       
  7241       iFirstid = 0;
       
  7242 
       
  7243     if (iRawlen > 2)
       
  7244       iLastid  = mng_get_uint16 (pRawdata+2);
       
  7245     else
       
  7246       iLastid  = iFirstid;
       
  7247 
       
  7248     if (iRawlen > 4)
       
  7249       iMethodX = *(pRawdata+4);
       
  7250     else
       
  7251       iMethodX = 0;
       
  7252 
       
  7253     if (iRawlen > 5)
       
  7254       iMX      = mng_get_uint16 (pRawdata+5);
       
  7255     else
       
  7256       iMX      = 1;
       
  7257 
       
  7258     if (iRawlen > 7)
       
  7259       iMY      = mng_get_uint16 (pRawdata+7);
       
  7260     else
       
  7261       iMY      = iMX;
       
  7262 
       
  7263     if (iRawlen > 9)
       
  7264       iML      = mng_get_uint16 (pRawdata+9);
       
  7265     else
       
  7266       iML      = iMX;
       
  7267 
       
  7268     if (iRawlen > 11)
       
  7269       iMR      = mng_get_uint16 (pRawdata+11);
       
  7270     else
       
  7271       iMR      = iMX;
       
  7272 
       
  7273     if (iRawlen > 13)
       
  7274       iMT      = mng_get_uint16 (pRawdata+13);
       
  7275     else
       
  7276       iMT      = iMY;
       
  7277 
       
  7278     if (iRawlen > 15)
       
  7279       iMB      = mng_get_uint16 (pRawdata+15);
       
  7280     else
       
  7281       iMB      = iMY;
       
  7282 
       
  7283     if (iRawlen > 17)
       
  7284       iMethodY = *(pRawdata+17);
       
  7285     else
       
  7286       iMethodY = iMethodX;
       
  7287   }
       
  7288                                        /* check field validity */
       
  7289   if ((iMethodX > 5) || (iMethodY > 5))
       
  7290     MNG_ERROR (pData, MNG_INVALIDMETHOD);
       
  7291 
       
  7292 #ifdef MNG_SUPPORT_DISPLAY
       
  7293   {
       
  7294     mng_retcode iRetcode;
       
  7295 
       
  7296     iRetcode = mng_create_ani_magn (pData, iFirstid, iLastid, iMethodX,
       
  7297                                     iMX, iMY, iML, iMR, iMT, iMB, iMethodY);
       
  7298 
       
  7299 /*    if (!iRetcode)
       
  7300       iRetcode = mng_process_display_magn (pData, iFirstid, iLastid, iMethodX,
       
  7301                                            iMX, iMY, iML, iMR, iMT, iMB, iMethodY); */
       
  7302 
       
  7303     if (iRetcode)                      /* on error bail out */
       
  7304       return iRetcode;
       
  7305 
       
  7306   }
       
  7307 #endif /* MNG_SUPPORT_DISPLAY */
       
  7308 
       
  7309 #ifdef MNG_STORE_CHUNKS
       
  7310   if (pData->bStorechunks)
       
  7311   {                                    /* initialize storage */
       
  7312     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  7313 
       
  7314     if (iRetcode)                      /* on error bail out */
       
  7315       return iRetcode;
       
  7316                                        /* store the fields */
       
  7317     ((mng_magnp)*ppChunk)->iFirstid = iFirstid;
       
  7318     ((mng_magnp)*ppChunk)->iLastid  = iLastid;
       
  7319     ((mng_magnp)*ppChunk)->iMethodX = iMethodX;
       
  7320     ((mng_magnp)*ppChunk)->iMX      = iMX;
       
  7321     ((mng_magnp)*ppChunk)->iMY      = iMY;
       
  7322     ((mng_magnp)*ppChunk)->iML      = iML;
       
  7323     ((mng_magnp)*ppChunk)->iMR      = iMR;
       
  7324     ((mng_magnp)*ppChunk)->iMT      = iMT;
       
  7325     ((mng_magnp)*ppChunk)->iMB      = iMB;
       
  7326     ((mng_magnp)*ppChunk)->iMethodY = iMethodY;
       
  7327   }
       
  7328 #endif /* MNG_STORE_CHUNKS */
       
  7329 
       
  7330 #ifdef MNG_SUPPORT_TRACE
       
  7331   MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_END);
       
  7332 #endif
       
  7333 
       
  7334   return MNG_NOERROR;                  /* done */
       
  7335 }
       
  7336 #endif
       
  7337 #endif
       
  7338 
       
  7339 /* ************************************************************************** */
       
  7340 
       
  7341 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  7342 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
       
  7343 READ_CHUNK (mng_read_mpng)
       
  7344 {
       
  7345   mng_uint32  iFramewidth;
       
  7346   mng_uint32  iFrameheight;
       
  7347   mng_uint16  iTickspersec;
       
  7348   mng_uint32  iFramessize;
       
  7349   mng_uint32  iCompressedsize;
       
  7350 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  7351   mng_retcode iRetcode;
       
  7352   mng_uint16  iNumplays;
       
  7353   mng_uint32  iBufsize;
       
  7354   mng_uint8p  pBuf = 0;
       
  7355 #endif
       
  7356 
       
  7357 #ifdef MNG_SUPPORT_TRACE
       
  7358   MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_START);
       
  7359 #endif
       
  7360                                        /* sequence checks */
       
  7361   if (!pData->bHasIHDR)
       
  7362     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  7363 
       
  7364   if (iRawlen < 41)                    /* length must be at least 41 */
       
  7365     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7366 
       
  7367   iFramewidth     = mng_get_int32 (pRawdata);
       
  7368   if (iFramewidth == 0)                /* frame_width must not be zero */
       
  7369     MNG_ERROR (pData, MNG_INVALIDWIDTH);
       
  7370 
       
  7371   iFrameheight    = mng_get_int32 (pRawdata+4);
       
  7372   if (iFrameheight == 0)               /* frame_height must not be zero */
       
  7373     MNG_ERROR (pData, MNG_INVALIDHEIGHT);
       
  7374 
       
  7375   iTickspersec    = mng_get_uint16 (pRawdata+10);
       
  7376   if (iTickspersec == 0)               /* delay_den must not be zero */
       
  7377     MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
       
  7378 
       
  7379   if (*(pRawdata+12) != 0)             /* only deflate compression-method allowed */
       
  7380     MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
       
  7381 
       
  7382 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  7383   iNumplays       = mng_get_uint16 (pRawdata+8);
       
  7384   iCompressedsize = (mng_uint32)(iRawlen - 13);
       
  7385 #endif
       
  7386 
       
  7387 #ifdef MNG_SUPPORT_DISPLAY
       
  7388   {
       
  7389     iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize,
       
  7390                                    &pBuf, &iBufsize, &iFramessize);
       
  7391     if (iRetcode)                    /* on error bail out */
       
  7392     {
       
  7393       MNG_FREEX (pData, pBuf, iBufsize);
       
  7394       return iRetcode;
       
  7395     }
       
  7396 
       
  7397     if (iFramessize % 26)
       
  7398     {
       
  7399       MNG_FREEX (pData, pBuf, iBufsize);
       
  7400       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7401     }
       
  7402 
       
  7403     iRetcode = mng_create_mpng_obj (pData, iFramewidth, iFrameheight, iNumplays,
       
  7404                                     iTickspersec, iFramessize, pBuf);
       
  7405     if (iRetcode)                      /* on error bail out */
       
  7406     {
       
  7407       MNG_FREEX (pData, pBuf, iBufsize);
       
  7408       return iRetcode;
       
  7409     }
       
  7410   }
       
  7411 #endif /* MNG_SUPPORT_DISPLAY */
       
  7412 
       
  7413 #ifdef MNG_STORE_CHUNKS
       
  7414   if (pData->bStorechunks)
       
  7415   {                                    /* initialize storage */
       
  7416     iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  7417     if (iRetcode)                      /* on error bail out */
       
  7418       return iRetcode;
       
  7419                                        /* store the fields */
       
  7420     ((mng_mpngp)*ppChunk)->iFramewidth        = iFramewidth;
       
  7421     ((mng_mpngp)*ppChunk)->iFrameheight       = iFrameheight;
       
  7422     ((mng_mpngp)*ppChunk)->iNumplays          = iNumplays;
       
  7423     ((mng_mpngp)*ppChunk)->iTickspersec       = iTickspersec;
       
  7424     ((mng_mpngp)*ppChunk)->iCompressionmethod = *(pRawdata+14);
       
  7425 
       
  7426 #ifndef MNG_SUPPORT_DISPLAY
       
  7427     iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize,
       
  7428                                    &pBuf, &iBufsize, &iFramessize);
       
  7429     if (iRetcode)                    /* on error bail out */
       
  7430     {
       
  7431       MNG_FREEX (pData, pBuf, iBufsize);
       
  7432       return iRetcode;
       
  7433     }
       
  7434 
       
  7435     if (iFramessize % 26)
       
  7436     {
       
  7437       MNG_FREEX (pData, pBuf, iBufsize);
       
  7438       MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7439     }
       
  7440 #endif
       
  7441 
       
  7442     if (iFramessize)
       
  7443     {
       
  7444       MNG_ALLOCX (pData, ((mng_mpngp)*ppChunk)->pFrames, iFramessize);
       
  7445       if (((mng_mpngp)*ppChunk)->pFrames == 0)
       
  7446       {
       
  7447         MNG_FREEX (pData, pBuf, iBufsize);
       
  7448         MNG_ERROR (pData, MNG_OUTOFMEMORY);
       
  7449       }
       
  7450 
       
  7451       ((mng_mpngp)*ppChunk)->iFramessize = iFramessize;
       
  7452       MNG_COPY (((mng_mpngp)*ppChunk)->pFrames, pBuf, iFramessize);
       
  7453     }
       
  7454   }
       
  7455 #endif /* MNG_STORE_CHUNKS */
       
  7456 
       
  7457 #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
       
  7458   MNG_FREEX (pData, pBuf, iBufsize);
       
  7459 #endif
       
  7460 
       
  7461 #ifdef MNG_SUPPORT_TRACE
       
  7462   MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_END);
       
  7463 #endif
       
  7464 
       
  7465   return MNG_NOERROR;                  /* done */
       
  7466 }
       
  7467 #endif
       
  7468 #endif
       
  7469 
       
  7470 /* ************************************************************************** */
       
  7471 
       
  7472 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  7473 #ifndef MNG_SKIPCHUNK_evNT
       
  7474 READ_CHUNK (mng_read_evnt)
       
  7475 {
       
  7476 #ifdef MNG_SUPPORT_TRACE
       
  7477   MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_START);
       
  7478 #endif
       
  7479                                        /* sequence checks */
       
  7480   if ((!pData->bHasMHDR) || (pData->bHasSAVE))
       
  7481     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  7482 
       
  7483   if (iRawlen < 2)                     /* must have at least 1 entry ! */
       
  7484     MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7485 
       
  7486 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
       
  7487   {
       
  7488     if (iRawlen)                       /* not empty ? */
       
  7489     {
       
  7490       mng_retcode iRetcode;
       
  7491       mng_uint8p  pTemp;
       
  7492       mng_uint8p  pNull;
       
  7493       mng_uint32  iLen;
       
  7494       mng_uint8   iEventtype;
       
  7495       mng_uint8   iMasktype;
       
  7496       mng_int32   iLeft;
       
  7497       mng_int32   iRight;
       
  7498       mng_int32   iTop;
       
  7499       mng_int32   iBottom;
       
  7500       mng_uint16  iObjectid;
       
  7501       mng_uint8   iIndex;
       
  7502       mng_uint32  iNamesize;
       
  7503 
       
  7504       pTemp = pRawdata;
       
  7505       iLen  = iRawlen;
       
  7506 
       
  7507       while (iLen)                   /* anything left ? */
       
  7508       {
       
  7509         iEventtype = *pTemp;         /* eventtype */
       
  7510         if (iEventtype > 5)
       
  7511           MNG_ERROR (pData, MNG_INVALIDEVENT);
       
  7512 
       
  7513         pTemp++;
       
  7514 
       
  7515         iMasktype  = *pTemp;         /* masktype */
       
  7516         if (iMasktype > 5)
       
  7517           MNG_ERROR (pData, MNG_INVALIDMASK);
       
  7518 
       
  7519         pTemp++;
       
  7520         iLen -= 2;
       
  7521 
       
  7522         iLeft     = 0;
       
  7523         iRight    = 0;
       
  7524         iTop      = 0;
       
  7525         iBottom   = 0;
       
  7526         iObjectid = 0;
       
  7527         iIndex    = 0;
       
  7528 
       
  7529         switch (iMasktype)
       
  7530         {
       
  7531           case 1 :
       
  7532             {
       
  7533               if (iLen > 16)
       
  7534               {
       
  7535                 iLeft     = mng_get_int32 (pTemp);
       
  7536                 iRight    = mng_get_int32 (pTemp+4);
       
  7537                 iTop      = mng_get_int32 (pTemp+8);
       
  7538                 iBottom   = mng_get_int32 (pTemp+12);
       
  7539                 pTemp += 16;
       
  7540                 iLen -= 16;
       
  7541               }
       
  7542               else
       
  7543                 MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7544               break;
       
  7545             }
       
  7546           case 2 :
       
  7547             {
       
  7548               if (iLen > 2)
       
  7549               {
       
  7550                 iObjectid = mng_get_uint16 (pTemp);
       
  7551                 pTemp += 2;
       
  7552                 iLen -= 2;
       
  7553               }
       
  7554               else
       
  7555                 MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7556               break;
       
  7557             }
       
  7558           case 3 :
       
  7559             {
       
  7560               if (iLen > 3)
       
  7561               {
       
  7562                 iObjectid = mng_get_uint16 (pTemp);
       
  7563                 iIndex    = *(pTemp+2);
       
  7564                 pTemp += 3;
       
  7565                 iLen -= 3;
       
  7566               }
       
  7567               else
       
  7568                 MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7569               break;
       
  7570             }
       
  7571           case 4 :
       
  7572             {
       
  7573               if (iLen > 18)
       
  7574               {
       
  7575                 iLeft     = mng_get_int32 (pTemp);
       
  7576                 iRight    = mng_get_int32 (pTemp+4);
       
  7577                 iTop      = mng_get_int32 (pTemp+8);
       
  7578                 iBottom   = mng_get_int32 (pTemp+12);
       
  7579                 iObjectid = mng_get_uint16 (pTemp+16);
       
  7580                 pTemp += 18;
       
  7581                 iLen -= 18;
       
  7582               }
       
  7583               else
       
  7584                 MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7585               break;
       
  7586             }
       
  7587           case 5 :
       
  7588             {
       
  7589               if (iLen > 19)
       
  7590               {
       
  7591                 iLeft     = mng_get_int32 (pTemp);
       
  7592                 iRight    = mng_get_int32 (pTemp+4);
       
  7593                 iTop      = mng_get_int32 (pTemp+8);
       
  7594                 iBottom   = mng_get_int32 (pTemp+12);
       
  7595                 iObjectid = mng_get_uint16 (pTemp+16);
       
  7596                 iIndex    = *(pTemp+18);
       
  7597                 pTemp += 19;
       
  7598                 iLen -= 19;
       
  7599               }
       
  7600               else
       
  7601                 MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7602               break;
       
  7603             }
       
  7604         }
       
  7605 
       
  7606         pNull = find_null (pTemp);   /* get the name length */
       
  7607 
       
  7608         if ((pNull - pTemp) > (mng_int32)iLen)
       
  7609         {
       
  7610           iNamesize = iLen;          /* no null found; so end of evNT */
       
  7611           iLen      = 0;
       
  7612         }
       
  7613         else
       
  7614         {
       
  7615           iNamesize = pNull - pTemp; /* should be another entry */
       
  7616           iLen      = iLen - iNamesize - 1;
       
  7617 
       
  7618           if (!iLen)                 /* must not end with a null ! */
       
  7619             MNG_ERROR (pData, MNG_ENDWITHNULL);
       
  7620         }
       
  7621 
       
  7622         iRetcode = mng_create_event (pData, iEventtype, iMasktype, iLeft, iRight,
       
  7623                                             iTop, iBottom, iObjectid, iIndex,
       
  7624                                             iNamesize, (mng_pchar)pTemp);
       
  7625 
       
  7626         if (iRetcode)                 /* on error bail out */
       
  7627           return iRetcode;
       
  7628 
       
  7629         pTemp = pTemp + iNamesize + 1;
       
  7630       }
       
  7631     }
       
  7632   }
       
  7633 #endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_DYNAMICMNG */
       
  7634 
       
  7635 #ifdef MNG_STORE_CHUNKS
       
  7636   if (pData->bStorechunks)
       
  7637   {                                    /* initialize storage */
       
  7638     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  7639 
       
  7640     if (iRetcode)                      /* on error bail out */
       
  7641       return iRetcode;
       
  7642 
       
  7643     if (iRawlen)                       /* not empty ? */
       
  7644     {
       
  7645       mng_uint32      iX;
       
  7646       mng_uint32      iCount = 0;
       
  7647       mng_uint8p      pTemp;
       
  7648       mng_uint8p      pNull;
       
  7649       mng_uint32      iLen;
       
  7650       mng_uint8       iEventtype;
       
  7651       mng_uint8       iMasktype;
       
  7652       mng_int32       iLeft;
       
  7653       mng_int32       iRight;
       
  7654       mng_int32       iTop;
       
  7655       mng_int32       iBottom;
       
  7656       mng_uint16      iObjectid;
       
  7657       mng_uint8       iIndex;
       
  7658       mng_uint32      iNamesize;
       
  7659       mng_evnt_entryp pEntry = MNG_NULL;
       
  7660 
       
  7661       for (iX = 0; iX < 2; iX++)       /* do this twice to get the count first ! */
       
  7662       {
       
  7663         pTemp = pRawdata;
       
  7664         iLen  = iRawlen;
       
  7665 
       
  7666         if (iX)                        /* second run ? */
       
  7667         {
       
  7668           MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_evnt_entry)));
       
  7669 
       
  7670           ((mng_evntp)*ppChunk)->iCount   = iCount;
       
  7671           ((mng_evntp)*ppChunk)->pEntries = pEntry;
       
  7672         }
       
  7673 
       
  7674         while (iLen)                   /* anything left ? */
       
  7675         {
       
  7676           iEventtype = *pTemp;         /* eventtype */
       
  7677           if (iEventtype > 5)
       
  7678             MNG_ERROR (pData, MNG_INVALIDEVENT);
       
  7679 
       
  7680           pTemp++;
       
  7681 
       
  7682           iMasktype  = *pTemp;         /* masktype */
       
  7683           if (iMasktype > 5)
       
  7684             MNG_ERROR (pData, MNG_INVALIDMASK);
       
  7685 
       
  7686           pTemp++;
       
  7687           iLen -= 2;
       
  7688 
       
  7689           iLeft     = 0;
       
  7690           iRight    = 0;
       
  7691           iTop      = 0;
       
  7692           iBottom   = 0;
       
  7693           iObjectid = 0;
       
  7694           iIndex    = 0;
       
  7695 
       
  7696           switch (iMasktype)
       
  7697           {
       
  7698             case 1 :
       
  7699               {
       
  7700                 if (iLen > 16)
       
  7701                 {
       
  7702                   iLeft     = mng_get_int32 (pTemp);
       
  7703                   iRight    = mng_get_int32 (pTemp+4);
       
  7704                   iTop      = mng_get_int32 (pTemp+8);
       
  7705                   iBottom   = mng_get_int32 (pTemp+12);
       
  7706                   pTemp += 16;
       
  7707                   iLen -= 16;
       
  7708                 }
       
  7709                 else
       
  7710                   MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7711                 break;
       
  7712               }
       
  7713             case 2 :
       
  7714               {
       
  7715                 if (iLen > 2)
       
  7716                 {
       
  7717                   iObjectid = mng_get_uint16 (pTemp);
       
  7718                   pTemp += 2;
       
  7719                   iLen -= 2;
       
  7720                 }
       
  7721                 else
       
  7722                   MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7723                 break;
       
  7724               }
       
  7725             case 3 :
       
  7726               {
       
  7727                 if (iLen > 3)
       
  7728                 {
       
  7729                   iObjectid = mng_get_uint16 (pTemp);
       
  7730                   iIndex    = *(pTemp+2);
       
  7731                   pTemp += 3;
       
  7732                   iLen -= 3;
       
  7733                 }
       
  7734                 else
       
  7735                   MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7736                 break;
       
  7737               }
       
  7738             case 4 :
       
  7739               {
       
  7740                 if (iLen > 18)
       
  7741                 {
       
  7742                   iLeft     = mng_get_int32 (pTemp);
       
  7743                   iRight    = mng_get_int32 (pTemp+4);
       
  7744                   iTop      = mng_get_int32 (pTemp+8);
       
  7745                   iBottom   = mng_get_int32 (pTemp+12);
       
  7746                   iObjectid = mng_get_uint16 (pTemp+16);
       
  7747                   pTemp += 18;
       
  7748                   iLen -= 18;
       
  7749                 }
       
  7750                 else
       
  7751                   MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7752                 break;
       
  7753               }
       
  7754             case 5 :
       
  7755               {
       
  7756                 if (iLen > 19)
       
  7757                 {
       
  7758                   iLeft     = mng_get_int32 (pTemp);
       
  7759                   iRight    = mng_get_int32 (pTemp+4);
       
  7760                   iTop      = mng_get_int32 (pTemp+8);
       
  7761                   iBottom   = mng_get_int32 (pTemp+12);
       
  7762                   iObjectid = mng_get_uint16 (pTemp+16);
       
  7763                   iIndex    = *(pTemp+18);
       
  7764                   pTemp += 19;
       
  7765                   iLen -= 19;
       
  7766                 }
       
  7767                 else
       
  7768                   MNG_ERROR (pData, MNG_INVALIDLENGTH);
       
  7769                 break;
       
  7770               }
       
  7771           }
       
  7772 
       
  7773           pNull = find_null (pTemp);   /* get the name length */
       
  7774 
       
  7775           if ((pNull - pTemp) > (mng_int32)iLen)
       
  7776           {
       
  7777             iNamesize = iLen;          /* no null found; so end of evNT */
       
  7778             iLen      = 0;
       
  7779           }
       
  7780           else
       
  7781           {
       
  7782             iNamesize = pNull - pTemp; /* should be another entry */
       
  7783             iLen      = iLen - iNamesize - 1;
       
  7784 
       
  7785             if (!iLen)                 /* must not end with a null ! */
       
  7786               MNG_ERROR (pData, MNG_ENDWITHNULL);
       
  7787           }
       
  7788 
       
  7789           if (!iX)
       
  7790           {
       
  7791             iCount++;
       
  7792           }
       
  7793           else
       
  7794           {
       
  7795             pEntry->iEventtype       = iEventtype;
       
  7796             pEntry->iMasktype        = iMasktype;
       
  7797             pEntry->iLeft            = iLeft;
       
  7798             pEntry->iRight           = iRight;
       
  7799             pEntry->iTop             = iTop;
       
  7800             pEntry->iBottom          = iBottom;
       
  7801             pEntry->iObjectid        = iObjectid;
       
  7802             pEntry->iIndex           = iIndex;
       
  7803             pEntry->iSegmentnamesize = iNamesize;
       
  7804 
       
  7805             if (iNamesize)
       
  7806             {
       
  7807               MNG_ALLOC (pData, pEntry->zSegmentname, iNamesize+1);
       
  7808               MNG_COPY (pEntry->zSegmentname, pTemp, iNamesize);
       
  7809             }
       
  7810 
       
  7811             pEntry++;
       
  7812           }
       
  7813 
       
  7814           pTemp = pTemp + iNamesize + 1;
       
  7815         }
       
  7816       }
       
  7817     }
       
  7818   }
       
  7819 #endif /* MNG_STORE_CHUNKS */
       
  7820 
       
  7821 #ifdef MNG_SUPPORT_TRACE
       
  7822   MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_END);
       
  7823 #endif
       
  7824 
       
  7825   return MNG_NOERROR;                  /* done */
       
  7826 }
       
  7827 #endif
       
  7828 #endif
       
  7829 
       
  7830 /* ************************************************************************** */
       
  7831 
       
  7832 #ifndef MNG_OPTIMIZE_CHUNKREADER
       
  7833 READ_CHUNK (mng_read_unknown)
       
  7834 {
       
  7835 #ifdef MNG_SUPPORT_TRACE
       
  7836   MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_START);
       
  7837 #endif
       
  7838                                        /* sequence checks */
       
  7839 #ifdef MNG_INCLUDE_JNG
       
  7840   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  7841       (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
       
  7842 #else
       
  7843   if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
       
  7844       (!pData->bHasBASI) && (!pData->bHasDHDR)    )
       
  7845 #endif
       
  7846     MNG_ERROR (pData, MNG_SEQUENCEERROR);
       
  7847                                        /* critical chunk ? */
       
  7848   if ((((mng_uint32)pData->iChunkname & 0x20000000) == 0)
       
  7849 #ifdef MNG_SKIPCHUNK_SAVE
       
  7850     && (pData->iChunkname != MNG_UINT_SAVE)
       
  7851 #endif
       
  7852 #ifdef MNG_SKIPCHUNK_SEEK
       
  7853     && (pData->iChunkname != MNG_UINT_SEEK)
       
  7854 #endif
       
  7855 #ifdef MNG_SKIPCHUNK_DBYK
       
  7856     && (pData->iChunkname != MNG_UINT_DBYK)
       
  7857 #endif
       
  7858 #ifdef MNG_SKIPCHUNK_ORDR
       
  7859     && (pData->iChunkname != MNG_UINT_ORDR)
       
  7860 #endif
       
  7861       )
       
  7862     MNG_ERROR (pData, MNG_UNKNOWNCRITICAL);
       
  7863 
       
  7864   if (pData->fProcessunknown)          /* let the app handle it ? */
       
  7865   {
       
  7866     mng_bool bOke = pData->fProcessunknown ((mng_handle)pData, pData->iChunkname,
       
  7867                                             iRawlen, (mng_ptr)pRawdata);
       
  7868 
       
  7869     if (!bOke)
       
  7870       MNG_ERROR (pData, MNG_APPMISCERROR);
       
  7871   }
       
  7872 
       
  7873 #ifdef MNG_STORE_CHUNKS
       
  7874   if (pData->bStorechunks)
       
  7875   {                                    /* initialize storage */
       
  7876     mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
       
  7877 
       
  7878     if (iRetcode)                      /* on error bail out */
       
  7879       return iRetcode;
       
  7880                                        /* store the length */
       
  7881     ((mng_chunk_headerp)*ppChunk)->iChunkname = pData->iChunkname;
       
  7882     ((mng_unknown_chunkp)*ppChunk)->iDatasize = iRawlen;
       
  7883 
       
  7884     if (iRawlen == 0)                  /* any data at all ? */
       
  7885       ((mng_unknown_chunkp)*ppChunk)->pData = 0;
       
  7886     else
       
  7887     {                                  /* then store it */
       
  7888       MNG_ALLOC (pData, ((mng_unknown_chunkp)*ppChunk)->pData, iRawlen);
       
  7889       MNG_COPY (((mng_unknown_chunkp)*ppChunk)->pData, pRawdata, iRawlen);
       
  7890     }
       
  7891   }
       
  7892 #endif /* MNG_STORE_CHUNKS */
       
  7893 
       
  7894 #ifdef MNG_SUPPORT_TRACE
       
  7895   MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_END);
       
  7896 #endif
       
  7897 
       
  7898   return MNG_NOERROR;                  /* done */
       
  7899 }
       
  7900 #endif
       
  7901 
       
  7902 /* ************************************************************************** */
       
  7903 
       
  7904 #endif /* MNG_INCLUDE_READ_PROCS */
       
  7905 
       
  7906 /* ************************************************************************** */
       
  7907 /* *                                                                        * */
       
  7908 /* * chunk write functions                                                  * */
       
  7909 /* *                                                                        * */
       
  7910 /* ************************************************************************** */
       
  7911 
       
  7912 #ifdef MNG_INCLUDE_WRITE_PROCS
       
  7913 
       
  7914 /* ************************************************************************** */
       
  7915 
       
  7916 WRITE_CHUNK (mng_write_ihdr)
       
  7917 {
       
  7918   mng_ihdrp   pIHDR;
       
  7919   mng_uint8p  pRawdata;
       
  7920   mng_uint32  iRawlen;
       
  7921   mng_retcode iRetcode;
       
  7922 
       
  7923 #ifdef MNG_SUPPORT_TRACE
       
  7924   MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_START);
       
  7925 #endif
       
  7926 
       
  7927   pIHDR    = (mng_ihdrp)pChunk;        /* address the proper chunk */
       
  7928   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  7929   iRawlen  = 13;
       
  7930                                        /* fill the output buffer */
       
  7931   mng_put_uint32 (pRawdata,   pIHDR->iWidth);
       
  7932   mng_put_uint32 (pRawdata+4, pIHDR->iHeight);
       
  7933 
       
  7934   *(pRawdata+8)  = pIHDR->iBitdepth;
       
  7935   *(pRawdata+9)  = pIHDR->iColortype;
       
  7936   *(pRawdata+10) = pIHDR->iCompression;
       
  7937   *(pRawdata+11) = pIHDR->iFilter;
       
  7938   *(pRawdata+12) = pIHDR->iInterlace;
       
  7939                                        /* and write it */
       
  7940   iRetcode = write_raw_chunk (pData, pIHDR->sHeader.iChunkname, iRawlen, pRawdata);
       
  7941 
       
  7942 #ifdef MNG_SUPPORT_TRACE
       
  7943   MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_END);
       
  7944 #endif
       
  7945 
       
  7946   return iRetcode;
       
  7947 }
       
  7948 
       
  7949 /* ************************************************************************** */
       
  7950 
       
  7951 WRITE_CHUNK (mng_write_plte)
       
  7952 {
       
  7953   mng_pltep   pPLTE;
       
  7954   mng_uint8p  pRawdata;
       
  7955   mng_uint32  iRawlen;
       
  7956   mng_retcode iRetcode;
       
  7957   mng_uint8p  pTemp;
       
  7958   mng_uint32  iX;
       
  7959 
       
  7960 #ifdef MNG_SUPPORT_TRACE
       
  7961   MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_START);
       
  7962 #endif
       
  7963 
       
  7964   pPLTE    = (mng_pltep)pChunk;        /* address the proper chunk */
       
  7965 
       
  7966   if (pPLTE->bEmpty)                   /* write empty chunk ? */
       
  7967     iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, 0, 0);
       
  7968   else
       
  7969   {
       
  7970     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  7971     iRawlen  = pPLTE->iEntrycount * 3;
       
  7972                                        /* fill the output buffer */
       
  7973     pTemp = pRawdata;
       
  7974 
       
  7975     for (iX = 0; iX < pPLTE->iEntrycount; iX++)
       
  7976     {
       
  7977       *pTemp     = pPLTE->aEntries [iX].iRed;
       
  7978       *(pTemp+1) = pPLTE->aEntries [iX].iGreen;
       
  7979       *(pTemp+2) = pPLTE->aEntries [iX].iBlue;
       
  7980 
       
  7981       pTemp += 3;
       
  7982     }
       
  7983                                        /* and write it */
       
  7984     iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, iRawlen, pRawdata);
       
  7985   }
       
  7986 
       
  7987 #ifdef MNG_SUPPORT_TRACE
       
  7988   MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_END);
       
  7989 #endif
       
  7990 
       
  7991   return iRetcode;
       
  7992 }
       
  7993 
       
  7994 /* ************************************************************************** */
       
  7995 
       
  7996 WRITE_CHUNK (mng_write_idat)
       
  7997 {
       
  7998   mng_idatp   pIDAT;
       
  7999   mng_retcode iRetcode;
       
  8000 
       
  8001 #ifdef MNG_SUPPORT_TRACE
       
  8002   MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_START);
       
  8003 #endif
       
  8004 
       
  8005   pIDAT = (mng_idatp)pChunk;           /* address the proper chunk */
       
  8006 
       
  8007   if (pIDAT->bEmpty)                   /* and write it */
       
  8008     iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname, 0, 0);
       
  8009   else
       
  8010     iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname,
       
  8011                                 pIDAT->iDatasize, pIDAT->pData);
       
  8012 
       
  8013 #ifdef MNG_SUPPORT_TRACE
       
  8014   MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_END);
       
  8015 #endif
       
  8016 
       
  8017   return iRetcode;
       
  8018 }
       
  8019 
       
  8020 /* ************************************************************************** */
       
  8021 
       
  8022 WRITE_CHUNK (mng_write_iend)
       
  8023 {
       
  8024   mng_iendp   pIEND;
       
  8025   mng_retcode iRetcode;
       
  8026 
       
  8027 #ifdef MNG_SUPPORT_TRACE
       
  8028   MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_START);
       
  8029 #endif
       
  8030 
       
  8031   pIEND = (mng_iendp)pChunk;           /* address the proper chunk */
       
  8032                                        /* and write it */
       
  8033   iRetcode = write_raw_chunk (pData, pIEND->sHeader.iChunkname, 0, 0);
       
  8034 
       
  8035 #ifdef MNG_SUPPORT_TRACE
       
  8036   MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_END);
       
  8037 #endif
       
  8038 
       
  8039   return iRetcode;
       
  8040 }
       
  8041 
       
  8042 /* ************************************************************************** */
       
  8043 
       
  8044 WRITE_CHUNK (mng_write_trns)
       
  8045 {
       
  8046   mng_trnsp   pTRNS;
       
  8047   mng_uint8p  pRawdata;
       
  8048   mng_uint32  iRawlen;
       
  8049   mng_retcode iRetcode;
       
  8050   mng_uint8p  pTemp;
       
  8051   mng_uint32  iX;
       
  8052 
       
  8053 #ifdef MNG_SUPPORT_TRACE
       
  8054   MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_START);
       
  8055 #endif
       
  8056 
       
  8057   pTRNS = (mng_trnsp)pChunk;           /* address the proper chunk */
       
  8058 
       
  8059   if (pTRNS->bEmpty)                   /* write empty chunk ? */
       
  8060     iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, 0, 0);
       
  8061   else
       
  8062   if (pTRNS->bGlobal)                  /* write global chunk ? */
       
  8063     iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
       
  8064                                 pTRNS->iRawlen, (mng_uint8p)pTRNS->aRawdata);
       
  8065   else
       
  8066   {
       
  8067     pRawdata = pData->pWritebuf+8;     /* init output buffer */
       
  8068     iRawlen  = 0;                      /* and default size */
       
  8069 
       
  8070     switch (pTRNS->iType)
       
  8071     {
       
  8072       case 0: {
       
  8073                 iRawlen   = 2;         /* fill the size & output buffer */
       
  8074                 mng_put_uint16 (pRawdata, pTRNS->iGray);
       
  8075 
       
  8076                 break;
       
  8077               }
       
  8078       case 2: {
       
  8079                 iRawlen       = 6;     /* fill the size & output buffer */
       
  8080                 mng_put_uint16 (pRawdata,   pTRNS->iRed);
       
  8081                 mng_put_uint16 (pRawdata+2, pTRNS->iGreen);
       
  8082                 mng_put_uint16 (pRawdata+4, pTRNS->iBlue);
       
  8083 
       
  8084                 break;
       
  8085               }
       
  8086       case 3: {                        /* init output buffer size */
       
  8087                 iRawlen = pTRNS->iCount;
       
  8088 
       
  8089                 pTemp   = pRawdata;    /* fill the output buffer */
       
  8090 
       
  8091                 for (iX = 0; iX < pTRNS->iCount; iX++)
       
  8092                 {
       
  8093                   *pTemp = pTRNS->aEntries[iX];
       
  8094                   pTemp++;
       
  8095                 }
       
  8096 
       
  8097                 break;
       
  8098               }
       
  8099     }
       
  8100                                        /* write the chunk */
       
  8101     iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
       
  8102                                 iRawlen, pRawdata);
       
  8103   }
       
  8104 
       
  8105 #ifdef MNG_SUPPORT_TRACE
       
  8106   MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_END);
       
  8107 #endif
       
  8108 
       
  8109   return iRetcode;
       
  8110 }
       
  8111 
       
  8112 /* ************************************************************************** */
       
  8113 
       
  8114 WRITE_CHUNK (mng_write_gama)
       
  8115 {
       
  8116   mng_gamap   pGAMA;
       
  8117   mng_uint8p  pRawdata;
       
  8118   mng_uint32  iRawlen;
       
  8119   mng_retcode iRetcode;
       
  8120 
       
  8121 #ifdef MNG_SUPPORT_TRACE
       
  8122   MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_START);
       
  8123 #endif
       
  8124 
       
  8125   pGAMA = (mng_gamap)pChunk;           /* address the proper chunk */
       
  8126 
       
  8127   if (pGAMA->bEmpty)                   /* write empty ? */
       
  8128     iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname, 0, 0);
       
  8129   else
       
  8130   {
       
  8131     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8132     iRawlen  = 4;
       
  8133                                        /* fill the buffer */
       
  8134     mng_put_uint32 (pRawdata, pGAMA->iGamma);
       
  8135                                        /* and write it */
       
  8136     iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname,
       
  8137                                 iRawlen, pRawdata);
       
  8138   }
       
  8139 
       
  8140 #ifdef MNG_SUPPORT_TRACE
       
  8141   MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_END);
       
  8142 #endif
       
  8143 
       
  8144   return iRetcode;
       
  8145 }
       
  8146 
       
  8147 /* ************************************************************************** */
       
  8148 
       
  8149 #ifndef MNG_SKIPCHUNK_cHRM
       
  8150 WRITE_CHUNK (mng_write_chrm)
       
  8151 {
       
  8152   mng_chrmp   pCHRM;
       
  8153   mng_uint8p  pRawdata;
       
  8154   mng_uint32  iRawlen;
       
  8155   mng_retcode iRetcode;
       
  8156 
       
  8157 #ifdef MNG_SUPPORT_TRACE
       
  8158   MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_START);
       
  8159 #endif
       
  8160 
       
  8161   pCHRM = (mng_chrmp)pChunk;           /* address the proper chunk */
       
  8162 
       
  8163   if (pCHRM->bEmpty)                   /* write empty ? */
       
  8164     iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname, 0, 0);
       
  8165   else
       
  8166   {
       
  8167     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8168     iRawlen  = 32;
       
  8169                                        /* fill the buffer */
       
  8170     mng_put_uint32 (pRawdata,    pCHRM->iWhitepointx);
       
  8171     mng_put_uint32 (pRawdata+4,  pCHRM->iWhitepointy);
       
  8172     mng_put_uint32 (pRawdata+8,  pCHRM->iRedx);
       
  8173     mng_put_uint32 (pRawdata+12, pCHRM->iRedy);
       
  8174     mng_put_uint32 (pRawdata+16, pCHRM->iGreenx);
       
  8175     mng_put_uint32 (pRawdata+20, pCHRM->iGreeny);
       
  8176     mng_put_uint32 (pRawdata+24, pCHRM->iBluex);
       
  8177     mng_put_uint32 (pRawdata+28, pCHRM->iBluey);
       
  8178                                        /* and write it */
       
  8179     iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname,
       
  8180                                 iRawlen, pRawdata);
       
  8181   }
       
  8182 
       
  8183 #ifdef MNG_SUPPORT_TRACE
       
  8184   MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_END);
       
  8185 #endif
       
  8186 
       
  8187   return iRetcode;
       
  8188 }
       
  8189 #endif
       
  8190 
       
  8191 /* ************************************************************************** */
       
  8192 
       
  8193 WRITE_CHUNK (mng_write_srgb)
       
  8194 {
       
  8195   mng_srgbp   pSRGB;
       
  8196   mng_uint8p  pRawdata;
       
  8197   mng_uint32  iRawlen;
       
  8198   mng_retcode iRetcode;
       
  8199 
       
  8200 #ifdef MNG_SUPPORT_TRACE
       
  8201   MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_START);
       
  8202 #endif
       
  8203 
       
  8204   pSRGB = (mng_srgbp)pChunk;           /* address the proper chunk */
       
  8205 
       
  8206   if (pSRGB->bEmpty)                   /* write empty ? */
       
  8207     iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname, 0, 0);
       
  8208   else
       
  8209   {
       
  8210     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8211     iRawlen  = 1;
       
  8212                                        /* fill the buffer */
       
  8213     *pRawdata = pSRGB->iRenderingintent;
       
  8214                                        /* and write it */
       
  8215     iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname,
       
  8216                                 iRawlen, pRawdata);
       
  8217   }
       
  8218 
       
  8219 #ifdef MNG_SUPPORT_TRACE
       
  8220   MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_END);
       
  8221 #endif
       
  8222 
       
  8223   return iRetcode;
       
  8224 }
       
  8225 
       
  8226 /* ************************************************************************** */
       
  8227 
       
  8228 #ifndef MNG_SKIPCHUNK_iCCP
       
  8229 WRITE_CHUNK (mng_write_iccp)
       
  8230 {
       
  8231   mng_iccpp   pICCP;
       
  8232   mng_uint8p  pRawdata;
       
  8233   mng_uint32  iRawlen;
       
  8234   mng_retcode iRetcode;
       
  8235   mng_uint8p  pTemp;
       
  8236   mng_uint8p  pBuf = 0;
       
  8237   mng_uint32  iBuflen;
       
  8238   mng_uint32  iReallen;
       
  8239 
       
  8240 #ifdef MNG_SUPPORT_TRACE
       
  8241   MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_START);
       
  8242 #endif
       
  8243 
       
  8244   pICCP = (mng_iccpp)pChunk;           /* address the proper chunk */
       
  8245 
       
  8246   if (pICCP->bEmpty)                   /* write empty ? */
       
  8247     iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname, 0, 0);
       
  8248   else
       
  8249   {                                    /* compress the profile */
       
  8250     iRetcode = deflate_buffer (pData, pICCP->pProfile, pICCP->iProfilesize,
       
  8251                                &pBuf, &iBuflen, &iReallen);
       
  8252 
       
  8253     if (!iRetcode)                     /* still oke ? */
       
  8254     {
       
  8255       pRawdata = pData->pWritebuf+8;   /* init output buffer & size */
       
  8256       iRawlen  = pICCP->iNamesize + 2 + iReallen;
       
  8257                                        /* requires large buffer ? */
       
  8258       if (iRawlen > pData->iWritebufsize)
       
  8259         MNG_ALLOC (pData, pRawdata, iRawlen);
       
  8260 
       
  8261       pTemp = pRawdata;                /* fill the buffer */
       
  8262 
       
  8263       if (pICCP->iNamesize)
       
  8264       {
       
  8265         MNG_COPY (pTemp, pICCP->zName, pICCP->iNamesize);
       
  8266         pTemp += pICCP->iNamesize;
       
  8267       }
       
  8268 
       
  8269       *pTemp     = 0;
       
  8270       *(pTemp+1) = pICCP->iCompression;
       
  8271       pTemp += 2;
       
  8272 
       
  8273       if (iReallen)
       
  8274         MNG_COPY (pTemp, pBuf, iReallen);
       
  8275                                        /* and write it */
       
  8276       iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname,
       
  8277                                   iRawlen, pRawdata);
       
  8278                                        /* drop the temp buffer ? */
       
  8279       if (iRawlen > pData->iWritebufsize)
       
  8280         MNG_FREEX (pData, pRawdata, iRawlen);
       
  8281 
       
  8282     }
       
  8283 
       
  8284     MNG_FREEX (pData, pBuf, iBuflen);  /* always drop the extra buffer */
       
  8285   }
       
  8286 
       
  8287 #ifdef MNG_SUPPORT_TRACE
       
  8288   MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_END);
       
  8289 #endif
       
  8290 
       
  8291   return iRetcode;
       
  8292 }
       
  8293 #endif
       
  8294 
       
  8295 /* ************************************************************************** */
       
  8296 
       
  8297 #ifndef MNG_SKIPCHUNK_tEXt
       
  8298 WRITE_CHUNK (mng_write_text)
       
  8299 {
       
  8300   mng_textp   pTEXT;
       
  8301   mng_uint8p  pRawdata;
       
  8302   mng_uint32  iRawlen;
       
  8303   mng_retcode iRetcode;
       
  8304   mng_uint8p  pTemp;
       
  8305 
       
  8306 #ifdef MNG_SUPPORT_TRACE
       
  8307   MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_START);
       
  8308 #endif
       
  8309 
       
  8310   pTEXT = (mng_textp)pChunk;           /* address the proper chunk */
       
  8311 
       
  8312   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  8313   iRawlen  = pTEXT->iKeywordsize + 1 + pTEXT->iTextsize;
       
  8314                                        /* requires large buffer ? */
       
  8315   if (iRawlen > pData->iWritebufsize)
       
  8316     MNG_ALLOC (pData, pRawdata, iRawlen);
       
  8317 
       
  8318   pTemp = pRawdata;                    /* fill the buffer */
       
  8319 
       
  8320   if (pTEXT->iKeywordsize)
       
  8321   {
       
  8322     MNG_COPY (pTemp, pTEXT->zKeyword, pTEXT->iKeywordsize);
       
  8323     pTemp += pTEXT->iKeywordsize;
       
  8324   }
       
  8325 
       
  8326   *pTemp = 0;
       
  8327   pTemp += 1;
       
  8328 
       
  8329   if (pTEXT->iTextsize)
       
  8330     MNG_COPY (pTemp, pTEXT->zText, pTEXT->iTextsize);
       
  8331                                        /* and write it */
       
  8332   iRetcode = write_raw_chunk (pData, pTEXT->sHeader.iChunkname,
       
  8333                               iRawlen, pRawdata);
       
  8334 
       
  8335   if (iRawlen > pData->iWritebufsize)  /* drop the temp buffer ? */
       
  8336     MNG_FREEX (pData, pRawdata, iRawlen);
       
  8337 
       
  8338 #ifdef MNG_SUPPORT_TRACE
       
  8339   MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_END);
       
  8340 #endif
       
  8341 
       
  8342   return iRetcode;
       
  8343 }
       
  8344 #endif
       
  8345 
       
  8346 /* ************************************************************************** */
       
  8347 
       
  8348 #ifndef MNG_SKIPCHUNK_zTXt
       
  8349 WRITE_CHUNK (mng_write_ztxt)
       
  8350 {
       
  8351   mng_ztxtp   pZTXT;
       
  8352   mng_uint8p  pRawdata;
       
  8353   mng_uint32  iRawlen;
       
  8354   mng_retcode iRetcode;
       
  8355   mng_uint8p  pTemp;
       
  8356   mng_uint8p  pBuf = 0;
       
  8357   mng_uint32  iBuflen;
       
  8358   mng_uint32  iReallen;
       
  8359 
       
  8360 #ifdef MNG_SUPPORT_TRACE
       
  8361   MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_START);
       
  8362 #endif
       
  8363 
       
  8364   pZTXT = (mng_ztxtp)pChunk;           /* address the proper chunk */
       
  8365                                        /* compress the text */
       
  8366   iRetcode = deflate_buffer (pData, (mng_uint8p)pZTXT->zText, pZTXT->iTextsize,
       
  8367                              &pBuf, &iBuflen, &iReallen);
       
  8368 
       
  8369   if (!iRetcode)                       /* all ok ? */
       
  8370   {
       
  8371     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8372     iRawlen  = pZTXT->iKeywordsize + 2 + iReallen;
       
  8373                                        /* requires large buffer ? */
       
  8374     if (iRawlen > pData->iWritebufsize)
       
  8375       MNG_ALLOC (pData, pRawdata, iRawlen);
       
  8376 
       
  8377     pTemp = pRawdata;                  /* fill the buffer */
       
  8378 
       
  8379     if (pZTXT->iKeywordsize)
       
  8380     {
       
  8381       MNG_COPY (pTemp, pZTXT->zKeyword, pZTXT->iKeywordsize);
       
  8382       pTemp += pZTXT->iKeywordsize;
       
  8383     }
       
  8384 
       
  8385     *pTemp = 0;                        /* terminator zero */
       
  8386     pTemp++;
       
  8387     *pTemp = 0;                        /* compression type */
       
  8388     pTemp++;
       
  8389 
       
  8390     if (iReallen)
       
  8391       MNG_COPY (pTemp, pBuf, iReallen);
       
  8392                                        /* and write it */
       
  8393     iRetcode = write_raw_chunk (pData, pZTXT->sHeader.iChunkname,
       
  8394                                 iRawlen, pRawdata);
       
  8395                                        /* drop the temp buffer ? */
       
  8396     if (iRawlen > pData->iWritebufsize)
       
  8397       MNG_FREEX (pData, pRawdata, iRawlen);
       
  8398 
       
  8399   }
       
  8400 
       
  8401   MNG_FREEX (pData, pBuf, iBuflen);    /* always drop the compression buffer */
       
  8402 
       
  8403 #ifdef MNG_SUPPORT_TRACE
       
  8404   MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_END);
       
  8405 #endif
       
  8406 
       
  8407   return iRetcode;
       
  8408 }
       
  8409 #endif
       
  8410 
       
  8411 /* ************************************************************************** */
       
  8412 
       
  8413 #ifndef MNG_SKIPCHUNK_iTXt
       
  8414 WRITE_CHUNK (mng_write_itxt)
       
  8415 {
       
  8416   mng_itxtp   pITXT;
       
  8417   mng_uint8p  pRawdata;
       
  8418   mng_uint32  iRawlen;
       
  8419   mng_retcode iRetcode;
       
  8420   mng_uint8p  pTemp;
       
  8421   mng_uint8p  pBuf = 0;
       
  8422   mng_uint32  iBuflen;
       
  8423   mng_uint32  iReallen;
       
  8424 
       
  8425 #ifdef MNG_SUPPORT_TRACE
       
  8426   MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_START);
       
  8427 #endif
       
  8428 
       
  8429   pITXT = (mng_itxtp)pChunk;           /* address the proper chunk */
       
  8430 
       
  8431   if (pITXT->iCompressionflag)         /* compress the text */
       
  8432     iRetcode = deflate_buffer (pData, (mng_uint8p)pITXT->zText, pITXT->iTextsize,
       
  8433                                &pBuf, &iBuflen, &iReallen);
       
  8434   else
       
  8435     iRetcode = MNG_NOERROR;
       
  8436 
       
  8437   if (!iRetcode)                       /* all ok ? */
       
  8438   {
       
  8439     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8440     iRawlen  = pITXT->iKeywordsize + pITXT->iLanguagesize +
       
  8441                pITXT->iTranslationsize + 5;
       
  8442 
       
  8443     if (pITXT->iCompressionflag)
       
  8444       iRawlen = iRawlen + iReallen;
       
  8445     else
       
  8446       iRawlen = iRawlen + pITXT->iTextsize;
       
  8447                                        /* requires large buffer ? */
       
  8448     if (iRawlen > pData->iWritebufsize)
       
  8449       MNG_ALLOC (pData, pRawdata, iRawlen);
       
  8450 
       
  8451     pTemp = pRawdata;                  /* fill the buffer */
       
  8452 
       
  8453     if (pITXT->iKeywordsize)
       
  8454     {
       
  8455       MNG_COPY (pTemp, pITXT->zKeyword, pITXT->iKeywordsize);
       
  8456       pTemp += pITXT->iKeywordsize;
       
  8457     }
       
  8458 
       
  8459     *pTemp = 0;
       
  8460     pTemp++;
       
  8461     *pTemp = pITXT->iCompressionflag;
       
  8462     pTemp++;
       
  8463     *pTemp = pITXT->iCompressionmethod;
       
  8464     pTemp++;
       
  8465 
       
  8466     if (pITXT->iLanguagesize)
       
  8467     {
       
  8468       MNG_COPY (pTemp, pITXT->zLanguage, pITXT->iLanguagesize);
       
  8469       pTemp += pITXT->iLanguagesize;
       
  8470     }
       
  8471 
       
  8472     *pTemp = 0;
       
  8473     pTemp++;
       
  8474 
       
  8475     if (pITXT->iTranslationsize)
       
  8476     {
       
  8477       MNG_COPY (pTemp, pITXT->zTranslation, pITXT->iTranslationsize);
       
  8478       pTemp += pITXT->iTranslationsize;
       
  8479     }
       
  8480 
       
  8481     *pTemp = 0;
       
  8482     pTemp++;
       
  8483 
       
  8484     if (pITXT->iCompressionflag)
       
  8485     {
       
  8486       if (iReallen)
       
  8487         MNG_COPY (pTemp, pBuf, iReallen);
       
  8488     }
       
  8489     else
       
  8490     {
       
  8491       if (pITXT->iTextsize)
       
  8492         MNG_COPY (pTemp, pITXT->zText, pITXT->iTextsize);
       
  8493     }
       
  8494                                        /* and write it */
       
  8495     iRetcode = write_raw_chunk (pData, pITXT->sHeader.iChunkname,
       
  8496                                 iRawlen, pRawdata);
       
  8497                                        /* drop the temp buffer ? */
       
  8498     if (iRawlen > pData->iWritebufsize)
       
  8499       MNG_FREEX (pData, pRawdata, iRawlen);
       
  8500 
       
  8501   }
       
  8502 
       
  8503   MNG_FREEX (pData, pBuf, iBuflen);    /* always drop the compression buffer */
       
  8504 
       
  8505   if (iRetcode)                        /* on error bail out */
       
  8506     return iRetcode;
       
  8507 
       
  8508 #ifdef MNG_SUPPORT_TRACE
       
  8509   MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_END);
       
  8510 #endif
       
  8511 
       
  8512   return MNG_NOERROR;
       
  8513 }
       
  8514 #endif
       
  8515 
       
  8516 /* ************************************************************************** */
       
  8517 
       
  8518 #ifndef MNG_SKIPCHUNK_bKGD
       
  8519 WRITE_CHUNK (mng_write_bkgd)
       
  8520 {
       
  8521   mng_bkgdp   pBKGD;
       
  8522   mng_uint8p  pRawdata;
       
  8523   mng_uint32  iRawlen;
       
  8524   mng_retcode iRetcode;
       
  8525 
       
  8526 #ifdef MNG_SUPPORT_TRACE
       
  8527   MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_START);
       
  8528 #endif
       
  8529 
       
  8530   pBKGD = (mng_bkgdp)pChunk;           /* address the proper chunk */
       
  8531 
       
  8532   if (pBKGD->bEmpty)                   /* write empty ? */
       
  8533     iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname, 0, 0);
       
  8534   else
       
  8535   {
       
  8536     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8537     iRawlen  = 0;                      /* and default size */
       
  8538 
       
  8539     switch (pBKGD->iType)
       
  8540     {
       
  8541       case 0: {                        /* gray */
       
  8542                 iRawlen = 2;           /* fill the size & output buffer */
       
  8543                 mng_put_uint16 (pRawdata, pBKGD->iGray);
       
  8544 
       
  8545                 break;
       
  8546               }
       
  8547       case 2: {                        /* rgb */
       
  8548                 iRawlen = 6;           /* fill the size & output buffer */
       
  8549                 mng_put_uint16 (pRawdata,   pBKGD->iRed);
       
  8550                 mng_put_uint16 (pRawdata+2, pBKGD->iGreen);
       
  8551                 mng_put_uint16 (pRawdata+4, pBKGD->iBlue);
       
  8552 
       
  8553                 break;
       
  8554               }
       
  8555       case 3: {                        /* indexed */
       
  8556                 iRawlen   = 1;         /* fill the size & output buffer */
       
  8557                 *pRawdata = pBKGD->iIndex;
       
  8558 
       
  8559                 break;
       
  8560               }
       
  8561     }
       
  8562                                        /* and write it */
       
  8563     iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname,
       
  8564                                 iRawlen, pRawdata);
       
  8565   }
       
  8566 
       
  8567 #ifdef MNG_SUPPORT_TRACE
       
  8568   MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_END);
       
  8569 #endif
       
  8570 
       
  8571   return iRetcode;
       
  8572 }
       
  8573 #endif
       
  8574 
       
  8575 /* ************************************************************************** */
       
  8576 
       
  8577 #ifndef MNG_SKIPCHUNK_pHYs
       
  8578 WRITE_CHUNK (mng_write_phys)
       
  8579 {
       
  8580   mng_physp   pPHYS;
       
  8581   mng_uint8p  pRawdata;
       
  8582   mng_uint32  iRawlen;
       
  8583   mng_retcode iRetcode;
       
  8584 
       
  8585 #ifdef MNG_SUPPORT_TRACE
       
  8586   MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_START);
       
  8587 #endif
       
  8588 
       
  8589   pPHYS = (mng_physp)pChunk;           /* address the proper chunk */
       
  8590 
       
  8591   if (pPHYS->bEmpty)                   /* write empty ? */
       
  8592     iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname, 0, 0);
       
  8593   else
       
  8594   {
       
  8595     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8596     iRawlen  = 9;
       
  8597                                        /* fill the output buffer */
       
  8598     mng_put_uint32 (pRawdata,   pPHYS->iSizex);
       
  8599     mng_put_uint32 (pRawdata+4, pPHYS->iSizey);
       
  8600 
       
  8601     *(pRawdata+8) = pPHYS->iUnit;
       
  8602                                        /* and write it */
       
  8603     iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname,
       
  8604                                 iRawlen, pRawdata);
       
  8605   }
       
  8606 
       
  8607 #ifdef MNG_SUPPORT_TRACE
       
  8608   MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_END);
       
  8609 #endif
       
  8610 
       
  8611   return iRetcode;
       
  8612 }
       
  8613 #endif
       
  8614 
       
  8615 /* ************************************************************************** */
       
  8616 
       
  8617 #ifndef MNG_SKIPCHUNK_sBIT
       
  8618 WRITE_CHUNK (mng_write_sbit)
       
  8619 {
       
  8620   mng_sbitp   pSBIT;
       
  8621   mng_uint8p  pRawdata;
       
  8622   mng_uint32  iRawlen;
       
  8623   mng_retcode iRetcode;
       
  8624 
       
  8625 #ifdef MNG_SUPPORT_TRACE
       
  8626   MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_START);
       
  8627 #endif
       
  8628 
       
  8629   pSBIT = (mng_sbitp)pChunk;           /* address the proper chunk */
       
  8630 
       
  8631   if (pSBIT->bEmpty)                   /* write empty ? */
       
  8632     iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname, 0, 0);
       
  8633   else
       
  8634   {
       
  8635     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  8636     iRawlen  = 0;                      /* and default size */
       
  8637 
       
  8638     switch (pSBIT->iType)
       
  8639     {
       
  8640       case  0: {                       /* gray */
       
  8641                  iRawlen       = 1;    /* fill the size & output buffer */
       
  8642                  *pRawdata     = pSBIT->aBits[0];
       
  8643 
       
  8644                  break;
       
  8645                }
       
  8646       case  2: {                       /* rgb */
       
  8647                  iRawlen       = 3;    /* fill the size & output buffer */
       
  8648                  *pRawdata     = pSBIT->aBits[0];
       
  8649                  *(pRawdata+1) = pSBIT->aBits[1];
       
  8650                  *(pRawdata+2) = pSBIT->aBits[2];
       
  8651 
       
  8652                  break;
       
  8653                }
       
  8654       case  3: {                       /* indexed */
       
  8655                  iRawlen       = 3;    /* fill the size & output buffer */
       
  8656                  *pRawdata     = pSBIT->aBits[0];
       
  8657                  *pRawdata     = pSBIT->aBits[1];
       
  8658                  *pRawdata     = pSBIT->aBits[2];
       
  8659 
       
  8660                  break;
       
  8661                }
       
  8662       case  4: {                       /* gray + alpha */
       
  8663                  iRawlen       = 2;    /* fill the size & output buffer */
       
  8664                  *pRawdata     = pSBIT->aBits[0];
       
  8665                  *(pRawdata+1) = pSBIT->aBits[1];
       
  8666 
       
  8667                  break;
       
  8668                }
       
  8669       case  6: {                       /* rgb + alpha */
       
  8670                  iRawlen       = 4;    /* fill the size & output buffer */
       
  8671                  *pRawdata     = pSBIT->aBits[0];
       
  8672                  *(pRawdata+1) = pSBIT->aBits[1];
       
  8673                  *(pRawdata+2) = pSBIT->aBits[2];
       
  8674                  *(pRawdata+3) = pSBIT->aBits[3];
       
  8675 
       
  8676                  break;
       
  8677                }
       
  8678       case 10: {                       /* jpeg gray */
       
  8679                  iRawlen       = 1;    /* fill the size & output buffer */
       
  8680                  *pRawdata     = pSBIT->aBits[0];
       
  8681 
       
  8682                  break;
       
  8683                }
       
  8684       case 12: {                       /* jpeg rgb */
       
  8685                  iRawlen       = 3;    /* fill the size & output buffer */
       
  8686                  *pRawdata     = pSBIT->aBits[0];
       
  8687                  *(pRawdata+1) = pSBIT->aBits[1];
       
  8688                  *(pRawdata+2) = pSBIT->aBits[2];
       
  8689 
       
  8690                  break;
       
  8691                }
       
  8692       case 14: {                       /* jpeg gray + alpha */
       
  8693                  iRawlen       = 2;    /* fill the size & output buffer */
       
  8694                  *pRawdata     = pSBIT->aBits[0];
       
  8695                  *(pRawdata+1) = pSBIT->aBits[1];
       
  8696 
       
  8697                  break;
       
  8698                }
       
  8699       case 16: {                       /* jpeg rgb + alpha */
       
  8700                  iRawlen       = 4;    /* fill the size & output buffer */
       
  8701                  *pRawdata     = pSBIT->aBits[0];
       
  8702                  *(pRawdata+1) = pSBIT->aBits[1];
       
  8703                  *(pRawdata+2) = pSBIT->aBits[2];
       
  8704                  *(pRawdata+3) = pSBIT->aBits[3];
       
  8705 
       
  8706                  break;
       
  8707                }
       
  8708     }
       
  8709                                        /* and write it */
       
  8710     iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname,
       
  8711                                 iRawlen, pRawdata);
       
  8712   }
       
  8713 
       
  8714 #ifdef MNG_SUPPORT_TRACE
       
  8715   MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_END);
       
  8716 #endif
       
  8717 
       
  8718   return iRetcode;
       
  8719 }
       
  8720 #endif
       
  8721 
       
  8722 /* ************************************************************************** */
       
  8723 
       
  8724 #ifndef MNG_SKIPCHUNK_sPLT
       
  8725 WRITE_CHUNK (mng_write_splt)
       
  8726 {
       
  8727   mng_spltp   pSPLT;
       
  8728   mng_uint8p  pRawdata;
       
  8729   mng_uint32  iRawlen;
       
  8730   mng_retcode iRetcode;
       
  8731   mng_uint32  iEntrieslen;
       
  8732   mng_uint8p  pTemp;
       
  8733 
       
  8734 #ifdef MNG_SUPPORT_TRACE
       
  8735   MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_START);
       
  8736 #endif
       
  8737 
       
  8738   pSPLT = (mng_spltp)pChunk;           /* address the proper chunk */
       
  8739 
       
  8740   pRawdata    = pData->pWritebuf+8;    /* init output buffer & size */
       
  8741   iEntrieslen = ((pSPLT->iSampledepth >> 3) * 4 + 2) * pSPLT->iEntrycount;
       
  8742   iRawlen     = pSPLT->iNamesize + 2 + iEntrieslen;
       
  8743                                        /* requires large buffer ? */
       
  8744   if (iRawlen > pData->iWritebufsize)
       
  8745     MNG_ALLOC (pData, pRawdata, iRawlen);
       
  8746 
       
  8747   pTemp = pRawdata;                    /* fill the buffer */
       
  8748 
       
  8749   if (pSPLT->iNamesize)
       
  8750   {
       
  8751     MNG_COPY (pTemp, pSPLT->zName, pSPLT->iNamesize);
       
  8752     pTemp += pSPLT->iNamesize;
       
  8753   }
       
  8754 
       
  8755   *pTemp     = 0;
       
  8756   *(pTemp+1) = pSPLT->iSampledepth;
       
  8757   pTemp += 2;
       
  8758 
       
  8759   if (pSPLT->iEntrycount)
       
  8760     MNG_COPY (pTemp, pSPLT->pEntries, iEntrieslen);
       
  8761                                        /* and write it */
       
  8762   iRetcode = write_raw_chunk (pData, pSPLT->sHeader.iChunkname,
       
  8763                               iRawlen, pRawdata);
       
  8764 
       
  8765   if (iRawlen > pData->iWritebufsize)  /* drop the temp buffer ? */
       
  8766     MNG_FREEX (pData, pRawdata, iRawlen);
       
  8767 
       
  8768 #ifdef MNG_SUPPORT_TRACE
       
  8769   MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_END);
       
  8770 #endif
       
  8771 
       
  8772   return iRetcode;
       
  8773 }
       
  8774 #endif
       
  8775 
       
  8776 /* ************************************************************************** */
       
  8777 
       
  8778 #ifndef MNG_SKIPCHUNK_hIST
       
  8779 WRITE_CHUNK (mng_write_hist)
       
  8780 {
       
  8781   mng_histp   pHIST;
       
  8782   mng_uint8p  pRawdata;
       
  8783   mng_uint32  iRawlen;
       
  8784   mng_retcode iRetcode;
       
  8785   mng_uint8p  pTemp;
       
  8786   mng_uint32  iX;
       
  8787 
       
  8788 #ifdef MNG_SUPPORT_TRACE
       
  8789   MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_START);
       
  8790 #endif
       
  8791 
       
  8792   pHIST = (mng_histp)pChunk;           /* address the proper chunk */
       
  8793 
       
  8794   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  8795   iRawlen  = pHIST->iEntrycount << 1;
       
  8796 
       
  8797   pTemp    = pRawdata;                 /* fill the output buffer */
       
  8798 
       
  8799   for (iX = 0; iX < pHIST->iEntrycount; iX++)
       
  8800   {
       
  8801     mng_put_uint16 (pTemp, pHIST->aEntries [iX]);
       
  8802     pTemp += 2;
       
  8803   }
       
  8804                                        /* and write it */
       
  8805   iRetcode = write_raw_chunk (pData, pHIST->sHeader.iChunkname,
       
  8806                               iRawlen, pRawdata);
       
  8807 
       
  8808 #ifdef MNG_SUPPORT_TRACE
       
  8809   MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_END);
       
  8810 #endif
       
  8811 
       
  8812   return iRetcode;
       
  8813 }
       
  8814 #endif
       
  8815 
       
  8816 /* ************************************************************************** */
       
  8817 
       
  8818 #ifndef MNG_SKIPCHUNK_tIME
       
  8819 WRITE_CHUNK (mng_write_time)
       
  8820 {
       
  8821   mng_timep   pTIME;
       
  8822   mng_uint8p  pRawdata;
       
  8823   mng_uint32  iRawlen;
       
  8824   mng_retcode iRetcode;
       
  8825 
       
  8826 #ifdef MNG_SUPPORT_TRACE
       
  8827   MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_START);
       
  8828 #endif
       
  8829 
       
  8830   pTIME = (mng_timep)pChunk;           /* address the proper chunk */
       
  8831 
       
  8832   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  8833   iRawlen  = 7;
       
  8834                                        /* fill the output buffer */
       
  8835   mng_put_uint16 (pRawdata, pTIME->iYear);
       
  8836 
       
  8837   *(pRawdata+2) = pTIME->iMonth;
       
  8838   *(pRawdata+3) = pTIME->iDay;
       
  8839   *(pRawdata+4) = pTIME->iHour;
       
  8840   *(pRawdata+5) = pTIME->iMinute;
       
  8841   *(pRawdata+6) = pTIME->iSecond;
       
  8842                                        /* and write it */
       
  8843   iRetcode = write_raw_chunk (pData, pTIME->sHeader.iChunkname,
       
  8844                               iRawlen, pRawdata);
       
  8845 
       
  8846 #ifdef MNG_SUPPORT_TRACE
       
  8847   MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_END);
       
  8848 #endif
       
  8849 
       
  8850   return iRetcode;
       
  8851 }
       
  8852 #endif
       
  8853 
       
  8854 /* ************************************************************************** */
       
  8855 
       
  8856 WRITE_CHUNK (mng_write_mhdr)
       
  8857 {
       
  8858   mng_mhdrp   pMHDR;
       
  8859   mng_uint8p  pRawdata;
       
  8860   mng_uint32  iRawlen;
       
  8861   mng_retcode iRetcode;
       
  8862 
       
  8863 #ifdef MNG_SUPPORT_TRACE
       
  8864   MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_START);
       
  8865 #endif
       
  8866 
       
  8867   pMHDR = (mng_mhdrp)pChunk;           /* address the proper chunk */
       
  8868 
       
  8869   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  8870   iRawlen  = 28;
       
  8871                                        /* fill the output buffer */
       
  8872   mng_put_uint32 (pRawdata,    pMHDR->iWidth);
       
  8873   mng_put_uint32 (pRawdata+4,  pMHDR->iHeight);
       
  8874   mng_put_uint32 (pRawdata+8,  pMHDR->iTicks);
       
  8875   mng_put_uint32 (pRawdata+12, pMHDR->iLayercount);
       
  8876   mng_put_uint32 (pRawdata+16, pMHDR->iFramecount);
       
  8877   mng_put_uint32 (pRawdata+20, pMHDR->iPlaytime);
       
  8878   mng_put_uint32 (pRawdata+24, pMHDR->iSimplicity);
       
  8879 
       
  8880                                        /* and write it */
       
  8881   iRetcode = write_raw_chunk (pData, pMHDR->sHeader.iChunkname,
       
  8882                               iRawlen, pRawdata);
       
  8883 
       
  8884 #ifdef MNG_SUPPORT_TRACE
       
  8885   MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_END);
       
  8886 #endif
       
  8887 
       
  8888   return iRetcode;
       
  8889 }
       
  8890 
       
  8891 /* ************************************************************************** */
       
  8892 
       
  8893 WRITE_CHUNK (mng_write_mend)
       
  8894 {
       
  8895   mng_mendp   pMEND;
       
  8896   mng_retcode iRetcode;
       
  8897 
       
  8898 #ifdef MNG_SUPPORT_TRACE
       
  8899   MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_START);
       
  8900 #endif
       
  8901 
       
  8902   pMEND = (mng_mendp)pChunk;           /* address the proper chunk */
       
  8903                                        /* and write it */
       
  8904   iRetcode = write_raw_chunk (pData, pMEND->sHeader.iChunkname, 0, 0);
       
  8905 
       
  8906 #ifdef MNG_SUPPORT_TRACE
       
  8907   MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_END);
       
  8908 #endif
       
  8909 
       
  8910   return iRetcode;
       
  8911 }
       
  8912 
       
  8913 /* ************************************************************************** */
       
  8914 
       
  8915 WRITE_CHUNK (mng_write_loop)
       
  8916 {
       
  8917   mng_loopp   pLOOP;
       
  8918   mng_uint8p  pRawdata;
       
  8919   mng_uint32  iRawlen;
       
  8920   mng_retcode iRetcode;
       
  8921 #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
       
  8922   mng_uint8p  pTemp1;
       
  8923   mng_uint32p pTemp2;
       
  8924   mng_uint32  iX;
       
  8925 #endif
       
  8926 
       
  8927 #ifdef MNG_SUPPORT_TRACE
       
  8928   MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_START);
       
  8929 #endif
       
  8930 
       
  8931   pLOOP = (mng_loopp)pChunk;           /* address the proper chunk */
       
  8932 
       
  8933   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  8934   iRawlen  = 5;
       
  8935                                        /* fill the output buffer */
       
  8936   *pRawdata = pLOOP->iLevel;
       
  8937   mng_put_uint32 (pRawdata+1,  pLOOP->iRepeat);
       
  8938 
       
  8939   if (pLOOP->iTermination)
       
  8940   {
       
  8941     iRawlen++;
       
  8942     *(pRawdata+5) = pLOOP->iTermination;
       
  8943 
       
  8944     if ((pLOOP->iCount) ||
       
  8945         (pLOOP->iItermin != 1) || (pLOOP->iItermax != 0x7FFFFFFFL))
       
  8946     {
       
  8947       iRawlen += 8;
       
  8948 
       
  8949       mng_put_uint32 (pRawdata+6,  pLOOP->iItermin);
       
  8950       mng_put_uint32 (pRawdata+10, pLOOP->iItermax);
       
  8951 
       
  8952 #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
       
  8953       if (pLOOP->iCount)
       
  8954       {
       
  8955         iRawlen += pLOOP->iCount * 4;
       
  8956 
       
  8957         pTemp1 = pRawdata+14;
       
  8958         pTemp2 = pLOOP->pSignals;
       
  8959 
       
  8960         for (iX = 0; iX < pLOOP->iCount; iX++)
       
  8961         {
       
  8962           mng_put_uint32 (pTemp1, *pTemp2);
       
  8963 
       
  8964           pTemp1 += 4;
       
  8965           pTemp2++;
       
  8966         }
       
  8967       }
       
  8968 #endif
       
  8969     }
       
  8970   }
       
  8971                                        /* and write it */
       
  8972   iRetcode = write_raw_chunk (pData, pLOOP->sHeader.iChunkname,
       
  8973                               iRawlen, pRawdata);
       
  8974 
       
  8975 #ifdef MNG_SUPPORT_TRACE
       
  8976   MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_END);
       
  8977 #endif
       
  8978 
       
  8979   return iRetcode;
       
  8980 }
       
  8981 
       
  8982 /* ************************************************************************** */
       
  8983 
       
  8984 WRITE_CHUNK (mng_write_endl)
       
  8985 {
       
  8986   mng_endlp   pENDL;
       
  8987   mng_uint8p  pRawdata;
       
  8988   mng_uint32  iRawlen;
       
  8989   mng_retcode iRetcode;
       
  8990 
       
  8991 #ifdef MNG_SUPPORT_TRACE
       
  8992   MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_START);
       
  8993 #endif
       
  8994 
       
  8995   pENDL     = (mng_endlp)pChunk;       /* address the proper chunk */
       
  8996 
       
  8997   pRawdata  = pData->pWritebuf+8;      /* init output buffer & size */
       
  8998   iRawlen   = 1;
       
  8999 
       
  9000   *pRawdata = pENDL->iLevel;           /* fill the output buffer */
       
  9001                                        /* and write it */
       
  9002   iRetcode  = write_raw_chunk (pData, pENDL->sHeader.iChunkname,
       
  9003                                iRawlen, pRawdata);
       
  9004 
       
  9005 #ifdef MNG_SUPPORT_TRACE
       
  9006   MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_END);
       
  9007 #endif
       
  9008 
       
  9009   return iRetcode;
       
  9010 }
       
  9011 
       
  9012 /* ************************************************************************** */
       
  9013 
       
  9014 WRITE_CHUNK (mng_write_defi)
       
  9015 {
       
  9016   mng_defip   pDEFI;
       
  9017   mng_uint8p  pRawdata;
       
  9018   mng_uint32  iRawlen;
       
  9019   mng_retcode iRetcode;
       
  9020 
       
  9021 #ifdef MNG_SUPPORT_TRACE
       
  9022   MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_START);
       
  9023 #endif
       
  9024 
       
  9025   pDEFI = (mng_defip)pChunk;           /* address the proper chunk */
       
  9026 
       
  9027   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9028   iRawlen  = 2;
       
  9029                                        /* fill the output buffer */
       
  9030   mng_put_uint16 (pRawdata, pDEFI->iObjectid);
       
  9031 
       
  9032   if ((pDEFI->iDonotshow) || (pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
       
  9033   {
       
  9034     iRawlen++;
       
  9035     *(pRawdata+2) = pDEFI->iDonotshow;
       
  9036 
       
  9037     if ((pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
       
  9038     {
       
  9039       iRawlen++;
       
  9040       *(pRawdata+3) = pDEFI->iConcrete;
       
  9041 
       
  9042       if ((pDEFI->bHasloca) || (pDEFI->bHasclip))
       
  9043       {
       
  9044         iRawlen += 8;
       
  9045 
       
  9046         mng_put_uint32 (pRawdata+4, pDEFI->iXlocation);
       
  9047         mng_put_uint32 (pRawdata+8, pDEFI->iYlocation);
       
  9048 
       
  9049         if (pDEFI->bHasclip)
       
  9050         {
       
  9051           iRawlen += 16;
       
  9052 
       
  9053           mng_put_uint32 (pRawdata+12, pDEFI->iLeftcb);
       
  9054           mng_put_uint32 (pRawdata+16, pDEFI->iRightcb);
       
  9055           mng_put_uint32 (pRawdata+20, pDEFI->iTopcb);
       
  9056           mng_put_uint32 (pRawdata+24, pDEFI->iBottomcb);
       
  9057         }
       
  9058       }
       
  9059     }
       
  9060   }
       
  9061                                        /* and write it */
       
  9062   iRetcode = write_raw_chunk (pData, pDEFI->sHeader.iChunkname,
       
  9063                               iRawlen, pRawdata);
       
  9064 
       
  9065 #ifdef MNG_SUPPORT_TRACE
       
  9066   MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_END);
       
  9067 #endif
       
  9068 
       
  9069   return iRetcode;
       
  9070 }
       
  9071 
       
  9072 /* ************************************************************************** */
       
  9073 
       
  9074 WRITE_CHUNK (mng_write_basi)
       
  9075 {
       
  9076   mng_basip   pBASI;
       
  9077   mng_uint8p  pRawdata;
       
  9078   mng_uint32  iRawlen;
       
  9079   mng_retcode iRetcode;
       
  9080   mng_bool    bOpaque;
       
  9081 
       
  9082 #ifdef MNG_SUPPORT_TRACE
       
  9083   MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_START);
       
  9084 #endif
       
  9085 
       
  9086   pBASI = (mng_basip)pChunk;           /* address the proper chunk */
       
  9087 
       
  9088 #ifndef MNG_NO_16BIT_SUPPORT
       
  9089   if (pBASI->iBitdepth <= 8)           /* determine opacity alpha-field */
       
  9090 #endif
       
  9091     bOpaque = (mng_bool)(pBASI->iAlpha == 0xFF);
       
  9092 #ifndef MNG_NO_16BIT_SUPPORT
       
  9093   else
       
  9094     bOpaque = (mng_bool)(pBASI->iAlpha == 0xFFFF);
       
  9095 #endif
       
  9096 
       
  9097   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9098   iRawlen  = 13;
       
  9099                                        /* fill the output buffer */
       
  9100   mng_put_uint32 (pRawdata,   pBASI->iWidth);
       
  9101   mng_put_uint32 (pRawdata+4, pBASI->iHeight);
       
  9102 
       
  9103   *(pRawdata+8)  = pBASI->iBitdepth;
       
  9104   *(pRawdata+9)  = pBASI->iColortype;
       
  9105   *(pRawdata+10) = pBASI->iCompression;
       
  9106   *(pRawdata+11) = pBASI->iFilter;
       
  9107   *(pRawdata+12) = pBASI->iInterlace;
       
  9108 
       
  9109   if ((pBASI->iRed) || (pBASI->iGreen) || (pBASI->iBlue) ||
       
  9110       (!bOpaque) || (pBASI->iViewable))
       
  9111   {
       
  9112     iRawlen += 6;
       
  9113     mng_put_uint16 (pRawdata+13, pBASI->iRed);
       
  9114     mng_put_uint16 (pRawdata+15, pBASI->iGreen);
       
  9115     mng_put_uint16 (pRawdata+17, pBASI->iBlue);
       
  9116 
       
  9117     if ((!bOpaque) || (pBASI->iViewable))
       
  9118     {
       
  9119       iRawlen += 2;
       
  9120       mng_put_uint16 (pRawdata+19, pBASI->iAlpha);
       
  9121 
       
  9122       if (pBASI->iViewable)
       
  9123       {
       
  9124         iRawlen++;
       
  9125         *(pRawdata+21) = pBASI->iViewable;
       
  9126       }
       
  9127     }
       
  9128   }
       
  9129                                        /* and write it */
       
  9130   iRetcode = write_raw_chunk (pData, pBASI->sHeader.iChunkname,
       
  9131                               iRawlen, pRawdata);
       
  9132 
       
  9133 #ifdef MNG_SUPPORT_TRACE
       
  9134   MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_END);
       
  9135 #endif
       
  9136 
       
  9137   return iRetcode;
       
  9138 }
       
  9139 
       
  9140 /* ************************************************************************** */
       
  9141 
       
  9142 WRITE_CHUNK (mng_write_clon)
       
  9143 {
       
  9144   mng_clonp   pCLON;
       
  9145   mng_uint8p  pRawdata;
       
  9146   mng_uint32  iRawlen;
       
  9147   mng_retcode iRetcode;
       
  9148 
       
  9149 #ifdef MNG_SUPPORT_TRACE
       
  9150   MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_START);
       
  9151 #endif
       
  9152 
       
  9153   pCLON = (mng_clonp)pChunk;           /* address the proper chunk */
       
  9154 
       
  9155   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9156   iRawlen  = 4;
       
  9157                                        /* fill the output buffer */
       
  9158   mng_put_uint16 (pRawdata,   pCLON->iSourceid);
       
  9159   mng_put_uint16 (pRawdata+2, pCLON->iCloneid);
       
  9160 
       
  9161   if ((pCLON->iClonetype) || (pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
       
  9162   {
       
  9163     iRawlen++;
       
  9164     *(pRawdata+4) = pCLON->iClonetype;
       
  9165 
       
  9166     if ((pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
       
  9167     {
       
  9168       iRawlen++;
       
  9169       *(pRawdata+5) = pCLON->iDonotshow;
       
  9170 
       
  9171       if ((pCLON->iConcrete) || (pCLON->bHasloca))
       
  9172       {
       
  9173         iRawlen++;
       
  9174         *(pRawdata+6) = pCLON->iConcrete;
       
  9175 
       
  9176         if (pCLON->bHasloca)
       
  9177         {
       
  9178           iRawlen += 9;
       
  9179           *(pRawdata+7) = pCLON->iLocationtype;
       
  9180           mng_put_int32 (pRawdata+8,  pCLON->iLocationx);
       
  9181           mng_put_int32 (pRawdata+12, pCLON->iLocationy);
       
  9182         }
       
  9183       }
       
  9184     }
       
  9185   }
       
  9186                                        /* and write it */
       
  9187   iRetcode = write_raw_chunk (pData, pCLON->sHeader.iChunkname,
       
  9188                               iRawlen, pRawdata);
       
  9189 
       
  9190 #ifdef MNG_SUPPORT_TRACE
       
  9191   MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_END);
       
  9192 #endif
       
  9193 
       
  9194   return iRetcode;
       
  9195 }
       
  9196 
       
  9197 /* ************************************************************************** */
       
  9198 
       
  9199 #ifndef MNG_SKIPCHUNK_PAST
       
  9200 WRITE_CHUNK (mng_write_past)
       
  9201 {
       
  9202   mng_pastp        pPAST;
       
  9203   mng_uint8p       pRawdata;
       
  9204   mng_uint32       iRawlen;
       
  9205   mng_retcode      iRetcode;
       
  9206   mng_past_sourcep pSource;
       
  9207   mng_uint32       iX;
       
  9208   mng_uint8p       pTemp;
       
  9209 
       
  9210 #ifdef MNG_SUPPORT_TRACE
       
  9211   MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_START);
       
  9212 #endif
       
  9213 
       
  9214   pPAST = (mng_pastp)pChunk;           /* address the proper chunk */
       
  9215 
       
  9216   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9217   iRawlen  = 11 + (30 * pPAST->iCount);
       
  9218                                        /* requires large buffer ? */
       
  9219   if (iRawlen > pData->iWritebufsize)
       
  9220     MNG_ALLOC (pData, pRawdata, iRawlen);
       
  9221                                        /* fill the output buffer */
       
  9222   mng_put_uint16 (pRawdata,   pPAST->iDestid);
       
  9223 
       
  9224   *(pRawdata+2) = pPAST->iTargettype;
       
  9225 
       
  9226   mng_put_int32  (pRawdata+3, pPAST->iTargetx);
       
  9227   mng_put_int32  (pRawdata+7, pPAST->iTargety);
       
  9228 
       
  9229   pTemp   = pRawdata+11;
       
  9230   pSource = pPAST->pSources;
       
  9231 
       
  9232   for (iX = 0; iX < pPAST->iCount; iX++)
       
  9233   {
       
  9234     mng_put_uint16 (pTemp,    pSource->iSourceid);
       
  9235 
       
  9236     *(pTemp+2)  = pSource->iComposition;
       
  9237     *(pTemp+3)  = pSource->iOrientation;
       
  9238     *(pTemp+4)  = pSource->iOffsettype;
       
  9239 
       
  9240     mng_put_int32  (pTemp+5,  pSource->iOffsetx);
       
  9241     mng_put_int32  (pTemp+9,  pSource->iOffsety);
       
  9242 
       
  9243     *(pTemp+13) = pSource->iBoundarytype;
       
  9244 
       
  9245     mng_put_int32  (pTemp+14, pSource->iBoundaryl);
       
  9246     mng_put_int32  (pTemp+18, pSource->iBoundaryr);
       
  9247     mng_put_int32  (pTemp+22, pSource->iBoundaryt);
       
  9248     mng_put_int32  (pTemp+26, pSource->iBoundaryb);
       
  9249 
       
  9250     pSource++;
       
  9251     pTemp += 30;
       
  9252   }
       
  9253                                        /* and write it */
       
  9254   iRetcode = write_raw_chunk (pData, pPAST->sHeader.iChunkname,
       
  9255                               iRawlen, pRawdata);
       
  9256                                        /* free temporary buffer ? */
       
  9257   if (iRawlen > pData->iWritebufsize)
       
  9258     MNG_FREEX (pData, pRawdata, iRawlen);
       
  9259 
       
  9260 #ifdef MNG_SUPPORT_TRACE
       
  9261   MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_END);
       
  9262 #endif
       
  9263 
       
  9264   return iRetcode;
       
  9265 }
       
  9266 #endif
       
  9267 
       
  9268 /* ************************************************************************** */
       
  9269 
       
  9270 WRITE_CHUNK (mng_write_disc)
       
  9271 {
       
  9272   mng_discp        pDISC;
       
  9273   mng_uint8p       pRawdata;
       
  9274   mng_uint32       iRawlen;
       
  9275   mng_retcode      iRetcode;
       
  9276   mng_uint32       iX;
       
  9277   mng_uint8p       pTemp1;
       
  9278   mng_uint16p      pTemp2;
       
  9279 
       
  9280 #ifdef MNG_SUPPORT_TRACE
       
  9281   MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_START);
       
  9282 #endif
       
  9283 
       
  9284   pDISC    = (mng_discp)pChunk;        /* address the proper chunk */
       
  9285 
       
  9286   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9287   iRawlen  = pDISC->iCount << 1;
       
  9288 
       
  9289   pTemp1   = pRawdata;                 /* fill the output buffer */
       
  9290   pTemp2   = pDISC->pObjectids;
       
  9291 
       
  9292   for (iX = 0; iX < pDISC->iCount; iX++)
       
  9293   {
       
  9294     mng_put_uint16 (pTemp1, *pTemp2);
       
  9295 
       
  9296     pTemp2++;
       
  9297     pTemp1 += 2;
       
  9298   }
       
  9299                                        /* and write it */
       
  9300   iRetcode = write_raw_chunk (pData, pDISC->sHeader.iChunkname,
       
  9301                               iRawlen, pRawdata);
       
  9302 
       
  9303 #ifdef MNG_SUPPORT_TRACE
       
  9304   MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_END);
       
  9305 #endif
       
  9306 
       
  9307   return iRetcode;
       
  9308 }
       
  9309 
       
  9310 /* ************************************************************************** */
       
  9311 
       
  9312 WRITE_CHUNK (mng_write_back)
       
  9313 {
       
  9314   mng_backp   pBACK;
       
  9315   mng_uint8p  pRawdata;
       
  9316   mng_uint32  iRawlen;
       
  9317   mng_retcode iRetcode;
       
  9318 
       
  9319 #ifdef MNG_SUPPORT_TRACE
       
  9320   MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_START);
       
  9321 #endif
       
  9322 
       
  9323   pBACK = (mng_backp)pChunk;           /* address the proper chunk */
       
  9324 
       
  9325   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9326   iRawlen  = 6;
       
  9327                                        /* fill the output buffer */
       
  9328   mng_put_uint16 (pRawdata,   pBACK->iRed);
       
  9329   mng_put_uint16 (pRawdata+2, pBACK->iGreen);
       
  9330   mng_put_uint16 (pRawdata+4, pBACK->iBlue);
       
  9331 
       
  9332   if ((pBACK->iMandatory) || (pBACK->iImageid) || (pBACK->iTile))
       
  9333   {
       
  9334     iRawlen++;
       
  9335     *(pRawdata+6) = pBACK->iMandatory;
       
  9336 
       
  9337     if ((pBACK->iImageid) || (pBACK->iTile))
       
  9338     {
       
  9339       iRawlen += 2;
       
  9340       mng_put_uint16 (pRawdata+7, pBACK->iImageid);
       
  9341 
       
  9342       if (pBACK->iTile)
       
  9343       {
       
  9344         iRawlen++;
       
  9345         *(pRawdata+9) = pBACK->iTile;
       
  9346       }
       
  9347     }
       
  9348   }
       
  9349                                        /* and write it */
       
  9350   iRetcode = write_raw_chunk (pData, pBACK->sHeader.iChunkname,
       
  9351                               iRawlen, pRawdata);
       
  9352 
       
  9353 #ifdef MNG_SUPPORT_TRACE
       
  9354   MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_END);
       
  9355 #endif
       
  9356 
       
  9357   return iRetcode;
       
  9358 }
       
  9359 
       
  9360 /* ************************************************************************** */
       
  9361 
       
  9362 WRITE_CHUNK (mng_write_fram)
       
  9363 {
       
  9364   mng_framp   pFRAM;
       
  9365   mng_uint8p  pRawdata;
       
  9366   mng_uint32  iRawlen;
       
  9367   mng_retcode iRetcode;
       
  9368   mng_uint8p  pTemp;
       
  9369   mng_uint32p pTemp2;
       
  9370   mng_uint32  iX;
       
  9371 
       
  9372 #ifdef MNG_SUPPORT_TRACE
       
  9373   MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_START);
       
  9374 #endif
       
  9375 
       
  9376   pFRAM = (mng_framp)pChunk;           /* address the proper chunk */
       
  9377 
       
  9378   if (pFRAM->bEmpty)                   /* empty ? */
       
  9379     iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname, 0, 0);
       
  9380   else
       
  9381   {
       
  9382     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  9383     iRawlen  = 1;
       
  9384                                        /* fill the output buffer */
       
  9385     *pRawdata = pFRAM->iMode;
       
  9386 
       
  9387     if ((pFRAM->iNamesize      ) ||
       
  9388         (pFRAM->iChangedelay   ) || (pFRAM->iChangetimeout) ||
       
  9389         (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid )    )
       
  9390     {
       
  9391       if (pFRAM->iNamesize)
       
  9392         MNG_COPY (pRawdata+1, pFRAM->zName, pFRAM->iNamesize);
       
  9393 
       
  9394       iRawlen += pFRAM->iNamesize;
       
  9395       pTemp = pRawdata + pFRAM->iNamesize + 1;
       
  9396 
       
  9397       if ((pFRAM->iChangedelay   ) || (pFRAM->iChangetimeout) ||
       
  9398           (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid )    )
       
  9399       {
       
  9400         *pTemp     = 0;
       
  9401         *(pTemp+1) = pFRAM->iChangedelay;
       
  9402         *(pTemp+2) = pFRAM->iChangetimeout;
       
  9403         *(pTemp+3) = pFRAM->iChangeclipping;
       
  9404         *(pTemp+4) = pFRAM->iChangesyncid;
       
  9405 
       
  9406         iRawlen += 5;
       
  9407         pTemp   += 5;
       
  9408 
       
  9409         if (pFRAM->iChangedelay)
       
  9410         {
       
  9411           mng_put_uint32 (pTemp, pFRAM->iDelay);
       
  9412           iRawlen += 4;
       
  9413           pTemp   += 4;
       
  9414         }
       
  9415 
       
  9416         if (pFRAM->iChangetimeout)
       
  9417         {
       
  9418           mng_put_uint32 (pTemp, pFRAM->iTimeout);
       
  9419           iRawlen += 4;
       
  9420           pTemp   += 4;
       
  9421         }
       
  9422 
       
  9423         if (pFRAM->iChangeclipping)
       
  9424         {
       
  9425           *pTemp = pFRAM->iBoundarytype;
       
  9426 
       
  9427           mng_put_uint32 (pTemp+1,  pFRAM->iBoundaryl);
       
  9428           mng_put_uint32 (pTemp+5,  pFRAM->iBoundaryr);
       
  9429           mng_put_uint32 (pTemp+9,  pFRAM->iBoundaryt);
       
  9430           mng_put_uint32 (pTemp+13, pFRAM->iBoundaryb);
       
  9431 
       
  9432           iRawlen += 17;
       
  9433           pTemp   += 17;
       
  9434         }
       
  9435 
       
  9436         if (pFRAM->iChangesyncid)
       
  9437         {
       
  9438           iRawlen += pFRAM->iCount * 4;
       
  9439           pTemp2 = pFRAM->pSyncids;
       
  9440 
       
  9441           for (iX = 0; iX < pFRAM->iCount; iX++)
       
  9442           {
       
  9443             mng_put_uint32 (pTemp, *pTemp2);
       
  9444 
       
  9445             pTemp2++;
       
  9446             pTemp += 4;
       
  9447           }  
       
  9448         }
       
  9449       }
       
  9450     }
       
  9451                                        /* and write it */
       
  9452     iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname,
       
  9453                                 iRawlen, pRawdata);
       
  9454   }
       
  9455 
       
  9456 #ifdef MNG_SUPPORT_TRACE
       
  9457   MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_END);
       
  9458 #endif
       
  9459 
       
  9460   return iRetcode;
       
  9461 }
       
  9462 
       
  9463 /* ************************************************************************** */
       
  9464 
       
  9465 WRITE_CHUNK (mng_write_move)
       
  9466 {
       
  9467   mng_movep   pMOVE;
       
  9468   mng_uint8p  pRawdata;
       
  9469   mng_uint32  iRawlen;
       
  9470   mng_retcode iRetcode;
       
  9471 
       
  9472 #ifdef MNG_SUPPORT_TRACE
       
  9473   MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_START);
       
  9474 #endif
       
  9475 
       
  9476   pMOVE = (mng_movep)pChunk;           /* address the proper chunk */
       
  9477 
       
  9478   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9479   iRawlen  = 13;
       
  9480                                        /* fill the output buffer */
       
  9481   mng_put_uint16 (pRawdata,   pMOVE->iFirstid);
       
  9482   mng_put_uint16 (pRawdata+2, pMOVE->iLastid);
       
  9483 
       
  9484   *(pRawdata+4) = pMOVE->iMovetype;
       
  9485 
       
  9486   mng_put_int32  (pRawdata+5, pMOVE->iMovex);
       
  9487   mng_put_int32  (pRawdata+9, pMOVE->iMovey);
       
  9488                                        /* and write it */
       
  9489   iRetcode = write_raw_chunk (pData, pMOVE->sHeader.iChunkname,
       
  9490                               iRawlen, pRawdata);
       
  9491 
       
  9492 #ifdef MNG_SUPPORT_TRACE
       
  9493   MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_END);
       
  9494 #endif
       
  9495 
       
  9496   return iRetcode;
       
  9497 }
       
  9498 
       
  9499 /* ************************************************************************** */
       
  9500 
       
  9501 WRITE_CHUNK (mng_write_clip)
       
  9502 {
       
  9503   mng_clipp   pCLIP;
       
  9504   mng_uint8p  pRawdata;
       
  9505   mng_uint32  iRawlen;
       
  9506   mng_retcode iRetcode;
       
  9507 
       
  9508 #ifdef MNG_SUPPORT_TRACE
       
  9509   MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_START);
       
  9510 #endif
       
  9511 
       
  9512   pCLIP = (mng_clipp)pChunk;           /* address the proper chunk */
       
  9513 
       
  9514   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9515   iRawlen  = 21;
       
  9516                                        /* fill the output buffer */
       
  9517   mng_put_uint16 (pRawdata,    pCLIP->iFirstid);
       
  9518   mng_put_uint16 (pRawdata+2,  pCLIP->iLastid);
       
  9519 
       
  9520   *(pRawdata+4) = pCLIP->iCliptype;
       
  9521 
       
  9522   mng_put_int32  (pRawdata+5,  pCLIP->iClipl);
       
  9523   mng_put_int32  (pRawdata+9,  pCLIP->iClipr);
       
  9524   mng_put_int32  (pRawdata+13, pCLIP->iClipt);
       
  9525   mng_put_int32  (pRawdata+17, pCLIP->iClipb);
       
  9526                                        /* and write it */
       
  9527   iRetcode = write_raw_chunk (pData, pCLIP->sHeader.iChunkname,
       
  9528                               iRawlen, pRawdata);
       
  9529 
       
  9530 #ifdef MNG_SUPPORT_TRACE
       
  9531   MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_END);
       
  9532 #endif
       
  9533 
       
  9534   return iRetcode;
       
  9535 }
       
  9536 
       
  9537 /* ************************************************************************** */
       
  9538 
       
  9539 WRITE_CHUNK (mng_write_show)
       
  9540 {
       
  9541   mng_showp   pSHOW;
       
  9542   mng_uint8p  pRawdata;
       
  9543   mng_uint32  iRawlen;
       
  9544   mng_retcode iRetcode;
       
  9545 
       
  9546 #ifdef MNG_SUPPORT_TRACE
       
  9547   MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_START);
       
  9548 #endif
       
  9549 
       
  9550   pSHOW = (mng_showp)pChunk;           /* address the proper chunk */
       
  9551 
       
  9552   if (pSHOW->bEmpty)                   /* empty ? */
       
  9553     iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname, 0, 0);
       
  9554   else
       
  9555   {
       
  9556     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  9557     iRawlen  = 2;
       
  9558                                        /* fill the output buffer */
       
  9559     mng_put_uint16 (pRawdata, pSHOW->iFirstid);
       
  9560 
       
  9561     if ((pSHOW->iLastid != pSHOW->iFirstid) || (pSHOW->iMode))
       
  9562     {
       
  9563       iRawlen += 2;
       
  9564       mng_put_uint16 (pRawdata+2, pSHOW->iLastid);
       
  9565 
       
  9566       if (pSHOW->iMode)
       
  9567       {
       
  9568         iRawlen++;
       
  9569         *(pRawdata+4) = pSHOW->iMode;
       
  9570       }
       
  9571     }
       
  9572                                        /* and write it */
       
  9573     iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname,
       
  9574                                 iRawlen, pRawdata);
       
  9575   }
       
  9576 
       
  9577 #ifdef MNG_SUPPORT_TRACE
       
  9578   MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_END);
       
  9579 #endif
       
  9580 
       
  9581   return iRetcode;
       
  9582 }
       
  9583 
       
  9584 /* ************************************************************************** */
       
  9585 
       
  9586 WRITE_CHUNK (mng_write_term)
       
  9587 {
       
  9588   mng_termp   pTERM;
       
  9589   mng_uint8p  pRawdata;
       
  9590   mng_uint32  iRawlen;
       
  9591   mng_retcode iRetcode;
       
  9592 
       
  9593 #ifdef MNG_SUPPORT_TRACE
       
  9594   MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_START);
       
  9595 #endif
       
  9596 
       
  9597   pTERM     = (mng_termp)pChunk;       /* address the proper chunk */
       
  9598 
       
  9599   pRawdata  = pData->pWritebuf+8;      /* init output buffer & size */
       
  9600   iRawlen   = 1;
       
  9601 
       
  9602   *pRawdata = pTERM->iTermaction;      /* fill the output buffer */
       
  9603 
       
  9604   if (pTERM->iTermaction == 3)
       
  9605   {
       
  9606     iRawlen       = 10;
       
  9607     *(pRawdata+1) = pTERM->iIteraction;
       
  9608 
       
  9609     mng_put_uint32 (pRawdata+2, pTERM->iDelay);
       
  9610     mng_put_uint32 (pRawdata+6, pTERM->iItermax);
       
  9611   }
       
  9612                                        /* and write it */
       
  9613   iRetcode = write_raw_chunk (pData, pTERM->sHeader.iChunkname,
       
  9614                               iRawlen, pRawdata);
       
  9615 
       
  9616 #ifdef MNG_SUPPORT_TRACE
       
  9617   MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_END);
       
  9618 #endif
       
  9619 
       
  9620   return iRetcode;
       
  9621 }
       
  9622 
       
  9623 /* ************************************************************************** */
       
  9624 
       
  9625 #ifndef MNG_SKIPCHUNK_SAVE
       
  9626 WRITE_CHUNK (mng_write_save)
       
  9627 {
       
  9628   mng_savep       pSAVE;
       
  9629   mng_uint8p      pRawdata;
       
  9630   mng_uint32      iRawlen;
       
  9631   mng_retcode     iRetcode;
       
  9632   mng_save_entryp pEntry;
       
  9633   mng_uint32      iEntrysize;
       
  9634   mng_uint8p      pTemp;
       
  9635   mng_uint32      iX;
       
  9636 
       
  9637 #ifdef MNG_SUPPORT_TRACE
       
  9638   MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_START);
       
  9639 #endif
       
  9640 
       
  9641   pSAVE = (mng_savep)pChunk;           /* address the proper chunk */
       
  9642 
       
  9643   if (pSAVE->bEmpty)                   /* empty ? */
       
  9644     iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname, 0, 0);
       
  9645   else
       
  9646   {
       
  9647     pRawdata  = pData->pWritebuf+8;    /* init output buffer & size */
       
  9648     iRawlen   = 1;
       
  9649 
       
  9650     *pRawdata = pSAVE->iOffsettype;    /* fill the output buffer */
       
  9651 
       
  9652     if (pSAVE->iOffsettype == 16)
       
  9653       iEntrysize = 25;
       
  9654     else
       
  9655       iEntrysize = 17;
       
  9656 
       
  9657     pTemp  = pRawdata+1;
       
  9658     pEntry = pSAVE->pEntries;
       
  9659 
       
  9660     for (iX = 0; iX < pSAVE->iCount; iX++)
       
  9661     {
       
  9662       if (iX)                          /* put separator null-byte, except the first */
       
  9663       {
       
  9664         *pTemp = 0;
       
  9665         pTemp++;
       
  9666         iRawlen++;
       
  9667       }
       
  9668 
       
  9669       iRawlen += iEntrysize + pEntry->iNamesize;
       
  9670       *pTemp = pEntry->iEntrytype;
       
  9671 
       
  9672       if (pSAVE->iOffsettype == 16)
       
  9673       {
       
  9674         mng_put_uint32 (pTemp+1,  pEntry->iOffset[0]);
       
  9675         mng_put_uint32 (pTemp+5,  pEntry->iOffset[1]);
       
  9676         mng_put_uint32 (pTemp+9,  pEntry->iStarttime[0]);
       
  9677         mng_put_uint32 (pTemp+13, pEntry->iStarttime[1]);
       
  9678         mng_put_uint32 (pTemp+17, pEntry->iLayernr);
       
  9679         mng_put_uint32 (pTemp+21, pEntry->iFramenr);
       
  9680 
       
  9681         pTemp += 25;
       
  9682       }
       
  9683       else
       
  9684       {
       
  9685         mng_put_uint32 (pTemp+1,  pEntry->iOffset[1]);
       
  9686         mng_put_uint32 (pTemp+5,  pEntry->iStarttime[1]);
       
  9687         mng_put_uint32 (pTemp+9,  pEntry->iLayernr);
       
  9688         mng_put_uint32 (pTemp+13, pEntry->iFramenr);
       
  9689 
       
  9690         pTemp += 17;
       
  9691       }
       
  9692 
       
  9693       if (pEntry->iNamesize)
       
  9694       {
       
  9695         MNG_COPY (pTemp, pEntry->zName, pEntry->iNamesize);
       
  9696         pTemp += pEntry->iNamesize;
       
  9697       }
       
  9698 
       
  9699       pEntry++;  
       
  9700     }
       
  9701                                        /* and write it */
       
  9702     iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname,
       
  9703                                 iRawlen, pRawdata);
       
  9704   }
       
  9705 
       
  9706 #ifdef MNG_SUPPORT_TRACE
       
  9707   MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_END);
       
  9708 #endif
       
  9709 
       
  9710   return iRetcode;
       
  9711 }
       
  9712 #endif
       
  9713 
       
  9714 /* ************************************************************************** */
       
  9715 
       
  9716 #ifndef MNG_SKIPCHUNK_SEEK
       
  9717 WRITE_CHUNK (mng_write_seek)
       
  9718 {
       
  9719   mng_seekp   pSEEK;
       
  9720   mng_uint8p  pRawdata;
       
  9721   mng_uint32  iRawlen;
       
  9722   mng_retcode iRetcode;
       
  9723 
       
  9724 #ifdef MNG_SUPPORT_TRACE
       
  9725   MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_START);
       
  9726 #endif
       
  9727 
       
  9728   pSEEK    = (mng_seekp)pChunk;        /* address the proper chunk */
       
  9729 
       
  9730   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9731   iRawlen  = pSEEK->iNamesize;
       
  9732 
       
  9733   if (iRawlen)                         /* fill the output buffer */
       
  9734     MNG_COPY (pRawdata, pSEEK->zName, iRawlen);
       
  9735                                        /* and write it */
       
  9736   iRetcode = write_raw_chunk (pData, pSEEK->sHeader.iChunkname,
       
  9737                               iRawlen, pRawdata);
       
  9738 
       
  9739 #ifdef MNG_SUPPORT_TRACE
       
  9740   MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_END);
       
  9741 #endif
       
  9742 
       
  9743   return iRetcode;
       
  9744 }
       
  9745 #endif
       
  9746 
       
  9747 /* ************************************************************************** */
       
  9748 
       
  9749 #ifndef MNG_SKIPCHUNK_eXPI
       
  9750 WRITE_CHUNK (mng_write_expi)
       
  9751 {
       
  9752   mng_expip   pEXPI;
       
  9753   mng_uint8p  pRawdata;
       
  9754   mng_uint32  iRawlen;
       
  9755   mng_retcode iRetcode;
       
  9756 
       
  9757 #ifdef MNG_SUPPORT_TRACE
       
  9758   MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_START);
       
  9759 #endif
       
  9760 
       
  9761   pEXPI    = (mng_expip)pChunk;        /* address the proper chunk */
       
  9762 
       
  9763   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9764   iRawlen  = 2 + pEXPI->iNamesize;
       
  9765                                        /* fill the output buffer */
       
  9766   mng_put_uint16 (pRawdata, pEXPI->iSnapshotid);
       
  9767 
       
  9768   if (pEXPI->iNamesize)
       
  9769     MNG_COPY (pRawdata+2, pEXPI->zName, pEXPI->iNamesize);
       
  9770                                        /* and write it */
       
  9771   iRetcode = write_raw_chunk (pData, pEXPI->sHeader.iChunkname,
       
  9772                               iRawlen, pRawdata);
       
  9773 
       
  9774 #ifdef MNG_SUPPORT_TRACE
       
  9775   MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_END);
       
  9776 #endif
       
  9777 
       
  9778   return iRetcode;
       
  9779 }
       
  9780 #endif
       
  9781 
       
  9782 /* ************************************************************************** */
       
  9783 
       
  9784 #ifndef MNG_SKIPCHUNK_fPRI
       
  9785 WRITE_CHUNK (mng_write_fpri)
       
  9786 {
       
  9787   mng_fprip   pFPRI;
       
  9788   mng_uint8p  pRawdata;
       
  9789   mng_uint32  iRawlen;
       
  9790   mng_retcode iRetcode;
       
  9791 
       
  9792 #ifdef MNG_SUPPORT_TRACE
       
  9793   MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_START);
       
  9794 #endif
       
  9795 
       
  9796   pFPRI         = (mng_fprip)pChunk;   /* address the proper chunk */
       
  9797 
       
  9798   pRawdata      = pData->pWritebuf+8;  /* init output buffer & size */
       
  9799   iRawlen       = 2;
       
  9800 
       
  9801   *pRawdata     = pFPRI->iDeltatype;   /* fill the output buffer */
       
  9802   *(pRawdata+1) = pFPRI->iPriority;
       
  9803                                        /* and write it */
       
  9804   iRetcode = write_raw_chunk (pData, pFPRI->sHeader.iChunkname,
       
  9805                               iRawlen, pRawdata);
       
  9806 
       
  9807 #ifdef MNG_SUPPORT_TRACE
       
  9808   MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_END);
       
  9809 #endif
       
  9810 
       
  9811   return iRetcode;
       
  9812 }
       
  9813 #endif
       
  9814 
       
  9815 /* ************************************************************************** */
       
  9816 
       
  9817 #ifndef MNG_SKIPCHUNK_nEED
       
  9818 WRITE_CHUNK (mng_write_need)
       
  9819 {
       
  9820   mng_needp   pNEED;
       
  9821   mng_uint8p  pRawdata;
       
  9822   mng_uint32  iRawlen;
       
  9823   mng_retcode iRetcode;
       
  9824 
       
  9825 #ifdef MNG_SUPPORT_TRACE
       
  9826   MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_START);
       
  9827 #endif
       
  9828 
       
  9829   pNEED    = (mng_needp)pChunk;        /* address the proper chunk */
       
  9830 
       
  9831   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9832   iRawlen  = pNEED->iKeywordssize;
       
  9833                                        /* fill the output buffer */
       
  9834   if (pNEED->iKeywordssize)
       
  9835     MNG_COPY (pRawdata, pNEED->zKeywords, pNEED->iKeywordssize);
       
  9836                                        /* and write it */
       
  9837   iRetcode = write_raw_chunk (pData, pNEED->sHeader.iChunkname,
       
  9838                               iRawlen, pRawdata);
       
  9839 
       
  9840 #ifdef MNG_SUPPORT_TRACE
       
  9841   MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_END);
       
  9842 #endif
       
  9843 
       
  9844   return iRetcode;
       
  9845 }
       
  9846 #endif
       
  9847 
       
  9848 /* ************************************************************************** */
       
  9849 
       
  9850 #ifndef MNG_SKIPCHUNK_pHYg
       
  9851 WRITE_CHUNK (mng_write_phyg)
       
  9852 {
       
  9853   mng_phygp   pPHYG;
       
  9854   mng_uint8p  pRawdata;
       
  9855   mng_uint32  iRawlen;
       
  9856   mng_retcode iRetcode;
       
  9857 
       
  9858 #ifdef MNG_SUPPORT_TRACE
       
  9859   MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_START);
       
  9860 #endif
       
  9861 
       
  9862   pPHYG = (mng_phygp)pChunk;           /* address the proper chunk */
       
  9863 
       
  9864   if (pPHYG->bEmpty)                   /* write empty ? */
       
  9865     iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname, 0, 0);
       
  9866   else
       
  9867   {
       
  9868     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
  9869     iRawlen  = 9;
       
  9870                                        /* fill the output buffer */
       
  9871     mng_put_uint32 (pRawdata,   pPHYG->iSizex);
       
  9872     mng_put_uint32 (pRawdata+4, pPHYG->iSizey);
       
  9873 
       
  9874     *(pRawdata+8) = pPHYG->iUnit;
       
  9875                                        /* and write it */
       
  9876     iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname,
       
  9877                                 iRawlen, pRawdata);
       
  9878   }
       
  9879 
       
  9880 #ifdef MNG_SUPPORT_TRACE
       
  9881   MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_END);
       
  9882 #endif
       
  9883 
       
  9884   return iRetcode;
       
  9885 }
       
  9886 #endif
       
  9887 
       
  9888 /* ************************************************************************** */
       
  9889 
       
  9890 /* B004 */
       
  9891 #ifdef MNG_INCLUDE_JNG
       
  9892 /* B004 */
       
  9893 WRITE_CHUNK (mng_write_jhdr)
       
  9894 {
       
  9895   mng_jhdrp   pJHDR;
       
  9896   mng_uint8p  pRawdata;
       
  9897   mng_uint32  iRawlen;
       
  9898   mng_retcode iRetcode;
       
  9899 
       
  9900 #ifdef MNG_SUPPORT_TRACE
       
  9901   MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_START);
       
  9902 #endif
       
  9903 
       
  9904   pJHDR    = (mng_jhdrp)pChunk;        /* address the proper chunk */
       
  9905   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
  9906   iRawlen  = 16;
       
  9907                                        /* fill the output buffer */
       
  9908   mng_put_uint32 (pRawdata,   pJHDR->iWidth);
       
  9909   mng_put_uint32 (pRawdata+4, pJHDR->iHeight);
       
  9910 
       
  9911   *(pRawdata+8)  = pJHDR->iColortype;
       
  9912   *(pRawdata+9)  = pJHDR->iImagesampledepth;
       
  9913   *(pRawdata+10) = pJHDR->iImagecompression;
       
  9914   *(pRawdata+11) = pJHDR->iImageinterlace;
       
  9915   *(pRawdata+12) = pJHDR->iAlphasampledepth;
       
  9916   *(pRawdata+13) = pJHDR->iAlphacompression;
       
  9917   *(pRawdata+14) = pJHDR->iAlphafilter;
       
  9918   *(pRawdata+15) = pJHDR->iAlphainterlace;
       
  9919                                        /* and write it */
       
  9920   iRetcode = write_raw_chunk (pData, pJHDR->sHeader.iChunkname, iRawlen, pRawdata);
       
  9921 
       
  9922 #ifdef MNG_SUPPORT_TRACE
       
  9923   MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_END);
       
  9924 #endif
       
  9925 
       
  9926   return iRetcode;
       
  9927 }
       
  9928 #else
       
  9929 #define write_jhdr 0
       
  9930 /* B004 */
       
  9931 #endif /* MNG_INCLUDE_JNG */
       
  9932 /* B004 */
       
  9933 
       
  9934 /* ************************************************************************** */
       
  9935 
       
  9936 #ifdef MNG_INCLUDE_JNG
       
  9937 WRITE_CHUNK (mng_write_jdaa)
       
  9938 {
       
  9939   mng_jdatp   pJDAA;
       
  9940   mng_retcode iRetcode;
       
  9941 
       
  9942 #ifdef MNG_SUPPORT_TRACE
       
  9943   MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_START);
       
  9944 #endif
       
  9945 
       
  9946   pJDAA = (mng_jdaap)pChunk;           /* address the proper chunk */
       
  9947 
       
  9948   if (pJDAA->bEmpty)                   /* and write it */
       
  9949     iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname, 0, 0);
       
  9950   else
       
  9951     iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname,
       
  9952                                 pJDAA->iDatasize, pJDAA->pData);
       
  9953 
       
  9954 #ifdef MNG_SUPPORT_TRACE
       
  9955   MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_END);
       
  9956 #endif
       
  9957 
       
  9958   return iRetcode;
       
  9959 }
       
  9960 #else
       
  9961 #define write_jdaa 0
       
  9962 #endif /* MNG_INCLUDE_JNG */
       
  9963 
       
  9964 /* ************************************************************************** */
       
  9965 
       
  9966 /* B004 */
       
  9967 #ifdef MNG_INCLUDE_JNG
       
  9968 /* B004 */
       
  9969 WRITE_CHUNK (mng_write_jdat)
       
  9970 {
       
  9971   mng_jdatp   pJDAT;
       
  9972   mng_retcode iRetcode;
       
  9973 
       
  9974 #ifdef MNG_SUPPORT_TRACE
       
  9975   MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_START);
       
  9976 #endif
       
  9977 
       
  9978   pJDAT = (mng_jdatp)pChunk;           /* address the proper chunk */
       
  9979 
       
  9980   if (pJDAT->bEmpty)                   /* and write it */
       
  9981     iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname, 0, 0);
       
  9982   else
       
  9983     iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname,
       
  9984                                 pJDAT->iDatasize, pJDAT->pData);
       
  9985 
       
  9986 #ifdef MNG_SUPPORT_TRACE
       
  9987   MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_END);
       
  9988 #endif
       
  9989 
       
  9990   return iRetcode;
       
  9991 }
       
  9992 #else
       
  9993 #define write_jdat 0
       
  9994 /* B004 */
       
  9995 #endif /* MNG_INCLUDE_JNG */
       
  9996 /* B004 */
       
  9997 
       
  9998 /* ************************************************************************** */
       
  9999 
       
 10000 /* B004 */
       
 10001 #ifdef MNG_INCLUDE_JNG
       
 10002 /* B004 */
       
 10003 WRITE_CHUNK (mng_write_jsep)
       
 10004 {
       
 10005   mng_jsepp   pJSEP;
       
 10006   mng_retcode iRetcode;
       
 10007 
       
 10008 #ifdef MNG_SUPPORT_TRACE
       
 10009   MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_START);
       
 10010 #endif
       
 10011 
       
 10012   pJSEP = (mng_jsepp)pChunk;           /* address the proper chunk */
       
 10013                                        /* and write it */
       
 10014   iRetcode = write_raw_chunk (pData, pJSEP->sHeader.iChunkname, 0, 0);
       
 10015 
       
 10016 #ifdef MNG_SUPPORT_TRACE
       
 10017   MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_END);
       
 10018 #endif
       
 10019 
       
 10020   return iRetcode;
       
 10021 }
       
 10022 #else
       
 10023 #define write_jsep 0
       
 10024 /* B004 */
       
 10025 #endif /* MNG_INCLUDE_JNG */
       
 10026 /* B004 */
       
 10027 
       
 10028 /* ************************************************************************** */
       
 10029 
       
 10030 #ifndef MNG_NO_DELTA_PNG
       
 10031 WRITE_CHUNK (mng_write_dhdr)
       
 10032 {
       
 10033   mng_dhdrp   pDHDR;
       
 10034   mng_uint8p  pRawdata;
       
 10035   mng_uint32  iRawlen;
       
 10036   mng_retcode iRetcode;
       
 10037 
       
 10038 #ifdef MNG_SUPPORT_TRACE
       
 10039   MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_START);
       
 10040 #endif
       
 10041 
       
 10042   pDHDR    = (mng_dhdrp)pChunk;        /* address the proper chunk */
       
 10043 
       
 10044   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10045   iRawlen  = 4;
       
 10046                                        /* fill the output buffer */
       
 10047   mng_put_uint16 (pRawdata, pDHDR->iObjectid);
       
 10048 
       
 10049   *(pRawdata+2) = pDHDR->iImagetype;
       
 10050   *(pRawdata+3) = pDHDR->iDeltatype;
       
 10051 
       
 10052   if (pDHDR->iDeltatype != 7)
       
 10053   {
       
 10054     iRawlen += 8;
       
 10055     mng_put_uint32 (pRawdata+4, pDHDR->iBlockwidth);
       
 10056     mng_put_uint32 (pRawdata+8, pDHDR->iBlockheight);
       
 10057 
       
 10058     if (pDHDR->iDeltatype != 0)
       
 10059     {
       
 10060       iRawlen += 8;
       
 10061       mng_put_uint32 (pRawdata+12, pDHDR->iBlockx);
       
 10062       mng_put_uint32 (pRawdata+16, pDHDR->iBlocky);
       
 10063     }
       
 10064   }
       
 10065                                        /* and write it */
       
 10066   iRetcode = write_raw_chunk (pData, pDHDR->sHeader.iChunkname,
       
 10067                               iRawlen, pRawdata);
       
 10068 
       
 10069 #ifdef MNG_SUPPORT_TRACE
       
 10070   MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_END);
       
 10071 #endif
       
 10072 
       
 10073   return iRetcode;
       
 10074 }
       
 10075 #endif
       
 10076 
       
 10077 /* ************************************************************************** */
       
 10078 
       
 10079 #ifndef MNG_NO_DELTA_PNG
       
 10080 WRITE_CHUNK (mng_write_prom)
       
 10081 {
       
 10082   mng_promp   pPROM;
       
 10083   mng_uint8p  pRawdata;
       
 10084   mng_uint32  iRawlen;
       
 10085   mng_retcode iRetcode;
       
 10086 
       
 10087 #ifdef MNG_SUPPORT_TRACE
       
 10088   MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_START);
       
 10089 #endif
       
 10090 
       
 10091   pPROM    = (mng_promp)pChunk;        /* address the proper chunk */
       
 10092 
       
 10093   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10094   iRawlen  = 3;
       
 10095 
       
 10096   *pRawdata     = pPROM->iColortype;   /* fill the output buffer */
       
 10097   *(pRawdata+1) = pPROM->iSampledepth;
       
 10098   *(pRawdata+2) = pPROM->iFilltype;
       
 10099                                        /* and write it */
       
 10100   iRetcode = write_raw_chunk (pData, pPROM->sHeader.iChunkname,
       
 10101                               iRawlen, pRawdata);
       
 10102 
       
 10103 #ifdef MNG_SUPPORT_TRACE
       
 10104   MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_END);
       
 10105 #endif
       
 10106 
       
 10107   return iRetcode;
       
 10108 }
       
 10109 #endif
       
 10110 
       
 10111 /* ************************************************************************** */
       
 10112 
       
 10113 #ifndef MNG_NO_DELTA_PNG
       
 10114 WRITE_CHUNK (mng_write_ipng)
       
 10115 {
       
 10116   mng_ipngp   pIPNG;
       
 10117   mng_retcode iRetcode;
       
 10118 
       
 10119 #ifdef MNG_SUPPORT_TRACE
       
 10120   MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_START);
       
 10121 #endif
       
 10122 
       
 10123   pIPNG = (mng_ipngp)pChunk;           /* address the proper chunk */
       
 10124                                        /* and write it */
       
 10125   iRetcode = write_raw_chunk (pData, pIPNG->sHeader.iChunkname, 0, 0);
       
 10126 
       
 10127 #ifdef MNG_SUPPORT_TRACE
       
 10128   MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_END);
       
 10129 #endif
       
 10130 
       
 10131   return iRetcode;
       
 10132 }
       
 10133 #endif
       
 10134 
       
 10135 /* ************************************************************************** */
       
 10136 
       
 10137 #ifndef MNG_NO_DELTA_PNG
       
 10138 WRITE_CHUNK (mng_write_pplt)
       
 10139 {
       
 10140   mng_ppltp       pPPLT;
       
 10141   mng_uint8p      pRawdata;
       
 10142   mng_uint32      iRawlen;
       
 10143   mng_retcode     iRetcode;
       
 10144   mng_pplt_entryp pEntry;
       
 10145   mng_uint8p      pTemp;
       
 10146   mng_uint32      iX;
       
 10147   mng_bool        bHasgroup;
       
 10148   mng_uint8p      pLastid = 0;
       
 10149 
       
 10150 #ifdef MNG_SUPPORT_TRACE
       
 10151   MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_START);
       
 10152 #endif
       
 10153 
       
 10154   pPPLT = (mng_ppltp)pChunk;           /* address the proper chunk */
       
 10155 
       
 10156   pRawdata  = pData->pWritebuf+8;      /* init output buffer & size */
       
 10157   iRawlen   = 1;
       
 10158 
       
 10159   *pRawdata = pPPLT->iDeltatype;       /* fill the output buffer */
       
 10160 
       
 10161   pTemp     = pRawdata+1;
       
 10162   bHasgroup = MNG_FALSE;
       
 10163 
       
 10164   for (iX = 0; iX < pPPLT->iCount; iX++)
       
 10165   {
       
 10166     pEntry = &pPPLT->aEntries[iX];
       
 10167     
       
 10168     if (pEntry->bUsed)                 /* valid entry ? */
       
 10169     {
       
 10170       if (!bHasgroup)                  /* start a new group ? */
       
 10171       {
       
 10172         bHasgroup  = MNG_TRUE;
       
 10173         pLastid    = pTemp+1;
       
 10174 
       
 10175         *pTemp     = (mng_uint8)iX;
       
 10176         *(pTemp+1) = 0;
       
 10177 
       
 10178         pTemp += 2;
       
 10179         iRawlen += 2;
       
 10180       }
       
 10181 
       
 10182       switch (pPPLT->iDeltatype)       /* add group-entry depending on type */
       
 10183       {
       
 10184         case 0: ;
       
 10185         case 1: {
       
 10186                   *pTemp     = pEntry->iRed;
       
 10187                   *(pTemp+1) = pEntry->iGreen;
       
 10188                   *(pTemp+2) = pEntry->iBlue;
       
 10189 
       
 10190                   pTemp += 3;
       
 10191                   iRawlen += 3;
       
 10192 
       
 10193                   break;
       
 10194                 }
       
 10195 
       
 10196         case 2: ;
       
 10197         case 3: {
       
 10198                   *pTemp     = pEntry->iAlpha;
       
 10199 
       
 10200                   pTemp++;
       
 10201                   iRawlen++;
       
 10202 
       
 10203                   break;
       
 10204                 }
       
 10205 
       
 10206         case 4: ;
       
 10207         case 5: {
       
 10208                   *pTemp     = pEntry->iRed;
       
 10209                   *(pTemp+1) = pEntry->iGreen;
       
 10210                   *(pTemp+2) = pEntry->iBlue;
       
 10211                   *(pTemp+3) = pEntry->iAlpha;
       
 10212 
       
 10213                   pTemp += 4;
       
 10214                   iRawlen += 4;
       
 10215 
       
 10216                   break;
       
 10217                 }
       
 10218 
       
 10219       }
       
 10220     }
       
 10221     else
       
 10222     {
       
 10223       if (bHasgroup)                   /* finish off a group ? */
       
 10224         *pLastid = (mng_uint8)(iX-1);
       
 10225 
       
 10226       bHasgroup = MNG_FALSE;
       
 10227     }
       
 10228   }
       
 10229 
       
 10230   if (bHasgroup)                       /* last group unfinished ? */
       
 10231     *pLastid = (mng_uint8)(pPPLT->iCount-1);
       
 10232                                        /* write the output buffer */
       
 10233   iRetcode = write_raw_chunk (pData, pPPLT->sHeader.iChunkname,
       
 10234                               iRawlen, pRawdata);
       
 10235 
       
 10236 #ifdef MNG_SUPPORT_TRACE
       
 10237   MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_END);
       
 10238 #endif
       
 10239 
       
 10240   return iRetcode;
       
 10241 }
       
 10242 #endif
       
 10243 
       
 10244 /* ************************************************************************** */
       
 10245 
       
 10246 #ifndef MNG_NO_DELTA_PNG
       
 10247 #ifdef MNG_INCLUDE_JNG
       
 10248 WRITE_CHUNK (mng_write_ijng)
       
 10249 {
       
 10250   mng_ijngp   pIJNG;
       
 10251   mng_retcode iRetcode;
       
 10252 
       
 10253 #ifdef MNG_SUPPORT_TRACE
       
 10254   MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_START);
       
 10255 #endif
       
 10256 
       
 10257   pIJNG = (mng_ijngp)pChunk;           /* address the proper chunk */
       
 10258                                        /* and write it */
       
 10259   iRetcode = write_raw_chunk (pData, pIJNG->sHeader.iChunkname, 0, 0);
       
 10260 
       
 10261 #ifdef MNG_SUPPORT_TRACE
       
 10262   MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_END);
       
 10263 #endif
       
 10264 
       
 10265   return iRetcode;
       
 10266 }
       
 10267 #endif
       
 10268 #endif
       
 10269 
       
 10270 /* ************************************************************************** */
       
 10271 
       
 10272 #ifndef MNG_NO_DELTA_PNG
       
 10273 WRITE_CHUNK (mng_write_drop)
       
 10274 {
       
 10275   mng_dropp        pDROP;
       
 10276   mng_uint8p       pRawdata;
       
 10277   mng_uint32       iRawlen;
       
 10278   mng_retcode      iRetcode;
       
 10279   mng_uint32       iX;
       
 10280   mng_uint8p       pTemp1;
       
 10281   mng_chunkidp     pTemp2;
       
 10282 
       
 10283 #ifdef MNG_SUPPORT_TRACE
       
 10284   MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_START);
       
 10285 #endif
       
 10286 
       
 10287   pDROP    = (mng_dropp)pChunk;        /* address the proper chunk */
       
 10288 
       
 10289   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10290   iRawlen  = pDROP->iCount << 2;
       
 10291 
       
 10292   pTemp1   = pRawdata;                 /* fill the output buffer */
       
 10293   pTemp2   = pDROP->pChunknames;
       
 10294 
       
 10295   for (iX = 0; iX < pDROP->iCount; iX++)
       
 10296   {
       
 10297     mng_put_uint32 (pTemp1, (mng_uint32)*pTemp2);
       
 10298 
       
 10299     pTemp2++;
       
 10300     pTemp1 += 4;
       
 10301   }
       
 10302                                        /* and write it */
       
 10303   iRetcode = write_raw_chunk (pData, pDROP->sHeader.iChunkname,
       
 10304                               iRawlen, pRawdata);
       
 10305 
       
 10306 #ifdef MNG_SUPPORT_TRACE
       
 10307   MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_END);
       
 10308 #endif
       
 10309 
       
 10310   return iRetcode;
       
 10311 }
       
 10312 #endif
       
 10313 
       
 10314 /* ************************************************************************** */
       
 10315 
       
 10316 #ifndef MNG_NO_DELTA_PNG
       
 10317 #ifndef MNG_SKIPCHUNK_DBYK
       
 10318 WRITE_CHUNK (mng_write_dbyk)
       
 10319 {
       
 10320   mng_dbykp   pDBYK;
       
 10321   mng_uint8p  pRawdata;
       
 10322   mng_uint32  iRawlen;
       
 10323   mng_retcode iRetcode;
       
 10324 
       
 10325 #ifdef MNG_SUPPORT_TRACE
       
 10326   MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_START);
       
 10327 #endif
       
 10328 
       
 10329   pDBYK = (mng_dbykp)pChunk;           /* address the proper chunk */
       
 10330 
       
 10331   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10332   iRawlen  = 5 + pDBYK->iKeywordssize;
       
 10333                                        /* fill the output buffer */
       
 10334   mng_put_uint32 (pRawdata, pDBYK->iChunkname);
       
 10335   *(pRawdata+4) = pDBYK->iPolarity;
       
 10336 
       
 10337   if (pDBYK->iKeywordssize)
       
 10338     MNG_COPY (pRawdata+5, pDBYK->zKeywords, pDBYK->iKeywordssize);
       
 10339                                        /* and write it */
       
 10340   iRetcode = write_raw_chunk (pData, pDBYK->sHeader.iChunkname,
       
 10341                               iRawlen, pRawdata);
       
 10342 
       
 10343 #ifdef MNG_SUPPORT_TRACE
       
 10344   MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_END);
       
 10345 #endif
       
 10346 
       
 10347   return iRetcode;
       
 10348 }
       
 10349 #endif
       
 10350 #endif
       
 10351 
       
 10352 /* ************************************************************************** */
       
 10353 
       
 10354 #ifndef MNG_NO_DELTA_PNG
       
 10355 #ifndef MNG_SKIPCHUNK_ORDR
       
 10356 WRITE_CHUNK (mng_write_ordr)
       
 10357 {
       
 10358   mng_ordrp       pORDR;
       
 10359   mng_uint8p      pRawdata;
       
 10360   mng_uint32      iRawlen;
       
 10361   mng_retcode     iRetcode;
       
 10362   mng_uint8p      pTemp;
       
 10363   mng_ordr_entryp pEntry;
       
 10364   mng_uint32      iX;
       
 10365 
       
 10366 #ifdef MNG_SUPPORT_TRACE
       
 10367   MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_START);
       
 10368 #endif
       
 10369 
       
 10370   pORDR    = (mng_ordrp)pChunk;        /* address the proper chunk */
       
 10371 
       
 10372   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10373   iRawlen  = pORDR->iCount * 5;
       
 10374 
       
 10375   pTemp    = pRawdata;                 /* fill the output buffer */
       
 10376   pEntry   = pORDR->pEntries;
       
 10377 
       
 10378   for (iX = 0; iX < pORDR->iCount; iX++)
       
 10379   {
       
 10380     mng_put_uint32 (pTemp, pEntry->iChunkname);
       
 10381     *(pTemp+4) = pEntry->iOrdertype;
       
 10382     pTemp += 5;
       
 10383     pEntry++;
       
 10384   }
       
 10385                                        /* and write it */
       
 10386   iRetcode = write_raw_chunk (pData, pORDR->sHeader.iChunkname,
       
 10387                               iRawlen, pRawdata);
       
 10388 
       
 10389 #ifdef MNG_SUPPORT_TRACE
       
 10390   MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_END);
       
 10391 #endif
       
 10392 
       
 10393   return iRetcode;
       
 10394 }
       
 10395 #endif
       
 10396 #endif
       
 10397 
       
 10398 /* ************************************************************************** */
       
 10399 
       
 10400 WRITE_CHUNK (mng_write_magn)
       
 10401 {
       
 10402   mng_magnp   pMAGN;
       
 10403   mng_uint8p  pRawdata;
       
 10404   mng_uint32  iRawlen;
       
 10405   mng_retcode iRetcode;
       
 10406 
       
 10407 #ifdef MNG_SUPPORT_TRACE
       
 10408   MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_START);
       
 10409 #endif
       
 10410 
       
 10411   pMAGN    = (mng_magnp)pChunk;        /* address the proper chunk */
       
 10412 
       
 10413   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10414   iRawlen  = 18;
       
 10415                                        /* fill the output buffer */
       
 10416   mng_put_uint16 (pRawdata,    pMAGN->iFirstid);
       
 10417   mng_put_uint16 (pRawdata+2,  pMAGN->iLastid);
       
 10418   *(pRawdata+4) = pMAGN->iMethodX;
       
 10419   mng_put_uint16 (pRawdata+5,  pMAGN->iMX);
       
 10420   mng_put_uint16 (pRawdata+7,  pMAGN->iMY);
       
 10421   mng_put_uint16 (pRawdata+9,  pMAGN->iML);
       
 10422   mng_put_uint16 (pRawdata+11, pMAGN->iMR);
       
 10423   mng_put_uint16 (pRawdata+13, pMAGN->iMT);
       
 10424   mng_put_uint16 (pRawdata+15, pMAGN->iMB);
       
 10425   *(pRawdata+17) = pMAGN->iMethodY;
       
 10426                                        /* optimize length */
       
 10427   if (pMAGN->iMethodY == pMAGN->iMethodX)
       
 10428   {
       
 10429     iRawlen--;
       
 10430 
       
 10431     if (pMAGN->iMB == pMAGN->iMY)
       
 10432     {
       
 10433       iRawlen -= 2;
       
 10434 
       
 10435       if (pMAGN->iMT == pMAGN->iMY)
       
 10436       {
       
 10437         iRawlen -= 2;
       
 10438 
       
 10439         if (pMAGN->iMR == pMAGN->iMX)
       
 10440         {
       
 10441           iRawlen -= 2;
       
 10442 
       
 10443           if (pMAGN->iML == pMAGN->iMX)
       
 10444           {
       
 10445             iRawlen -= 2;
       
 10446 
       
 10447             if (pMAGN->iMY == pMAGN->iMX)
       
 10448             {
       
 10449               iRawlen -= 2;
       
 10450 
       
 10451               if (pMAGN->iMX == 1)
       
 10452               {
       
 10453                 iRawlen -= 2;
       
 10454 
       
 10455                 if (pMAGN->iMethodX == 0)
       
 10456                 {
       
 10457                   iRawlen--;
       
 10458 
       
 10459                   if (pMAGN->iLastid == pMAGN->iFirstid)
       
 10460                   {
       
 10461                     iRawlen -= 2;
       
 10462 
       
 10463                     if (pMAGN->iFirstid == 0)
       
 10464                       iRawlen = 0;
       
 10465 
       
 10466                   }
       
 10467                 }
       
 10468               }
       
 10469             }
       
 10470           }
       
 10471         }
       
 10472       }
       
 10473     }
       
 10474   }
       
 10475                                        /* and write it */
       
 10476   iRetcode = write_raw_chunk (pData, pMAGN->sHeader.iChunkname,
       
 10477                               iRawlen, pRawdata);
       
 10478 
       
 10479 #ifdef MNG_SUPPORT_TRACE
       
 10480   MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_END);
       
 10481 #endif
       
 10482 
       
 10483   return iRetcode;
       
 10484 }
       
 10485 
       
 10486 /* ************************************************************************** */
       
 10487 
       
 10488 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
       
 10489 WRITE_CHUNK (mng_write_mpng)
       
 10490 {
       
 10491   mng_mpngp   pMPNG;
       
 10492   mng_uint8p  pRawdata;
       
 10493   mng_uint32  iRawlen;
       
 10494   mng_retcode iRetcode;
       
 10495   mng_uint8p  pBuf = 0;
       
 10496   mng_uint32  iBuflen;
       
 10497   mng_uint32  iReallen;
       
 10498 
       
 10499 #ifdef MNG_SUPPORT_TRACE
       
 10500   MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_START);
       
 10501 #endif
       
 10502 
       
 10503   pMPNG = (mng_mpngp)pChunk;           /* address the proper chunk */
       
 10504                                        /* compress the frame structures */
       
 10505   iRetcode = deflate_buffer (pData, (mng_uint8p)pMPNG->pFrames, pMPNG->iFramessize,
       
 10506                              &pBuf, &iBuflen, &iReallen);
       
 10507 
       
 10508   if (!iRetcode)                       /* all ok ? */
       
 10509   {
       
 10510     pRawdata = pData->pWritebuf+8;     /* init output buffer & size */
       
 10511     iRawlen  = 15 + iReallen;
       
 10512                                        /* requires large buffer ? */
       
 10513     if (iRawlen > pData->iWritebufsize)
       
 10514       MNG_ALLOC (pData, pRawdata, iRawlen);
       
 10515                                        /* fill the buffer */
       
 10516     mng_put_uint32 (pRawdata,    pMPNG->iFramewidth);
       
 10517     mng_put_uint32 (pRawdata+4,  pMPNG->iFrameheight);
       
 10518     mng_put_uint16 (pRawdata+8,  pMPNG->iNumplays);
       
 10519     mng_put_uint16 (pRawdata+10, pMPNG->iTickspersec);
       
 10520     *(pRawdata+12) = pMPNG->iCompressionmethod;
       
 10521 
       
 10522     if (iReallen)
       
 10523       MNG_COPY (pRawdata+13, pBuf, iReallen);
       
 10524                                        /* and write it */
       
 10525     iRetcode = write_raw_chunk (pData, pMPNG->sHeader.iChunkname,
       
 10526                                 iRawlen, pRawdata);
       
 10527                                        /* drop the temp buffer ? */
       
 10528     if (iRawlen > pData->iWritebufsize)
       
 10529       MNG_FREEX (pData, pRawdata, iRawlen);
       
 10530   }
       
 10531 
       
 10532   MNG_FREEX (pData, pBuf, iBuflen);    /* always drop the compression buffer */
       
 10533 
       
 10534 #ifdef MNG_SUPPORT_TRACE
       
 10535   MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_END);
       
 10536 #endif
       
 10537 
       
 10538   return iRetcode;
       
 10539 }
       
 10540 #endif
       
 10541 
       
 10542 /* ************************************************************************** */
       
 10543 
       
 10544 #ifdef MNG_INCLUDE_ANG_PROPOSAL
       
 10545 WRITE_CHUNK (mng_write_ahdr)
       
 10546 {
       
 10547   mng_ahdrp   pAHDR;
       
 10548   mng_uint8p  pRawdata;
       
 10549   mng_uint32  iRawlen;
       
 10550   mng_retcode iRetcode;
       
 10551 
       
 10552 #ifdef MNG_SUPPORT_TRACE
       
 10553   MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_START);
       
 10554 #endif
       
 10555 
       
 10556   pAHDR    = (mng_ahdrp)pChunk;        /* address the proper chunk */
       
 10557   pRawdata = pData->pWritebuf+8;       /* init output buffer & size */
       
 10558   iRawlen  = 22;
       
 10559                                        /* fill the buffer */
       
 10560   mng_put_uint32 (pRawdata,    pAHDR->iNumframes);
       
 10561   mng_put_uint32 (pRawdata+4,  pAHDR->iTickspersec);
       
 10562   mng_put_uint32 (pRawdata+8,  pAHDR->iNumplays);
       
 10563   mng_put_uint32 (pRawdata+12, pAHDR->iTilewidth);
       
 10564   mng_put_uint32 (pRawdata+16, pAHDR->iTileheight);
       
 10565   *(pRawdata+20) = pAHDR->iInterlace;
       
 10566   *(pRawdata+21) = pAHDR->iStillused;
       
 10567                                        /* and write it */
       
 10568   iRetcode = write_raw_chunk (pData, pAHDR->sHeader.iChunkname,
       
 10569                               iRawlen, pRawdata);
       
 10570 
       
 10571 #ifdef MNG_SUPPORT_TRACE
       
 10572   MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_END);
       
 10573 #endif
       
 10574 
       
 10575   return iRetcode;
       
 10576 }
       
 10577 #endif
       
 10578 
       
 10579 /* ************************************************************************** */
       
 10580 
       
 10581 #ifdef MNG_INCLUDE_ANG_PROPOSAL
       
 10582 WRITE_CHUNK (mng_write_adat)
       
 10583 {
       
 10584 
       
 10585   /* TODO: something */
       
 10586 
       
 10587   return MNG_NOERROR;
       
 10588 }
       
 10589 #endif
       
 10590 
       
 10591 /* ************************************************************************** */
       
 10592 
       
 10593 #ifndef MNG_SKIPCHUNK_evNT
       
 10594 WRITE_CHUNK (mng_write_evnt)
       
 10595 {
       
 10596   mng_evntp       pEVNT;
       
 10597   mng_uint8p      pRawdata;
       
 10598   mng_uint32      iRawlen;
       
 10599   mng_retcode     iRetcode;
       
 10600   mng_evnt_entryp pEntry;
       
 10601   mng_uint8p      pTemp;
       
 10602   mng_uint32      iX;
       
 10603   mng_uint32      iNamesize;
       
 10604 
       
 10605 #ifdef MNG_SUPPORT_TRACE
       
 10606   MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_START);
       
 10607 #endif
       
 10608 
       
 10609   pEVNT = (mng_evntp)pChunk;           /* address the proper chunk */
       
 10610 
       
 10611   if (!pEVNT->iCount)                  /* empty ? */
       
 10612     iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname, 0, 0);
       
 10613   else
       
 10614   {
       
 10615     pRawdata  = pData->pWritebuf+8;    /* init output buffer & size */
       
 10616     iRawlen   = 0;
       
 10617     pTemp     = pRawdata;
       
 10618     pEntry    = pEVNT->pEntries;
       
 10619 
       
 10620     for (iX = 0; iX < pEVNT->iCount; iX++)
       
 10621     {
       
 10622       if (iX)                          /* put separator null-byte, except the first */
       
 10623       {
       
 10624         *pTemp = 0;
       
 10625         pTemp++;
       
 10626         iRawlen++;
       
 10627       }
       
 10628 
       
 10629       *pTemp     = pEntry->iEventtype;
       
 10630       *(pTemp+1) = pEntry->iMasktype;
       
 10631       pTemp   += 2;
       
 10632       iRawlen += 2;
       
 10633 
       
 10634       switch (pEntry->iMasktype)
       
 10635       {
       
 10636         case 1 :
       
 10637           {
       
 10638             mng_put_int32 (pTemp, pEntry->iLeft);
       
 10639             mng_put_int32 (pTemp+4, pEntry->iRight);
       
 10640             mng_put_int32 (pTemp+8, pEntry->iTop);
       
 10641             mng_put_int32 (pTemp+12, pEntry->iBottom);
       
 10642             pTemp   += 16;
       
 10643             iRawlen += 16;
       
 10644             break;
       
 10645           }
       
 10646         case 2 :
       
 10647           {
       
 10648             mng_put_uint16 (pTemp, pEntry->iObjectid);
       
 10649             pTemp   += 2;
       
 10650             iRawlen += 2;
       
 10651             break;
       
 10652           }
       
 10653         case 3 :
       
 10654           {
       
 10655             mng_put_uint16 (pTemp, pEntry->iObjectid);
       
 10656             *(pTemp+2) = pEntry->iIndex;
       
 10657             pTemp   += 3;
       
 10658             iRawlen += 3;
       
 10659             break;
       
 10660           }
       
 10661         case 4 :
       
 10662           {
       
 10663             mng_put_int32 (pTemp, pEntry->iLeft);
       
 10664             mng_put_int32 (pTemp+4, pEntry->iRight);
       
 10665             mng_put_int32 (pTemp+8, pEntry->iTop);
       
 10666             mng_put_int32 (pTemp+12, pEntry->iBottom);
       
 10667             mng_put_uint16 (pTemp+16, pEntry->iObjectid);
       
 10668             pTemp   += 18;
       
 10669             iRawlen += 18;
       
 10670             break;
       
 10671           }
       
 10672         case 5 :
       
 10673           {
       
 10674             mng_put_int32 (pTemp, pEntry->iLeft);
       
 10675             mng_put_int32 (pTemp+4, pEntry->iRight);
       
 10676             mng_put_int32 (pTemp+8, pEntry->iTop);
       
 10677             mng_put_int32 (pTemp+12, pEntry->iBottom);
       
 10678             mng_put_uint16 (pTemp+16, pEntry->iObjectid);
       
 10679             *(pTemp+18) = pEntry->iIndex;
       
 10680             pTemp   += 19;
       
 10681             iRawlen += 19;
       
 10682             break;
       
 10683           }
       
 10684       }
       
 10685 
       
 10686       iNamesize = pEntry->iSegmentnamesize;
       
 10687 
       
 10688       if (iNamesize)
       
 10689       {
       
 10690         MNG_COPY (pTemp, pEntry->zSegmentname, iNamesize);
       
 10691         pTemp   += iNamesize;
       
 10692         iRawlen += iNamesize;
       
 10693       }
       
 10694 
       
 10695       pEntry++;  
       
 10696     }
       
 10697                                        /* and write it */
       
 10698     iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname,
       
 10699                                 iRawlen, pRawdata);
       
 10700   }
       
 10701 
       
 10702 #ifdef MNG_SUPPORT_TRACE
       
 10703   MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_END);
       
 10704 #endif
       
 10705 
       
 10706   return iRetcode;
       
 10707 }
       
 10708 #endif
       
 10709 
       
 10710 /* ************************************************************************** */
       
 10711 
       
 10712 WRITE_CHUNK (mng_write_unknown)
       
 10713 {
       
 10714   mng_unknown_chunkp pUnknown;
       
 10715   mng_retcode        iRetcode;
       
 10716 
       
 10717 #ifdef MNG_SUPPORT_TRACE
       
 10718   MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_START);
       
 10719 #endif
       
 10720                                        /* address the proper chunk */
       
 10721   pUnknown = (mng_unknown_chunkp)pChunk;
       
 10722                                        /* and write it */
       
 10723   iRetcode = write_raw_chunk (pData, pUnknown->sHeader.iChunkname,
       
 10724                               pUnknown->iDatasize, pUnknown->pData);
       
 10725 
       
 10726 #ifdef MNG_SUPPORT_TRACE
       
 10727   MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_END);
       
 10728 #endif
       
 10729 
       
 10730   return iRetcode;
       
 10731 }
       
 10732 
       
 10733 /* ************************************************************************** */
       
 10734 
       
 10735 #endif /* MNG_INCLUDE_WRITE_PROCS */
       
 10736 
       
 10737 /* ************************************************************************** */
       
 10738 /* * end of file                                                            * */
       
 10739 /* ************************************************************************** */
       
 10740