1 /* ************************************************************************** */
2 /* *             For conditions of distribution and use,                    * */
3 /* *                see copyright notice in libmng.h                        * */
4 /* ************************************************************************** */
5 /* *                                                                        * */
6 /* * project   : libmng                                                     * */
7 /* * file      : libmng_hlapi.c            copyright (c) 2000-2007 G.Juyn   * */
8 /* * version   : 1.0.10                                                     * */
9 /* *                                                                        * */
10 /* * purpose   : high-level application API (implementation)                * */
11 /* *                                                                        * */
12 /* * author    : G.Juyn                                                     * */
13 /* *                                                                        * */
14 /* * comment   : implementation of the high-level function interface        * */
15 /* *             for applications.                                          * */
16 /* *                                                                        * */
17 /* * changes   : 0.5.1 - 05/06/2000 - G.Juyn                                * */
18 /* *             - added init of iPLTEcount                                 * */
19 /* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
20 /* *             - changed calling-convention definition                    * */
21 /* *             - changed status-handling of display-routines              * */
22 /* *             - added versioning-control routines                        * */
23 /* *             - filled the write routine                                 * */
24 /* *             - changed strict-ANSI stuff                                * */
25 /* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
26 /* *             - added callback error-reporting support                   * */
27 /* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
28 /* *             - changed trace to macro for callback error-reporting      * */
29 /* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
30 /* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
31 /* *             - added TERM animation object pointer (easier reference)   * */
32 /* *             0.5.1 - 05/14/2000 - G.Juyn                                * */
33 /* *             - added cleanup of saved-data (SAVE/SEEK processing)       * */
34 /* *             0.5.1 - 05/16/2000 - G.Juyn                                * */
35 /* *             - moved the actual write_graphic functionality from here   * */
36 /* *               to its appropriate function in the mng_write module      * */
37 /* *                                                                        * */
38 /* *             0.5.2 - 05/19/2000 - G.Juyn                                * */
39 /* *             - cleaned up some code regarding mixed support             * */
40 /* *             - added JNG support                                        * */
41 /* *             0.5.2 - 05/24/2000 - G.Juyn                                * */
42 /* *             - moved init of default zlib parms here from "mng_zlib.c"  * */
43 /* *             - added init of default IJG parms                          * */
44 /* *             0.5.2 - 05/29/2000 - G.Juyn                                * */
45 /* *             - fixed inconsistancy with freeing global iCCP profile     * */
46 /* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
47 /* *             - added delta-image field initialization                   * */
48 /* *             0.5.2 - 06/06/2000 - G.Juyn                                * */
49 /* *             - added initialization of the buffer-suspend parameter     * */
50 /* *                                                                        * */
51 /* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
52 /* *             - added initialization of update-region for refresh        * */
53 /* *             - added initialization of Needrefresh parameter            * */
54 /* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
55 /* *             - added initialization of Deltaimmediate                   * */
56 /* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
57 /* *             - added initialization of Speed                            * */
58 /* *             - added initialization of Imagelevel                       * */
59 /* *             0.5.3 - 06/26/2000 - G.Juyn                                * */
60 /* *             - changed userdata variable to mng_ptr                     * */
61 /* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
62 /* *             - fixed initialization routine for new mng_handle type     * */
63 /* *                                                                        * */
64 /* *             0.9.1 - 07/06/2000 - G.Juyn                                * */
65 /* *             - changed mng_display_resume to allow to be called after   * */
66 /* *               a suspension return with MNG_NEEDMOREDATA                * */
67 /* *             - added returncode MNG_NEEDTIMERWAIT for timer breaks      * */
68 /* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
69 /* *             - implemented support for freeze/reset/resume & go_xxxx    * */
70 /* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
71 /* *             - added support for improved timing                        * */
72 /* *             - added support for improved I/O-suspension                * */
73 /* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
74 /* *             - changed EOF processing behavior                          * */
75 /* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
76 /* *             - added callbacks for SAVE/SEEK processing                 * */
77 /* *             - added variable for NEEDSECTIONWAIT breaks                * */
78 /* *             - added variable for freeze & reset processing             * */
79 /* *             0.9.1 - 07/17/2000 - G.Juyn                                * */
80 /* *             - added error cleanup processing                           * */
81 /* *             - fixed support for mng_display_reset()                    * */
82 /* *             - fixed suspension-buffering for 32K+ chunks               * */
83 /* *                                                                        * */
84 /* *             0.9.2 - 07/29/2000 - G.Juyn                                * */
85 /* *             - fixed small bugs in display processing                   * */
86 /* *             0.9.2 - 07/31/2000 - G.Juyn                                * */
87 /* *             - fixed wrapping of suspension parameters                  * */
88 /* *             0.9.2 - 08/04/2000 - G.Juyn                                * */
89 /* *             - B111096 - fixed large-buffer read-suspension             * */
90 /* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
91 /* *             - changed file-prefixes                                    * */
92 /* *                                                                        * */
93 /* *             0.9.3 - 09/07/2000 - G.Juyn                                * */
94 /* *             - added support for new filter_types                       * */
95 /* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
96 /* *             - fixed DEFI behavior                                      * */
97 /* *             0.9.3 - 10/11/2000 - G.Juyn                                * */
98 /* *             - added support for nEED                                   * */
99 /* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
100 /* *             - added optional support for bKGD for PNG images           * */
101 /* *             - raised initial maximum canvas size                       * */
102 /* *             - added support for JDAA                                   * */
103 /* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
104 /* *             - added callback to process non-critical unknown chunks    * */
105 /* *             - fixed support for delta-images during read() / display() * */
106 /* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
107 /* *             - added closestream() processing for mng_cleanup()         * */
108 /* *             0.9.3 - 10/27/2000 - G.Juyn                                * */
109 /* *             - fixed separate read() & display() processing             * */
110 /* *                                                                        * */
111 /* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
112 /* *             - fixed unwanted repetition in mng_readdisplay()           * */
113 /* *             0.9.4 - 11/24/2000 - G.Juyn                                * */
114 /* *             - moved restore of object 0 to libmng_display              * */
115 /* *                                                                        * */
116 /* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
117 /* *             - added MEND processing callback                           * */
118 /* *             1.0.1 - 02/13/2001 - G.Juyn                                * */
119 /* *             - fixed first FRAM_MODE=4 timing problem                   * */
120 /* *             1.0.1 - 04/21/2001 - G.Juyn                                * */
121 /* *             - fixed bug with display_reset/display_resume (Thanks G!)  * */
122 /* *             1.0.1 - 04/22/2001 - G.Juyn                                * */
123 /* *             - fixed memory-leak (Thanks Gregg!)                        * */
124 /* *             1.0.1 - 04/23/2001 - G.Juyn                                * */
125 /* *             - fixed reset_rundata to drop all objects                  * */
126 /* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
127 /* *             - moved mng_clear_cms to libmng_cms                        * */
128 /* *                                                                        * */
129 /* *             1.0.2 - 06/23/2001 - G.Juyn                                * */
130 /* *             - added optimization option for MNG-video playback         * */
131 /* *             - added processterm callback                               * */
132 /* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
133 /* *             - added option to turn off progressive refresh             * */
134 /* *                                                                        * */
135 /* *             1.0.5 - 07/08/2002 - G.Juyn                                * */
136 /* *             - B578572 - removed eMNGma hack (thanks Dimitri!)          * */
137 /* *             1.0.5 - 07/16/2002 - G.Juyn                                * */
138 /* *             - B581625 - large chunks fail with suspension reads        * */
139 /* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
140 /* *             - B597134 - libmng pollutes the linker namespace           * */
141 /* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
142 /* *             - fixed LOOP iteration=0 special case                      * */
143 /* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
144 /* *             - added another fix for misplaced TERM chunk               * */
145 /* *             - completed support for condition=2 in TERM chunk          * */
146 /* *             - added beta version function & constant                   * */
147 /* *             1.0.5 - 10/11/2002 - G.Juyn                                * */
148 /* *             - added mng_status_dynamic to supports function            * */
149 /* *             1.0.5 - 11/04/2002 - G.Juyn                                * */
150 /* *             - changed FRAMECOUNT/LAYERCOUNT/PLAYTIME error to warning  * */
151 /* *             1.0.5 - 11/07/2002 - G.Juyn                                * */
152 /* *             - added support to get totals after mng_read()             * */
153 /* *             1.0.5 - 11/29/2002 - G.Juyn                                * */
154 /* *             - fixed goxxxxx() support for zero values                  * */
155 /* *                                                                        * */
156 /* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
157 /* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
158 /* *             1.0.6 - 07/11/2003 - G.R-P                                 * */
159 /* *             - added conditionals zlib and jpeg property accessors      * */
160 /* *             1.0.6 - 07/14/2003 - G.R-P                                 * */
161 /* *             - added conditionals around "mng_display_go*" and other    * */
162 /* *               unused functions                                         * */
163 /* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
164 /* *             - added conditionals around PAST chunk support             * */
165 /* *                                                                        * */
166 /* *             1.0.7 - 03/07/2004 - G. Randers-Pehrson                    * */
167 /* *             - put gamma, cms-related declarations inside #ifdef        * */
168 /* *             1.0.7 - 03/10/2004 - G.R-P                                 * */
169 /* *             - added conditionals around openstream/closestream         * */
170 /* *             1.0.7 - 03/24/2004 - G.R-P                                 * */
171 /* *             - fixed zTXT -> zTXt typo                                  * */
172 /* *                                                                        * */
173 /* *             1.0.8 - 04/02/2004 - G.Juyn                                * */
174 /* *             - added CRC existence & checking flags                     * */
175 /* *             1.0.8 - 04/10/2004 - G.Juyn                                * */
176 /* *             - added data-push mechanisms for specialized decoders      * */
177 /* *             1.0.8 - 07/06/2004 - G.R-P                                 * */
178 /* *             - defend against using undefined openstream function       * */
179 /* *             1.0.8 - 08/02/2004 - G.Juyn                                * */
180 /* *             - added conditional to allow easier writing of large MNG's * */
181 /* *                                                                        * */
182 /* *             1.0.9 - 08/17/2004 - G.R-P                                 * */
183 /* *             - added more SKIPCHUNK conditionals                        * */
184 /* *             1.0.9 - 09/25/2004 - G.Juyn                                * */
185 /* *             - replaced MNG_TWEAK_LARGE_FILES with permanent solution   * */
186 /* *             1.0.9 - 10/03/2004 - G.Juyn                                * */
187 /* *             - added function to retrieve current FRAM delay            * */
188 /* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
189 /* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
190 /* *                                                                        * */
191 /* *             1.0.10 - 07/06/2005 - G.R-P                                * */
192 /* *             - added more SKIPCHUNK conditionals                        * */
193 /* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
194 /* *             - added support for mPNG proposal                          * */
195 /* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
196 /* *             - added support for ANG proposal                           * */
197 /* *             1.0.10 - 07/06/2007 - G.R-P bugfix by Lucas Quintana       * */
198 /* *                                                                        * */
199 /* ************************************************************************** */
200 
201 #include "libmng.h"
202 #include "libmng_data.h"
203 #include "libmng_error.h"
204 #include "libmng_trace.h"
205 #ifdef __BORLANDC__
206 #pragma hdrstop
207 #endif
208 #include "libmng_objects.h"
209 #include "libmng_object_prc.h"
210 #include "libmng_chunks.h"
211 #include "libmng_memory.h"
212 #include "libmng_read.h"
213 #include "libmng_write.h"
214 #include "libmng_display.h"
215 #include "libmng_zlib.h"
216 #include "libmng_jpeg.h"
217 #include "libmng_cms.h"
218 #include "libmng_pixels.h"
219 
220 #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
221 #pragma option -A                      /* force ANSI-C */
222 #endif
223 
224 /* ************************************************************************** */
225 /* *                                                                        * */
226 /* * local routines                                                         * */
227 /* *                                                                        * */
228 /* ************************************************************************** */
229 
230 #ifdef MNG_SUPPORT_DISPLAY
mng_drop_objects(mng_datap pData,mng_bool bDropaniobj)231 MNG_LOCAL mng_retcode mng_drop_objects (mng_datap pData,
232                                         mng_bool  bDropaniobj)
233 {
234   mng_objectp       pObject;
235   mng_objectp       pNext;
236   mng_cleanupobject fCleanup;
237 
238 #ifdef MNG_SUPPORT_TRACE
239   MNG_TRACE (pData, MNG_FN_DROP_OBJECTS, MNG_LC_START);
240 #endif
241 
242   pObject = pData->pFirstimgobj;       /* get first stored image-object (if any) */
243 
244   while (pObject)                      /* more objects to discard ? */
245   {
246     pNext = ((mng_object_headerp)pObject)->pNext;
247                                        /* call appropriate cleanup */
248     fCleanup = ((mng_object_headerp)pObject)->fCleanup;
249     fCleanup (pData, pObject);
250 
251     pObject = pNext;                   /* neeeext */
252   }
253 
254   pData->pFirstimgobj = MNG_NULL;      /* clean this up!!! */
255   pData->pLastimgobj  = MNG_NULL;
256 
257   if (bDropaniobj)                     /* drop animation objects ? */
258   {
259     pObject = pData->pFirstaniobj;     /* get first stored animation-object (if any) */
260 
261     while (pObject)                    /* more objects to discard ? */
262     {
263       pNext = ((mng_object_headerp)pObject)->pNext;
264                                        /* call appropriate cleanup */
265       fCleanup = ((mng_object_headerp)pObject)->fCleanup;
266       fCleanup (pData, pObject);
267 
268       pObject = pNext;                 /* neeeext */
269     }
270 
271     pData->pFirstaniobj = MNG_NULL;    /* clean this up!!! */
272     pData->pLastaniobj  = MNG_NULL;
273 
274 #ifdef MNG_SUPPORT_DYNAMICMNG
275     pObject = pData->pFirstevent;      /* get first event-object (if any) */
276 
277     while (pObject)                    /* more objects to discard ? */
278     {
279       pNext = ((mng_object_headerp)pObject)->pNext;
280                                        /* call appropriate cleanup */
281       fCleanup = ((mng_object_headerp)pObject)->fCleanup;
282       fCleanup (pData, pObject);
283 
284       pObject = pNext;                 /* neeeext */
285     }
286 
287     pData->pFirstevent = MNG_NULL;     /* clean this up!!! */
288     pData->pLastevent  = MNG_NULL;
289 #endif
290   }
291 
292 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
293   if (pData->pMPNG)                    /* drop MPNG data (if any) */
294   {
295     fCleanup = ((mng_object_headerp)pData->pMPNG)->fCleanup;
296     fCleanup (pData, pData->pMPNG);
297     pData->pMPNG = MNG_NULL;
298   }
299 #endif
300 
301 #ifdef MNG_INCLUDE_ANG_PROPOSAL
302   if (pData->pANG)                     /* drop ANG data (if any) */
303   {
304     fCleanup = ((mng_object_headerp)pData->pANG)->fCleanup;
305     fCleanup (pData, pData->pANG);
306     pData->pANG = MNG_NULL;
307   }
308 #endif
309 
310 #ifdef MNG_SUPPORT_TRACE
311   MNG_TRACE (pData, MNG_FN_DROP_OBJECTS, MNG_LC_END);
312 #endif
313 
314   return MNG_NOERROR;
315 }
316 #endif /* MNG_SUPPORT_DISPLAY */
317 
318 /* ************************************************************************** */
319 
320 #ifdef MNG_SUPPORT_DISPLAY
321 #ifndef MNG_SKIPCHUNK_SAVE
mng_drop_savedata(mng_datap pData)322 MNG_LOCAL mng_retcode mng_drop_savedata (mng_datap pData)
323 {
324 #ifdef MNG_SUPPORT_TRACE
325   MNG_TRACE (pData, MNG_FN_DROP_SAVEDATA, MNG_LC_START);
326 #endif
327 
328   if (pData->pSavedata)                /* sanity check */
329   {                                    /* address it more directly */
330     mng_savedatap pSave = pData->pSavedata;
331 
332     if (pSave->iGlobalProfilesize)     /* cleanup the profile ? */
333       MNG_FREEX (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize);
334                                        /* cleanup the save structure */
335     MNG_FREE (pData, pData->pSavedata, sizeof (mng_savedata));
336   }
337 
338 #ifdef MNG_SUPPORT_TRACE
339   MNG_TRACE (pData, MNG_FN_DROP_SAVEDATA, MNG_LC_END);
340 #endif
341 
342   return MNG_NOERROR;
343 }
344 #endif
345 #endif /* MNG_SUPPORT_DISPLAY */
346 
347 /* ************************************************************************** */
348 
349 #ifdef MNG_SUPPORT_DISPLAY
mng_reset_rundata(mng_datap pData)350 MNG_LOCAL mng_retcode mng_reset_rundata (mng_datap pData)
351 {
352   mng_drop_invalid_objects (pData);    /* drop invalidly stored objects */
353 #ifndef MNG_SKIPCHUNK_SAVE
354   mng_drop_savedata        (pData);    /* drop stored savedata */
355 #endif
356   mng_reset_objzero        (pData);    /* reset object 0 */
357                                        /* drop stored objects (if any) */
358   mng_drop_objects         (pData, MNG_FALSE);
359 
360   pData->bFramedone            = MNG_FALSE;
361   pData->iFrameseq             = 0;    /* reset counters & stuff */
362   pData->iLayerseq             = 0;
363   pData->iFrametime            = 0;
364 
365   pData->bSkipping             = MNG_FALSE;
366 
367 #ifdef MNG_SUPPORT_DYNAMICMNG
368   pData->bRunningevent         = MNG_FALSE;
369   pData->bStopafterseek        = MNG_FALSE;
370   pData->iEventx               = 0;
371   pData->iEventy               = 0;
372   pData->pLastmousemove        = MNG_NULL;
373 #endif
374 
375   pData->iRequestframe         = 0;
376   pData->iRequestlayer         = 0;
377   pData->iRequesttime          = 0;
378   pData->bSearching            = MNG_FALSE;
379 
380   pData->iRuntime              = 0;
381   pData->iSynctime             = 0;
382   pData->iStarttime            = 0;
383   pData->iEndtime              = 0;
384   pData->bRunning              = MNG_FALSE;
385   pData->bTimerset             = MNG_FALSE;
386   pData->iBreakpoint           = 0;
387   pData->bSectionwait          = MNG_FALSE;
388   pData->bFreezing             = MNG_FALSE;
389   pData->bResetting            = MNG_FALSE;
390   pData->bNeedrefresh          = MNG_FALSE;
391   pData->bOnlyfirstframe       = MNG_FALSE;
392   pData->iFramesafterTERM      = 0;
393 
394   pData->iIterations           = 0;
395                                        /* start of animation objects! */
396   pData->pCurraniobj           = MNG_NULL;
397 
398   pData->iUpdateleft           = 0;    /* reset region */
399   pData->iUpdateright          = 0;
400   pData->iUpdatetop            = 0;
401   pData->iUpdatebottom         = 0;
402   pData->iPLTEcount            = 0;    /* reset PLTE data */
403 
404 #ifndef MNG_SKIPCHUNK_DEFI
405   pData->iDEFIobjectid         = 0;    /* reset DEFI data */
406   pData->bDEFIhasdonotshow     = MNG_FALSE;
407   pData->iDEFIdonotshow        = 0;
408   pData->bDEFIhasconcrete      = MNG_FALSE;
409   pData->iDEFIconcrete         = 0;
410   pData->bDEFIhasloca          = MNG_FALSE;
411   pData->iDEFIlocax            = 0;
412   pData->iDEFIlocay            = 0;
413   pData->bDEFIhasclip          = MNG_FALSE;
414   pData->iDEFIclipl            = 0;
415   pData->iDEFIclipr            = 0;
416   pData->iDEFIclipt            = 0;
417   pData->iDEFIclipb            = 0;
418 #endif
419 
420 #ifndef MNG_SKIPCHUNK_BACK
421   pData->iBACKred              = 0;    /* reset BACK data */
422   pData->iBACKgreen            = 0;
423   pData->iBACKblue             = 0;
424   pData->iBACKmandatory        = 0;
425   pData->iBACKimageid          = 0;
426   pData->iBACKtile             = 0;
427 #endif
428 
429 #ifndef MNG_SKIPCHUNK_FRAM
430   pData->iFRAMmode             = 1;     /* default global FRAM variables */
431   pData->iFRAMdelay            = 1;
432   pData->iFRAMtimeout          = 0x7fffffffl;
433   pData->bFRAMclipping         = MNG_FALSE;
434   pData->iFRAMclipl            = 0;
435   pData->iFRAMclipr            = 0;
436   pData->iFRAMclipt            = 0;
437   pData->iFRAMclipb            = 0;
438 
439   pData->iFramemode            = 1;     /* again for the current frame */
440   pData->iFramedelay           = 1;
441   pData->iFrametimeout         = 0x7fffffffl;
442   pData->bFrameclipping        = MNG_FALSE;
443   pData->iFrameclipl           = 0;
444   pData->iFrameclipr           = 0;
445   pData->iFrameclipt           = 0;
446   pData->iFrameclipb           = 0;
447 
448   pData->iNextdelay            = 1;
449 
450   pData->bForcedelay           = MNG_FALSE;
451   pData->iAccumdelay           = 0;
452 #endif
453 
454 #ifndef MNG_SKIPCHUNK_SHOW
455   pData->iSHOWmode             = 0;    /* reset SHOW data */
456   pData->iSHOWfromid           = 0;
457   pData->iSHOWtoid             = 0;
458   pData->iSHOWnextid           = 0;
459   pData->iSHOWskip             = 0;
460 #endif
461 
462   pData->iGlobalPLTEcount      = 0;    /* reset global PLTE data */
463 
464   pData->iGlobalTRNSrawlen     = 0;    /* reset global tRNS data */
465 
466   pData->iGlobalGamma          = 0;    /* reset global gAMA data */
467 
468 #ifndef MNG_SKIPCHUNK_cHRM
469   pData->iGlobalWhitepointx    = 0;    /* reset global cHRM data */
470   pData->iGlobalWhitepointy    = 0;
471   pData->iGlobalPrimaryredx    = 0;
472   pData->iGlobalPrimaryredy    = 0;
473   pData->iGlobalPrimarygreenx  = 0;
474   pData->iGlobalPrimarygreeny  = 0;
475   pData->iGlobalPrimarybluex   = 0;
476   pData->iGlobalPrimarybluey   = 0;
477 #endif
478 
479 #ifndef MNG_SKIPCHUNK_sRGB
480   pData->iGlobalRendintent     = 0;    /* reset global sRGB data */
481 #endif
482 
483 #ifndef MNG_SKIPCHUNK_iCCP
484   if (pData->iGlobalProfilesize)       /* drop global profile (if any) */
485     MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
486 
487   pData->iGlobalProfilesize    = 0;
488 #endif
489 
490 #ifndef MNG_SKIPCHUNK_bKGD
491   pData->iGlobalBKGDred        = 0;    /* reset global bKGD data */
492   pData->iGlobalBKGDgreen      = 0;
493   pData->iGlobalBKGDblue       = 0;
494 #endif
495 #ifndef MNG_NO_DELTA_PNG
496                                        /* reset delta-image */
497   pData->pDeltaImage           = MNG_NULL;
498   pData->iDeltaImagetype       = 0;
499   pData->iDeltatype            = 0;
500   pData->iDeltaBlockwidth      = 0;
501   pData->iDeltaBlockheight     = 0;
502   pData->iDeltaBlockx          = 0;
503   pData->iDeltaBlocky          = 0;
504   pData->bDeltaimmediate       = MNG_FALSE;
505 
506   pData->fDeltagetrow          = MNG_NULL;
507   pData->fDeltaaddrow          = MNG_NULL;
508   pData->fDeltareplacerow      = MNG_NULL;
509   pData->fDeltaputrow          = MNG_NULL;
510 
511   pData->fPromoterow           = MNG_NULL;
512   pData->fPromBitdepth         = MNG_NULL;
513   pData->pPromBuf              = MNG_NULL;
514   pData->iPromColortype        = 0;
515   pData->iPromBitdepth         = 0;
516   pData->iPromFilltype         = 0;
517   pData->iPromWidth            = 0;
518   pData->pPromSrc              = MNG_NULL;
519   pData->pPromDst              = MNG_NULL;
520 #endif
521 
522 #ifndef MNG_SKIPCHUNK_MAGN
523   pData->iMAGNfromid           = 0;
524   pData->iMAGNtoid             = 0;
525 #endif
526 
527 #ifndef MNG_SKIPCHUNK_PAST
528   pData->iPastx                = 0;
529   pData->iPasty                = 0;
530 #endif
531 
532   pData->pLastseek             = MNG_NULL;
533 
534   return MNG_NOERROR;
535 }
536 #endif /* MNG_SUPPORT_DISPLAY */
537 
538 /* ************************************************************************** */
539 
cleanup_errors(mng_datap pData)540 MNG_LOCAL void cleanup_errors (mng_datap pData)
541 {
542   pData->iErrorcode = MNG_NOERROR;
543   pData->iSeverity  = 0;
544   pData->iErrorx1   = 0;
545   pData->iErrorx2   = 0;
546   pData->zErrortext = MNG_NULL;
547 
548   return;
549 }
550 
551 /* ************************************************************************** */
552 
553 #ifdef MNG_SUPPORT_READ
make_pushbuffer(mng_datap pData,mng_ptr pPushdata,mng_size_t iLength,mng_bool bTakeownership,mng_pushdatap * pPush)554 MNG_LOCAL mng_retcode make_pushbuffer (mng_datap       pData,
555                                        mng_ptr         pPushdata,
556                                        mng_size_t      iLength,
557                                        mng_bool        bTakeownership,
558                                        mng_pushdatap * pPush)
559 {
560   mng_pushdatap pTemp;
561 
562   MNG_ALLOC (pData, pTemp, sizeof(mng_pushdata));
563 
564   pTemp->pNext      = MNG_NULL;
565 
566   if (bTakeownership)                  /* are we going to own the buffer? */
567   {                                    /* then just copy the pointer */
568     pTemp->pData    = (mng_uint8p)pPushdata;
569   }
570   else
571   {                                    /* otherwise create new buffer */
572     MNG_ALLOCX (pData, pTemp->pData, iLength);
573     if (!pTemp->pData)                 /* succeeded? */
574     {
575       MNG_FREEX (pData, pTemp, sizeof(mng_pushdata));
576       MNG_ERROR (pData, MNG_OUTOFMEMORY);
577     }
578                                        /* and copy the bytes across */
579     MNG_COPY (pTemp->pData, pPushdata, iLength);
580   }
581 
582   pTemp->iLength    = iLength;
583   pTemp->bOwned     = bTakeownership;
584   pTemp->pDatanext  = pTemp->pData;
585   pTemp->iRemaining = iLength;
586 
587   *pPush            = pTemp;           /* return it */
588 
589   return MNG_NOERROR;                  /* and all's well */
590 }
591 #endif
592 
593 #ifdef MNG_VERSION_QUERY_SUPPORT
594 /* ************************************************************************** */
595 /* *                                                                        * */
596 /* *  Versioning control                                                    * */
597 /* *                                                                        * */
598 /* ************************************************************************** */
599 
mng_version_text(void)600 mng_pchar MNG_DECL mng_version_text    (void)
601 {
602   return MNG_VERSION_TEXT;
603 }
604 
605 /* ************************************************************************** */
606 
mng_version_so(void)607 mng_uint8 MNG_DECL mng_version_so      (void)
608 {
609   return MNG_VERSION_SO;
610 }
611 
612 /* ************************************************************************** */
613 
mng_version_dll(void)614 mng_uint8 MNG_DECL mng_version_dll     (void)
615 {
616   return MNG_VERSION_DLL;
617 }
618 
619 /* ************************************************************************** */
620 
mng_version_major(void)621 mng_uint8 MNG_DECL mng_version_major   (void)
622 {
623   return MNG_VERSION_MAJOR;
624 }
625 
626 /* ************************************************************************** */
627 
mng_version_minor(void)628 mng_uint8 MNG_DECL mng_version_minor   (void)
629 {
630   return MNG_VERSION_MINOR;
631 }
632 
633 /* ************************************************************************** */
634 
mng_version_release(void)635 mng_uint8 MNG_DECL mng_version_release (void)
636 {
637   return MNG_VERSION_RELEASE;
638 }
639 
640 /* ************************************************************************** */
641 
mng_version_beta(void)642 mng_bool MNG_DECL mng_version_beta (void)
643 {
644   return MNG_VERSION_BETA;
645 }
646 #endif
647 
648 /* ************************************************************************** */
649 /* *                                                                        * */
650 /* * 'supports' function                                                    * */
651 /* *                                                                        * */
652 /* ************************************************************************** */
653 
654 #ifdef MNG_SUPPORT_FUNCQUERY
655 typedef struct {
656                  mng_pchar  zFunction;
657                  mng_uint8  iMajor;    /* Major == 0 means not implemented ! */
658                  mng_uint8  iMinor;
659                  mng_uint8  iRelease;
660                } mng_func_entry;
661 typedef mng_func_entry const * mng_func_entryp;
662 
663 MNG_LOCAL mng_func_entry const func_table [] =
664   {                                    /* keep it alphabetically sorted !!!!! */
665     {"mng_cleanup",                1, 0, 0},
666     {"mng_copy_chunk",             1, 0, 5},
667     {"mng_create",                 1, 0, 0},
668     {"mng_display",                1, 0, 0},
669     {"mng_display_freeze",         1, 0, 0},
670 #ifndef MNG_NO_DISPLAY_GO_SUPPORTED
671     {"mng_display_goframe",        1, 0, 0},
672     {"mng_display_golayer",        1, 0, 0},
673     {"mng_display_gotime",         1, 0, 0},
674 #endif
675     {"mng_display_reset",          1, 0, 0},
676     {"mng_display_resume",         1, 0, 0},
677     {"mng_get_alphabitdepth",      1, 0, 0},
678     {"mng_get_alphacompression",   1, 0, 0},
679     {"mng_get_alphadepth",         1, 0, 0},
680     {"mng_get_alphafilter",        1, 0, 0},
681     {"mng_get_alphainterlace",     1, 0, 0},
682     {"mng_get_bgcolor",            1, 0, 0},
683     {"mng_get_bitdepth",           1, 0, 0},
684     {"mng_get_bkgdstyle",          1, 0, 0},
685     {"mng_get_cacheplayback",      1, 0, 2},
686     {"mng_get_canvasstyle",        1, 0, 0},
687     {"mng_get_colortype",          1, 0, 0},
688     {"mng_get_compression",        1, 0, 0},
689 #ifndef MNG_NO_CURRENT_INFO
690     {"mng_get_currentframe",       1, 0, 0},
691     {"mng_get_currentlayer",       1, 0, 0},
692     {"mng_get_currentplaytime",    1, 0, 0},
693 #endif
694     {"mng_get_currframdelay",      1, 0, 9},
695 #ifndef MNG_NO_DFLT_INFO
696     {"mng_get_dfltimggamma",       1, 0, 0},
697     {"mng_get_dfltimggammaint",    1, 0, 0},
698 #endif
699     {"mng_get_displaygamma",       1, 0, 0},
700     {"mng_get_displaygammaint",    1, 0, 0},
701     {"mng_get_doprogressive",      1, 0, 2},
702     {"mng_get_filter",             1, 0, 0},
703     {"mng_get_framecount",         1, 0, 0},
704     {"mng_get_imageheight",        1, 0, 0},
705     {"mng_get_imagelevel",         1, 0, 0},
706     {"mng_get_imagetype",          1, 0, 0},
707     {"mng_get_imagewidth",         1, 0, 0},
708     {"mng_get_interlace",          1, 0, 0},
709 #ifdef MNG_ACCESS_JPEG
710     {"mng_get_jpeg_dctmethod",     1, 0, 0},
711     {"mng_get_jpeg_maxjdat",       1, 0, 0},
712     {"mng_get_jpeg_optimized",     1, 0, 0},
713     {"mng_get_jpeg_progressive",   1, 0, 0},
714     {"mng_get_jpeg_quality",       1, 0, 0},
715     {"mng_get_jpeg_smoothing",     1, 0, 0},
716 #endif
717     {"mng_get_lastbackchunk",      1, 0, 3},
718     {"mng_get_lastseekname",       1, 0, 5},
719     {"mng_get_layercount",         1, 0, 0},
720 #ifndef MNG_SKIP_MAXCANVAS
721     {"mng_get_maxcanvasheight",    1, 0, 0},
722     {"mng_get_maxcanvaswidth",     1, 0, 0},
723 #endif
724     {"mng_get_playtime",           1, 0, 0},
725     {"mng_get_refreshpass",        1, 0, 0},
726     {"mng_get_runtime",            1, 0, 0},
727     {"mng_get_sectionbreaks",      1, 0, 0},
728     {"mng_get_sigtype",            1, 0, 0},
729     {"mng_get_simplicity",         1, 0, 0},
730     {"mng_get_speed",              1, 0, 0},
731     {"mng_get_srgb",               1, 0, 0},
732     {"mng_get_starttime",          1, 0, 0},
733     {"mng_get_storechunks",        1, 0, 0},
734     {"mng_get_suspensionmode",     1, 0, 0},
735     {"mng_get_ticks",              1, 0, 0},
736 #ifndef MNG_NO_CURRENT_INFO
737     {"mng_get_totalframes",        1, 0, 5},
738     {"mng_get_totallayers",        1, 0, 5},
739     {"mng_get_totalplaytime",      1, 0, 5},
740 #endif
741     {"mng_get_usebkgd",            1, 0, 0},
742     {"mng_get_userdata",           1, 0, 0},
743 #if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
744     {"mng_get_viewgamma",          1, 0, 0},
745     {"mng_get_viewgammaint",       1, 0, 0},
746 #endif
747 #ifdef MNG_ACCESS_ZLIB
748     {"mng_get_zlib_level",         1, 0, 0},
749     {"mng_get_zlib_maxidat",       1, 0, 0},
750     {"mng_get_zlib_memlevel",      1, 0, 0},
751     {"mng_get_zlib_method",        1, 0, 0},
752     {"mng_get_zlib_strategy",      1, 0, 0},
753     {"mng_get_zlib_windowbits",    1, 0, 0},
754 #endif
755 #ifndef MNG_NO_OPEN_CLOSE_STREAM
756     {"mng_getcb_closestream",      1, 0, 0},
757 #endif
758     {"mng_getcb_errorproc",        1, 0, 0},
759     {"mng_getcb_getalphaline",     1, 0, 0},
760     {"mng_getcb_getbkgdline",      1, 0, 0},
761     {"mng_getcb_getcanvasline",    1, 0, 0},
762     {"mng_getcb_gettickcount",     1, 0, 0},
763     {"mng_getcb_memalloc",         1, 0, 0},
764     {"mng_getcb_memfree",          1, 0, 0},
765 #ifndef MNG_NO_OPEN_CLOSE_STREAM
766     {"mng_getcb_openstream",       1, 0, 0},
767 #endif
768     {"mng_getcb_processarow",      1, 0, 0},
769     {"mng_getcb_processchroma",    1, 0, 0},
770     {"mng_getcb_processgamma",     1, 0, 0},
771     {"mng_getcb_processheader",    1, 0, 0},
772     {"mng_getcb_processiccp",      1, 0, 0},
773     {"mng_getcb_processmend",      1, 0, 1},
774     {"mng_getcb_processneed",      1, 0, 0},
775     {"mng_getcb_processsave",      1, 0, 0},
776     {"mng_getcb_processseek",      1, 0, 0},
777     {"mng_getcb_processsrgb",      1, 0, 0},
778     {"mng_getcb_processterm",      1, 0, 2},
779     {"mng_getcb_processtext",      1, 0, 0},
780     {"mng_getcb_processunknown",   1, 0, 0},
781     {"mng_getcb_readdata",         1, 0, 0},
782     {"mng_getcb_refresh",          1, 0, 0},
783     {"mng_getcb_releasedata",      1, 0, 8},
784     {"mng_getcb_settimer",         1, 0, 0},
785     {"mng_getcb_traceproc",        1, 0, 0},
786     {"mng_getcb_writedata",        1, 0, 0},
787     {"mng_getchunk_back",          1, 0, 0},
788     {"mng_getchunk_basi",          1, 0, 0},
789 #ifndef MNG_SKIPCHUNK_bKGD
790     {"mng_getchunk_bkgd",          1, 0, 0},
791 #endif
792 #ifndef MNG_SKIPCHUNK_cHRM
793     {"mng_getchunk_chrm",          1, 0, 0},
794 #endif
795     {"mng_getchunk_clip",          1, 0, 0},
796     {"mng_getchunk_clon",          1, 0, 0},
797 #ifndef MNG_NO_DELTA_PNG
798 #ifndef MNG_SKIPCHUNK_dBYK
799     {"mng_getchunk_dbyk",          1, 0, 0},
800 #endif
801 #endif
802     {"mng_getchunk_defi",          1, 0, 0},
803 #ifndef MNG_NO_DELTA_PNG
804     {"mng_getchunk_dhdr",          1, 0, 0},
805 #endif
806     {"mng_getchunk_disc",          1, 0, 0},
807 #ifndef MNG_NO_DELTA_PNG
808     {"mng_getchunk_drop",          1, 0, 0},
809 #endif
810     {"mng_getchunk_endl",          1, 0, 0},
811 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
812     {"mng_getchunk_mpng",          1, 0, 10},
813     {"mng_getchunk_mpng_frame",    1, 0, 10},
814 #endif
815 #ifndef MNG_SKIPCHUNK_evNT
816     {"mng_getchunk_evnt",          1, 0, 5},
817     {"mng_getchunk_evnt_entry",    1, 0, 5},
818 #endif
819 #ifndef MNG_SKIPCHUNK_eXPI
820     {"mng_getchunk_expi",          1, 0, 0},
821 #endif
822 #ifndef MNG_SKIPCHUNK_fPRI
823     {"mng_getchunk_fpri",          1, 0, 0},
824 #endif
825     {"mng_getchunk_fram",          1, 0, 0},
826     {"mng_getchunk_gama",          1, 0, 0},
827 #ifndef MNG_SKIPCHUNK_hIST
828     {"mng_getchunk_hist",          1, 0, 0},
829 #endif
830 #ifndef MNG_SKIPCHUNK_iCCP
831     {"mng_getchunk_iccp",          1, 0, 0},
832 #endif
833     {"mng_getchunk_idat",          1, 0, 0},
834     {"mng_getchunk_iend",          1, 0, 0},
835     {"mng_getchunk_ihdr",          1, 0, 0},
836 #ifndef MNG_NO_DELTA_PNG
837 #ifdef MNG_INCLUDE_JNG
838     {"mng_getchunk_ijng",          1, 0, 0},
839 #endif
840     {"mng_getchunk_ipng",          1, 0, 0},
841 #endif
842 #ifndef MNG_SKIPCHUNK_iTXt
843     {"mng_getchunk_itxt",          1, 0, 0},
844 #endif
845 #ifdef MNG_INCLUDE_JNG
846     {"mng_getchunk_jdaa",          1, 0, 0},
847     {"mng_getchunk_jdat",          1, 0, 0},
848     {"mng_getchunk_jhdr",          1, 0, 0},
849     {"mng_getchunk_jsep",          1, 0, 0},
850 #endif
851     {"mng_getchunk_loop",          1, 0, 0},
852 #ifndef MNG_SKIPCHUNK_MAGN
853     {"mng_getchunk_magn",          1, 0, 0},
854 #endif
855     {"mng_getchunk_mend",          1, 0, 0},
856     {"mng_getchunk_mhdr",          1, 0, 0},
857     {"mng_getchunk_move",          1, 0, 0},
858 #ifndef MNG_SKIPCHUNK_nEED
859     {"mng_getchunk_need",          1, 0, 0},
860 #endif
861 #ifndef MNG_SKIPCHUNK_ORDR
862 #ifndef MNG_NO_DELTA_PNG
863     {"mng_getchunk_ordr",          1, 0, 0},
864     {"mng_getchunk_ordr_entry",    1, 0, 0},
865 #endif
866 #endif
867 #ifndef MNG_SKIPCHUNK_PAST
868     {"mng_getchunk_past",          1, 0, 0},
869     {"mng_getchunk_past_src",      1, 0, 0},
870 #endif
871 #ifndef MNG_SKIPCHUNK_pHYg
872     {"mng_getchunk_phyg",          1, 0, 0},
873 #endif
874 #ifndef MNG_SKIPCHUNK_pHYs
875     {"mng_getchunk_phys",          1, 0, 0},
876 #endif
877 #ifndef MNG_NO_DELTA_PNG
878     {"mng_getchunk_plte",          1, 0, 0},
879     {"mng_getchunk_pplt",          1, 0, 0},
880     {"mng_getchunk_pplt_entry",    1, 0, 0},
881     {"mng_getchunk_prom",          1, 0, 0},
882 #endif
883 #ifndef MNG_SKIPCHUNK_SAVE
884     {"mng_getchunk_save",          1, 0, 0},
885     {"mng_getchunk_save_entry",    1, 0, 0},
886 #endif
887 #ifndef MNG_SKIPCHUNK_sBIT
888     {"mng_getchunk_sbit",          1, 0, 0},
889 #endif
890 #ifndef MNG_SKIPCHUNK_SEEK
891     {"mng_getchunk_seek",          1, 0, 0},
892 #endif
893     {"mng_getchunk_show",          1, 0, 0},
894 #ifndef MNG_SKIPCHUNK_sPLT
895     {"mng_getchunk_splt",          1, 0, 0},
896 #endif
897 #ifndef MNG_SKIPCHUNK_sRGB
898     {"mng_getchunk_srgb",          1, 0, 0},
899 #endif
900     {"mng_getchunk_term",          1, 0, 0},
901 #ifndef MNG_SKIPCHUNK_tEXt
902     {"mng_getchunk_text",          1, 0, 0},
903 #endif
904 #ifndef MNG_SKIPCHUNK_tIME
905     {"mng_getchunk_time",          1, 0, 0},
906 #endif
907     {"mng_getchunk_trns",          1, 0, 0},
908     {"mng_getchunk_unkown",        1, 0, 0},
909 #ifndef MNG_SKIPCHUNK_zTXt
910     {"mng_getchunk_ztxt",          1, 0, 0},
911 #endif
912     {"mng_getimgdata_chunk",       0, 0, 0},
913     {"mng_getimgdata_chunkseq",    0, 0, 0},
914     {"mng_getimgdata_seq",         0, 0, 0},
915     {"mng_getlasterror",           1, 0, 0},
916     {"mng_initialize",             1, 0, 0},
917     {"mng_iterate_chunks",         1, 0, 0},
918     {"mng_putchunk_back",          1, 0, 0},
919 #ifndef MNG_SKIPCHUNK_BASI
920     {"mng_putchunk_basi",          1, 0, 0},
921 #endif
922 #ifndef MNG_SKIPCHUNK_bKGD
923     {"mng_putchunk_bkgd",          1, 0, 0},
924 #endif
925 #ifndef MNG_SKIPCHUNK_cHRM
926     {"mng_putchunk_chrm",          1, 0, 0},
927 #endif
928     {"mng_putchunk_clip",          1, 0, 0},
929     {"mng_putchunk_clon",          1, 0, 0},
930 #ifndef MNG_NO_DELTA_PNG
931 #ifndef MNG_SKIPCHUNK_DBYK
932     {"mng_putchunk_dbyk",          1, 0, 0},
933 #endif
934 #endif
935     {"mng_putchunk_defi",          1, 0, 0},
936 #ifndef MNG_NO_DELTA_PNG
937     {"mng_putchunk_dhdr",          1, 0, 0},
938 #endif
939     {"mng_putchunk_disc",          1, 0, 0},
940 #ifndef MNG_NO_DELTA_PNG
941     {"mng_putchunk_drop",          1, 0, 0},
942 #endif
943     {"mng_putchunk_endl",          1, 0, 0},
944 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
945     {"mng_putchunk_mpng",          1, 0, 10},
946     {"mng_putchunk_mpng_frame",    1, 0, 10},
947 #endif
948 #ifndef MNG_SKIPCHUNK_evNT
949     {"mng_putchunk_evnt",          1, 0, 5},
950     {"mng_putchunk_evnt_entry",    1, 0, 5},
951 #endif
952 #ifndef MNG_SKIPCHUNK_eXPI
953     {"mng_putchunk_expi",          1, 0, 0},
954 #endif
955 #ifndef MNG_SKIPCHUNK_fPRI
956     {"mng_putchunk_fpri",          1, 0, 0},
957 #endif
958 #ifndef MNG_SKIPCHUNK_FRAM
959     {"mng_putchunk_fram",          1, 0, 0},
960 #endif
961     {"mng_putchunk_gama",          1, 0, 0},
962 #ifndef MNG_SKIPCHUNK_hIST
963     {"mng_putchunk_hist",          1, 0, 0},
964 #endif
965 #ifndef MNG_SKIPCHUNK_iCCP
966     {"mng_putchunk_iccp",          1, 0, 0},
967 #endif
968     {"mng_putchunk_idat",          1, 0, 0},
969     {"mng_putchunk_iend",          1, 0, 0},
970     {"mng_putchunk_ihdr",          1, 0, 0},
971 #ifndef MNG_NO_DELTA_PNG
972 #ifdef MNG_INCLUDE_JNG
973     {"mng_putchunk_ijng",          1, 0, 0},
974 #endif
975     {"mng_putchunk_ipng",          1, 0, 0},
976 #endif
977 #ifndef MNG_SKIPCHUNK_iTXt
978     {"mng_putchunk_itxt",          1, 0, 0},
979 #endif
980 #ifdef MNG_INCLUDE_JNG
981     {"mng_putchunk_jdaa",          1, 0, 0},
982     {"mng_putchunk_jdat",          1, 0, 0},
983     {"mng_putchunk_jhdr",          1, 0, 0},
984     {"mng_putchunk_jsep",          1, 0, 0},
985 #endif
986     {"mng_putchunk_loop",          1, 0, 0},
987 #ifndef MNG_SKIPCHUNK_MAGN
988     {"mng_putchunk_magn",          1, 0, 0},
989 #endif
990     {"mng_putchunk_mend",          1, 0, 0},
991     {"mng_putchunk_mhdr",          1, 0, 0},
992     {"mng_putchunk_move",          1, 0, 0},
993 #ifndef MNG_SKIPCHUNK_nEED
994     {"mng_putchunk_need",          1, 0, 0},
995 #endif
996 #ifndef MNG_NO_DELTA_PNG
997 #ifndef MNG_SKIPCHUNK_ORDR
998     {"mng_putchunk_ordr",          1, 0, 0},
999     {"mng_putchunk_ordr_entry",    1, 0, 0},
1000 #endif
1001 #endif
1002 #ifndef MNG_SKIPCHUNK_PAST
1003     {"mng_putchunk_past",          1, 0, 0},
1004     {"mng_putchunk_past_src",      1, 0, 0},
1005 #endif
1006 #ifndef MNG_SKIPCHUNK_pHYg
1007     {"mng_putchunk_phyg",          1, 0, 0},
1008 #endif
1009 #ifndef MNG_SKIPCHUNK_pHYs
1010     {"mng_putchunk_phys",          1, 0, 0},
1011 #endif
1012 #ifndef MNG_NO_DELTA_PNG
1013     {"mng_putchunk_plte",          1, 0, 0},
1014     {"mng_putchunk_pplt",          1, 0, 0},
1015     {"mng_putchunk_pplt_entry",    1, 0, 0},
1016     {"mng_putchunk_prom",          1, 0, 0},
1017 #endif
1018 #ifndef MNG_SKIPCHUNK_SAVE
1019     {"mng_putchunk_save",          1, 0, 0},
1020     {"mng_putchunk_save_entry",    1, 0, 0},
1021 #endif
1022 #ifndef MNG_SKIPCHUNK_sBIT
1023     {"mng_putchunk_sbit",          1, 0, 0},
1024 #endif
1025 #ifndef MNG_SKIPCHUNK_SEEK
1026     {"mng_putchunk_seek",          1, 0, 0},
1027 #endif
1028     {"mng_putchunk_show",          1, 0, 0},
1029 #ifndef MNG_SKIPCHUNK_sPLT
1030     {"mng_putchunk_splt",          1, 0, 0},
1031 #endif
1032 #ifndef MNG_SKIPCHUNK_sRGB
1033     {"mng_putchunk_srgb",          1, 0, 0},
1034 #endif
1035     {"mng_putchunk_term",          1, 0, 0},
1036 #ifndef MNG_SKIPCHUNK_tEXt
1037     {"mng_putchunk_text",          1, 0, 0},
1038 #endif
1039 #ifndef MNG_SKIPCHUNK_tIME
1040     {"mng_putchunk_time",          1, 0, 0},
1041 #endif
1042     {"mng_putchunk_trns",          1, 0, 0},
1043     {"mng_putchunk_unkown",        1, 0, 0},
1044 #ifndef MNG_SKIPCHUNK_zTXt
1045     {"mng_putchunk_ztxt",          1, 0, 0},
1046 #endif
1047     {"mng_putimgdata_ihdr",        0, 0, 0},
1048     {"mng_putimgdata_jhdr",        0, 0, 0},
1049     {"mng_reset",                  1, 0, 0},
1050     {"mng_read",                   1, 0, 0},
1051     {"mng_read_pushchunk",         1, 0, 8},
1052     {"mng_read_pushdata",          1, 0, 8},
1053     {"mng_read_pushsig",           1, 0, 8},
1054     {"mng_read_resume",            1, 0, 0},
1055     {"mng_readdisplay",            1, 0, 0},
1056     {"mng_set_bgcolor",            1, 0, 0},
1057     {"mng_set_bkgdstyle",          1, 0, 0},
1058     {"mng_set_cacheplayback",      1, 0, 2},
1059     {"mng_set_canvasstyle",        1, 0, 0},
1060     {"mng_set_dfltimggamma",       1, 0, 0},
1061 #ifndef MNG_NO_DFLT_INFO
1062     {"mng_set_dfltimggammaint",    1, 0, 0},
1063 #endif
1064     {"mng_set_displaygamma",       1, 0, 0},
1065     {"mng_set_displaygammaint",    1, 0, 0},
1066     {"mng_set_doprogressive",      1, 0, 2},
1067 #ifdef MNG_ACCESS_JPEG
1068     {"mng_set_jpeg_dctmethod",     1, 0, 0},
1069     {"mng_set_jpeg_maxjdat",       1, 0, 0},
1070     {"mng_set_jpeg_optimized",     1, 0, 0},
1071     {"mng_set_jpeg_progressive",   1, 0, 0},
1072     {"mng_set_jpeg_quality",       1, 0, 0},
1073     {"mng_set_jpeg_smoothing",     1, 0, 0},
1074 #endif
1075 #ifndef MNG_SKIP_MAXCANVAS
1076     {"mng_set_maxcanvasheight",    1, 0, 0},
1077     {"mng_set_maxcanvassize",      1, 0, 0},
1078     {"mng_set_maxcanvaswidth",     1, 0, 0},
1079 #endif
1080     {"mng_set_outputprofile",      1, 0, 0},
1081     {"mng_set_outputprofile2",     1, 0, 0},
1082     {"mng_set_outputsrgb",         1, 0, 1},
1083     {"mng_set_sectionbreaks",      1, 0, 0},
1084     {"mng_set_speed",              1, 0, 0},
1085     {"mng_set_srgb",               1, 0, 0},
1086     {"mng_set_srgbimplicit",       1, 0, 1},
1087     {"mng_set_srgbprofile",        1, 0, 0},
1088     {"mng_set_srgbprofile2",       1, 0, 0},
1089     {"mng_set_storechunks",        1, 0, 0},
1090     {"mng_set_suspensionmode",     1, 0, 0},
1091     {"mng_set_usebkgd",            1, 0, 0},
1092     {"mng_set_userdata",           1, 0, 0},
1093 #if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY) || defined(MNG_APP_CMS)
1094     {"mng_set_viewgamma",          1, 0, 0},
1095     {"mng_set_viewgammaint",       1, 0, 0},
1096 #endif
1097 #ifdef MNG_ACCESS_ZLIB
1098     {"mng_set_zlib_level",         1, 0, 0},
1099     {"mng_set_zlib_maxidat",       1, 0, 0},
1100     {"mng_set_zlib_memlevel",      1, 0, 0},
1101     {"mng_set_zlib_method",        1, 0, 0},
1102     {"mng_set_zlib_strategy",      1, 0, 0},
1103     {"mng_set_zlib_windowbits",    1, 0, 0},
1104 #endif
1105 #ifndef MNG_NO_OPEN_CLOSE_STREAM
1106     {"mng_setcb_closestream",      1, 0, 0},
1107 #endif
1108     {"mng_setcb_errorproc",        1, 0, 0},
1109     {"mng_setcb_getalphaline",     1, 0, 0},
1110     {"mng_setcb_getbkgdline",      1, 0, 0},
1111     {"mng_setcb_getcanvasline",    1, 0, 0},
1112     {"mng_setcb_gettickcount",     1, 0, 0},
1113     {"mng_setcb_memalloc",         1, 0, 0},
1114     {"mng_setcb_memfree",          1, 0, 0},
1115 #ifndef MNG_NO_OPEN_CLOSE_STREAM
1116     {"mng_setcb_openstream",       1, 0, 0},
1117 #endif
1118     {"mng_setcb_processarow",      1, 0, 0},
1119     {"mng_setcb_processchroma",    1, 0, 0},
1120     {"mng_setcb_processgamma",     1, 0, 0},
1121     {"mng_setcb_processheader",    1, 0, 0},
1122     {"mng_setcb_processiccp",      1, 0, 0},
1123     {"mng_setcb_processmend",      1, 0, 1},
1124     {"mng_setcb_processneed",      1, 0, 0},
1125     {"mng_setcb_processsave",      1, 0, 0},
1126     {"mng_setcb_processseek",      1, 0, 0},
1127     {"mng_setcb_processsrgb",      1, 0, 0},
1128     {"mng_setcb_processterm",      1, 0, 2},
1129     {"mng_setcb_processtext",      1, 0, 0},
1130     {"mng_setcb_processunknown",   1, 0, 0},
1131     {"mng_setcb_readdata",         1, 0, 0},
1132     {"mng_setcb_refresh",          1, 0, 0},
1133     {"mng_setcb_releasedata",      1, 0, 8},
1134     {"mng_setcb_settimer",         1, 0, 0},
1135     {"mng_setcb_traceproc",        1, 0, 0},
1136     {"mng_setcb_writedata",        1, 0, 0},
1137     {"mng_status_creating",        1, 0, 0},
1138     {"mng_status_displaying",      1, 0, 0},
1139     {"mng_status_dynamic",         1, 0, 5},
1140     {"mng_status_error",           1, 0, 0},
1141     {"mng_status_reading",         1, 0, 0},
1142     {"mng_status_running",         1, 0, 0},
1143     {"mng_status_runningevent",    1, 0, 5},
1144     {"mng_status_suspendbreak",    1, 0, 0},
1145     {"mng_status_timerbreak",      1, 0, 0},
1146     {"mng_status_writing",         1, 0, 0},
1147     {"mng_supports_func",          1, 0, 5},
1148     {"mng_trapevent",              1, 0, 5},
1149     {"mng_updatemngheader",        1, 0, 0},
1150     {"mng_updatemngsimplicity",    1, 0, 0},
1151     {"mng_version_beta",           1, 0, 5},
1152     {"mng_version_dll",            1, 0, 0},
1153     {"mng_version_major",          1, 0, 0},
1154     {"mng_version_minor",          1, 0, 0},
1155     {"mng_version_release",        1, 0, 0},
1156     {"mng_version_so",             1, 0, 0},
1157     {"mng_version_text",           1, 0, 0},
1158     {"mng_write",                  1, 0, 0},
1159   };
1160 
mng_supports_func(mng_pchar zFunction,mng_uint8 * iMajor,mng_uint8 * iMinor,mng_uint8 * iRelease)1161 mng_bool MNG_DECL mng_supports_func (mng_pchar  zFunction,
1162                                      mng_uint8* iMajor,
1163                                      mng_uint8* iMinor,
1164                                      mng_uint8* iRelease)
1165 {
1166   mng_int32       iTop, iLower, iUpper, iMiddle;
1167   mng_func_entryp pEntry;          /* pointer to found entry */
1168                                    /* determine max index of table */
1169   iTop = (sizeof (func_table) / sizeof (func_table [0])) - 1;
1170 
1171   iLower  = 0;                     /* initialize binary search */
1172   iMiddle = iTop >> 1;             /* start in the middle */
1173   iUpper  = iTop;
1174   pEntry  = 0;                     /* no goods yet! */
1175 
1176   do                               /* the binary search itself */
1177     {
1178       mng_int32 iRslt = strcmp(func_table [iMiddle].zFunction, zFunction);
1179       if (iRslt < 0)
1180         iLower = iMiddle + 1;
1181       else if (iRslt > 0)
1182         iUpper = iMiddle - 1;
1183       else
1184       {
1185         pEntry = &func_table [iMiddle];
1186         break;
1187       };
1188 
1189       iMiddle = (iLower + iUpper) >> 1;
1190     }
1191   while (iLower <= iUpper);
1192 
1193   if (pEntry)                      /* found it ? */
1194   {
1195     *iMajor   = pEntry->iMajor;
1196     *iMinor   = pEntry->iMinor;
1197     *iRelease = pEntry->iRelease;
1198     return MNG_TRUE;
1199   }
1200   else
1201   {
1202     *iMajor   = 0;
1203     *iMinor   = 0;
1204     *iRelease = 0;
1205     return MNG_FALSE;
1206   }
1207 }
1208 #endif
1209 
1210 /* ************************************************************************** */
1211 /* *                                                                        * */
1212 /* * HLAPI routines                                                         * */
1213 /* *                                                                        * */
1214 /* ************************************************************************** */
1215 
mng_initialize(mng_ptr pUserdata,mng_memalloc fMemalloc,mng_memfree fMemfree,mng_traceproc fTraceproc)1216 mng_handle MNG_DECL mng_initialize (mng_ptr       pUserdata,
1217                                     mng_memalloc  fMemalloc,
1218                                     mng_memfree   fMemfree,
1219                                     mng_traceproc fTraceproc)
1220 {
1221   mng_datap   pData;
1222 #ifdef MNG_SUPPORT_DISPLAY
1223   mng_retcode iRetcode;
1224   mng_imagep  pImage;
1225 #endif
1226 
1227 #ifdef MNG_INTERNAL_MEMMNGMT           /* allocate the main datastruc */
1228   pData = (mng_datap)calloc (1, sizeof (mng_data));
1229 #else
1230   pData = (mng_datap)fMemalloc (sizeof (mng_data));
1231 #endif
1232 
1233   if (!pData)
1234     return MNG_NULL;                   /* error: out of memory?? */
1235                                        /* validate the structure */
1236   pData->iMagic                = MNG_MAGIC;
1237                                        /* save userdata field */
1238   pData->pUserdata             = pUserdata;
1239                                        /* remember trace callback */
1240   pData->fTraceproc            = fTraceproc;
1241 
1242 #ifdef MNG_SUPPORT_TRACE
1243   if (mng_trace (pData, MNG_FN_INITIALIZE, MNG_LC_INITIALIZE))
1244   {
1245     MNG_FREEX (pData, pData, sizeof (mng_data));
1246     return MNG_NULL;
1247   }
1248 #endif
1249                                        /* default canvas styles are 8-bit RGB */
1250   pData->iCanvasstyle          = MNG_CANVAS_RGB8;
1251   pData->iBkgdstyle            = MNG_CANVAS_RGB8;
1252 
1253   pData->iBGred                = 0;  /* black */
1254   pData->iBGgreen              = 0;
1255   pData->iBGblue               = 0;
1256 
1257   pData->bUseBKGD              = MNG_TRUE;
1258 
1259 #ifdef MNG_FULL_CMS
1260   pData->bIssRGB               = MNG_TRUE;
1261   pData->hProf1                = 0;    /* no profiles yet */
1262   pData->hProf2                = 0;
1263   pData->hProf3                = 0;
1264   pData->hTrans                = 0;
1265 #endif
1266 
1267   pData->dViewgamma            = 1.0;
1268   pData->dDisplaygamma         = 2.2;
1269   pData->dDfltimggamma         = 0.45455;
1270                                        /* initially remember chunks */
1271   pData->bStorechunks          = MNG_TRUE;
1272                                        /* no breaks at section-borders */
1273   pData->bSectionbreaks        = MNG_FALSE;
1274                                        /* initially cache playback info */
1275   pData->bCacheplayback        = MNG_TRUE;
1276                                        /* progressive refresh for large images */
1277   pData->bDoProgressive        = MNG_TRUE;
1278                                        /* crc exists; should check; error for
1279                                           critical chunks; warning for ancillery;
1280                                           generate crc for output */
1281   pData->iCrcmode              = MNG_CRC_DEFAULT;
1282                                        /* normal animation-speed ! */
1283   pData->iSpeed                = mng_st_normal;
1284                                        /* initial image limits */
1285   pData->iMaxwidth             = 10000;
1286   pData->iMaxheight            = 10000;
1287 
1288 #ifdef MNG_INTERNAL_MEMMNGMT           /* internal management */
1289   pData->fMemalloc             = MNG_NULL;
1290   pData->fMemfree              = MNG_NULL;
1291 #else                                  /* keep callbacks */
1292   pData->fMemalloc             = fMemalloc;
1293   pData->fMemfree              = fMemfree;
1294 #endif
1295                                        /* no value (yet) */
1296   pData->fReleasedata          = MNG_NULL;
1297 #ifndef MNG_NO_OPEN_CLOSE_STREAM
1298   pData->fOpenstream           = MNG_NULL;
1299   pData->fClosestream          = MNG_NULL;
1300 #endif
1301   pData->fReaddata             = MNG_NULL;
1302   pData->fWritedata            = MNG_NULL;
1303   pData->fErrorproc            = MNG_NULL;
1304   pData->fProcessheader        = MNG_NULL;
1305   pData->fProcesstext          = MNG_NULL;
1306   pData->fProcesssave          = MNG_NULL;
1307   pData->fProcessseek          = MNG_NULL;
1308   pData->fProcessneed          = MNG_NULL;
1309   pData->fProcessmend          = MNG_NULL;
1310   pData->fProcessunknown       = MNG_NULL;
1311   pData->fProcessterm          = MNG_NULL;
1312   pData->fGetcanvasline        = MNG_NULL;
1313   pData->fGetbkgdline          = MNG_NULL;
1314   pData->fGetalphaline         = MNG_NULL;
1315   pData->fRefresh              = MNG_NULL;
1316   pData->fGettickcount         = MNG_NULL;
1317   pData->fSettimer             = MNG_NULL;
1318   pData->fProcessgamma         = MNG_NULL;
1319   pData->fProcesschroma        = MNG_NULL;
1320   pData->fProcesssrgb          = MNG_NULL;
1321   pData->fProcessiccp          = MNG_NULL;
1322   pData->fProcessarow          = MNG_NULL;
1323 
1324 #if defined(MNG_SUPPORT_DISPLAY) && (defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS))
1325   pData->dLastgamma            = 0;    /* lookup table needs first-time calc */
1326 #endif
1327 
1328 #ifdef MNG_SUPPORT_DISPLAY             /* create object 0 */
1329   iRetcode = mng_create_imageobject (pData, 0, MNG_TRUE, MNG_TRUE, MNG_TRUE,
1330                                      0, 0, 0, 0, 0, 0, 0, 0, 0, MNG_FALSE,
1331                                      0, 0, 0, 0, &pImage);
1332 
1333   if (iRetcode)                        /* on error drop out */
1334   {
1335     MNG_FREEX (pData, pData, sizeof (mng_data));
1336     return MNG_NULL;
1337   }
1338 
1339   pData->pObjzero = pImage;
1340 #endif
1341 
1342 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_INCLUDE_LCMS)
1343   mnglcms_initlibrary ();              /* init lcms particulars */
1344 #endif
1345 
1346 #ifdef MNG_SUPPORT_READ
1347   pData->bSuspensionmode       = MNG_FALSE;
1348   pData->iSuspendbufsize       = 0;
1349   pData->pSuspendbuf           = MNG_NULL;
1350   pData->pSuspendbufnext       = MNG_NULL;
1351   pData->iSuspendbufleft       = 0;
1352   pData->iChunklen             = 0;
1353   pData->pReadbufnext          = MNG_NULL;
1354   pData->pLargebufnext         = MNG_NULL;
1355 
1356   pData->pFirstpushchunk       = MNG_NULL;
1357   pData->pLastpushchunk        = MNG_NULL;
1358   pData->pFirstpushdata        = MNG_NULL;
1359   pData->pLastpushdata         = MNG_NULL;
1360 #endif
1361 
1362 #ifdef MNG_INCLUDE_ZLIB
1363   mngzlib_initialize (pData);          /* initialize zlib structures and such */
1364                                        /* default zlib compression parameters */
1365   pData->iZlevel               = MNG_ZLIB_LEVEL;
1366   pData->iZmethod              = MNG_ZLIB_METHOD;
1367   pData->iZwindowbits          = MNG_ZLIB_WINDOWBITS;
1368   pData->iZmemlevel            = MNG_ZLIB_MEMLEVEL;
1369   pData->iZstrategy            = MNG_ZLIB_STRATEGY;
1370                                        /* default maximum IDAT data size */
1371   pData->iMaxIDAT              = MNG_MAX_IDAT_SIZE;
1372 #endif
1373 
1374 #ifdef MNG_INCLUDE_JNG                 /* default IJG compression parameters */
1375   pData->eJPEGdctmethod        = MNG_JPEG_DCT;
1376   pData->iJPEGquality          = MNG_JPEG_QUALITY;
1377   pData->iJPEGsmoothing        = MNG_JPEG_SMOOTHING;
1378   pData->bJPEGcompressprogr    = MNG_JPEG_PROGRESSIVE;
1379   pData->bJPEGcompressopt      = MNG_JPEG_OPTIMIZED;
1380                                        /* default maximum JDAT data size */
1381   pData->iMaxJDAT              = MNG_MAX_JDAT_SIZE;
1382 #endif
1383 
1384   mng_reset ((mng_handle)pData);
1385 
1386 #ifdef MNG_SUPPORT_TRACE
1387   if (mng_trace (pData, MNG_FN_INITIALIZE, MNG_LC_END))
1388   {
1389     MNG_FREEX (pData, pData, sizeof (mng_data));
1390     return MNG_NULL;
1391   }
1392 #endif
1393 
1394   return (mng_handle)pData;            /* if we get here, we're in business */
1395 }
1396 
1397 /* ************************************************************************** */
1398 
mng_reset(mng_handle hHandle)1399 mng_retcode MNG_DECL mng_reset (mng_handle hHandle)
1400 {
1401   mng_datap pData;
1402 
1403 #ifdef MNG_SUPPORT_TRACE
1404   MNG_TRACE (((mng_datap)hHandle), MNG_FN_RESET, MNG_LC_START);
1405 #endif
1406 
1407   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
1408   pData = ((mng_datap)(hHandle));      /* address main structure */
1409 
1410 #ifdef MNG_SUPPORT_DISPLAY
1411 #ifndef MNG_SKIPCHUNK_SAVE
1412   mng_drop_savedata (pData);           /* cleanup saved-data from SAVE/SEEK */
1413 #endif
1414 #endif
1415 
1416 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
1417   mng_clear_cms (pData);               /* cleanup left-over cms stuff if any */
1418 #endif
1419 
1420 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_INCLUDE_JNG)
1421   mngjpeg_cleanup (pData);             /* cleanup jpeg stuff */
1422 #endif
1423 
1424 #ifdef MNG_INCLUDE_ZLIB
1425   if (pData->bInflating)               /* if we've been inflating */
1426   {
1427 #ifdef MNG_INCLUDE_DISPLAY_PROCS
1428     mng_cleanup_rowproc (pData);       /* cleanup row-processing, */
1429 #endif
1430     mngzlib_inflatefree (pData);       /* cleanup inflate! */
1431   }
1432 #endif /* MNG_INCLUDE_ZLIB */
1433 
1434 #ifdef MNG_SUPPORT_READ
1435   if ((pData->bReading) && (!pData->bEOF))
1436     mng_process_eof (pData);           /* cleanup app streaming */
1437                                        /* cleanup default read buffers */
1438   MNG_FREE (pData, pData->pReadbuf,    pData->iReadbufsize);
1439   MNG_FREE (pData, pData->pLargebuf,   pData->iLargebufsize);
1440   MNG_FREE (pData, pData->pSuspendbuf, pData->iSuspendbufsize);
1441 
1442   while (pData->pFirstpushdata)        /* release any pushed data & chunks */
1443     mng_release_pushdata (pData);
1444   while (pData->pFirstpushchunk)
1445     mng_release_pushchunk (pData);
1446 #endif
1447 
1448 #ifdef MNG_SUPPORT_WRITE               /* cleanup default write buffer */
1449   MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize);
1450 #endif
1451 
1452 #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1453   mng_drop_chunks  (pData);            /* drop stored chunks (if any) */
1454 #endif
1455 
1456 #ifdef MNG_SUPPORT_DISPLAY
1457   mng_drop_objects (pData, MNG_TRUE);  /* drop stored objects (if any) */
1458 
1459 #ifndef MNG_SKIPCHUNK_iCCP
1460   if (pData->iGlobalProfilesize)       /* drop global profile (if any) */
1461     MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
1462 #endif
1463 #endif
1464 
1465   pData->eSigtype              = mng_it_unknown;
1466   pData->eImagetype            = mng_it_unknown;
1467   pData->iWidth                = 0;    /* these are unknown yet */
1468   pData->iHeight               = 0;
1469   pData->iTicks                = 0;
1470   pData->iLayercount           = 0;
1471   pData->iFramecount           = 0;
1472   pData->iPlaytime             = 0;
1473   pData->iSimplicity           = 0;
1474   pData->iAlphadepth           = 16;   /* assume the worst! */
1475 
1476   pData->iImagelevel           = 0;    /* no image encountered */
1477 
1478   pData->iMagnify              = 0;    /* 1-to-1 display */
1479   pData->iOffsetx              = 0;    /* no offsets */
1480   pData->iOffsety              = 0;
1481   pData->iCanvaswidth          = 0;    /* let the app decide during processheader */
1482   pData->iCanvasheight         = 0;
1483                                        /* so far, so good */
1484   pData->iErrorcode            = MNG_NOERROR;
1485   pData->iSeverity             = 0;
1486   pData->iErrorx1              = 0;
1487   pData->iErrorx2              = 0;
1488   pData->zErrortext            = MNG_NULL;
1489 
1490 #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1491                                        /* let's assume the best scenario */
1492 #ifndef MNG_NO_OLD_VERSIONS
1493   pData->bPreDraft48           = MNG_FALSE;
1494 #endif
1495                                        /* the unknown chunk */
1496   pData->iChunkname            = MNG_UINT_HUH;
1497   pData->iChunkseq             = 0;
1498   pData->pFirstchunk           = MNG_NULL;
1499   pData->pLastchunk            = MNG_NULL;
1500                                        /* nothing processed yet */
1501   pData->bHasheader            = MNG_FALSE;
1502   pData->bHasMHDR              = MNG_FALSE;
1503   pData->bHasIHDR              = MNG_FALSE;
1504   pData->bHasBASI              = MNG_FALSE;
1505   pData->bHasDHDR              = MNG_FALSE;
1506 #ifdef MNG_INCLUDE_JNG
1507   pData->bHasJHDR              = MNG_FALSE;
1508   pData->bHasJSEP              = MNG_FALSE;
1509   pData->bHasJDAA              = MNG_FALSE;
1510   pData->bHasJDAT              = MNG_FALSE;
1511 #endif
1512   pData->bHasPLTE              = MNG_FALSE;
1513   pData->bHasTRNS              = MNG_FALSE;
1514   pData->bHasGAMA              = MNG_FALSE;
1515   pData->bHasCHRM              = MNG_FALSE;
1516   pData->bHasSRGB              = MNG_FALSE;
1517   pData->bHasICCP              = MNG_FALSE;
1518   pData->bHasBKGD              = MNG_FALSE;
1519   pData->bHasIDAT              = MNG_FALSE;
1520 
1521   pData->bHasSAVE              = MNG_FALSE;
1522   pData->bHasBACK              = MNG_FALSE;
1523   pData->bHasFRAM              = MNG_FALSE;
1524   pData->bHasTERM              = MNG_FALSE;
1525   pData->bHasLOOP              = MNG_FALSE;
1526                                        /* there's no global stuff yet either */
1527   pData->bHasglobalPLTE        = MNG_FALSE;
1528   pData->bHasglobalTRNS        = MNG_FALSE;
1529   pData->bHasglobalGAMA        = MNG_FALSE;
1530   pData->bHasglobalCHRM        = MNG_FALSE;
1531   pData->bHasglobalSRGB        = MNG_FALSE;
1532   pData->bHasglobalICCP        = MNG_FALSE;
1533 
1534   pData->iDatawidth            = 0;    /* no IHDR/BASI/DHDR done yet */
1535   pData->iDataheight           = 0;
1536   pData->iBitdepth             = 0;
1537   pData->iColortype            = 0;
1538   pData->iCompression          = 0;
1539   pData->iFilter               = 0;
1540   pData->iInterlace            = 0;
1541 
1542 #ifdef MNG_INCLUDE_JNG
1543   pData->iJHDRcolortype        = 0;    /* no JHDR data */
1544   pData->iJHDRimgbitdepth      = 0;
1545   pData->iJHDRimgcompression   = 0;
1546   pData->iJHDRimginterlace     = 0;
1547   pData->iJHDRalphabitdepth    = 0;
1548   pData->iJHDRalphacompression = 0;
1549   pData->iJHDRalphafilter      = 0;
1550   pData->iJHDRalphainterlace   = 0;
1551 #endif
1552 
1553 #endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1554 
1555 #ifdef MNG_SUPPORT_READ                /* no reading done */
1556   pData->bReading              = MNG_FALSE;
1557   pData->bHavesig              = MNG_FALSE;
1558   pData->bEOF                  = MNG_FALSE;
1559   pData->iReadbufsize          = 0;
1560   pData->pReadbuf              = MNG_NULL;
1561 
1562   pData->iLargebufsize         = 0;
1563   pData->pLargebuf             = MNG_NULL;
1564 
1565   pData->iSuspendtime          = 0;
1566   pData->bSuspended            = MNG_FALSE;
1567   pData->iSuspendpoint         = 0;
1568 
1569   pData->pSuspendbufnext       = pData->pSuspendbuf;
1570   pData->iSuspendbufleft       = 0;
1571 #endif /* MNG_SUPPORT_READ */
1572 
1573 #ifdef MNG_SUPPORT_WRITE               /* no creating/writing done */
1574   pData->bCreating             = MNG_FALSE;
1575   pData->bWriting              = MNG_FALSE;
1576   pData->iFirstchunkadded      = 0;
1577   pData->iWritebufsize         = 0;
1578   pData->pWritebuf             = MNG_NULL;
1579 #endif /* MNG_SUPPORT_WRITE */
1580 
1581 #ifdef MNG_SUPPORT_DISPLAY             /* done nuttin' yet */
1582   pData->bDisplaying           = MNG_FALSE;
1583   pData->iFrameseq             = 0;
1584   pData->iLayerseq             = 0;
1585   pData->iFrametime            = 0;
1586 
1587   pData->iTotallayers          = 0;
1588   pData->iTotalframes          = 0;
1589   pData->iTotalplaytime        = 0;
1590 
1591   pData->bSkipping             = MNG_FALSE;
1592 
1593 #ifdef MNG_SUPPORT_DYNAMICMNG
1594   pData->bDynamic              = MNG_FALSE;
1595   pData->bRunningevent         = MNG_FALSE;
1596   pData->bStopafterseek        = MNG_FALSE;
1597   pData->iEventx               = 0;
1598   pData->iEventy               = 0;
1599   pData->pLastmousemove        = MNG_NULL;
1600 #endif
1601 
1602   pData->iRequestframe         = 0;
1603   pData->iRequestlayer         = 0;
1604   pData->iRequesttime          = 0;
1605   pData->bSearching            = MNG_FALSE;
1606 
1607   pData->bRestorebkgd          = MNG_FALSE;
1608 
1609   pData->iRuntime              = 0;
1610   pData->iSynctime             = 0;
1611   pData->iStarttime            = 0;
1612   pData->iEndtime              = 0;
1613   pData->bRunning              = MNG_FALSE;
1614   pData->bTimerset             = MNG_FALSE;
1615   pData->iBreakpoint           = 0;
1616   pData->bSectionwait          = MNG_FALSE;
1617   pData->bFreezing             = MNG_FALSE;
1618   pData->bResetting            = MNG_FALSE;
1619   pData->bNeedrefresh          = MNG_FALSE;
1620   pData->bMisplacedTERM        = MNG_FALSE;
1621   pData->bOnlyfirstframe       = MNG_FALSE;
1622   pData->iFramesafterTERM      = 0;
1623                                        /* these don't exist yet */
1624   pData->pCurrentobj           = MNG_NULL;
1625   pData->pCurraniobj           = MNG_NULL;
1626   pData->pTermaniobj           = MNG_NULL;
1627   pData->pLastclone            = MNG_NULL;
1628   pData->pStoreobj             = MNG_NULL;
1629   pData->pStorebuf             = MNG_NULL;
1630   pData->pRetrieveobj          = MNG_NULL;
1631                                        /* no saved data ! */
1632   pData->pSavedata             = MNG_NULL;
1633 
1634   pData->iUpdateleft           = 0;    /* no region updated yet */
1635   pData->iUpdateright          = 0;
1636   pData->iUpdatetop            = 0;
1637   pData->iUpdatebottom         = 0;
1638 
1639   pData->iPass                 = -1;   /* interlacing stuff and temp buffers */
1640   pData->iRow                  = 0;
1641   pData->iRowinc               = 1;
1642   pData->iCol                  = 0;
1643   pData->iColinc               = 1;
1644   pData->iRowsamples           = 0;
1645   pData->iSamplemul            = 0;
1646   pData->iSampleofs            = 0;
1647   pData->iSamplediv            = 0;
1648   pData->iRowsize              = 0;
1649   pData->iRowmax               = 0;
1650   pData->iFilterofs            = 0;
1651   pData->iPixelofs             = 1;
1652   pData->iLevel0               = 0;
1653   pData->iLevel1               = 0;
1654   pData->iLevel2               = 0;
1655   pData->iLevel3               = 0;
1656   pData->pWorkrow              = MNG_NULL;
1657   pData->pPrevrow              = MNG_NULL;
1658   pData->pRGBArow              = MNG_NULL;
1659   pData->bIsRGBA16             = MNG_TRUE;
1660   pData->bIsOpaque             = MNG_TRUE;
1661   pData->iFilterbpp            = 1;
1662 
1663   pData->iSourcel              = 0;    /* always initialized just before */
1664   pData->iSourcer              = 0;    /* compositing the next layer */
1665   pData->iSourcet              = 0;
1666   pData->iSourceb              = 0;
1667   pData->iDestl                = 0;
1668   pData->iDestr                = 0;
1669   pData->iDestt                = 0;
1670   pData->iDestb                = 0;
1671                                        /* lists are empty */
1672   pData->pFirstimgobj          = MNG_NULL;
1673   pData->pLastimgobj           = MNG_NULL;
1674   pData->pFirstaniobj          = MNG_NULL;
1675   pData->pLastaniobj           = MNG_NULL;
1676 #ifdef MNG_SUPPORT_DYNAMICMNG
1677   pData->pFirstevent           = MNG_NULL;
1678   pData->pLastevent            = MNG_NULL;
1679 #endif
1680                                        /* no processing callbacks */
1681   pData->fDisplayrow           = MNG_NULL;
1682   pData->fRestbkgdrow          = MNG_NULL;
1683   pData->fCorrectrow           = MNG_NULL;
1684   pData->fRetrieverow          = MNG_NULL;
1685   pData->fStorerow             = MNG_NULL;
1686   pData->fProcessrow           = MNG_NULL;
1687   pData->fDifferrow            = MNG_NULL;
1688   pData->fScalerow             = MNG_NULL;
1689   pData->fDeltarow             = MNG_NULL;
1690 #ifndef MNG_SKIPCHUNK_PAST
1691   pData->fFliprow              = MNG_NULL;
1692   pData->fTilerow              = MNG_NULL;
1693 #endif
1694   pData->fInitrowproc          = MNG_NULL;
1695 
1696   pData->iPLTEcount            = 0;    /* no PLTE data */
1697 
1698 #ifndef MNG_SKIPCHUNK_DEFI
1699   pData->iDEFIobjectid         = 0;    /* no DEFI data */
1700   pData->bDEFIhasdonotshow     = MNG_FALSE;
1701   pData->iDEFIdonotshow        = 0;
1702   pData->bDEFIhasconcrete      = MNG_FALSE;
1703   pData->iDEFIconcrete         = 0;
1704   pData->bDEFIhasloca          = MNG_FALSE;
1705   pData->iDEFIlocax            = 0;
1706   pData->iDEFIlocay            = 0;
1707   pData->bDEFIhasclip          = MNG_FALSE;
1708   pData->iDEFIclipl            = 0;
1709   pData->iDEFIclipr            = 0;
1710   pData->iDEFIclipt            = 0;
1711   pData->iDEFIclipb            = 0;
1712 #endif
1713 
1714 #ifndef MNG_SKIPCHUNK_BACK
1715   pData->iBACKred              = 0;    /* no BACK data */
1716   pData->iBACKgreen            = 0;
1717   pData->iBACKblue             = 0;
1718   pData->iBACKmandatory        = 0;
1719   pData->iBACKimageid          = 0;
1720   pData->iBACKtile             = 0;
1721 #endif
1722 
1723 #ifndef MNG_SKIPCHUNK_FRAM
1724   pData->iFRAMmode             = 1;     /* default global FRAM variables */
1725   pData->iFRAMdelay            = 1;
1726   pData->iFRAMtimeout          = 0x7fffffffl;
1727   pData->bFRAMclipping         = MNG_FALSE;
1728   pData->iFRAMclipl            = 0;
1729   pData->iFRAMclipr            = 0;
1730   pData->iFRAMclipt            = 0;
1731   pData->iFRAMclipb            = 0;
1732 
1733   pData->iFramemode            = 1;     /* again for the current frame */
1734   pData->iFramedelay           = 1;
1735   pData->iFrametimeout         = 0x7fffffffl;
1736   pData->bFrameclipping        = MNG_FALSE;
1737   pData->iFrameclipl           = 0;
1738   pData->iFrameclipr           = 0;
1739   pData->iFrameclipt           = 0;
1740   pData->iFrameclipb           = 0;
1741 
1742   pData->iNextdelay            = 1;
1743 
1744   pData->bForcedelay           = MNG_FALSE;
1745   pData->iAccumdelay           = 0;
1746 #endif
1747 
1748 #ifndef MNG_SKIPCHUNK_SHOW
1749   pData->iSHOWmode             = 0;    /* no SHOW data */
1750   pData->iSHOWfromid           = 0;
1751   pData->iSHOWtoid             = 0;
1752   pData->iSHOWnextid           = 0;
1753   pData->iSHOWskip             = 0;
1754 #endif
1755 
1756   pData->iGlobalPLTEcount      = 0;    /* no global PLTE data */
1757 
1758   pData->iGlobalTRNSrawlen     = 0;    /* no global tRNS data */
1759 
1760   pData->iGlobalGamma          = 0;    /* no global gAMA data */
1761 
1762 #ifndef MNG_SKIPCHUNK_cHRM
1763   pData->iGlobalWhitepointx    = 0;    /* no global cHRM data */
1764   pData->iGlobalWhitepointy    = 0;
1765   pData->iGlobalPrimaryredx    = 0;
1766   pData->iGlobalPrimaryredy    = 0;
1767   pData->iGlobalPrimarygreenx  = 0;
1768   pData->iGlobalPrimarygreeny  = 0;
1769   pData->iGlobalPrimarybluex   = 0;
1770   pData->iGlobalPrimarybluey   = 0;
1771 #endif
1772 
1773   pData->iGlobalRendintent     = 0;    /* no global sRGB data */
1774 
1775 #ifndef MNG_SKIPCHUNK_iCCP
1776   pData->iGlobalProfilesize    = 0;    /* no global iCCP data */
1777   pData->pGlobalProfile        = MNG_NULL;
1778 #endif
1779 
1780 #ifndef MNG_SKIPCHUNK_bKGD
1781   pData->iGlobalBKGDred        = 0;    /* no global bKGD data */
1782   pData->iGlobalBKGDgreen      = 0;
1783   pData->iGlobalBKGDblue       = 0;
1784 #endif
1785                                        /* no delta-image */
1786 #ifndef MNG_NO_DELTA_PNG
1787   pData->pDeltaImage           = MNG_NULL;
1788   pData->iDeltaImagetype       = 0;
1789   pData->iDeltatype            = 0;
1790   pData->iDeltaBlockwidth      = 0;
1791   pData->iDeltaBlockheight     = 0;
1792   pData->iDeltaBlockx          = 0;
1793   pData->iDeltaBlocky          = 0;
1794   pData->bDeltaimmediate       = MNG_FALSE;
1795 
1796   pData->fDeltagetrow          = MNG_NULL;
1797   pData->fDeltaaddrow          = MNG_NULL;
1798   pData->fDeltareplacerow      = MNG_NULL;
1799   pData->fDeltaputrow          = MNG_NULL;
1800 
1801   pData->fPromoterow           = MNG_NULL;
1802   pData->fPromBitdepth         = MNG_NULL;
1803   pData->pPromBuf              = MNG_NULL;
1804   pData->iPromColortype        = 0;
1805   pData->iPromBitdepth         = 0;
1806   pData->iPromFilltype         = 0;
1807   pData->iPromWidth            = 0;
1808   pData->pPromSrc              = MNG_NULL;
1809   pData->pPromDst              = MNG_NULL;
1810 #endif
1811 
1812 #ifndef MNG_SKIPCHUNK_MAGN
1813   pData->iMAGNfromid           = 0;
1814   pData->iMAGNtoid             = 0;
1815 #endif
1816 
1817 #ifndef MNG_SKIPCHUNK_PAST
1818   pData->iPastx                = 0;
1819   pData->iPasty                = 0;
1820 #endif
1821 
1822   pData->pLastseek             = MNG_NULL;
1823 #endif
1824 
1825 #ifdef MNG_INCLUDE_ZLIB
1826   pData->bInflating            = 0;    /* no inflating or deflating */
1827   pData->bDeflating            = 0;    /* going on at the moment */
1828 #endif
1829 
1830 #ifdef MNG_SUPPORT_DISPLAY             /* reset object 0 */
1831   mng_reset_objzero (pData);
1832 #endif
1833 
1834 #ifdef MNG_SUPPORT_TRACE
1835   MNG_TRACE (((mng_datap)hHandle), MNG_FN_RESET, MNG_LC_END);
1836 #endif
1837 
1838   return MNG_NOERROR;
1839 }
1840 
1841 /* ************************************************************************** */
1842 
mng_cleanup(mng_handle * hHandle)1843 mng_retcode MNG_DECL mng_cleanup (mng_handle* hHandle)
1844 {
1845   mng_datap pData;                     /* local vars */
1846 #ifndef MNG_INTERNAL_MEMMNGMT
1847   mng_memfree fFree;
1848 #endif
1849 
1850 #ifdef MNG_SUPPORT_TRACE
1851   MNG_TRACE (((mng_datap)*hHandle), MNG_FN_CLEANUP, MNG_LC_START);
1852 #endif
1853 
1854   MNG_VALIDHANDLE (*hHandle)           /* check validity handle */
1855   pData = ((mng_datap)(*hHandle));     /* and address main structure */
1856 
1857   mng_reset (*hHandle);                /* do an implicit reset to cleanup most stuff */
1858 
1859 #ifdef MNG_SUPPORT_DISPLAY             /* drop object 0 */
1860   mng_free_imageobject (pData, (mng_imagep)pData->pObjzero);
1861 #endif
1862 
1863 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
1864   if (pData->hProf2)                   /* output profile defined ? */
1865     mnglcms_freeprofile (pData->hProf2);
1866 
1867   if (pData->hProf3)                   /* sRGB profile defined ? */
1868     mnglcms_freeprofile (pData->hProf3);
1869 #endif
1870 
1871 #ifdef MNG_INCLUDE_ZLIB
1872   mngzlib_cleanup (pData);             /* cleanup zlib stuff */
1873 #endif
1874 
1875 #ifdef MNG_SUPPORT_TRACE
1876   MNG_TRACE (((mng_datap)*hHandle), MNG_FN_CLEANUP, MNG_LC_CLEANUP)
1877 #endif
1878 
1879   pData->iMagic = 0;                   /* invalidate the actual memory */
1880 
1881 #ifdef MNG_INTERNAL_MEMMNGMT
1882   free ((void *)*hHandle);             /* cleanup the data-structure */
1883 #else
1884   fFree = ((mng_datap)*hHandle)->fMemfree;
1885   fFree ((mng_ptr)*hHandle, sizeof (mng_data));
1886 #endif
1887 
1888   *hHandle = 0;                        /* wipe pointer to inhibit future use */
1889 
1890   return MNG_NOERROR;                  /* and we're done */
1891 }
1892 
1893 /* ************************************************************************** */
1894 
1895 #ifdef MNG_SUPPORT_READ
mng_read(mng_handle hHandle)1896 mng_retcode MNG_DECL mng_read (mng_handle hHandle)
1897 {
1898   mng_datap   pData;                   /* local vars */
1899   mng_retcode iRetcode;
1900 
1901 #ifdef MNG_SUPPORT_TRACE
1902   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ, MNG_LC_START);
1903 #endif
1904 
1905   MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
1906   pData = ((mng_datap)hHandle);        /* and make it addressable */
1907 
1908 #ifndef MNG_INTERNAL_MEMMNGMT
1909   MNG_VALIDCB (hHandle, fMemalloc)
1910   MNG_VALIDCB (hHandle, fMemfree)
1911 #endif
1912 
1913 #ifndef MNG_NO_OPEN_CLOSE_STREAM
1914   MNG_VALIDCB (hHandle, fOpenstream)
1915   MNG_VALIDCB (hHandle, fClosestream)
1916 #endif
1917   MNG_VALIDCB (hHandle, fReaddata)
1918 
1919 #ifdef MNG_SUPPORT_DISPLAY             /* valid at this point ? */
1920   if ((pData->bReading) || (pData->bDisplaying))
1921 #else
1922   if (pData->bReading)
1923 #endif
1924     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
1925 
1926 #ifdef MNG_SUPPORT_WRITE
1927   if ((pData->bWriting) || (pData->bCreating))
1928     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
1929 #endif
1930 
1931   if (!pData->bCacheplayback)          /* must store playback info to work!! */
1932     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
1933 
1934   cleanup_errors (pData);              /* cleanup previous errors */
1935 
1936   pData->bReading = MNG_TRUE;          /* read only! */
1937 
1938 #ifndef MNG_NO_OPEN_CLOSE_STREAM
1939   if (pData->fOpenstream && !pData->fOpenstream (hHandle))
1940     /* open it and start reading */
1941     iRetcode = MNG_APPIOERROR;
1942   else
1943 #endif
1944     iRetcode = mng_read_graphic (pData);
1945 
1946   if (pData->bEOF)                     /* already at EOF ? */
1947   {
1948     pData->bReading = MNG_FALSE;       /* then we're no longer reading */
1949 
1950 #ifdef MNG_SUPPORT_DISPLAY
1951     mng_reset_rundata (pData);         /* reset rundata */
1952 #endif
1953   }
1954 
1955   if (iRetcode)                        /* on error bail out */
1956     return iRetcode;
1957 
1958   if (pData->bSuspended)               /* read suspension ? */
1959   {
1960      iRetcode            = MNG_NEEDMOREDATA;
1961      pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
1962   }
1963 
1964 #ifdef MNG_SUPPORT_TRACE
1965   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ, MNG_LC_END);
1966 #endif
1967 
1968   return iRetcode;
1969 }
1970 #endif /* MNG_SUPPORT_READ */
1971 
1972 /* ************************************************************************** */
1973 
1974 #ifdef MNG_SUPPORT_READ
mng_read_pushdata(mng_handle hHandle,mng_ptr pData,mng_size_t iLength,mng_bool bTakeownership)1975 mng_retcode MNG_DECL mng_read_pushdata (mng_handle hHandle,
1976                                         mng_ptr    pData,
1977                                         mng_size_t iLength,
1978                                         mng_bool   bTakeownership)
1979 {
1980   mng_datap     pMyData;               /* local vars */
1981   mng_pushdatap pPush;
1982   mng_retcode   iRetcode;
1983 
1984 #ifdef MNG_SUPPORT_TRACE
1985   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHDATA, MNG_LC_START);
1986 #endif
1987 
1988   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
1989   pMyData = ((mng_datap)hHandle);      /* and make it addressable */
1990                                        /* create a containing buffer */
1991   iRetcode = make_pushbuffer (pMyData, pData, iLength, bTakeownership, &pPush);
1992   if (iRetcode)
1993     return iRetcode;
1994 
1995   if (pMyData->pLastpushdata)          /* and update the buffer chain */
1996     pMyData->pLastpushdata->pNext = pPush;
1997   else
1998     pMyData->pFirstpushdata = pPush;
1999 
2000   pMyData->pLastpushdata = pPush;
2001 
2002 #ifdef MNG_SUPPORT_TRACE
2003   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHDATA, MNG_LC_END);
2004 #endif
2005 
2006   return MNG_NOERROR;
2007 }
2008 #endif /* MNG_SUPPORT_READ */
2009 
2010 /* ************************************************************************** */
2011 
2012 #ifdef MNG_SUPPORT_READ
mng_read_pushsig(mng_handle hHandle,mng_imgtype eSigtype)2013 mng_retcode MNG_DECL mng_read_pushsig (mng_handle  hHandle,
2014                                        mng_imgtype eSigtype)
2015 {
2016   mng_datap pData;                     /* local vars */
2017 
2018 #ifdef MNG_SUPPORT_TRACE
2019   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHSIG, MNG_LC_START);
2020 #endif
2021 
2022   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2023   pData = ((mng_datap)hHandle);        /* and make it addressable */
2024 
2025   if (pData->bHavesig)                 /* can we expect this call ? */
2026     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2027 
2028   pData->eSigtype = eSigtype;
2029   pData->bHavesig = MNG_TRUE;
2030 
2031 #ifdef MNG_SUPPORT_TRACE
2032   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHSIG, MNG_LC_END);
2033 #endif
2034 
2035   return MNG_NOERROR;
2036 }
2037 #endif /* MNG_SUPPORT_READ */
2038 
2039 /* ************************************************************************** */
2040 
2041 #ifdef MNG_SUPPORT_READ
mng_read_pushchunk(mng_handle hHandle,mng_ptr pChunk,mng_size_t iLength,mng_bool bTakeownership)2042 mng_retcode MNG_DECL mng_read_pushchunk (mng_handle hHandle,
2043                                          mng_ptr    pChunk,
2044                                          mng_size_t iLength,
2045                                          mng_bool   bTakeownership)
2046 {
2047   mng_datap     pMyData;               /* local vars */
2048   mng_pushdatap pPush;
2049   mng_retcode   iRetcode;
2050 
2051 #ifdef MNG_SUPPORT_TRACE
2052   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHCHUNK, MNG_LC_START);
2053 #endif
2054 
2055   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2056   pMyData = ((mng_datap)hHandle);      /* and make it addressable */
2057                                        /* create a containing buffer */
2058   iRetcode = make_pushbuffer (pMyData, pChunk, iLength, bTakeownership, &pPush);
2059   if (iRetcode)
2060     return iRetcode;
2061 
2062   if (pMyData->pLastpushchunk)         /* and update the buffer chain */
2063     pMyData->pLastpushchunk->pNext = pPush;
2064   else
2065     pMyData->pFirstpushchunk = pPush;
2066 
2067   pMyData->pLastpushchunk = pPush;
2068 
2069 #ifdef MNG_SUPPORT_TRACE
2070   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_PUSHCHUNK, MNG_LC_END);
2071 #endif
2072 
2073   return MNG_NOERROR;
2074 }
2075 #endif /* MNG_SUPPORT_READ */
2076 
2077 /* ************************************************************************** */
2078 
2079 #ifdef MNG_SUPPORT_READ
mng_read_resume(mng_handle hHandle)2080 mng_retcode MNG_DECL mng_read_resume (mng_handle hHandle)
2081 {
2082   mng_datap   pData;                   /* local vars */
2083   mng_retcode iRetcode;
2084 
2085 #ifdef MNG_SUPPORT_TRACE
2086   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_RESUME, MNG_LC_START);
2087 #endif
2088 
2089   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2090   pData = ((mng_datap)hHandle);        /* and make it addressable */
2091                                        /* can we expect this call ? */
2092   if ((!pData->bReading) || (!pData->bSuspended))
2093     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2094 
2095   cleanup_errors (pData);              /* cleanup previous errors */
2096 
2097   pData->bSuspended = MNG_FALSE;       /* reset the flag */
2098 
2099 #ifdef MNG_SUPPORT_DISPLAY             /* re-synchronize ? */
2100   if ((pData->bDisplaying) && (pData->bRunning))
2101     pData->iSynctime  = pData->iSynctime - pData->iSuspendtime +
2102                         pData->fGettickcount (hHandle);
2103 #endif
2104 
2105   iRetcode = mng_read_graphic (pData); /* continue reading now */
2106 
2107   if (pData->bEOF)                     /* at EOF ? */
2108   {
2109     pData->bReading = MNG_FALSE;       /* then we're no longer reading */
2110 
2111 #ifdef MNG_SUPPORT_DISPLAY
2112     mng_reset_rundata (pData);         /* reset rundata */
2113 #endif
2114   }
2115 
2116   if (iRetcode)                        /* on error bail out */
2117     return iRetcode;
2118 
2119   if (pData->bSuspended)               /* read suspension ? */
2120   {
2121      iRetcode            = MNG_NEEDMOREDATA;
2122      pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
2123   }
2124 
2125 #ifdef MNG_SUPPORT_TRACE
2126   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_RESUME, MNG_LC_END);
2127 #endif
2128 
2129   return iRetcode;
2130 }
2131 #endif /* MNG_SUPPORT_READ */
2132 
2133 /* ************************************************************************** */
2134 
2135 #ifdef MNG_SUPPORT_WRITE
mng_write(mng_handle hHandle)2136 mng_retcode MNG_DECL mng_write (mng_handle hHandle)
2137 {
2138   mng_datap   pData;
2139   mng_retcode iRetcode;
2140 
2141 #ifdef MNG_SUPPORT_TRACE
2142   MNG_TRACE (((mng_datap)hHandle), MNG_FN_WRITE, MNG_LC_START);
2143 #endif
2144 
2145   MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
2146   pData = ((mng_datap)hHandle);        /* and make it addressable */
2147 
2148 #ifndef MNG_INTERNAL_MEMMNGMT
2149   MNG_VALIDCB (hHandle, fMemalloc)
2150   MNG_VALIDCB (hHandle, fMemfree)
2151 #endif
2152 
2153 #ifndef MNG_NO_OPEN_CLOSE_STREAM
2154   MNG_VALIDCB (hHandle, fOpenstream)
2155   MNG_VALIDCB (hHandle, fClosestream)
2156 #endif
2157   MNG_VALIDCB (hHandle, fWritedata)
2158 
2159 #ifdef MNG_SUPPORT_READ
2160   if (pData->bReading)                 /* valid at this point ? */
2161     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2162 #endif
2163 
2164   cleanup_errors (pData);              /* cleanup previous errors */
2165 
2166   iRetcode = mng_write_graphic (pData);/* do the write */
2167 
2168   if (iRetcode)                        /* on error bail out */
2169     return iRetcode;
2170 
2171 #ifdef MNG_SUPPORT_TRACE
2172   MNG_TRACE (((mng_datap)hHandle), MNG_FN_WRITE, MNG_LC_END);
2173 #endif
2174 
2175   return MNG_NOERROR;
2176 }
2177 #endif /* MNG_SUPPORT_WRITE */
2178 
2179 /* ************************************************************************** */
2180 
2181 #ifdef MNG_SUPPORT_WRITE
mng_create(mng_handle hHandle)2182 mng_retcode MNG_DECL mng_create (mng_handle hHandle)
2183 {
2184   mng_datap   pData;
2185   mng_retcode iRetcode;
2186 
2187 #ifdef MNG_SUPPORT_TRACE
2188   MNG_TRACE (((mng_datap)hHandle), MNG_FN_CREATE, MNG_LC_START);
2189 #endif
2190 
2191   MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
2192   pData = ((mng_datap)hHandle);        /* and make it addressable */
2193 
2194 #ifndef MNG_INTERNAL_MEMMNGMT
2195   MNG_VALIDCB (hHandle, fMemalloc)
2196   MNG_VALIDCB (hHandle, fMemfree)
2197 #endif
2198 
2199 #ifdef MNG_SUPPORT_READ
2200   if (pData->bReading)                 /* valid at this point ? */
2201     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2202 #endif
2203 
2204   if ((pData->bWriting) || (pData->bCreating))
2205     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2206 
2207   cleanup_errors (pData);              /* cleanup previous errors */
2208 
2209   iRetcode = mng_reset (hHandle);      /* clear any previous stuff */
2210 
2211   if (iRetcode)                        /* on error bail out */
2212     return iRetcode;
2213 
2214   pData->bCreating = MNG_TRUE;         /* indicate we're creating a new file */
2215 
2216 #ifdef MNG_SUPPORT_TRACE
2217   MNG_TRACE (((mng_datap)hHandle), MNG_FN_CREATE, MNG_LC_END);
2218 #endif
2219 
2220   return MNG_NOERROR;
2221 }
2222 #endif /* MNG_SUPPORT_WRITE */
2223 
2224 /* ************************************************************************** */
2225 
2226 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_READ)
mng_readdisplay(mng_handle hHandle)2227 mng_retcode MNG_DECL mng_readdisplay (mng_handle hHandle)
2228 {
2229   mng_datap   pData;                   /* local vars */
2230   mng_retcode iRetcode;
2231 
2232 #ifdef MNG_SUPPORT_TRACE
2233   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READDISPLAY, MNG_LC_START);
2234 #endif
2235 
2236   MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
2237   pData = ((mng_datap)hHandle);        /* and make it addressable */
2238 
2239 #ifndef MNG_INTERNAL_MEMMNGMT
2240   MNG_VALIDCB (hHandle, fMemalloc)
2241   MNG_VALIDCB (hHandle, fMemfree)
2242 #endif
2243 
2244   MNG_VALIDCB (hHandle, fReaddata)
2245   MNG_VALIDCB (hHandle, fGetcanvasline)
2246   MNG_VALIDCB (hHandle, fRefresh)
2247   MNG_VALIDCB (hHandle, fGettickcount)
2248   MNG_VALIDCB (hHandle, fSettimer)
2249                                        /* valid at this point ? */
2250   if ((pData->bReading) || (pData->bDisplaying))
2251     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2252 
2253 #ifdef MNG_SUPPORT_WRITE
2254   if ((pData->bWriting) || (pData->bCreating))
2255     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2256 #endif
2257 
2258   cleanup_errors (pData);              /* cleanup previous errors */
2259 
2260   pData->bReading      = MNG_TRUE;     /* read & display! */
2261   pData->bDisplaying   = MNG_TRUE;
2262   pData->bRunning      = MNG_TRUE;
2263   pData->iFrameseq     = 0;
2264   pData->iLayerseq     = 0;
2265   pData->iFrametime    = 0;
2266   pData->iRequestframe = 0;
2267   pData->iRequestlayer = 0;
2268   pData->iRequesttime  = 0;
2269   pData->bSearching    = MNG_FALSE;
2270   pData->iRuntime      = 0;
2271   pData->iSynctime     = pData->fGettickcount (hHandle);
2272   pData->iSuspendtime  = 0;
2273   pData->iStarttime    = pData->iSynctime;
2274   pData->iEndtime      = 0;
2275 
2276 #ifndef MNG_NO_OPEN_CLOSE_STREAM
2277   if (pData->fOpenstream && !pData->fOpenstream (hHandle))
2278     /* open it and start reading */
2279     iRetcode = MNG_APPIOERROR;
2280   else
2281 #endif
2282     iRetcode = mng_read_graphic (pData);
2283 
2284   if (pData->bEOF)                     /* already at EOF ? */
2285   {
2286     pData->bReading = MNG_FALSE;       /* then we're no longer reading */
2287     mng_drop_invalid_objects (pData);  /* drop invalidly stored objects */
2288   }
2289 
2290   if (iRetcode)                        /* on error bail out */
2291     return iRetcode;
2292 
2293   if (pData->bSuspended)               /* read suspension ? */
2294   {
2295      iRetcode            = MNG_NEEDMOREDATA;
2296      pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
2297   }
2298   else
2299   if (pData->bTimerset)                /* indicate timer break ? */
2300     iRetcode = MNG_NEEDTIMERWAIT;
2301   else
2302   if (pData->bSectionwait)             /* indicate section break ? */
2303     iRetcode = MNG_NEEDSECTIONWAIT;
2304   else
2305   {                                    /* no breaks = end of run */
2306     pData->bRunning = MNG_FALSE;
2307 
2308     if (pData->bFreezing)              /* dynamic MNG reached SEEK ? */
2309       pData->bFreezing = MNG_FALSE;    /* reset it ! */
2310   }
2311 
2312 #ifdef MNG_SUPPORT_TRACE
2313   MNG_TRACE (((mng_datap)hHandle), MNG_FN_READDISPLAY, MNG_LC_END);
2314 #endif
2315 
2316   return iRetcode;
2317 }
2318 #endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_READ */
2319 
2320 /* ************************************************************************** */
2321 
2322 #ifdef MNG_SUPPORT_DISPLAY
mng_display(mng_handle hHandle)2323 mng_retcode MNG_DECL mng_display (mng_handle hHandle)
2324 {
2325   mng_datap   pData;                   /* local vars */
2326   mng_retcode iRetcode;
2327 
2328 #ifdef MNG_SUPPORT_TRACE
2329   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY, MNG_LC_START);
2330 #endif
2331 
2332   MNG_VALIDHANDLE (hHandle)            /* check validity handle and callbacks */
2333   pData = ((mng_datap)hHandle);        /* and make it addressable */
2334 
2335 #ifndef MNG_INTERNAL_MEMMNGMT
2336   MNG_VALIDCB (hHandle, fMemalloc)
2337   MNG_VALIDCB (hHandle, fMemfree)
2338 #endif
2339 
2340   MNG_VALIDCB (hHandle, fGetcanvasline)
2341   MNG_VALIDCB (hHandle, fRefresh)
2342   MNG_VALIDCB (hHandle, fGettickcount)
2343   MNG_VALIDCB (hHandle, fSettimer)
2344 
2345   if (pData->bDisplaying)              /* valid at this point ? */
2346     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2347 
2348 #ifdef MNG_SUPPORT_READ
2349   if (pData->bReading)
2350     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2351 #endif
2352 
2353 #ifdef MNG_SUPPORT_WRITE
2354   if ((pData->bWriting) || (pData->bCreating))
2355     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2356 #endif
2357 
2358   cleanup_errors (pData);              /* cleanup previous errors */
2359 
2360   pData->bDisplaying   = MNG_TRUE;     /* display! */
2361   pData->bRunning      = MNG_TRUE;
2362   pData->iFrameseq     = 0;
2363   pData->iLayerseq     = 0;
2364   pData->iFrametime    = 0;
2365   pData->iRequestframe = 0;
2366   pData->iRequestlayer = 0;
2367   pData->iRequesttime  = 0;
2368   pData->bSearching    = MNG_FALSE;
2369   pData->iRuntime      = 0;
2370   pData->iSynctime     = pData->fGettickcount (hHandle);
2371 #ifdef MNG_SUPPORT_READ
2372   pData->iSuspendtime  = 0;
2373 #endif
2374   pData->iStarttime    = pData->iSynctime;
2375   pData->iEndtime      = 0;
2376   pData->pCurraniobj   = pData->pFirstaniobj;
2377                                        /* go do it */
2378   iRetcode = mng_process_display (pData);
2379 
2380   if (iRetcode)                        /* on error bail out */
2381     return iRetcode;
2382 
2383   if (pData->bTimerset)                /* indicate timer break ? */
2384     iRetcode = MNG_NEEDTIMERWAIT;
2385   else
2386   {                                    /* no breaks = end of run */
2387     pData->bRunning = MNG_FALSE;
2388 
2389     if (pData->bFreezing)              /* dynamic MNG reached SEEK ? */
2390       pData->bFreezing = MNG_FALSE;    /* reset it ! */
2391   }
2392 
2393 #ifdef MNG_SUPPORT_TRACE
2394   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY, MNG_LC_END);
2395 #endif
2396 
2397   return iRetcode;
2398 }
2399 #endif /* MNG_SUPPORT_DISPLAY */
2400 
2401 /* ************************************************************************** */
2402 
2403 #ifdef MNG_SUPPORT_DISPLAY
mng_display_resume(mng_handle hHandle)2404 mng_retcode MNG_DECL mng_display_resume (mng_handle hHandle)
2405 {
2406   mng_datap   pData;                   /* local vars */
2407   mng_retcode iRetcode;
2408 
2409 #ifdef MNG_SUPPORT_TRACE
2410   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESUME, MNG_LC_START);
2411 #endif
2412 
2413   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2414   pData = ((mng_datap)hHandle);        /* and make it addressable */
2415 
2416   if (!pData->bDisplaying)             /* can we expect this call ? */
2417     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2418 
2419   cleanup_errors (pData);              /* cleanup previous errors */
2420                                        /* was it running ? */
2421   if ((pData->bRunning) || (pData->bReading))
2422   {                                    /* are we expecting this call ? */
2423     if ((pData->bTimerset) || (pData->bSuspended) || (pData->bSectionwait))
2424     {
2425       pData->bTimerset    = MNG_FALSE; /* reset the flags */
2426       pData->bSectionwait = MNG_FALSE;
2427 
2428 #ifdef MNG_SUPPORT_READ
2429       if (pData->bReading)             /* set during read&display ? */
2430       {
2431         if (pData->bSuspended)         /* calculate proper synchronization */
2432           pData->iSynctime = pData->iSynctime - pData->iSuspendtime +
2433                              pData->fGettickcount (hHandle);
2434         else
2435           pData->iSynctime = pData->fGettickcount (hHandle);
2436 
2437         pData->bSuspended = MNG_FALSE; /* now reset this flag */
2438                                        /* and continue reading */
2439         iRetcode = mng_read_graphic (pData);
2440 
2441         if (pData->bEOF)               /* already at EOF ? */
2442         {
2443           pData->bReading = MNG_FALSE; /* then we're no longer reading */
2444                                        /* drop invalidly stored objects */
2445           mng_drop_invalid_objects (pData);
2446         }
2447       }
2448       else
2449 #endif /* MNG_SUPPORT_READ */
2450       {                                /* synchronize timing */
2451         pData->iSynctime = pData->fGettickcount (hHandle);
2452                                        /* resume display processing */
2453         iRetcode = mng_process_display (pData);
2454       }
2455     }
2456     else
2457     {
2458       MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2459     }
2460   }
2461   else
2462   {                                    /* synchronize timing */
2463     pData->iSynctime = pData->fGettickcount (hHandle);
2464     pData->bRunning  = MNG_TRUE;       /* it's restarted again ! */
2465                                        /* resume display processing */
2466     iRetcode = mng_process_display (pData);
2467   }
2468 
2469   if (iRetcode)                        /* on error bail out */
2470     return iRetcode;
2471 
2472   if (pData->bSuspended)               /* read suspension ? */
2473   {
2474      iRetcode            = MNG_NEEDMOREDATA;
2475      pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
2476   }
2477   else
2478   if (pData->bTimerset)                /* indicate timer break ? */
2479     iRetcode = MNG_NEEDTIMERWAIT;
2480   else
2481   if (pData->bSectionwait)             /* indicate section break ? */
2482     iRetcode = MNG_NEEDSECTIONWAIT;
2483   else
2484   {                                    /* no breaks = end of run */
2485     pData->bRunning = MNG_FALSE;
2486 
2487     if (pData->bFreezing)              /* trying to freeze ? */
2488       pData->bFreezing = MNG_FALSE;    /* then we're there */
2489 
2490     if (pData->bResetting)             /* trying to reset as well ? */
2491     {                                  /* full stop!!! */
2492       pData->bDisplaying = MNG_FALSE;
2493 
2494       iRetcode = mng_reset_rundata (pData);
2495 
2496       if (iRetcode)                    /* on error bail out */
2497         return iRetcode;
2498     }
2499   }
2500 
2501 #ifdef MNG_SUPPORT_TRACE
2502   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESUME, MNG_LC_END);
2503 #endif
2504 
2505   return iRetcode;
2506 }
2507 #endif /* MNG_SUPPORT_DISPLAY */
2508 
2509 /* ************************************************************************** */
2510 
2511 #ifdef MNG_SUPPORT_DISPLAY
mng_display_freeze(mng_handle hHandle)2512 mng_retcode MNG_DECL mng_display_freeze (mng_handle hHandle)
2513 {
2514   mng_datap pData;
2515 
2516 #ifdef MNG_SUPPORT_TRACE
2517   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_FREEZE, MNG_LC_START);
2518 #endif
2519 
2520   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2521   pData = ((mng_datap)hHandle);        /* and make it addressable */
2522                                        /* can we expect this call ? */
2523   if ((!pData->bDisplaying) || (pData->bReading))
2524     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2525 
2526   cleanup_errors (pData);              /* cleanup previous errors */
2527 
2528   if (pData->bRunning)                 /* is it running ? */
2529   {
2530     mng_retcode iRetcode;
2531 
2532     pData->bFreezing = MNG_TRUE;       /* indicate we need to freeze */
2533                                        /* continue "normal" processing */
2534     iRetcode = mng_display_resume (hHandle);
2535 
2536     if (iRetcode)                      /* on error bail out */
2537       return iRetcode;
2538   }
2539 
2540 #ifdef MNG_SUPPORT_TRACE
2541   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_FREEZE, MNG_LC_END);
2542 #endif
2543 
2544   return MNG_NOERROR;
2545 }
2546 #endif /* MNG_SUPPORT_DISPLAY */
2547 
2548 /* ************************************************************************** */
2549 
2550 #ifdef MNG_SUPPORT_DISPLAY
mng_display_reset(mng_handle hHandle)2551 mng_retcode MNG_DECL mng_display_reset (mng_handle hHandle)
2552 {
2553   mng_datap   pData;
2554   mng_retcode iRetcode;
2555 
2556 #ifdef MNG_SUPPORT_TRACE
2557   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESET, MNG_LC_START);
2558 #endif
2559 
2560   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2561   pData = ((mng_datap)hHandle);        /* and make it addressable */
2562                                        /* can we expect this call ? */
2563   if ((!pData->bDisplaying) || (pData->bReading))
2564     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2565 
2566   if (!pData->bCacheplayback)          /* must store playback info to work!! */
2567     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2568 
2569   cleanup_errors (pData);              /* cleanup previous errors */
2570 
2571   if (pData->bRunning)                 /* is it running ? */
2572   {
2573     pData->bFreezing  = MNG_TRUE;      /* indicate we need to freeze */
2574     pData->bResetting = MNG_TRUE;      /* indicate we're about to reset too */
2575                                        /* continue normal processing ? */
2576     iRetcode = mng_display_resume (hHandle);
2577 
2578     if (iRetcode)                      /* on error bail out */
2579       return iRetcode;
2580   }
2581   else
2582   {                                    /* full stop!!! */
2583     pData->bDisplaying = MNG_FALSE;
2584 
2585     iRetcode = mng_reset_rundata (pData);
2586 
2587     if (iRetcode)                      /* on error bail out */
2588       return iRetcode;
2589   }
2590 
2591 #ifdef MNG_SUPPORT_TRACE
2592   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESET, MNG_LC_END);
2593 #endif
2594 
2595   return MNG_NOERROR;
2596 }
2597 #endif /* MNG_SUPPORT_DISPLAY */
2598 
2599 /* ************************************************************************** */
2600 
2601 #ifdef MNG_SUPPORT_DISPLAY
2602 #ifndef MNG_NO_DISPLAY_GO_SUPPORTED
mng_display_goframe(mng_handle hHandle,mng_uint32 iFramenr)2603 mng_retcode MNG_DECL mng_display_goframe (mng_handle hHandle,
2604                                           mng_uint32 iFramenr)
2605 {
2606   mng_datap   pData;
2607   mng_retcode iRetcode;
2608 
2609 #ifdef MNG_SUPPORT_TRACE
2610   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOFRAME, MNG_LC_START);
2611 #endif
2612 
2613   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2614   pData = ((mng_datap)hHandle);        /* and make it addressable */
2615 
2616   if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
2617     MNG_ERROR (pData, MNG_NOTANANIMATION);
2618                                        /* can we expect this call ? */
2619   if ((!pData->bDisplaying) || (pData->bRunning))
2620     MNG_ERROR ((mng_datap)hHandle, MNG_FUNCTIONINVALID);
2621 
2622   if (!pData->bCacheplayback)          /* must store playback info to work!! */
2623     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2624 
2625   if (iFramenr > pData->iTotalframes)  /* is the parameter within bounds ? */
2626     MNG_ERROR (pData, MNG_FRAMENRTOOHIGH);
2627                                        /* within MHDR bounds ? */
2628   if ((pData->iFramecount) && (iFramenr > pData->iFramecount))
2629     MNG_WARNING (pData, MNG_FRAMENRTOOHIGH);
2630 
2631   cleanup_errors (pData);              /* cleanup previous errors */
2632 
2633   if (pData->iFrameseq > iFramenr)     /* search from current or go back to start ? */
2634   {
2635     iRetcode = mng_reset_rundata (pData);
2636     if (iRetcode)                      /* on error bail out */
2637       return iRetcode;
2638   }
2639 
2640   if (iFramenr)
2641   {
2642     pData->iRequestframe = iFramenr;   /* go find the requested frame then */
2643     iRetcode = mng_process_display (pData);
2644 
2645     if (iRetcode)                      /* on error bail out */
2646       return iRetcode;
2647 
2648     pData->bTimerset = MNG_FALSE;      /* reset just to be safe */
2649   }
2650 
2651 #ifdef MNG_SUPPORT_TRACE
2652   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOFRAME, MNG_LC_END);
2653 #endif
2654 
2655   return MNG_NOERROR;
2656 }
2657 #endif
2658 #endif /* MNG_SUPPORT_DISPLAY */
2659 
2660 /* ************************************************************************** */
2661 
2662 #ifdef MNG_SUPPORT_DISPLAY
2663 #ifndef MNG_NO_DISPLAY_GO_SUPPORTED
mng_display_golayer(mng_handle hHandle,mng_uint32 iLayernr)2664 mng_retcode MNG_DECL mng_display_golayer (mng_handle hHandle,
2665                                           mng_uint32 iLayernr)
2666 {
2667   mng_datap   pData;
2668   mng_retcode iRetcode;
2669 
2670 #ifdef MNG_SUPPORT_TRACE
2671   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOLAYER, MNG_LC_START);
2672 #endif
2673 
2674   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2675   pData = ((mng_datap)hHandle);        /* and make it addressable */
2676 
2677   if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
2678     MNG_ERROR (pData, MNG_NOTANANIMATION);
2679                                        /* can we expect this call ? */
2680   if ((!pData->bDisplaying) || (pData->bRunning))
2681     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2682 
2683   if (!pData->bCacheplayback)          /* must store playback info to work!! */
2684     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2685 
2686   if (iLayernr > pData->iTotallayers)  /* is the parameter within bounds ? */
2687     MNG_ERROR (pData, MNG_LAYERNRTOOHIGH);
2688                                        /* within MHDR bounds ? */
2689   if ((pData->iLayercount) && (iLayernr > pData->iLayercount))
2690     MNG_WARNING (pData, MNG_LAYERNRTOOHIGH);
2691 
2692   cleanup_errors (pData);              /* cleanup previous errors */
2693 
2694   if (pData->iLayerseq > iLayernr)     /* search from current or go back to start ? */
2695   {
2696     iRetcode = mng_reset_rundata (pData);
2697     if (iRetcode)                      /* on error bail out */
2698       return iRetcode;
2699   }
2700 
2701   if (iLayernr)
2702   {
2703     pData->iRequestlayer = iLayernr;   /* go find the requested layer then */
2704     iRetcode = mng_process_display (pData);
2705 
2706     if (iRetcode)                      /* on error bail out */
2707       return iRetcode;
2708 
2709     pData->bTimerset = MNG_FALSE;      /* reset just to be safe */
2710   }
2711 
2712 #ifdef MNG_SUPPORT_TRACE
2713   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOLAYER, MNG_LC_END);
2714 #endif
2715 
2716   return MNG_NOERROR;
2717 }
2718 #endif
2719 #endif /* MNG_SUPPORT_DISPLAY */
2720 
2721 /* ************************************************************************** */
2722 
2723 #ifdef MNG_SUPPORT_DISPLAY
2724 #ifndef MNG_NO_DISPLAY_GO_SUPPORTED
mng_display_gotime(mng_handle hHandle,mng_uint32 iPlaytime)2725 mng_retcode MNG_DECL mng_display_gotime (mng_handle hHandle,
2726                                          mng_uint32 iPlaytime)
2727 {
2728   mng_datap   pData;
2729   mng_retcode iRetcode;
2730 
2731 #ifdef MNG_SUPPORT_TRACE
2732   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOTIME, MNG_LC_START);
2733 #endif
2734 
2735   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2736   pData = ((mng_datap)hHandle);        /* and make it addressable */
2737 
2738   if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
2739     MNG_ERROR (pData, MNG_NOTANANIMATION);
2740                                        /* can we expect this call ? */
2741   if ((!pData->bDisplaying) || (pData->bRunning))
2742     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2743 
2744   if (!pData->bCacheplayback)          /* must store playback info to work!! */
2745     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2746                                        /* is the parameter within bounds ? */
2747   if (iPlaytime > pData->iTotalplaytime)
2748     MNG_ERROR (pData, MNG_PLAYTIMETOOHIGH);
2749                                        /* within MHDR bounds ? */
2750   if ((pData->iPlaytime) && (iPlaytime > pData->iPlaytime))
2751     MNG_WARNING (pData, MNG_PLAYTIMETOOHIGH);
2752 
2753   cleanup_errors (pData);              /* cleanup previous errors */
2754 
2755   if (pData->iFrametime > iPlaytime)   /* search from current or go back to start ? */
2756   {
2757     iRetcode = mng_reset_rundata (pData);
2758     if (iRetcode)                      /* on error bail out */
2759       return iRetcode;
2760   }
2761 
2762   if (iPlaytime)
2763   {
2764     pData->iRequesttime = iPlaytime;   /* go find the requested playtime then */
2765     iRetcode = mng_process_display (pData);
2766 
2767     if (iRetcode)                      /* on error bail out */
2768       return iRetcode;
2769 
2770     pData->bTimerset = MNG_FALSE;      /* reset just to be safe */
2771   }
2772 
2773 #ifdef MNG_SUPPORT_TRACE
2774   MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOTIME, MNG_LC_END);
2775 #endif
2776 
2777   return MNG_NOERROR;
2778 }
2779 #endif
2780 #endif /* MNG_SUPPORT_DISPLAY */
2781 
2782 /* ************************************************************************** */
2783 
2784 #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
mng_trapevent(mng_handle hHandle,mng_uint8 iEventtype,mng_int32 iX,mng_int32 iY)2785 mng_retcode MNG_DECL mng_trapevent (mng_handle hHandle,
2786                                     mng_uint8  iEventtype,
2787                                     mng_int32  iX,
2788                                     mng_int32  iY)
2789 {
2790   mng_datap   pData;
2791   mng_eventp  pEvent;
2792   mng_bool    bFound = MNG_FALSE;
2793   mng_retcode iRetcode;
2794   mng_imagep  pImage;
2795   mng_uint8p  pPixel;
2796 
2797 #ifdef MNG_SUPPORT_TRACE
2798   MNG_TRACE (((mng_datap)hHandle), MNG_FN_TRAPEVENT, MNG_LC_START);
2799 #endif
2800 
2801   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2802   pData = ((mng_datap)hHandle);        /* and make it addressable */
2803 
2804   if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
2805     MNG_ERROR (pData, MNG_NOTANANIMATION);
2806 
2807   if (!pData->bDisplaying)             /* can we expect this call ? */
2808     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2809 
2810   if (!pData->bCacheplayback)          /* must store playback info to work!! */
2811     MNG_ERROR (pData, MNG_FUNCTIONINVALID);
2812                                        /* let's find a matching event object */
2813   pEvent = (mng_eventp)pData->pFirstevent;
2814 
2815   while ((pEvent) && (!bFound))
2816   {                                    /* matching eventtype ? */
2817     if (pEvent->iEventtype == iEventtype)
2818     {
2819       switch (pEvent->iMasktype)       /* check X/Y on basis of masktype */
2820       {
2821         case MNG_MASK_NONE :           /* no mask is easy */
2822           {
2823             bFound = MNG_TRUE;
2824             break;
2825           }
2826 
2827         case MNG_MASK_BOX :            /* inside the given box ? */
2828           {                            /* right- and bottom-border don't count ! */
2829             if ((iX >= pEvent->iLeft) && (iX < pEvent->iRight) &&
2830                 (iY >= pEvent->iTop) && (iY < pEvent->iBottom))
2831               bFound = MNG_TRUE;
2832             break;
2833           }
2834 
2835         case MNG_MASK_OBJECT :         /* non-zero pixel in the image object ? */
2836           {
2837             pImage = mng_find_imageobject (pData, pEvent->iObjectid);
2838                                        /* valid image ? */
2839             if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
2840                 ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
2841                 ((mng_int32)pImage->pImgbuf->iWidth  > iX) &&
2842                 ((mng_int32)pImage->pImgbuf->iHeight > iY))
2843             {
2844               pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iY) + iX);
2845 
2846               if (*pPixel)             /* non-zero ? */
2847                 bFound = MNG_TRUE;
2848             }
2849 
2850             break;
2851           }
2852 
2853         case MNG_MASK_OBJECTIX :       /* pixel in the image object matches index ? */
2854           {
2855             pImage = mng_find_imageobject (pData, pEvent->iObjectid);
2856                                        /* valid image ? */
2857             if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
2858                 ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
2859                 ((mng_int32)pImage->pImgbuf->iWidth  > iX) && (iX >= 0) &&
2860                 ((mng_int32)pImage->pImgbuf->iHeight > iY) && (iY >= 0))
2861             {
2862               pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iY) + iX);
2863                                        /* matching index ? */
2864               if (*pPixel == pEvent->iIndex)
2865                 bFound = MNG_TRUE;
2866             }
2867 
2868             break;
2869           }
2870 
2871         case MNG_MASK_BOXOBJECT :      /* non-zero pixel in the image object ? */
2872           {
2873             mng_int32 iTempx = iX - pEvent->iLeft;
2874             mng_int32 iTempy = iY - pEvent->iTop;
2875 
2876             pImage = mng_find_imageobject (pData, pEvent->iObjectid);
2877                                        /* valid image ? */
2878             if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
2879                 ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
2880                 (iTempx < (mng_int32)pImage->pImgbuf->iWidth) &&
2881                 (iTempx >= 0) && (iX < pEvent->iRight) &&
2882                 (iTempy < (mng_int32)pImage->pImgbuf->iHeight) &&
2883                 (iTempy >= 0) && (iY < pEvent->iBottom))
2884             {
2885               pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iTempy) + iTempx);
2886 
2887               if (*pPixel)             /* non-zero ? */
2888                 bFound = MNG_TRUE;
2889             }
2890 
2891             break;
2892           }
2893 
2894         case MNG_MASK_BOXOBJECTIX :    /* pixel in the image object matches index ? */
2895           {
2896             mng_int32 iTempx = iX - pEvent->iLeft;
2897             mng_int32 iTempy = iY - pEvent->iTop;
2898 
2899             pImage = mng_find_imageobject (pData, pEvent->iObjectid);
2900                                        /* valid image ? */
2901             if ((pImage) && (pImage->pImgbuf->iBitdepth <= 8) &&
2902                 ((pImage->pImgbuf->iColortype == 0) || (pImage->pImgbuf->iColortype == 3)) &&
2903                 (iTempx < (mng_int32)pImage->pImgbuf->iWidth) &&
2904                 (iTempx >= 0) && (iX < pEvent->iRight) &&
2905                 (iTempy < (mng_int32)pImage->pImgbuf->iHeight) &&
2906                 (iTempy >= 0) && (iY < pEvent->iBottom))
2907             {
2908               pPixel = pImage->pImgbuf->pImgdata + ((pImage->pImgbuf->iWidth * iTempy) + iTempx);
2909                                        /* matching index ? */
2910               if (*pPixel == pEvent->iIndex)
2911                 bFound = MNG_TRUE;
2912             }
2913 
2914             break;
2915           }
2916 
2917       }
2918     }
2919 
2920     if (!bFound)                       /* try the next one */
2921       pEvent = (mng_eventp)pEvent->sHeader.pNext;
2922   }
2923                                        /* found one that's not the last mousemove ? */
2924   if ((pEvent) && ((mng_objectp)pEvent != pData->pLastmousemove))
2925   {                                    /* can we start an event process now ? */
2926     if ((!pData->bReading) && (!pData->bRunning))
2927     {
2928       pData->iEventx = iX;             /* save coordinates */
2929       pData->iEventy = iY;
2930                                        /* do it then ! */
2931       iRetcode = pEvent->sHeader.fProcess (pData, pEvent);
2932 
2933       if (iRetcode)                    /* on error bail out */
2934         return iRetcode;
2935                                        /* remember last mousemove event */
2936       if (pEvent->iEventtype == MNG_EVENT_MOUSEMOVE)
2937         pData->pLastmousemove = (mng_objectp)pEvent;
2938       else
2939         pData->pLastmousemove = MNG_NULL;
2940     }
2941     else
2942     {
2943 
2944       /* TODO: store unprocessed events or not ??? */
2945 
2946     }
2947   }
2948 
2949 #ifdef MNG_SUPPORT_TRACE
2950   MNG_TRACE (((mng_datap)hHandle), MNG_FN_TRAPEVENT, MNG_LC_END);
2951 #endif
2952 
2953   return MNG_NOERROR;
2954 }
2955 #endif
2956 
2957 /* ************************************************************************** */
2958 
mng_getlasterror(mng_handle hHandle,mng_int8 * iSeverity,mng_chunkid * iChunkname,mng_uint32 * iChunkseq,mng_int32 * iExtra1,mng_int32 * iExtra2,mng_pchar * zErrortext)2959 mng_retcode MNG_DECL mng_getlasterror (mng_handle   hHandle,
2960                                        mng_int8*    iSeverity,
2961                                        mng_chunkid* iChunkname,
2962                                        mng_uint32*  iChunkseq,
2963                                        mng_int32*   iExtra1,
2964                                        mng_int32*   iExtra2,
2965                                        mng_pchar*   zErrortext)
2966 {
2967   mng_datap pData;                     /* local vars */
2968 
2969 #ifdef MNG_SUPPORT_TRACE
2970   MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETLASTERROR, MNG_LC_START);
2971 #endif
2972 
2973   MNG_VALIDHANDLE (hHandle)            /* check validity handle */
2974   pData = ((mng_datap)hHandle);        /* and make it addressable */
2975 
2976   *iSeverity  = pData->iSeverity;      /* return the appropriate fields */
2977 
2978 #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
2979   *iChunkname = pData->iChunkname;
2980   *iChunkseq  = pData->iChunkseq;
2981 #else
2982   *iChunkname = MNG_UINT_HUH;
2983   *iChunkseq  = 0;
2984 #endif
2985 
2986   *iExtra1    = pData->iErrorx1;
2987   *iExtra2    = pData->iErrorx2;
2988   *zErrortext = pData->zErrortext;
2989 
2990 #ifdef MNG_SUPPORT_TRACE
2991   MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETLASTERROR, MNG_LC_END);
2992 #endif
2993 
2994   return pData->iErrorcode;            /* and the errorcode */
2995 }
2996 
2997 /* ************************************************************************** */
2998 /* * end of file                                                            * */
2999 /* ************************************************************************** */
3000 
3001 
3002