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