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
make_crc_table(mng_datap pData)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
update_crc(mng_datap pData,mng_uint32 iCrc,mng_uint8p pBuf,mng_int32 iLen)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]. */
mng_crc(mng_datap pData,mng_uint8p pBuf,mng_int32 iLen)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
mng_get_uint32(mng_uint8p pBuf)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
mng_get_int32(mng_uint8p pBuf)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
mng_get_uint16(mng_uint8p pBuf)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
mng_put_uint32(mng_uint8p pBuf,mng_uint32 i)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
mng_put_int32(mng_uint8p pBuf,mng_int32 i)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
mng_put_uint16(mng_uint8p pBuf,mng_uint16 i)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
find_null(mng_uint8p pIn)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)
mng_inflate_buffer(mng_datap pData,mng_uint8p pInbuf,mng_uint32 iInsize,mng_uint8p * pOutbuf,mng_uint32 * iOutsize,mng_uint32 * iRealsize)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)
deflate_buffer(mng_datap pData,mng_uint8p pInbuf,mng_uint32 iInsize,mng_uint8p * pOutbuf,mng_uint32 * iOutsize,mng_uint32 * iRealsize)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
write_raw_chunk(mng_datap pData,mng_chunkid iChunkname,mng_uint32 iRawlen,mng_uint8p pRawdata)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
create_chunk_storage(mng_datap pData,mng_chunkp pHeader,mng_uint32 iRawlen,mng_uint8p pRawdata,mng_field_descp pField,mng_uint16 iFields,mng_chunkp * ppChunk,mng_bool bWorkcopy)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
READ_CHUNK(mng_read_general)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
READ_CHUNK(mng_read_ihdr)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
READ_CHUNK(mng_read_plte)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
READ_CHUNK(mng_read_idat)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
READ_CHUNK(mng_read_iend)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
READ_CHUNK(mng_read_trns)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
READ_CHUNK(mng_read_gama)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_srgb)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_mhdr)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
READ_CHUNK(mng_read_mend)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_endl)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
CheckKeyword(mng_datap pData,mng_uint8p pKeyword)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_jhdr)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
READ_CHUNK(mng_read_jdaa)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
READ_CHUNK(mng_read_jdat)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
READ_CHUNK(mng_read_jsep)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
READ_CHUNK(mng_read_dhdr)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
READ_CHUNK(mng_read_prom)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
READ_CHUNK(mng_read_ipng)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
READ_CHUNK(mng_read_pplt)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
READ_CHUNK(mng_read_ijng)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
READ_CHUNK(mng_read_drop)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_mpng)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
READ_CHUNK(mng_read_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
READ_CHUNK(mng_read_unknown)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
WRITE_CHUNK(mng_write_ihdr)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
WRITE_CHUNK(mng_write_plte)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
WRITE_CHUNK(mng_write_idat)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
WRITE_CHUNK(mng_write_iend)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
WRITE_CHUNK(mng_write_trns)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
WRITE_CHUNK(mng_write_gama)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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_srgb)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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_mhdr)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
WRITE_CHUNK(mng_write_mend)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
WRITE_CHUNK(mng_write_loop)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
WRITE_CHUNK(mng_write_endl)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
WRITE_CHUNK(mng_write_defi)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
WRITE_CHUNK(mng_write_basi)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
WRITE_CHUNK(mng_write_clon)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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_disc)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
WRITE_CHUNK(mng_write_back)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
WRITE_CHUNK(mng_write_fram)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
WRITE_CHUNK(mng_write_move)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
WRITE_CHUNK(mng_write_clip)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
WRITE_CHUNK(mng_write_show)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
WRITE_CHUNK(mng_write_term)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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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 */
WRITE_CHUNK(mng_write_jhdr)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
WRITE_CHUNK(mng_write_jdaa)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 */
WRITE_CHUNK(mng_write_jdat)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 */
WRITE_CHUNK(mng_write_jsep)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
WRITE_CHUNK(mng_write_dhdr)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
WRITE_CHUNK(mng_write_prom)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
WRITE_CHUNK(mng_write_ipng)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
WRITE_CHUNK(mng_write_pplt)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
WRITE_CHUNK(mng_write_ijng)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
WRITE_CHUNK(mng_write_drop)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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_magn)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
WRITE_CHUNK(mng_write_mpng)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
WRITE_CHUNK(mng_write_ahdr)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
WRITE_CHUNK(mng_write_adat)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
WRITE_CHUNK(mng_write_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
WRITE_CHUNK(mng_write_unknown)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
10741