1 /* ************************************************************************** */
2 /* *             For conditions of distribution and use,                    * */
3 /* *                see copyright notice in libmng.h                        * */
4 /* ************************************************************************** */
5 /* *                                                                        * */
6 /* * project   : libmng                                                     * */
7 /* * file      : libmng_display.c          copyright (c) 2000-2007 G.Juyn   * */
8 /* * version   : 1.0.10                                                     * */
9 /* *                                                                        * */
10 /* * purpose   : Display management (implementation)                        * */
11 /* *                                                                        * */
12 /* * author    : G.Juyn                                                     * */
13 /* *                                                                        * */
14 /* * comment   : implementation of the display management routines          * */
15 /* *                                                                        * */
16 /* * changes   : 0.5.1 - 05/08/2000 - G.Juyn                                * */
17 /* *             - changed strict-ANSI stuff                                * */
18 /* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
19 /* *             - added callback error-reporting support                   * */
20 /* *             - fixed frame_delay misalignment                           * */
21 /* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
22 /* *             - added sanity check for frozen status                     * */
23 /* *             - changed trace to macro for callback error-reporting      * */
24 /* *             0.5.1 - 05/13/2000 - G.Juyn                                * */
25 /* *             - changed display_mend to reset state to initial or SAVE   * */
26 /* *             - added eMNGma hack (will be removed in 1.0.0 !!!)         * */
27 /* *             - added TERM animation object pointer (easier reference)   * */
28 /* *             - added process_save & process_seek routines               * */
29 /* *             0.5.1 - 05/14/2000 - G.Juyn                                * */
30 /* *             - added save_state and restore_state for SAVE/SEEK/TERM    * */
31 /* *               processing                                               * */
32 /* *                                                                        * */
33 /* *             0.5.2 - 05/20/2000 - G.Juyn                                * */
34 /* *             - added JNG support (JHDR/JDAT)                            * */
35 /* *             0.5.2 - 05/23/2000 - G.Juyn                                * */
36 /* *             - fixed problem with DEFI clipping                         * */
37 /* *             0.5.2 - 05/30/2000 - G.Juyn                                * */
38 /* *             - added delta-image support (DHDR,PROM,IPNG,IJNG)          * */
39 /* *             0.5.2 - 05/31/2000 - G.Juyn                                * */
40 /* *             - fixed pointer confusion (contributed by Tim Rowley)      * */
41 /* *             0.5.2 - 06/03/2000 - G.Juyn                                * */
42 /* *             - fixed makeup for Linux gcc compile                       * */
43 /* *             0.5.2 - 06/05/2000 - G.Juyn                                * */
44 /* *             - added support for RGB8_A8 canvasstyle                    * */
45 /* *             0.5.2 - 06/09/2000 - G.Juyn                                * */
46 /* *             - fixed timer-handling to run with Mozilla (Tim Rowley)    * */
47 /* *             0.5.2 - 06/10/2000 - G.Juyn                                * */
48 /* *             - fixed some compilation-warnings (contrib Jason Morris)   * */
49 /* *                                                                        * */
50 /* *             0.5.3 - 06/12/2000 - G.Juyn                                * */
51 /* *             - fixed display of stored JNG images                       * */
52 /* *             0.5.3 - 06/13/2000 - G.Juyn                                * */
53 /* *             - fixed problem with BASI-IEND as object 0                 * */
54 /* *             0.5.3 - 06/16/2000 - G.Juyn                                * */
55 /* *             - changed progressive-display processing                   * */
56 /* *             0.5.3 - 06/17/2000 - G.Juyn                                * */
57 /* *             - changed delta-image processing                           * */
58 /* *             0.5.3 - 06/20/2000 - G.Juyn                                * */
59 /* *             - fixed some minor stuff                                   * */
60 /* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
61 /* *             - added speed-modifier to timing routine                   * */
62 /* *             0.5.3 - 06/22/2000 - G.Juyn                                * */
63 /* *             - added support for PPLT chunk processing                  * */
64 /* *             0.5.3 - 06/29/2000 - G.Juyn                                * */
65 /* *             - swapped refresh parameters                               * */
66 /* *                                                                        * */
67 /* *             0.9.0 - 06/30/2000 - G.Juyn                                * */
68 /* *             - changed refresh parameters to 'x,y,width,height'         * */
69 /* *                                                                        * */
70 /* *             0.9.1 - 07/07/2000 - G.Juyn                                * */
71 /* *             - implemented support for freeze/reset/resume & go_xxxx    * */
72 /* *             0.9.1 - 07/08/2000 - G.Juyn                                * */
73 /* *             - added support for improved timing                        * */
74 /* *             0.9.1 - 07/14/2000 - G.Juyn                                * */
75 /* *             - changed EOF processing behavior                          * */
76 /* *             - fixed TERM delay processing                              * */
77 /* *             0.9.1 - 07/15/2000 - G.Juyn                                * */
78 /* *             - fixed freeze & reset processing                          * */
79 /* *             0.9.1 - 07/16/2000 - G.Juyn                                * */
80 /* *             - fixed storage of images during mng_read()                * */
81 /* *             - fixed support for mng_display() after mng_read()         * */
82 /* *             0.9.1 - 07/24/2000 - G.Juyn                                * */
83 /* *             - fixed reading of still-images                            * */
84 /* *                                                                        * */
85 /* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
86 /* *             - changed file-prefixes                                    * */
87 /* *                                                                        * */
88 /* *             0.9.3 - 08/07/2000 - G.Juyn                                * */
89 /* *             - B111300 - fixup for improved portability                 * */
90 /* *             0.9.3 - 08/21/2000 - G.Juyn                                * */
91 /* *             - fixed TERM processing delay of 0 msecs                   * */
92 /* *             0.9.3 - 08/26/2000 - G.Juyn                                * */
93 /* *             - added MAGN chunk                                         * */
94 /* *             0.9.3 - 09/10/2000 - G.Juyn                                * */
95 /* *             - fixed problem with no refresh after TERM                 * */
96 /* *             - fixed DEFI behavior                                      * */
97 /* *             0.9.3 - 09/16/2000 - G.Juyn                                * */
98 /* *             - fixed timing & refresh behavior for single PNG/JNG       * */
99 /* *             0.9.3 - 09/19/2000 - G.Juyn                                * */
100 /* *             - refixed timing & refresh behavior for single PNG/JNG     * */
101 /* *             0.9.3 - 10/02/2000 - G.Juyn                                * */
102 /* *             - fixed timing again (this is getting boring...)           * */
103 /* *             - refixed problem with no refresh after TERM               * */
104 /* *             0.9.3 - 10/16/2000 - G.Juyn                                * */
105 /* *             - added JDAA chunk                                         * */
106 /* *             0.9.3 - 10/17/2000 - G.Juyn                                * */
107 /* *             - fixed support for bKGD                                   * */
108 /* *             0.9.3 - 10/18/2000 - G.Juyn                                * */
109 /* *             - fixed delta-processing behavior                          * */
110 /* *             0.9.3 - 10/19/2000 - G.Juyn                                * */
111 /* *             - added storage for pixel-/alpha-sampledepth for delta's   * */
112 /* *             0.9.3 - 10/27/2000 - G.Juyn                                * */
113 /* *             - fixed separate read() & display() processing             * */
114 /* *                                                                        * */
115 /* *             0.9.4 - 10/31/2000 - G.Juyn                                * */
116 /* *             - fixed possible loop in display_resume() (Thanks Vova!)   * */
117 /* *             0.9.4 - 11/20/2000 - G.Juyn                                * */
118 /* *             - fixed unwanted repetition in mng_readdisplay()           * */
119 /* *             0.9.4 - 11/24/2000 - G.Juyn                                * */
120 /* *             - moved restore of object 0 to libmng_display              * */
121 /* *             - added restore of object 0 to TERM processing !!!         * */
122 /* *             - fixed TERM delay processing                              * */
123 /* *             - fixed TERM end processing (count = 0)                    * */
124 /* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
125 /* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
126 /* *             0.9.4 -  1/18/2001 - G.Juyn                                * */
127 /* *             - removed test filter-methods 1 & 65                       * */
128 /* *             - set default level-set for filtertype=64 to all zeroes    * */
129 /* *                                                                        * */
130 /* *             0.9.5 -  1/20/2001 - G.Juyn                                * */
131 /* *             - fixed compiler-warnings Mozilla (thanks Tim)             * */
132 /* *             0.9.5 -  1/23/2001 - G.Juyn                                * */
133 /* *             - fixed timing-problem with switching framing_modes        * */
134 /* *                                                                        * */
135 /* *             1.0.1 - 02/08/2001 - G.Juyn                                * */
136 /* *             - added MEND processing callback                           * */
137 /* *             1.0.1 - 02/13/2001 - G.Juyn                                * */
138 /* *             - fixed first FRAM_MODE=4 timing problem                   * */
139 /* *             1.0.1 - 04/21/2001 - G.Juyn                                * */
140 /* *             - fixed memory-leak for JNGs with alpha (Thanks Gregg!)    * */
141 /* *             - added BGRA8 canvas with premultiplied alpha              * */
142 /* *                                                                        * */
143 /* *             1.0.2 - 06/25/2001 - G.Juyn                                * */
144 /* *             - fixed memory-leak with delta-images (Thanks Michael!)    * */
145 /* *                                                                        * */
146 /* *             1.0.5 - 08/15/2002 - G.Juyn                                * */
147 /* *             - completed PROM support                                   * */
148 /* *             - completed delta-image support                            * */
149 /* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
150 /* *             - B597134 - libmng pollutes the linker namespace           * */
151 /* *             1.0.5 - 09/13/2002 - G.Juyn                                * */
152 /* *             - fixed read/write of MAGN chunk                           * */
153 /* *             1.0.5 - 09/15/2002 - G.Juyn                                * */
154 /* *             - fixed LOOP iteration=0 special case                      * */
155 /* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
156 /* *             - fixed color-correction for restore-background handling   * */
157 /* *             - optimized restore-background for bKGD cases              * */
158 /* *             - cleaned up some old stuff                                * */
159 /* *             1.0.5 - 09/20/2002 - G.Juyn                                * */
160 /* *             - finished support for BACK image & tiling                 * */
161 /* *             - added support for PAST                                   * */
162 /* *             1.0.5 - 09/22/2002 - G.Juyn                                * */
163 /* *             - added bgrx8 canvas (filler byte)                         * */
164 /* *             1.0.5 - 10/05/2002 - G.Juyn                                * */
165 /* *             - fixed dropping mix of frozen/unfrozen objects            * */
166 /* *             1.0.5 - 10/07/2002 - G.Juyn                                * */
167 /* *             - added proposed change in handling of TERM- & if-delay    * */
168 /* *             - added another fix for misplaced TERM chunk               * */
169 /* *             - completed support for condition=2 in TERM chunk          * */
170 /* *             1.0.5 - 10/18/2002 - G.Juyn                                * */
171 /* *             - fixed clipping-problem with BACK tiling (Thanks Sakura!) * */
172 /* *             1.0.5 - 10/20/2002 - G.Juyn                                * */
173 /* *             - fixed processing for multiple objects in MAGN            * */
174 /* *             - fixed display of visible target of PAST operation        * */
175 /* *             1.0.5 - 10/30/2002 - G.Juyn                                * */
176 /* *             - modified TERM/MEND processing for max(1, TERM_delay,     * */
177 /* *               interframe_delay)                                        * */
178 /* *             1.0.5 - 11/04/2002 - G.Juyn                                * */
179 /* *             - fixed layer- & frame-counting during read()              * */
180 /* *             - fixed goframe/golayer/gotime processing                  * */
181 /* *             1.0.5 - 01/19/2003 - G.Juyn                                * */
182 /* *             - B654627 - fixed SEGV when no gettickcount callback       * */
183 /* *             - B664383 - fixed typo                                     * */
184 /* *             - finalized changes in TERM/final_delay to elected proposal* */
185 /* *                                                                        * */
186 /* *             1.0.6 - 05/11/2003 - G. Juyn                               * */
187 /* *             - added conditionals around canvas update routines         * */
188 /* *             1.0.6 - 05/25/2003 - G.R-P                                 * */
189 /* *             - added MNG_SKIPCHUNK_cHNK footprint optimizations         * */
190 /* *             1.0.6 - 07/07/2003 - G.R-P                                 * */
191 /* *             - added conditionals around some JNG-supporting code       * */
192 /* *             - added conditionals around 16-bit supporting code         * */
193 /* *             - reversed some loops to use decrementing counter          * */
194 /* *             - combined init functions into one function                * */
195 /* *             1.0.6 - 07/10/2003 - G.R-P                                 * */
196 /* *             - replaced nested switches with simple init setup function * */
197 /* *             1.0.6 - 07/29/2003 - G.R-P                                 * */
198 /* *             - added conditionals around PAST chunk support             * */
199 /* *             1.0.6 - 08/17/2003 - G.R-P                                 * */
200 /* *             - added conditionals around non-VLC chunk support          * */
201 /* *                                                                        * */
202 /* *             1.0.7 - 11/27/2003 - R.A                                   * */
203 /* *             - added CANVAS_RGB565 and CANVAS_BGR565                    * */
204 /* *             1.0.7 - 12/06/2003 - R.A                                   * */
205 /* *             - added CANVAS_RGBA565 and CANVAS_BGRA565                  * */
206 /* *             1.0.7 - 01/25/2004 - J.S                                   * */
207 /* *             - added premultiplied alpha canvas' for RGBA, ARGB, ABGR   * */
208 /* *                                                                        * */
209 /* *             1.0.8 - 03/31/2004 - G.Juyn                                * */
210 /* *             - fixed problem with PAST usage where source > dest        * */
211 /* *             1.0.8 - 05/04/2004 - G.R-P.                                * */
212 /* *             - fixed misplaced 16-bit conditionals                      * */
213 /* *                                                                        * */
214 /* *             1.0.9 - 09/18/2004 - G.R-P.                                * */
215 /* *             - revised some SKIPCHUNK conditionals                      * */
216 /* *             1.0.9 - 10/10/2004 - G.R-P.                                * */
217 /* *             - added MNG_NO_1_2_4BIT_SUPPORT                            * */
218 /* *             1.0.9 - 10/14/2004 - G.Juyn                                * */
219 /* *             - added bgr565_a8 canvas-style (thanks to J. Elvander)     * */
220 /* *             1.0.9 - 12/11/2004 - G.Juyn                                * */
221 /* *             - added conditional MNG_OPTIMIZE_DISPLAYCALLS              * */
222 /* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
223 /* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
224 /* *                                                                        * */
225 /* *             1.0.10 - 07/06/2005 - G.R-P.                               * */
226 /* *             - added more SKIPCHUNK conditionals                        * */
227 /* *             1.0.10 - 12/28/2005 - G.R-P.                               * */
228 /* *             - added missing SKIPCHUNK_MAGN conditional                 * */
229 /* *             1.0.10 - 03/07/2006 - (thanks to W. Manthey)               * */
230 /* *             - added CANVAS_RGB555 and CANVAS_BGR555                    * */
231 /* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
232 /* *             - fixed several compiler warnings                          * */
233 /* *             1.0.10 - 04/08/2007 - G.Juyn                               * */
234 /* *             - added support for mPNG proposal                          * */
235 /* *             1.0.10 - 04/12/2007 - G.Juyn                               * */
236 /* *             - added support for ANG proposal                           * */
237 /* *                                                                        * */
238 /* ************************************************************************** */
239 
240 #include "libmng.h"
241 #include "libmng_data.h"
242 #include "libmng_error.h"
243 #include "libmng_trace.h"
244 #ifdef __BORLANDC__
245 #pragma hdrstop
246 #endif
247 #include "libmng_chunks.h"
248 #include "libmng_objects.h"
249 #include "libmng_object_prc.h"
250 #include "libmng_memory.h"
251 #include "libmng_zlib.h"
252 #include "libmng_jpeg.h"
253 #include "libmng_cms.h"
254 #include "libmng_pixels.h"
255 #include "libmng_display.h"
256 
257 #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
258 #pragma option -A                      /* force ANSI-C */
259 #endif
260 
261 /* ************************************************************************** */
262 
263 #ifdef MNG_INCLUDE_DISPLAY_PROCS
264 
265 /* ************************************************************************** */
266 
set_delay(mng_datap pData,mng_uint32 iInterval)267 MNG_LOCAL mng_retcode set_delay (mng_datap  pData,
268                                  mng_uint32 iInterval)
269 {
270   if (!iInterval)                      /* at least 1 msec please! */
271     iInterval = 1;
272 
273   if (pData->bRunning)                 /* only when really displaying */
274     if (!pData->fSettimer ((mng_handle)pData, iInterval))
275       MNG_ERROR (pData, MNG_APPTIMERERROR);
276 
277 #ifdef MNG_SUPPORT_DYNAMICMNG
278   if ((!pData->bDynamic) || (pData->bRunning))
279 #else
280   if (pData->bRunning)
281 #endif
282     pData->bTimerset = MNG_TRUE;       /* and indicate so */
283 
284   return MNG_NOERROR;
285 }
286 
287 /* ************************************************************************** */
288 
calculate_delay(mng_datap pData,mng_uint32 iDelay)289 MNG_LOCAL mng_uint32 calculate_delay (mng_datap  pData,
290                                       mng_uint32 iDelay)
291 {
292   mng_uint32 iTicks   = pData->iTicks;
293   mng_uint32 iWaitfor = 1;             /* default non-MNG delay */
294 
295   if (!iTicks)                         /* tick_count not specified ? */
296     if (pData->eImagetype == mng_it_mng)
297       iTicks = 1000;
298 
299   if (iTicks)
300   {
301     switch (pData->iSpeed)             /* honor speed modifier */
302     {
303       case mng_st_fast :
304         {
305           iWaitfor = (mng_uint32)(( 500 * iDelay) / iTicks);
306           break;
307         }
308       case mng_st_slow :
309         {
310           iWaitfor = (mng_uint32)((3000 * iDelay) / iTicks);
311           break;
312         }
313       case mng_st_slowest :
314         {
315           iWaitfor = (mng_uint32)((8000 * iDelay) / iTicks);
316           break;
317         }
318       default :
319         {
320           iWaitfor = (mng_uint32)((1000 * iDelay) / iTicks);
321         }
322     }
323   }
324 
325   return iWaitfor;
326 }
327 
328 /* ************************************************************************** */
329 /* *                                                                        * */
330 /* * Progressive display refresh - does the call to the refresh callback    * */
331 /* * and sets the timer to allow the app to perform the actual refresh to   * */
332 /* * the screen (eg. process its main message-loop)                         * */
333 /* *                                                                        * */
334 /* ************************************************************************** */
335 
mng_display_progressive_refresh(mng_datap pData,mng_uint32 iInterval)336 mng_retcode mng_display_progressive_refresh (mng_datap  pData,
337                                              mng_uint32 iInterval)
338 {
339   {                                    /* let the app refresh first ? */
340     if ((pData->bRunning) && (!pData->bSkipping) &&
341         (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
342     {
343       if (!pData->fRefresh (((mng_handle)pData),
344                             pData->iUpdateleft, pData->iUpdatetop,
345                             pData->iUpdateright  - pData->iUpdateleft,
346                             pData->iUpdatebottom - pData->iUpdatetop))
347         MNG_ERROR (pData, MNG_APPMISCERROR);
348 
349       pData->iUpdateleft   = 0;        /* reset update-region */
350       pData->iUpdateright  = 0;
351       pData->iUpdatetop    = 0;
352       pData->iUpdatebottom = 0;        /* reset refreshneeded indicator */
353       pData->bNeedrefresh  = MNG_FALSE;
354                                        /* interval requested ? */
355       if ((!pData->bFreezing) && (iInterval))
356       {                                /* setup the timer */
357         mng_retcode iRetcode = set_delay (pData, iInterval);
358 
359         if (iRetcode)                  /* on error bail out */
360           return iRetcode;
361       }
362     }
363   }
364 
365   return MNG_NOERROR;
366 }
367 
368 /* ************************************************************************** */
369 /* *                                                                        * */
370 /* * Generic display routines                                               * */
371 /* *                                                                        * */
372 /* ************************************************************************** */
373 
interframe_delay(mng_datap pData)374 MNG_LOCAL mng_retcode interframe_delay (mng_datap pData)
375 {
376   mng_uint32  iWaitfor = 0;
377   mng_uint32  iInterval;
378   mng_uint32  iRuninterval;
379   mng_retcode iRetcode;
380 
381 #ifdef MNG_SUPPORT_TRACE
382   MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_START);
383 #endif
384 
385   {
386 #ifndef MNG_SKIPCHUNK_FRAM
387     if (pData->iFramedelay > 0 || pData->bForcedelay) /* real delay ? */
388     {                                  /* let the app refresh first ? */
389       pData->bForcedelay = MNG_FALSE;
390       if ((pData->bRunning) && (!pData->bSkipping) &&
391           (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
392         if (!pData->fRefresh (((mng_handle)pData),
393                               pData->iUpdateleft,  pData->iUpdatetop,
394                               pData->iUpdateright - pData->iUpdateleft,
395                               pData->iUpdatebottom - pData->iUpdatetop))
396           MNG_ERROR (pData, MNG_APPMISCERROR);
397 
398       pData->iUpdateleft   = 0;        /* reset update-region */
399       pData->iUpdateright  = 0;
400       pData->iUpdatetop    = 0;
401       pData->iUpdatebottom = 0;        /* reset refreshneeded indicator */
402       pData->bNeedrefresh  = MNG_FALSE;
403 
404 #ifndef MNG_SKIPCHUNK_TERM
405       if (pData->bOnlyfirstframe)      /* only processing first frame after TERM ? */
406       {
407         pData->iFramesafterTERM++;
408                                        /* did we do a frame yet ? */
409         if (pData->iFramesafterTERM > 1)
410         {                              /* then that's it; just stop right here ! */
411           pData->pCurraniobj = MNG_NULL;
412           pData->bRunning    = MNG_FALSE;
413 
414           return MNG_NOERROR;
415         }
416       }
417 #endif
418 
419       if (pData->fGettickcount)
420       {                                /* get current tickcount */
421         pData->iRuntime = pData->fGettickcount ((mng_handle)pData);
422                                        /* calculate interval since last sync-point */
423         if (pData->iRuntime < pData->iSynctime)
424           iRuninterval    = pData->iRuntime + ~pData->iSynctime + 1;
425         else
426           iRuninterval    = pData->iRuntime - pData->iSynctime;
427                                        /* calculate actual run-time */
428         if (pData->iRuntime < pData->iStarttime)
429           pData->iRuntime = pData->iRuntime + ~pData->iStarttime + 1;
430         else
431           pData->iRuntime = pData->iRuntime - pData->iStarttime;
432       }
433       else
434       {
435         iRuninterval = 0;
436       }
437 
438       iWaitfor = calculate_delay (pData, pData->iFramedelay);
439 
440       if (iWaitfor > iRuninterval)     /* delay necessary ? */
441         iInterval = iWaitfor - iRuninterval;
442       else
443         iInterval = 1;                 /* force app to process messageloop */
444                                        /* set the timer ? */
445       if (((pData->bRunning) || (pData->bSearching) || (pData->bReading)) &&
446           (!pData->bSkipping))
447       {
448         iRetcode = set_delay (pData, iInterval);
449 
450         if (iRetcode)                  /* on error bail out */
451           return iRetcode;
452       }
453     }
454 
455     if (!pData->bSkipping)             /* increase frametime in advance */
456       pData->iFrametime = pData->iFrametime + iWaitfor;
457                                        /* setup for next delay */
458     pData->iFramedelay = pData->iNextdelay;
459     pData->iAccumdelay += pData->iFramedelay;
460 #endif
461   }
462 
463 #ifdef MNG_SUPPORT_TRACE
464   MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_END);
465 #endif
466 
467   return MNG_NOERROR;
468 }
469 
470 /* ************************************************************************** */
471 
set_display_routine(mng_datap pData)472 MNG_LOCAL void set_display_routine (mng_datap pData)
473 {                                        /* actively running ? */
474   if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
475   {
476     switch (pData->iCanvasstyle)         /* determine display routine */
477     {
478 #ifndef MNG_SKIPCANVAS_RGB8
479       case MNG_CANVAS_RGB8    : { pData->fDisplayrow = (mng_fptr)mng_display_rgb8;     break; }
480 #endif
481 #ifndef MNG_SKIPCANVAS_RGBA8
482       case MNG_CANVAS_RGBA8   : { pData->fDisplayrow = (mng_fptr)mng_display_rgba8;    break; }
483 #endif
484 #ifndef MNG_SKIPCANVAS_RGBA8_PM
485       case MNG_CANVAS_RGBA8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_rgba8_pm; break; }
486 #endif
487 #ifndef MNG_SKIPCANVAS_ARGB8
488       case MNG_CANVAS_ARGB8   : { pData->fDisplayrow = (mng_fptr)mng_display_argb8;    break; }
489 #endif
490 #ifndef MNG_SKIPCANVAS_ARGB8_PM
491       case MNG_CANVAS_ARGB8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_argb8_pm; break; }
492 #endif
493 #ifndef MNG_SKIPCANVAS_RGB8_A8
494       case MNG_CANVAS_RGB8_A8 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb8_a8;  break; }
495 #endif
496 #ifndef MNG_SKIPCANVAS_BGR8
497       case MNG_CANVAS_BGR8    : { pData->fDisplayrow = (mng_fptr)mng_display_bgr8;     break; }
498 #endif
499 #ifndef MNG_SKIPCANVAS_BGRX8
500       case MNG_CANVAS_BGRX8   : { pData->fDisplayrow = (mng_fptr)mng_display_bgrx8;    break; }
501 #endif
502 #ifndef MNG_SKIPCANVAS_BGRA8
503       case MNG_CANVAS_BGRA8   : { pData->fDisplayrow = (mng_fptr)mng_display_bgra8;    break; }
504 #endif
505 #ifndef MNG_SKIPCANVAS_BGRA8_PM
506       case MNG_CANVAS_BGRA8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_bgra8_pm; break; }
507 #endif
508 #ifndef MNG_SKIPCANVAS_ABGR8
509       case MNG_CANVAS_ABGR8   : { pData->fDisplayrow = (mng_fptr)mng_display_abgr8;    break; }
510 #endif
511 #ifndef MNG_SKIPCANVAS_ABGR8_PM
512       case MNG_CANVAS_ABGR8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_abgr8_pm; break; }
513 #endif
514 #ifndef MNG_SKIPCANVAS_RGB565
515       case MNG_CANVAS_RGB565  : { pData->fDisplayrow = (mng_fptr)mng_display_rgb565;   break; }
516 #endif
517 #ifndef MNG_SKIPCANVAS_RGBA565
518       case MNG_CANVAS_RGBA565 : { pData->fDisplayrow = (mng_fptr)mng_display_rgba565;  break; }
519 #endif
520 #ifndef MNG_SKIPCANVAS_BGR565
521       case MNG_CANVAS_BGR565  : { pData->fDisplayrow = (mng_fptr)mng_display_bgr565;   break; }
522 #endif
523 #ifndef MNG_SKIPCANVAS_BGRA565
524       case MNG_CANVAS_BGRA565 : { pData->fDisplayrow = (mng_fptr)mng_display_bgra565;  break; }
525 #endif
526 #ifndef MNG_SKIPCANVAS_BGR565_A8
527       case MNG_CANVAS_BGR565_A8 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr565_a8;  break; }
528 #endif
529 #ifndef MNG_SKIPCANVAS_RGB555
530       case MNG_CANVAS_RGB555  : { pData->fDisplayrow = (mng_fptr)mng_display_rgb555;  break; }
531 #endif
532 #ifndef MNG_SKIPCANVAS_BGR555
533       case MNG_CANVAS_BGR555  : { pData->fDisplayrow = (mng_fptr)mng_display_bgr555;  break; }
534 #endif
535 
536 #ifndef MNG_NO_16BIT_SUPPORT
537 /*      case MNG_CANVAS_RGB16   : { pData->fDisplayrow = (mng_fptr)mng_display_rgb16;    break; } */
538 /*      case MNG_CANVAS_RGBA16  : { pData->fDisplayrow = (mng_fptr)mng_display_rgba16;   break; } */
539 /*      case MNG_CANVAS_ARGB16  : { pData->fDisplayrow = (mng_fptr)mng_display_argb16;   break; } */
540 /*      case MNG_CANVAS_BGR16   : { pData->fDisplayrow = (mng_fptr)mng_display_bgr16;    break; } */
541 /*      case MNG_CANVAS_BGRA16  : { pData->fDisplayrow = (mng_fptr)mng_display_bgra16;   break; } */
542 /*      case MNG_CANVAS_ABGR16  : { pData->fDisplayrow = (mng_fptr)mng_display_abgr16;   break; } */
543 #endif
544 /*      case MNG_CANVAS_INDEX8  : { pData->fDisplayrow = (mng_fptr)mng_display_index8;   break; } */
545 /*      case MNG_CANVAS_INDEXA8 : { pData->fDisplayrow = (mng_fptr)mng_display_indexa8;  break; } */
546 /*      case MNG_CANVAS_AINDEX8 : { pData->fDisplayrow = (mng_fptr)mng_display_aindex8;  break; } */
547 /*      case MNG_CANVAS_GRAY8   : { pData->fDisplayrow = (mng_fptr)mng_display_gray8;    break; } */
548 /*      case MNG_CANVAS_AGRAY8  : { pData->fDisplayrow = (mng_fptr)mng_display_agray8;   break; } */
549 /*      case MNG_CANVAS_GRAYA8  : { pData->fDisplayrow = (mng_fptr)mng_display_graya8;   break; } */
550 #ifndef MNG_NO_16BIT_SUPPORT
551 /*      case MNG_CANVAS_GRAY16  : { pData->fDisplayrow = (mng_fptr)mng_display_gray16;   break; } */
552 /*      case MNG_CANVAS_GRAYA16 : { pData->fDisplayrow = (mng_fptr)mng_display_graya16;  break; } */
553 /*      case MNG_CANVAS_AGRAY16 : { pData->fDisplayrow = (mng_fptr)mng_display_agray16;  break; } */
554 #endif
555 /*      case MNG_CANVAS_DX15    : { pData->fDisplayrow = (mng_fptr)mng_display_dx15;     break; } */
556 /*      case MNG_CANVAS_DX16    : { pData->fDisplayrow = (mng_fptr)mng_display_dx16;     break; } */
557     }
558   }
559 
560   return;
561 }
562 
563 /* ************************************************************************** */
564 
load_bkgdlayer(mng_datap pData)565 MNG_LOCAL mng_retcode load_bkgdlayer (mng_datap pData)
566 {
567 #ifdef MNG_SUPPORT_TRACE
568   MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_START);
569 #endif
570                                        /* actively running ? */
571   if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
572   {
573     mng_int32   iY;
574     mng_retcode iRetcode;
575     mng_bool    bColorcorr   = MNG_FALSE;
576                                        /* save values */
577     mng_int32   iDestl       = pData->iDestl;
578     mng_int32   iDestr       = pData->iDestr;
579     mng_int32   iDestt       = pData->iDestt;
580     mng_int32   iDestb       = pData->iDestb;
581     mng_int32   iSourcel     = pData->iSourcel;
582     mng_int32   iSourcer     = pData->iSourcer;
583     mng_int32   iSourcet     = pData->iSourcet;
584     mng_int32   iSourceb     = pData->iSourceb;
585     mng_int8    iPass        = pData->iPass;
586     mng_int32   iRow         = pData->iRow;
587     mng_int32   iRowinc      = pData->iRowinc;
588     mng_int32   iCol         = pData->iCol;
589     mng_int32   iColinc      = pData->iColinc;
590     mng_int32   iRowsamples  = pData->iRowsamples;
591     mng_int32   iRowsize     = pData->iRowsize;
592     mng_uint8p  pPrevrow     = pData->pPrevrow;
593     mng_uint8p  pRGBArow     = pData->pRGBArow;
594     mng_bool    bIsRGBA16    = pData->bIsRGBA16;
595     mng_bool    bIsOpaque    = pData->bIsOpaque;
596     mng_fptr    fCorrectrow  = pData->fCorrectrow;
597     mng_fptr    fDisplayrow  = pData->fDisplayrow;
598     mng_fptr    fRetrieverow = pData->fRetrieverow;
599     mng_objectp pCurrentobj  = pData->pCurrentobj;
600     mng_objectp pRetrieveobj = pData->pRetrieveobj;
601 
602     pData->iDestl   = 0;               /* determine clipping region */
603     pData->iDestt   = 0;
604     pData->iDestr   = pData->iWidth;
605     pData->iDestb   = pData->iHeight;
606 
607 #ifndef MNG_SKIPCHUNK_FRAM
608     if (pData->bFrameclipping)         /* frame clipping specified ? */
609     {
610       pData->iDestl = MAX_COORD (pData->iDestl,  pData->iFrameclipl);
611       pData->iDestt = MAX_COORD (pData->iDestt,  pData->iFrameclipt);
612       pData->iDestr = MIN_COORD (pData->iDestr,  pData->iFrameclipr);
613       pData->iDestb = MIN_COORD (pData->iDestb,  pData->iFrameclipb);
614     }
615 #endif
616                                        /* anything to clear ? */
617     if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
618     {
619       pData->iPass       = -1;         /* these are the object's dimensions now */
620       pData->iRow        = 0;
621       pData->iRowinc     = 1;
622       pData->iCol        = 0;
623       pData->iColinc     = 1;
624       pData->iRowsamples = pData->iWidth;
625       pData->iRowsize    = pData->iRowsamples << 2;
626       pData->bIsRGBA16   = MNG_FALSE;  /* let's keep it simple ! */
627       pData->bIsOpaque   = MNG_TRUE;
628 
629       pData->iSourcel    = 0;          /* source relative to destination */
630       pData->iSourcer    = pData->iDestr - pData->iDestl;
631       pData->iSourcet    = 0;
632       pData->iSourceb    = pData->iDestb - pData->iDestt;
633 
634       set_display_routine (pData);     /* determine display routine */
635                                        /* default restore using preset BG color */
636       pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgcolor;
637 
638 #ifndef MNG_SKIPCHUNK_bKGD
639       if (((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng)) &&
640           (pData->bUseBKGD))
641       {                                /* prefer bKGD in PNG/JNG */
642         if (!pData->pCurrentobj)
643           pData->pCurrentobj = pData->pObjzero;
644 
645         if (((mng_imagep)pData->pCurrentobj)->pImgbuf->bHasBKGD)
646         {
647           pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bkgd;
648           bColorcorr          = MNG_TRUE;
649         }
650       }
651 #endif
652 
653       if (pData->fGetbkgdline)         /* background-canvas-access callback set ? */
654       {
655         switch (pData->iBkgdstyle)
656         {
657 #ifndef MNG_SKIPCANVAS_RGB8
658           case MNG_CANVAS_RGB8    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb8;    break; }
659 #endif
660 #ifndef MNG_SKIPCANVAS_BGR8
661           case MNG_CANVAS_BGR8    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr8;    break; }
662 #endif
663 #ifndef MNG_SKIPCANVAS_BGRX8
664           case MNG_CANVAS_BGRX8   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgrx8;   break; }
665 #endif
666 #ifndef MNG_SKIPCANVAS_BGR565
667           case MNG_CANVAS_BGR565  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr565;  break; }
668 #endif
669 #ifndef MNG_SKIPCANVAS_RGB565
670           case MNG_CANVAS_RGB565  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb565;  break; }
671 #endif
672 #ifndef MNG_NO_16BIT_SUPPORT
673   /*        case MNG_CANVAS_RGB16   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb16;   break; } */
674   /*        case MNG_CANVAS_BGR16   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr16;   break; } */
675 #endif
676   /*        case MNG_CANVAS_INDEX8  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_index8;  break; } */
677   /*        case MNG_CANVAS_GRAY8   : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_gray8;   break; } */
678 #ifndef MNG_NO_16BIT_SUPPORT
679   /*        case MNG_CANVAS_GRAY16  : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_gray16;  break; } */
680 #endif
681   /*        case MNG_CANVAS_DX15    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_dx15;    break; } */
682   /*        case MNG_CANVAS_DX16    : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_dx16;    break; } */
683         }
684       }
685 
686 #ifndef MNG_SKIPCHUNK_BACK
687       if (pData->bHasBACK)
688       {                                /* background image ? */
689         if ((pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
690         {
691           pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_backcolor;
692           bColorcorr          = MNG_TRUE;
693         }
694         else                           /* background color ? */
695         if (pData->iBACKmandatory & 0x01)
696         {
697           pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_backcolor;
698           bColorcorr          = MNG_TRUE;
699         }
700       }
701 #endif
702 
703       pData->fCorrectrow = MNG_NULL;   /* default no color-correction */
704 
705       if (bColorcorr)                  /* do we have to do color-correction ? */
706       {
707 #ifdef MNG_NO_CMS
708         iRetcode = MNG_NOERROR;
709 #else
710 #if defined(MNG_FULL_CMS)              /* determine color-management routine */
711         iRetcode = mng_init_full_cms   (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
712 #elif defined(MNG_GAMMA_ONLY)
713         iRetcode = mng_init_gamma_only (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
714 #elif defined(MNG_APP_CMS)
715         iRetcode = mng_init_app_cms    (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
716 #endif
717         if (iRetcode)                  /* on error bail out */
718           return iRetcode;
719 #endif /* MNG_NO_CMS */
720       }
721                                        /* get a temporary row-buffer */
722       MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
723 
724       iY       = pData->iDestt;        /* this is where we start */
725       iRetcode = MNG_NOERROR;          /* so far, so good */
726 
727       while ((!iRetcode) && (iY < pData->iDestb))
728       {                                /* restore a background row */
729         iRetcode = ((mng_restbkgdrow)pData->fRestbkgdrow) (pData);
730                                        /* color correction ? */
731         if ((!iRetcode) && (pData->fCorrectrow))
732           iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
733 
734         if (!iRetcode)                 /* so... display it */
735           iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
736 
737         if (!iRetcode)
738           iRetcode = mng_next_row (pData);
739 
740         iY++;                          /* and next line */
741       }
742                                        /* drop the temporary row-buffer */
743       MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
744 
745       if (iRetcode)                    /* on error bail out */
746         return iRetcode;
747 
748 #if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
749       if (bColorcorr)                  /* did we do color-correction ? */
750       {
751         iRetcode = mng_clear_cms (pData);
752 
753         if (iRetcode)                  /* on error bail out */
754           return iRetcode;
755       }
756 #endif
757 #ifndef MNG_SKIPCHUNK_BACK
758                                        /* background image ? */
759       if ((pData->bHasBACK) && (pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
760       {
761         mng_imagep pImage;
762                                        /* let's find that object then */
763         pData->pRetrieveobj = mng_find_imageobject (pData, pData->iBACKimageid);
764         pImage              = (mng_imagep)pData->pRetrieveobj;
765                                        /* exists, viewable and visible ? */
766         if ((pImage) && (pImage->bViewable) && (pImage->bVisible))
767         {                              /* will it fall within the target region ? */
768           if ((pImage->iPosx < pData->iDestr) && (pImage->iPosy < pData->iDestb)             &&
769               ((pData->iBACKtile) ||
770                ((pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth  >= pData->iDestl) &&
771                 (pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight >= pData->iDestt)    )) &&
772               ((!pImage->bClipped) ||
773                ((pImage->iClipl <= pImage->iClipr) && (pImage->iClipt <= pImage->iClipb)     &&
774                 (pImage->iClipl < pData->iDestr)   && (pImage->iClipr >= pData->iDestl)      &&
775                 (pImage->iClipt < pData->iDestb)   && (pImage->iClipb >= pData->iDestt)         )))
776           {                            /* right; we've got ourselves something to do */
777             if (pImage->bClipped)      /* clip output region with image's clipping region ? */
778             {
779               if (pImage->iClipl > pData->iDestl)
780                 pData->iDestl = pImage->iClipl;
781               if (pImage->iClipr < pData->iDestr)
782                 pData->iDestr = pImage->iClipr;
783               if (pImage->iClipt > pData->iDestt)
784                 pData->iDestt = pImage->iClipt;
785               if (pImage->iClipb < pData->iDestb)
786                 pData->iDestb = pImage->iClipb;
787             }
788                                        /* image offset does some extra clipping too ! */
789             if (pImage->iPosx > pData->iDestl)
790               pData->iDestl = pImage->iPosx;
791             if (pImage->iPosy > pData->iDestt)
792               pData->iDestt = pImage->iPosy;
793 
794             if (!pData->iBACKtile)     /* without tiling further clipping is needed */
795             {
796               if (pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth  < pData->iDestr)
797                 pData->iDestr = pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth;
798               if (pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight < pData->iDestb)
799                 pData->iDestb = pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight;
800             }
801 
802             pData->iSourcel    = 0;    /* source relative to destination */
803             pData->iSourcer    = pData->iDestr - pData->iDestl;
804             pData->iSourcet    = 0;
805             pData->iSourceb    = pData->iDestb - pData->iDestt;
806                                        /* 16-bit background ? */
807 
808 #ifdef MNG_NO_16BIT_SUPPORT
809             pData->bIsRGBA16   = MNG_FALSE;
810 #else
811             pData->bIsRGBA16      = (mng_bool)(pImage->pImgbuf->iBitdepth > 8);
812 #endif
813                                        /* let restore routine know the offsets !!! */
814             pData->iBackimgoffsx  = pImage->iPosx;
815             pData->iBackimgoffsy  = pImage->iPosy;
816             pData->iBackimgwidth  = pImage->pImgbuf->iWidth;
817             pData->iBackimgheight = pImage->pImgbuf->iHeight;
818             pData->iRow           = 0; /* start at the top again !! */
819                                        /* determine background object retrieval routine */
820             switch (pImage->pImgbuf->iColortype)
821             {
822               case  0 : {
823 #ifndef MNG_NO_16BIT_SUPPORT
824                           if (pImage->pImgbuf->iBitdepth > 8)
825                             pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
826                           else
827 #endif
828                             pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
829 
830                           pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
831                           break;
832                         }
833 
834               case  2 : {
835 #ifndef MNG_NO_16BIT_SUPPORT
836                           if (pImage->pImgbuf->iBitdepth > 8)
837                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
838                           else
839 #endif
840                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
841 
842                           pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
843                           break;
844                         }
845 
846               case  3 : { pData->fRetrieverow   = (mng_fptr)mng_retrieve_idx8;
847                           pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
848                           break;
849                         }
850 
851               case  4 : {
852 #ifndef MNG_NO_16BIT_SUPPORT
853 			if (pImage->pImgbuf->iBitdepth > 8)
854                             pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
855                           else
856 #endif
857                             pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
858 
859                           pData->bIsOpaque      = MNG_FALSE;
860                           break;
861                         }
862 
863               case  6 : {
864 #ifndef MNG_NO_16BIT_SUPPORT
865                           if (pImage->pImgbuf->iBitdepth > 8)
866                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
867                           else
868 #endif
869                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
870 
871                           pData->bIsOpaque      = MNG_FALSE;
872                           break;
873                         }
874 
875               case  8 : {
876 #ifndef MNG_NO_16BIT_SUPPORT
877                           if (pImage->pImgbuf->iBitdepth > 8)
878                             pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
879                           else
880 #endif
881                             pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
882 
883                           pData->bIsOpaque      = MNG_TRUE;
884                           break;
885                         }
886 
887               case 10 : {
888 #ifndef MNG_NO_16BIT_SUPPORT
889                           if (pImage->pImgbuf->iBitdepth > 8)
890                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
891                           else
892 #endif
893                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
894 
895                           pData->bIsOpaque      = MNG_TRUE;
896                           break;
897                         }
898 
899               case 12 : {
900 #ifndef MNG_NO_16BIT_SUPPORT
901                           if (pImage->pImgbuf->iBitdepth > 8)
902                             pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
903                           else
904 #endif
905                             pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
906 
907                           pData->bIsOpaque      = MNG_FALSE;
908                           break;
909                         }
910 
911               case 14 : {
912 #ifndef MNG_NO_16BIT_SUPPORT
913                           if (pImage->pImgbuf->iBitdepth > 8)
914                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
915                           else
916 #endif
917                             pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
918 
919                           pData->bIsOpaque      = MNG_FALSE;
920                           break;
921                         }
922             }
923 
924 #ifdef MNG_NO_CMS
925             iRetcode = MNG_NOERROR;
926 #else
927 #if defined(MNG_FULL_CMS)              /* determine color-management routine */
928             iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
929 #elif defined(MNG_GAMMA_ONLY)
930             iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
931 #elif defined(MNG_APP_CMS)
932             iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
933 #endif
934             if (iRetcode)              /* on error bail out */
935               return iRetcode;
936 #endif /* MNG_NO_CMS */
937                                        /* get temporary row-buffers */
938             MNG_ALLOC (pData, pData->pPrevrow, pData->iRowsize);
939             MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
940 
941             iY       = pData->iDestt;  /* this is where we start */
942             iRetcode = MNG_NOERROR;    /* so far, so good */
943 
944             while ((!iRetcode) && (iY < pData->iDestb))
945             {                          /* restore a background row */
946               iRetcode = mng_restore_bkgd_backimage (pData);
947                                        /* color correction ? */
948               if ((!iRetcode) && (pData->fCorrectrow))
949                 iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
950 
951               if (!iRetcode)           /* so... display it */
952                 iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
953 
954               if (!iRetcode)
955                 iRetcode = mng_next_row (pData);
956 
957               iY++;                    /* and next line */
958             }
959                                        /* drop temporary row-buffers */
960             MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
961             MNG_FREE (pData, pData->pPrevrow, pData->iRowsize);
962 
963             if (iRetcode)              /* on error bail out */
964               return iRetcode;
965 
966 #if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
967             iRetcode = mng_clear_cms (pData);
968 
969             if (iRetcode)              /* on error bail out */
970               return iRetcode;
971 #endif
972           }
973         }
974       }
975 #endif
976     }
977 
978     pData->iDestl       = iDestl;      /* restore values */
979     pData->iDestr       = iDestr;
980     pData->iDestt       = iDestt;
981     pData->iDestb       = iDestb;
982     pData->iSourcel     = iSourcel;
983     pData->iSourcer     = iSourcer;
984     pData->iSourcet     = iSourcet;
985     pData->iSourceb     = iSourceb;
986     pData->iPass        = iPass;
987     pData->iRow         = iRow;
988     pData->iRowinc      = iRowinc;
989     pData->iCol         = iCol;
990     pData->iColinc      = iColinc;
991     pData->iRowsamples  = iRowsamples;
992     pData->iRowsize     = iRowsize;
993     pData->pPrevrow     = pPrevrow;
994     pData->pRGBArow     = pRGBArow;
995     pData->bIsRGBA16    = bIsRGBA16;
996     pData->bIsOpaque    = bIsOpaque;
997     pData->fCorrectrow  = fCorrectrow;
998     pData->fDisplayrow  = fDisplayrow;
999     pData->fRetrieverow = fRetrieverow;
1000     pData->pCurrentobj  = pCurrentobj;
1001     pData->pRetrieveobj = pRetrieveobj;
1002   }
1003 
1004 #ifdef MNG_SUPPORT_TRACE
1005   MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_END);
1006 #endif
1007 
1008   return MNG_NOERROR;
1009 }
1010 
1011 /* ************************************************************************** */
1012 
clear_canvas(mng_datap pData)1013 MNG_LOCAL mng_retcode clear_canvas (mng_datap pData)
1014 {
1015   mng_int32   iY;
1016   mng_retcode iRetcode;
1017 
1018 #ifdef MNG_SUPPORT_TRACE
1019   MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_START);
1020 #endif
1021 
1022   pData->iDestl      = 0;              /* clipping region is full canvas! */
1023   pData->iDestt      = 0;
1024   pData->iDestr      = pData->iWidth;
1025   pData->iDestb      = pData->iHeight;
1026 
1027   pData->iSourcel    = 0;              /* source is same as destination */
1028   pData->iSourcer    = pData->iWidth;
1029   pData->iSourcet    = 0;
1030   pData->iSourceb    = pData->iHeight;
1031 
1032   pData->iPass       = -1;             /* these are the object's dimensions now */
1033   pData->iRow        = 0;
1034   pData->iRowinc     = 1;
1035   pData->iCol        = 0;
1036   pData->iColinc     = 1;
1037   pData->iRowsamples = pData->iWidth;
1038   pData->iRowsize    = pData->iRowsamples << 2;
1039   pData->bIsRGBA16   = MNG_FALSE;      /* let's keep it simple ! */
1040   pData->bIsOpaque   = MNG_TRUE;
1041 
1042   set_display_routine (pData);         /* determine display routine */
1043                                        /* get a temporary row-buffer */
1044                                        /* it's transparent black by default!! */
1045   MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
1046 
1047   iY       = pData->iDestt;            /* this is where we start */
1048   iRetcode = MNG_NOERROR;              /* so far, so good */
1049 
1050   while ((!iRetcode) && (iY < pData->iDestb))
1051   {                                    /* clear a row then */
1052     iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
1053 
1054     if (!iRetcode)
1055       iRetcode = mng_next_row (pData); /* adjust variables for next row */
1056 
1057     iY++;                              /* and next line */
1058   }
1059                                        /* drop the temporary row-buffer */
1060   MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
1061 
1062   if (iRetcode)                        /* on error bail out */
1063     return iRetcode;
1064 
1065 #ifdef MNG_SUPPORT_TRACE
1066   MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_END);
1067 #endif
1068 
1069   return MNG_NOERROR;
1070 }
1071 
1072 /* ************************************************************************** */
1073 
next_frame(mng_datap pData,mng_uint8 iFramemode,mng_uint8 iChangedelay,mng_uint32 iDelay,mng_uint8 iChangetimeout,mng_uint32 iTimeout,mng_uint8 iChangeclipping,mng_uint8 iCliptype,mng_int32 iClipl,mng_int32 iClipr,mng_int32 iClipt,mng_int32 iClipb)1074 MNG_LOCAL mng_retcode next_frame (mng_datap  pData,
1075                                   mng_uint8  iFramemode,
1076                                   mng_uint8  iChangedelay,
1077                                   mng_uint32 iDelay,
1078                                   mng_uint8  iChangetimeout,
1079                                   mng_uint32 iTimeout,
1080                                   mng_uint8  iChangeclipping,
1081                                   mng_uint8  iCliptype,
1082                                   mng_int32  iClipl,
1083                                   mng_int32  iClipr,
1084                                   mng_int32  iClipt,
1085                                   mng_int32  iClipb)
1086 {
1087   mng_retcode iRetcode = MNG_NOERROR;
1088 
1089 #ifdef MNG_SUPPORT_TRACE
1090   MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_START);
1091 #endif
1092 
1093   if (!pData->iBreakpoint)             /* no previous break here ? */
1094   {
1095 #ifndef MNG_SKIPCHUNK_FRAM
1096     mng_uint8 iOldmode = pData->iFramemode;
1097                                        /* interframe delay required ? */
1098     if ((iOldmode == 2) || (iOldmode == 4))
1099     {
1100       if ((pData->iFrameseq) && (iFramemode != 1) && (iFramemode != 3))
1101         iRetcode = interframe_delay (pData);
1102       else
1103         pData->iFramedelay = pData->iNextdelay;
1104     }
1105     else
1106     {                                  /* delay before inserting background layer? */
1107       if ((pData->bFramedone) && (iFramemode == 4))
1108         iRetcode = interframe_delay (pData);
1109     }
1110 
1111     if (iRetcode)                      /* on error bail out */
1112       return iRetcode;
1113                                        /* now we'll assume we're in the next frame! */
1114     if (iFramemode)                    /* save the new framing mode ? */
1115     {
1116       pData->iFRAMmode  = iFramemode;
1117       pData->iFramemode = iFramemode;
1118     }
1119     else                               /* reload default */
1120       pData->iFramemode = pData->iFRAMmode;
1121 
1122     if (iChangedelay)                  /* delay changed ? */
1123     {
1124       pData->iNextdelay = iDelay;      /* for *after* next subframe */
1125 
1126       if ((iOldmode == 2) || (iOldmode == 4))
1127         pData->iFramedelay = pData->iFRAMdelay;
1128 
1129       if (iChangedelay == 2)           /* also overall ? */
1130         pData->iFRAMdelay = iDelay;
1131     }
1132     else
1133     {                                  /* reload default */
1134       pData->iNextdelay = pData->iFRAMdelay;
1135     }
1136 
1137     if (iChangetimeout)                /* timeout changed ? */
1138     {                                  /* for next subframe */
1139       pData->iFrametimeout = iTimeout;
1140 
1141       if ((iChangetimeout == 2) ||     /* also overall ? */
1142           (iChangetimeout == 4) ||
1143           (iChangetimeout == 6) ||
1144           (iChangetimeout == 8))
1145         pData->iFRAMtimeout = iTimeout;
1146     }
1147     else                               /* reload default */
1148       pData->iFrametimeout = pData->iFRAMtimeout;
1149 
1150     if (iChangeclipping)               /* clipping changed ? */
1151     {
1152       pData->bFrameclipping = MNG_TRUE;
1153 
1154       if (!iCliptype)                  /* absolute ? */
1155       {
1156         pData->iFrameclipl = iClipl;
1157         pData->iFrameclipr = iClipr;
1158         pData->iFrameclipt = iClipt;
1159         pData->iFrameclipb = iClipb;
1160       }
1161       else                             /* relative */
1162       {
1163         pData->iFrameclipl = pData->iFrameclipl + iClipl;
1164         pData->iFrameclipr = pData->iFrameclipr + iClipr;
1165         pData->iFrameclipt = pData->iFrameclipt + iClipt;
1166         pData->iFrameclipb = pData->iFrameclipb + iClipb;
1167       }
1168 
1169       if (iChangeclipping == 2)        /* also overall ? */
1170       {
1171         pData->bFRAMclipping = MNG_TRUE;
1172 
1173         if (!iCliptype)                /* absolute ? */
1174         {
1175           pData->iFRAMclipl = iClipl;
1176           pData->iFRAMclipr = iClipr;
1177           pData->iFRAMclipt = iClipt;
1178           pData->iFRAMclipb = iClipb;
1179         }
1180         else                           /* relative */
1181         {
1182           pData->iFRAMclipl = pData->iFRAMclipl + iClipl;
1183           pData->iFRAMclipr = pData->iFRAMclipr + iClipr;
1184           pData->iFRAMclipt = pData->iFRAMclipt + iClipt;
1185           pData->iFRAMclipb = pData->iFRAMclipb + iClipb;
1186         }
1187       }
1188     }
1189     else
1190     {                                  /* reload defaults */
1191       pData->bFrameclipping = pData->bFRAMclipping;
1192       pData->iFrameclipl    = pData->iFRAMclipl;
1193       pData->iFrameclipr    = pData->iFRAMclipr;
1194       pData->iFrameclipt    = pData->iFRAMclipt;
1195       pData->iFrameclipb    = pData->iFRAMclipb;
1196     }
1197 #endif
1198   }
1199 
1200   if (!pData->bTimerset)               /* timer still off ? */
1201   {
1202     if (
1203 #ifndef MNG_SKIPCHUNK_FRAM
1204        (pData->iFramemode == 4) ||    /* insert background layer after a new frame */
1205 #endif
1206         (!pData->iLayerseq))           /* and certainly before the very first layer */
1207       iRetcode = load_bkgdlayer (pData);
1208 
1209     if (iRetcode)                      /* on error bail out */
1210       return iRetcode;
1211 
1212     pData->iFrameseq++;                /* count the frame ! */
1213     pData->bFramedone = MNG_TRUE;      /* and indicate we've done one */
1214   }
1215 
1216 #ifdef MNG_SUPPORT_TRACE
1217   MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_END);
1218 #endif
1219 
1220   return MNG_NOERROR;
1221 }
1222 
1223 /* ************************************************************************** */
1224 
next_layer(mng_datap pData)1225 MNG_LOCAL mng_retcode next_layer (mng_datap pData)
1226 {
1227   mng_imagep  pImage;
1228   mng_retcode iRetcode = MNG_NOERROR;
1229 
1230 #ifdef MNG_SUPPORT_TRACE
1231   MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_START);
1232 #endif
1233 
1234 #ifndef MNG_SKIPCHUNK_FRAM
1235   if (!pData->iBreakpoint)             /* no previous break here ? */
1236   {                                    /* interframe delay required ? */
1237     if ((pData->eImagetype == mng_it_mng) && (pData->iLayerseq) &&
1238         ((pData->iFramemode == 1) || (pData->iFramemode == 3)))
1239       iRetcode = interframe_delay (pData);
1240     else
1241       pData->iFramedelay = pData->iNextdelay;
1242 
1243     if (iRetcode)                      /* on error bail out */
1244       return iRetcode;
1245   }
1246 #endif
1247 
1248   if (!pData->bTimerset)               /* timer still off ? */
1249   {
1250     if (!pData->iLayerseq)             /* restore background for the very first layer ? */
1251     {                                  /* wait till IDAT/JDAT for PNGs & JNGs !!! */
1252       if ((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng))
1253         pData->bRestorebkgd = MNG_TRUE;
1254       else
1255       {                                /* for MNG we do it right away */
1256         iRetcode = load_bkgdlayer (pData);
1257         pData->iLayerseq++;            /* and it counts as a layer then ! */
1258       }
1259     }
1260 #ifndef MNG_SKIPCHUNK_FRAM
1261     else
1262     if (pData->iFramemode == 3)        /* restore background for each layer ? */
1263       iRetcode = load_bkgdlayer (pData);
1264 #endif
1265 
1266     if (iRetcode)                      /* on error bail out */
1267       return iRetcode;
1268 
1269 #ifndef MNG_NO_DELTA_PNG
1270     if (pData->bHasDHDR)               /* processing a delta-image ? */
1271       pImage = (mng_imagep)pData->pDeltaImage;
1272     else
1273 #endif
1274       pImage = (mng_imagep)pData->pCurrentobj;
1275 
1276     if (!pImage)                       /* not an active object ? */
1277       pImage = (mng_imagep)pData->pObjzero;
1278                                        /* determine display rectangle */
1279     pData->iDestl   = MAX_COORD ((mng_int32)0,   pImage->iPosx);
1280     pData->iDestt   = MAX_COORD ((mng_int32)0,   pImage->iPosy);
1281                                        /* is it a valid buffer ? */
1282     if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
1283     {
1284       pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
1285                                  pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth );
1286       pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
1287                                  pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight);
1288     }
1289     else                               /* it's a single image ! */
1290     {
1291       pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
1292                                  (mng_int32)pData->iDatawidth );
1293       pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
1294                                  (mng_int32)pData->iDataheight);
1295     }
1296 
1297 #ifndef MNG_SKIPCHUNK_FRAM
1298     if (pData->bFrameclipping)         /* frame clipping specified ? */
1299     {
1300       pData->iDestl = MAX_COORD (pData->iDestl,  pData->iFrameclipl);
1301       pData->iDestt = MAX_COORD (pData->iDestt,  pData->iFrameclipt);
1302       pData->iDestr = MIN_COORD (pData->iDestr,  pData->iFrameclipr);
1303       pData->iDestb = MIN_COORD (pData->iDestb,  pData->iFrameclipb);
1304     }
1305 #endif
1306 
1307     if (pImage->bClipped)              /* is the image clipped itself ? */
1308     {
1309       pData->iDestl = MAX_COORD (pData->iDestl,  pImage->iClipl);
1310       pData->iDestt = MAX_COORD (pData->iDestt,  pImage->iClipt);
1311       pData->iDestr = MIN_COORD (pData->iDestr,  pImage->iClipr);
1312       pData->iDestb = MIN_COORD (pData->iDestb,  pImage->iClipb);
1313     }
1314                                        /* determine source starting point */
1315     pData->iSourcel = MAX_COORD ((mng_int32)0,   pData->iDestl - pImage->iPosx);
1316     pData->iSourcet = MAX_COORD ((mng_int32)0,   pData->iDestt - pImage->iPosy);
1317 
1318     if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
1319     {                                  /* and maximum size  */
1320       pData->iSourcer = MIN_COORD ((mng_int32)pImage->pImgbuf->iWidth,
1321                                    pData->iSourcel + pData->iDestr - pData->iDestl);
1322       pData->iSourceb = MIN_COORD ((mng_int32)pImage->pImgbuf->iHeight,
1323                                    pData->iSourcet + pData->iDestb - pData->iDestt);
1324     }
1325     else                               /* it's a single image ! */
1326     {
1327       pData->iSourcer = pData->iSourcel + pData->iDestr - pData->iDestl;
1328       pData->iSourceb = pData->iSourcet + pData->iDestb - pData->iDestt;
1329     }
1330 
1331     pData->iLayerseq++;                /* count the layer ! */
1332   }
1333 
1334 #ifdef MNG_SUPPORT_TRACE
1335   MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_END);
1336 #endif
1337 
1338   return MNG_NOERROR;
1339 }
1340 
1341 /* ************************************************************************** */
1342 
mng_display_image(mng_datap pData,mng_imagep pImage,mng_bool bLayeradvanced)1343 mng_retcode mng_display_image (mng_datap  pData,
1344                                mng_imagep pImage,
1345                                mng_bool   bLayeradvanced)
1346 {
1347   mng_retcode iRetcode;
1348 
1349 #ifdef MNG_SUPPORT_TRACE
1350   MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_START);
1351 #endif
1352                                        /* actively running ? */
1353 #ifndef MNG_SKIPCHUNK_MAGN
1354   if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
1355   {
1356     if ( (!pData->iBreakpoint) &&      /* needs magnification ? */
1357          ( (pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY) ) )
1358     {
1359       iRetcode = mng_magnify_imageobject (pData, pImage);
1360 
1361       if (iRetcode)                    /* on error bail out */
1362         return iRetcode;
1363     }
1364   }
1365 #endif
1366 
1367   pData->pRetrieveobj = pImage;        /* so retrieve-row and color-correction can find it */
1368 
1369   if (!bLayeradvanced)                 /* need to advance the layer ? */
1370   {
1371     mng_imagep pSave    = pData->pCurrentobj;
1372     pData->pCurrentobj  = pImage;
1373     next_layer (pData);                /* advance to next layer */
1374     pData->pCurrentobj  = pSave;
1375   }
1376                                        /* need to restore the background ? */
1377   if ((!pData->bTimerset) && (pData->bRestorebkgd))
1378   {
1379     mng_imagep pSave    = pData->pCurrentobj;
1380     pData->pCurrentobj  = pImage;
1381     pData->bRestorebkgd = MNG_FALSE;
1382     iRetcode            = load_bkgdlayer (pData);
1383     pData->pCurrentobj  = pSave;
1384 
1385     if (iRetcode)                      /* on error bail out */
1386       return iRetcode;
1387 
1388     pData->iLayerseq++;                /* and it counts as a layer then ! */
1389   }
1390                                        /* actively running ? */
1391   if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
1392   {
1393     if (!pData->bTimerset)             /* all systems still go ? */
1394     {
1395       pData->iBreakpoint = 0;          /* let's make absolutely sure... */
1396                                        /* anything to display ? */
1397       if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
1398       {
1399         mng_int32 iY;
1400 
1401         set_display_routine (pData);   /* determine display routine */
1402                                        /* and image-buffer retrieval routine */
1403         switch (pImage->pImgbuf->iColortype)
1404         {
1405           case  0 : {
1406 #ifndef MNG_NO_16BIT_SUPPORT
1407                       if (pImage->pImgbuf->iBitdepth > 8)
1408                         pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
1409                       else
1410 #endif
1411                         pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
1412 
1413                       pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
1414                       break;
1415                     }
1416 
1417           case  2 : {
1418 #ifndef MNG_NO_16BIT_SUPPORT
1419                       if (pImage->pImgbuf->iBitdepth > 8)
1420                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
1421                       else
1422 #endif
1423                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
1424 
1425                       pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
1426                       break;
1427                     }
1428 
1429 
1430           case  3 : { pData->fRetrieverow   = (mng_fptr)mng_retrieve_idx8;
1431                       pData->bIsOpaque      = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
1432                       break;
1433                     }
1434 
1435 
1436           case  4 : {
1437 #ifndef MNG_NO_16BIT_SUPPORT
1438                       if (pImage->pImgbuf->iBitdepth > 8)
1439                         pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
1440                       else
1441 #endif
1442                         pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
1443 
1444                       pData->bIsOpaque      = MNG_FALSE;
1445                       break;
1446                     }
1447 
1448 
1449           case  6 : {
1450 #ifndef MNG_NO_16BIT_SUPPORT
1451                       if (pImage->pImgbuf->iBitdepth > 8)
1452                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
1453                       else
1454 #endif
1455                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
1456 
1457                       pData->bIsOpaque      = MNG_FALSE;
1458                       break;
1459                     }
1460 
1461           case  8 : {
1462 #ifndef MNG_NO_16BIT_SUPPORT
1463                       if (pImage->pImgbuf->iBitdepth > 8)
1464                         pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
1465                       else
1466 #endif
1467                         pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
1468 
1469                       pData->bIsOpaque      = MNG_TRUE;
1470                       break;
1471                     }
1472 
1473           case 10 : {
1474 #ifndef MNG_NO_16BIT_SUPPORT
1475                       if (pImage->pImgbuf->iBitdepth > 8)
1476                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
1477                       else
1478 #endif
1479                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
1480 
1481                       pData->bIsOpaque      = MNG_TRUE;
1482                       break;
1483                     }
1484 
1485 
1486           case 12 : {
1487 #ifndef MNG_NO_16BIT_SUPPORT
1488                       if (pImage->pImgbuf->iBitdepth > 8)
1489                         pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
1490                       else
1491 #endif
1492                         pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
1493 
1494                       pData->bIsOpaque      = MNG_FALSE;
1495                       break;
1496                     }
1497 
1498 
1499           case 14 : {
1500 #ifndef MNG_NO_16BIT_SUPPORT
1501                       if (pImage->pImgbuf->iBitdepth > 8)
1502                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
1503                       else
1504 #endif
1505                         pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
1506 
1507                       pData->bIsOpaque      = MNG_FALSE;
1508                       break;
1509                     }
1510 
1511         }
1512 
1513         pData->iPass       = -1;       /* these are the object's dimensions now */
1514         pData->iRow        = pData->iSourcet;
1515         pData->iRowinc     = 1;
1516         pData->iCol        = 0;
1517         pData->iColinc     = 1;
1518         pData->iRowsamples = pImage->pImgbuf->iWidth;
1519         pData->iRowsize    = pData->iRowsamples << 2;
1520         pData->bIsRGBA16   = MNG_FALSE;
1521                                        /* adjust for 16-bit object ? */
1522 #ifndef MNG_NO_16BIT_SUPPORT
1523         if (pImage->pImgbuf->iBitdepth > 8)
1524         {
1525           pData->bIsRGBA16 = MNG_TRUE;
1526           pData->iRowsize  = pData->iRowsamples << 3;
1527         }
1528 #endif
1529 
1530         pData->fCorrectrow = MNG_NULL; /* default no color-correction */
1531 
1532 #ifdef MNG_NO_CMS
1533         iRetcode = MNG_NOERROR;
1534 #else
1535 #if defined(MNG_FULL_CMS)              /* determine color-management routine */
1536         iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
1537 #elif defined(MNG_GAMMA_ONLY)
1538         iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
1539 #elif defined(MNG_APP_CMS)
1540         iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
1541 #endif
1542         if (iRetcode)                  /* on error bail out */
1543           return iRetcode;
1544 #endif /* MNG_NO_CMS */
1545                                        /* get a temporary row-buffer */
1546         MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
1547 
1548         iY = pData->iSourcet;          /* this is where we start */
1549 
1550         while ((!iRetcode) && (iY < pData->iSourceb))
1551         {                              /* get a row */
1552           iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
1553                                        /* color correction ? */
1554           if ((!iRetcode) && (pData->fCorrectrow))
1555             iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
1556 
1557           if (!iRetcode)               /* so... display it */
1558             iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
1559 
1560           if (!iRetcode)               /* adjust variables for next row */
1561             iRetcode = mng_next_row (pData);
1562 
1563           iY++;                        /* and next line */
1564         }
1565                                        /* drop the temporary row-buffer */
1566         MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
1567 
1568         if (iRetcode)                  /* on error bail out */
1569           return iRetcode;
1570 
1571 #if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
1572         iRetcode = mng_clear_cms (pData);
1573 
1574         if (iRetcode)                  /* on error bail out */
1575           return iRetcode;
1576 #endif
1577       }
1578     }
1579   }
1580 
1581 #ifdef MNG_SUPPORT_TRACE
1582   MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_END);
1583 #endif
1584 
1585   return MNG_NOERROR;                  /* whehehe, this is good ! */
1586 }
1587 
1588 /* ************************************************************************** */
1589 
1590 #ifndef MNG_NO_DELTA_PNG
mng_execute_delta_image(mng_datap pData,mng_imagep pTarget,mng_imagep pDelta)1591 mng_retcode mng_execute_delta_image (mng_datap  pData,
1592                                      mng_imagep pTarget,
1593                                      mng_imagep pDelta)
1594 {
1595   mng_imagedatap pBuftarget = pTarget->pImgbuf;
1596   mng_imagedatap pBufdelta  = pDelta->pImgbuf;
1597   mng_uint32     iY;
1598   mng_retcode    iRetcode;
1599   mng_ptr        pSaveRGBA;
1600 
1601 #ifdef MNG_SUPPORT_TRACE
1602   MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_START);
1603 #endif
1604                                        /* actively running ? */
1605   if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
1606   {
1607     if (pBufdelta->bHasPLTE)           /* palette in delta ? */
1608     {
1609       mng_uint32 iX;
1610                                        /* new palette larger than old one ? */
1611       if ((!pBuftarget->bHasPLTE) || (pBuftarget->iPLTEcount < pBufdelta->iPLTEcount))
1612         pBuftarget->iPLTEcount = pBufdelta->iPLTEcount;
1613                                        /* it's definitely got a PLTE now */
1614       pBuftarget->bHasPLTE = MNG_TRUE;
1615 
1616       for (iX = 0; iX < pBufdelta->iPLTEcount; iX++)
1617       {
1618         pBuftarget->aPLTEentries[iX].iRed   = pBufdelta->aPLTEentries[iX].iRed;
1619         pBuftarget->aPLTEentries[iX].iGreen = pBufdelta->aPLTEentries[iX].iGreen;
1620         pBuftarget->aPLTEentries[iX].iBlue  = pBufdelta->aPLTEentries[iX].iBlue;
1621       }
1622     }
1623 
1624     if (pBufdelta->bHasTRNS)           /* cheap transparency in delta ? */
1625     {
1626       switch (pData->iColortype)       /* drop it into the target */
1627       {
1628         case 0: {                      /* gray */
1629                   pBuftarget->iTRNSgray  = pBufdelta->iTRNSgray;
1630                   pBuftarget->iTRNSred   = 0;
1631                   pBuftarget->iTRNSgreen = 0;
1632                   pBuftarget->iTRNSblue  = 0;
1633                   pBuftarget->iTRNScount = 0;
1634                   break;
1635                 }
1636         case 2: {                      /* rgb */
1637                   pBuftarget->iTRNSgray  = 0;
1638                   pBuftarget->iTRNSred   = pBufdelta->iTRNSred;
1639                   pBuftarget->iTRNSgreen = pBufdelta->iTRNSgreen;
1640                   pBuftarget->iTRNSblue  = pBufdelta->iTRNSblue;
1641                   pBuftarget->iTRNScount = 0;
1642                   break;
1643                 }
1644         case 3: {                      /* indexed */
1645                   pBuftarget->iTRNSgray  = 0;
1646                   pBuftarget->iTRNSred   = 0;
1647                   pBuftarget->iTRNSgreen = 0;
1648                   pBuftarget->iTRNSblue  = 0;
1649                                        /* existing range smaller than new one ? */
1650                   if ((!pBuftarget->bHasTRNS) || (pBuftarget->iTRNScount < pBufdelta->iTRNScount))
1651                     pBuftarget->iTRNScount = pBufdelta->iTRNScount;
1652 
1653                   MNG_COPY (pBuftarget->aTRNSentries, pBufdelta->aTRNSentries, pBufdelta->iTRNScount);
1654                   break;
1655                 }
1656       }
1657 
1658       pBuftarget->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
1659     }
1660 
1661 #ifndef MNG_SKIPCHUNK_bKGD
1662     if (pBufdelta->bHasBKGD)           /* bkgd in source ? */
1663     {                                  /* drop it onto the target */
1664       pBuftarget->bHasBKGD   = MNG_TRUE;
1665       pBuftarget->iBKGDindex = pBufdelta->iBKGDindex;
1666       pBuftarget->iBKGDgray  = pBufdelta->iBKGDgray;
1667       pBuftarget->iBKGDred   = pBufdelta->iBKGDred;
1668       pBuftarget->iBKGDgreen = pBufdelta->iBKGDgreen;
1669       pBuftarget->iBKGDblue  = pBufdelta->iBKGDblue;
1670     }
1671 #endif
1672 
1673     if (pBufdelta->bHasGAMA)           /* gamma in source ? */
1674     {
1675       pBuftarget->bHasGAMA = MNG_TRUE; /* drop it onto the target */
1676       pBuftarget->iGamma   = pBufdelta->iGamma;
1677     }
1678 
1679 #ifndef MNG_SKIPCHUNK_cHRM
1680     if (pBufdelta->bHasCHRM)           /* chroma in delta ? */
1681     {                                  /* drop it onto the target */
1682       pBuftarget->bHasCHRM       = MNG_TRUE;
1683       pBuftarget->iWhitepointx   = pBufdelta->iWhitepointx;
1684       pBuftarget->iWhitepointy   = pBufdelta->iWhitepointy;
1685       pBuftarget->iPrimaryredx   = pBufdelta->iPrimaryredx;
1686       pBuftarget->iPrimaryredy   = pBufdelta->iPrimaryredy;
1687       pBuftarget->iPrimarygreenx = pBufdelta->iPrimarygreenx;
1688       pBuftarget->iPrimarygreeny = pBufdelta->iPrimarygreeny;
1689       pBuftarget->iPrimarybluex  = pBufdelta->iPrimarybluex;
1690       pBuftarget->iPrimarybluey  = pBufdelta->iPrimarybluey;
1691     }
1692 #endif
1693 
1694 #ifndef MNG_SKIPCHUNK_sRGB
1695     if (pBufdelta->bHasSRGB)           /* sRGB in delta ? */
1696     {                                  /* drop it onto the target */
1697       pBuftarget->bHasSRGB         = MNG_TRUE;
1698       pBuftarget->iRenderingintent = pBufdelta->iRenderingintent;
1699     }
1700 #endif
1701 
1702 #ifndef MNG_SKIPCHUNK_iCCP
1703     if (pBufdelta->bHasICCP)           /* ICC profile in delta ? */
1704     {
1705       pBuftarget->bHasICCP = MNG_TRUE; /* drop it onto the target */
1706 
1707       if (pBuftarget->pProfile)        /* profile existed ? */
1708         MNG_FREEX (pData, pBuftarget->pProfile, pBuftarget->iProfilesize);
1709                                        /* allocate a buffer & copy it */
1710       MNG_ALLOC (pData, pBuftarget->pProfile, pBufdelta->iProfilesize);
1711       MNG_COPY  (pBuftarget->pProfile, pBufdelta->pProfile, pBufdelta->iProfilesize);
1712                                        /* store its length as well */
1713       pBuftarget->iProfilesize = pBufdelta->iProfilesize;
1714     }
1715 #endif
1716                                        /* need to execute delta pixels ? */
1717     if ((!pData->bDeltaimmediate) && (pData->iDeltatype != MNG_DELTATYPE_NOCHANGE))
1718     {
1719       pData->fScalerow = MNG_NULL;     /* not needed by default */
1720 
1721       switch (pBufdelta->iBitdepth)    /* determine scaling routine */
1722       {
1723 #ifndef MNG_NO_1_2_4BIT_SUPPORT
1724         case  1 : {
1725                     switch (pBuftarget->iBitdepth)
1726                     {
1727                       case  2 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g2;  break; }
1728                       case  4 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g4;  break; }
1729 
1730                       case  8 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g8;  break; }
1731 #ifndef MNG_NO_16BIT_SUPPORT
1732                       case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g16; break; }
1733 #endif
1734                     }
1735                     break;
1736                   }
1737 
1738         case  2 : {
1739                     switch (pBuftarget->iBitdepth)
1740                     {
1741                       case  1 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g1;  break; }
1742                       case  4 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g4;  break; }
1743                       case  8 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g8;  break; }
1744 #ifndef MNG_NO_16BIT_SUPPORT
1745                       case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g16; break; }
1746 #endif
1747                     }
1748                     break;
1749                   }
1750 
1751         case  4 : {
1752                     switch (pBuftarget->iBitdepth)
1753                     {
1754                       case  1 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g1;  break; }
1755                       case  2 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g2;  break; }
1756                       case  8 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g8;  break; }
1757 #ifndef MNG_NO_16BIT_SUPPORT
1758                       case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g16; break; }
1759 #endif
1760                     }
1761                     break;
1762                   }
1763 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
1764 
1765         case  8 : {
1766                     switch (pBufdelta->iColortype)
1767                     {
1768                       case  0 : ;
1769                       case  3 : ;
1770                       case  8 : {
1771                                   switch (pBuftarget->iBitdepth)
1772                                   {
1773 #ifndef MNG_NO_1_2_4BIT_SUPPORT
1774                                     case  1 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g1;  break; }
1775                                     case  2 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g2;  break; }
1776                                     case  4 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g4;  break; }
1777 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
1778 #ifndef MNG_NO_16BIT_SUPPORT
1779                                     case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g16; break; }
1780 #endif
1781                                   }
1782                                   break;
1783                                 }
1784                       case  2 : ;
1785                       case 10 : {
1786 #ifndef MNG_NO_16BIT_SUPPORT
1787                                   if (pBuftarget->iBitdepth == 16)
1788                                     pData->fScalerow = (mng_fptr)mng_scale_rgb8_rgb16;
1789 #endif
1790                                   break;
1791                                 }
1792                       case  4 : ;
1793                       case 12 : {
1794 #ifndef MNG_NO_16BIT_SUPPORT
1795                                   if (pBuftarget->iBitdepth == 16)
1796                                     pData->fScalerow = (mng_fptr)mng_scale_ga8_ga16;
1797 #endif
1798                                   break;
1799                                 }
1800                       case  6 : ;
1801                       case 14 : {
1802 #ifndef MNG_NO_16BIT_SUPPORT
1803                                   if (pBuftarget->iBitdepth == 16)
1804                                     pData->fScalerow = (mng_fptr)mng_scale_rgba8_rgba16;
1805 #endif
1806                                   break;
1807                                 }
1808                     }
1809                     break;
1810                   }
1811 
1812 #ifndef MNG_NO_16BIT_SUPPORT
1813         case 16 : {
1814                     switch (pBufdelta->iColortype)
1815                     {
1816                       case  0 : ;
1817                       case  3 : ;
1818                       case  8 : {
1819                                   switch (pBuftarget->iBitdepth)
1820                                   {
1821 #ifndef MNG_NO_1_2_4BIT_SUPPORT
1822                                     case 1 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g1; break; }
1823                                     case 2 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g2; break; }
1824                                     case 4 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g4; break; }
1825 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
1826                                     case 8 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g8; break; }
1827                                   }
1828                                   break;
1829                                 }
1830                       case  2 : ;
1831                       case 10 : {
1832                                   if (pBuftarget->iBitdepth == 8)
1833                                     pData->fScalerow = (mng_fptr)mng_scale_rgb16_rgb8;
1834                                   break;
1835                                 }
1836                       case  4 : ;
1837                       case 12 : {
1838                                   if (pBuftarget->iBitdepth == 8)
1839                                     pData->fScalerow = (mng_fptr)mng_scale_ga16_ga8;
1840                                   break;
1841                                 }
1842                       case  6 : ;
1843                       case 14 : {
1844                                   if (pBuftarget->iBitdepth == 8)
1845                                     pData->fScalerow = (mng_fptr)mng_scale_rgba16_rgba8;
1846                                   break;
1847                                 }
1848                     }
1849                     break;
1850                   }
1851 #endif
1852 
1853       }
1854 
1855       pData->fDeltarow = MNG_NULL;     /* let's assume there's nothing to do */
1856 
1857       switch (pBuftarget->iColortype)  /* determine delta processing routine */
1858       {
1859         case  0 : ;
1860         case  8 : {                     /* gray */
1861                     if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1862                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1863                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1864                     {
1865                       if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
1866                           (pBufdelta->iColortype == 8))
1867                       {
1868                         switch (pBuftarget->iBitdepth)
1869                         {
1870 #ifndef MNG_NO_1_2_4BIT_SUPPORT
1871                           case  1 : { pData->fDeltarow = (mng_fptr)mng_delta_g1_g1;   break; }
1872                           case  2 : { pData->fDeltarow = (mng_fptr)mng_delta_g2_g2;   break; }
1873                           case  4 : { pData->fDeltarow = (mng_fptr)mng_delta_g4_g4;   break; }
1874 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
1875                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_g8_g8;   break; }
1876 #ifndef MNG_NO_16BIT_SUPPORT
1877                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_g16_g16; break; }
1878 #endif
1879                         }
1880                       }
1881                     }
1882 
1883                     break;
1884                   }
1885 
1886         case  2 : ;
1887         case 10 : {                     /* rgb */
1888                     if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1889                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1890                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1891                     {
1892                       if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
1893                       {
1894                         switch (pBuftarget->iBitdepth)
1895                         {
1896                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgb8_rgb8;   break; }
1897 #ifndef MNG_NO_16BIT_SUPPORT
1898                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgb16_rgb16; break; }
1899 #endif
1900                         }
1901                       }
1902                     }
1903 
1904                     break;
1905                   }
1906 
1907         case  3 : {                     /* indexed; abuse gray routines */
1908                     if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1909                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1910                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1911                     {
1912                       if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1913                       {
1914                         switch (pBuftarget->iBitdepth)
1915                         {
1916 #ifndef MNG_NO_1_2_4BIT_SUPPORT
1917                           case  1 : { pData->fDeltarow = (mng_fptr)mng_delta_g1_g1; break; }
1918                           case  2 : { pData->fDeltarow = (mng_fptr)mng_delta_g2_g2; break; }
1919                           case  4 : { pData->fDeltarow = (mng_fptr)mng_delta_g4_g4; break; }
1920 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
1921                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_g8_g8; break; }
1922                         }
1923                       }
1924                     }
1925 
1926                     break;
1927                   }
1928 
1929         case  4 : ;
1930         case 12 : {                     /* gray + alpha */
1931                     if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1932                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1933                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1934                     {
1935                       if ((pBufdelta->iColortype == 4) || (pBufdelta->iColortype == 12))
1936                       {
1937                         switch (pBuftarget->iBitdepth)
1938                         {
1939                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_ga8;   break; }
1940 #ifndef MNG_NO_16BIT_SUPPORT
1941                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_ga16; break; }
1942 #endif
1943                         }
1944                       }
1945                     }
1946                     else
1947                     if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
1948                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
1949                     {
1950                       if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
1951                           (pBufdelta->iColortype == 8))
1952                       {
1953                         switch (pBuftarget->iBitdepth)
1954                         {
1955                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_g8;   break; }
1956 #ifndef MNG_NO_16BIT_SUPPORT
1957                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_g16; break; }
1958 #endif
1959                         }
1960                       }
1961                     }
1962                     else
1963                     if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
1964                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
1965                     {
1966                       if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1967                       {
1968                         switch (pBuftarget->iBitdepth)
1969                         {
1970                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_a8;   break; }
1971 #ifndef MNG_NO_16BIT_SUPPORT
1972                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_a16; break; }
1973 #endif
1974                         }
1975                       }
1976                     }
1977 
1978                     break;
1979                   }
1980 
1981         case  6 : ;
1982         case 14 : {                     /* rgb + alpha */
1983                     if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE          ) ||
1984                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
1985                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
1986                     {
1987                       if ((pBufdelta->iColortype == 6) || (pBufdelta->iColortype == 14))
1988                       {
1989                         switch (pBuftarget->iBitdepth)
1990                         {
1991                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgba8;   break; }
1992 #ifndef MNG_NO_16BIT_SUPPORT
1993                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgba16; break; }
1994 #endif
1995                         }
1996                       }
1997                     }
1998                     else
1999                     if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
2000                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
2001                     {
2002                       if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
2003                       {
2004                         switch (pBuftarget->iBitdepth)
2005                         {
2006                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgb8;   break; }
2007 #ifndef MNG_NO_16BIT_SUPPORT
2008                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgb16; break; }
2009 #endif
2010                         }
2011                       }
2012                     }
2013                     else
2014                     if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
2015                         (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
2016                     {
2017                       if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
2018                       {
2019                         switch (pBuftarget->iBitdepth)
2020                         {
2021                           case  8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_a8;   break; }
2022 #ifndef MNG_NO_16BIT_SUPPORT
2023                           case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_a16; break; }
2024 #endif
2025                         }
2026                       }
2027                     }
2028 
2029                     break;
2030                   }
2031 
2032       }
2033 
2034       if (pData->fDeltarow)            /* do we need to take action ? */
2035       {
2036         pData->iPass        = -1;      /* setup row dimensions and stuff */
2037         pData->iRow         = pData->iDeltaBlocky;
2038         pData->iRowinc      = 1;
2039         pData->iCol         = pData->iDeltaBlockx;
2040         pData->iColinc      = 1;
2041         pData->iRowsamples  = pBufdelta->iWidth;
2042         pData->iRowsize     = pBuftarget->iRowsize;
2043                                        /* indicate where to retrieve & where to store */
2044         pData->pRetrieveobj = (mng_objectp)pDelta;
2045         pData->pStoreobj    = (mng_objectp)pTarget;
2046 
2047         pSaveRGBA = pData->pRGBArow;   /* save current temp-buffer! */
2048                                        /* get a temporary row-buffer */
2049         MNG_ALLOC (pData, pData->pRGBArow, (pBufdelta->iRowsize << 1));
2050 
2051         iY       = 0;                  /* this is where we start */
2052         iRetcode = MNG_NOERROR;        /* still oke for now */
2053 
2054         while ((!iRetcode) && (iY < pBufdelta->iHeight))
2055         {                              /* get a row */
2056           mng_uint8p pWork = pBufdelta->pImgdata + (iY * pBufdelta->iRowsize);
2057 
2058           MNG_COPY (pData->pRGBArow, pWork, pBufdelta->iRowsize);
2059 
2060           if (pData->fScalerow)        /* scale it (if necessary) */
2061             iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
2062 
2063           if (!iRetcode)               /* and... execute it */
2064             iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
2065 
2066           if (!iRetcode)               /* adjust variables for next row */
2067             iRetcode = mng_next_row (pData);
2068 
2069           iY++;                        /* and next line */
2070         }
2071                                        /* drop the temporary row-buffer */
2072         MNG_FREE (pData, pData->pRGBArow, (pBufdelta->iRowsize << 1));
2073         pData->pRGBArow = pSaveRGBA;   /* restore saved temp-buffer! */
2074 
2075         if (iRetcode)                  /* on error bail out */
2076           return iRetcode;
2077 
2078       }
2079       else
2080         MNG_ERROR (pData, MNG_INVALIDDELTA);
2081 
2082     }
2083   }
2084 
2085 #ifdef MNG_SUPPORT_TRACE
2086   MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_END);
2087 #endif
2088 
2089   return MNG_NOERROR;
2090 }
2091 #endif /* MNG_NO_DELTA_PNG */
2092 
2093 /* ************************************************************************** */
2094 
2095 #ifndef MNG_SKIPCHUNK_SAVE
save_state(mng_datap pData)2096 MNG_LOCAL mng_retcode save_state (mng_datap pData)
2097 {
2098   mng_savedatap pSave;
2099   mng_imagep    pImage;
2100 
2101 #ifdef MNG_SUPPORT_TRACE
2102   MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_START);
2103 #endif
2104 
2105   if (pData->pSavedata)                /* sanity check */
2106     MNG_ERROR (pData, MNG_INTERNALERROR);
2107                                        /* get a buffer for saving */
2108   MNG_ALLOC (pData, pData->pSavedata, sizeof (mng_savedata));
2109 
2110   pSave = pData->pSavedata;            /* address it more directly */
2111                                        /* and copy global data from the main struct */
2112 #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
2113   pSave->bHasglobalPLTE       = pData->bHasglobalPLTE;
2114   pSave->bHasglobalTRNS       = pData->bHasglobalTRNS;
2115   pSave->bHasglobalGAMA       = pData->bHasglobalGAMA;
2116   pSave->bHasglobalCHRM       = pData->bHasglobalCHRM;
2117   pSave->bHasglobalSRGB       = pData->bHasglobalSRGB;
2118   pSave->bHasglobalICCP       = pData->bHasglobalICCP;
2119   pSave->bHasglobalBKGD       = pData->bHasglobalBKGD;
2120 #endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
2121 
2122 #ifndef MNG_SKIPCHUNK_BACK
2123   pSave->iBACKred             = pData->iBACKred;
2124   pSave->iBACKgreen           = pData->iBACKgreen;
2125   pSave->iBACKblue            = pData->iBACKblue;
2126   pSave->iBACKmandatory       = pData->iBACKmandatory;
2127   pSave->iBACKimageid         = pData->iBACKimageid;
2128   pSave->iBACKtile            = pData->iBACKtile;
2129 #endif
2130 
2131 #ifndef MNG_SKIPCHUNK_FRAM
2132   pSave->iFRAMmode            = pData->iFRAMmode;
2133   pSave->iFRAMdelay           = pData->iFRAMdelay;
2134   pSave->iFRAMtimeout         = pData->iFRAMtimeout;
2135   pSave->bFRAMclipping        = pData->bFRAMclipping;
2136   pSave->iFRAMclipl           = pData->iFRAMclipl;
2137   pSave->iFRAMclipr           = pData->iFRAMclipr;
2138   pSave->iFRAMclipt           = pData->iFRAMclipt;
2139   pSave->iFRAMclipb           = pData->iFRAMclipb;
2140 #endif
2141 
2142   pSave->iGlobalPLTEcount     = pData->iGlobalPLTEcount;
2143 
2144   MNG_COPY (pSave->aGlobalPLTEentries, pData->aGlobalPLTEentries, sizeof (mng_rgbpaltab));
2145 
2146   pSave->iGlobalTRNSrawlen    = pData->iGlobalTRNSrawlen;
2147   MNG_COPY (pSave->aGlobalTRNSrawdata, pData->aGlobalTRNSrawdata, 256);
2148 
2149   pSave->iGlobalGamma         = pData->iGlobalGamma;
2150 
2151 #ifndef MNG_SKIPCHUNK_cHRM
2152   pSave->iGlobalWhitepointx   = pData->iGlobalWhitepointx;
2153   pSave->iGlobalWhitepointy   = pData->iGlobalWhitepointy;
2154   pSave->iGlobalPrimaryredx   = pData->iGlobalPrimaryredx;
2155   pSave->iGlobalPrimaryredy   = pData->iGlobalPrimaryredy;
2156   pSave->iGlobalPrimarygreenx = pData->iGlobalPrimarygreenx;
2157   pSave->iGlobalPrimarygreeny = pData->iGlobalPrimarygreeny;
2158   pSave->iGlobalPrimarybluex  = pData->iGlobalPrimarybluex;
2159   pSave->iGlobalPrimarybluey  = pData->iGlobalPrimarybluey;
2160 #endif
2161 
2162 #ifndef MNG_SKIPCHUNK_sRGB
2163   pSave->iGlobalRendintent    = pData->iGlobalRendintent;
2164 #endif
2165 
2166 #ifndef MNG_SKIPCHUNK_iCCP
2167   pSave->iGlobalProfilesize   = pData->iGlobalProfilesize;
2168 
2169   if (pSave->iGlobalProfilesize)       /* has a profile ? */
2170   {                                    /* then copy that ! */
2171     MNG_ALLOC (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize);
2172     MNG_COPY (pSave->pGlobalProfile, pData->pGlobalProfile, pSave->iGlobalProfilesize);
2173   }
2174 #endif
2175 
2176 #ifndef MNG_SKIPCHUNK_bKGD
2177   pSave->iGlobalBKGDred       = pData->iGlobalBKGDred;
2178   pSave->iGlobalBKGDgreen     = pData->iGlobalBKGDgreen;
2179   pSave->iGlobalBKGDblue      = pData->iGlobalBKGDblue;
2180 #endif
2181 
2182                                        /* freeze current image objects */
2183   pImage = (mng_imagep)pData->pFirstimgobj;
2184 
2185   while (pImage)
2186   {                                    /* freeze the object AND its buffer */
2187     pImage->bFrozen          = MNG_TRUE;
2188     pImage->pImgbuf->bFrozen = MNG_TRUE;
2189                                        /* neeeext */
2190     pImage = (mng_imagep)pImage->sHeader.pNext;
2191   }
2192 
2193 #ifdef MNG_SUPPORT_TRACE
2194   MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_END);
2195 #endif
2196 
2197   return MNG_NOERROR;
2198 }
2199 #endif
2200 
2201 /* ************************************************************************** */
2202 
mng_reset_objzero(mng_datap pData)2203 mng_retcode mng_reset_objzero (mng_datap pData)
2204 {
2205   mng_imagep  pImage   = (mng_imagep)pData->pObjzero;
2206   mng_retcode iRetcode = mng_reset_object_details (pData, pImage, 0, 0, 0,
2207                                                    0, 0, 0, 0, MNG_TRUE);
2208 
2209   if (iRetcode)                        /* on error bail out */
2210     return iRetcode;
2211 
2212   pImage->bVisible             = MNG_TRUE;
2213   pImage->bViewable            = MNG_TRUE;
2214   pImage->iPosx                = 0;
2215   pImage->iPosy                = 0;
2216   pImage->bClipped             = MNG_FALSE;
2217   pImage->iClipl               = 0;
2218   pImage->iClipr               = 0;
2219   pImage->iClipt               = 0;
2220   pImage->iClipb               = 0;
2221 #ifndef MNG_SKIPCHUNK_MAGN
2222   pImage->iMAGN_MethodX        = 0;
2223   pImage->iMAGN_MethodY        = 0;
2224   pImage->iMAGN_MX             = 0;
2225   pImage->iMAGN_MY             = 0;
2226   pImage->iMAGN_ML             = 0;
2227   pImage->iMAGN_MR             = 0;
2228   pImage->iMAGN_MT             = 0;
2229   pImage->iMAGN_MB             = 0;
2230 #endif
2231 
2232   return MNG_NOERROR;
2233 }
2234 
2235 /* ************************************************************************** */
2236 
restore_state(mng_datap pData)2237 MNG_LOCAL mng_retcode restore_state (mng_datap pData)
2238 {
2239 #ifndef MNG_SKIPCHUNK_SAVE
2240   mng_savedatap pSave;
2241 #endif
2242   mng_imagep    pImage;
2243   mng_retcode   iRetcode;
2244 
2245 #ifdef MNG_SUPPORT_TRACE
2246   MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_START);
2247 #endif
2248                                        /* restore object 0 status !!! */
2249   iRetcode = mng_reset_objzero (pData);
2250 
2251   if (iRetcode)                        /* on error bail out */
2252     return iRetcode;
2253                                        /* fresh cycle; fake no frames done yet */
2254   pData->bFramedone             = MNG_FALSE;
2255 
2256 #ifndef MNG_SKIPCHUNK_SAVE
2257   if (pData->pSavedata)                /* do we have a saved state ? */
2258   {
2259     pSave = pData->pSavedata;          /* address it more directly */
2260                                        /* and copy it back to the main struct */
2261 #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
2262     pData->bHasglobalPLTE       = pSave->bHasglobalPLTE;
2263     pData->bHasglobalTRNS       = pSave->bHasglobalTRNS;
2264     pData->bHasglobalGAMA       = pSave->bHasglobalGAMA;
2265     pData->bHasglobalCHRM       = pSave->bHasglobalCHRM;
2266     pData->bHasglobalSRGB       = pSave->bHasglobalSRGB;
2267     pData->bHasglobalICCP       = pSave->bHasglobalICCP;
2268     pData->bHasglobalBKGD       = pSave->bHasglobalBKGD;
2269 #endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
2270 
2271 #ifndef MNG_SKIPCHUNK_BACK
2272     pData->iBACKred             = pSave->iBACKred;
2273     pData->iBACKgreen           = pSave->iBACKgreen;
2274     pData->iBACKblue            = pSave->iBACKblue;
2275     pData->iBACKmandatory       = pSave->iBACKmandatory;
2276     pData->iBACKimageid         = pSave->iBACKimageid;
2277     pData->iBACKtile            = pSave->iBACKtile;
2278 #endif
2279 
2280 #ifndef MNG_SKIPCHUNK_FRAM
2281     pData->iFRAMmode            = pSave->iFRAMmode;
2282 /*    pData->iFRAMdelay           = pSave->iFRAMdelay; */
2283     pData->iFRAMtimeout         = pSave->iFRAMtimeout;
2284     pData->bFRAMclipping        = pSave->bFRAMclipping;
2285     pData->iFRAMclipl           = pSave->iFRAMclipl;
2286     pData->iFRAMclipr           = pSave->iFRAMclipr;
2287     pData->iFRAMclipt           = pSave->iFRAMclipt;
2288     pData->iFRAMclipb           = pSave->iFRAMclipb;
2289                                        /* NOOOOOOOOOOOO */
2290 /*    pData->iFramemode           = pSave->iFRAMmode;
2291     pData->iFramedelay          = pSave->iFRAMdelay;
2292     pData->iFrametimeout        = pSave->iFRAMtimeout;
2293     pData->bFrameclipping       = pSave->bFRAMclipping;
2294     pData->iFrameclipl          = pSave->iFRAMclipl;
2295     pData->iFrameclipr          = pSave->iFRAMclipr;
2296     pData->iFrameclipt          = pSave->iFRAMclipt;
2297     pData->iFrameclipb          = pSave->iFRAMclipb; */
2298 
2299 /*    pData->iNextdelay           = pSave->iFRAMdelay; */
2300     pData->iNextdelay           = pData->iFramedelay;
2301 #endif
2302 
2303     pData->iGlobalPLTEcount     = pSave->iGlobalPLTEcount;
2304     MNG_COPY (pData->aGlobalPLTEentries, pSave->aGlobalPLTEentries, sizeof (mng_rgbpaltab));
2305 
2306     pData->iGlobalTRNSrawlen    = pSave->iGlobalTRNSrawlen;
2307     MNG_COPY (pData->aGlobalTRNSrawdata, pSave->aGlobalTRNSrawdata, 256);
2308 
2309     pData->iGlobalGamma         = pSave->iGlobalGamma;
2310 
2311 #ifndef MNG_SKIPCHUNK_cHRM
2312     pData->iGlobalWhitepointx   = pSave->iGlobalWhitepointx;
2313     pData->iGlobalWhitepointy   = pSave->iGlobalWhitepointy;
2314     pData->iGlobalPrimaryredx   = pSave->iGlobalPrimaryredx;
2315     pData->iGlobalPrimaryredy   = pSave->iGlobalPrimaryredy;
2316     pData->iGlobalPrimarygreenx = pSave->iGlobalPrimarygreenx;
2317     pData->iGlobalPrimarygreeny = pSave->iGlobalPrimarygreeny;
2318     pData->iGlobalPrimarybluex  = pSave->iGlobalPrimarybluex;
2319     pData->iGlobalPrimarybluey  = pSave->iGlobalPrimarybluey;
2320 #endif
2321 
2322     pData->iGlobalRendintent    = pSave->iGlobalRendintent;
2323 
2324 #ifndef MNG_SKIPCHUNK_iCCP
2325     pData->iGlobalProfilesize   = pSave->iGlobalProfilesize;
2326 
2327     if (pData->iGlobalProfilesize)     /* has a profile ? */
2328     {                                  /* then copy that ! */
2329       MNG_ALLOC (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
2330       MNG_COPY (pData->pGlobalProfile, pSave->pGlobalProfile, pData->iGlobalProfilesize);
2331     }
2332 #endif
2333 
2334 #ifndef MNG_SKIPCHUNK_bKGD
2335     pData->iGlobalBKGDred       = pSave->iGlobalBKGDred;
2336     pData->iGlobalBKGDgreen     = pSave->iGlobalBKGDgreen;
2337     pData->iGlobalBKGDblue      = pSave->iGlobalBKGDblue;
2338 #endif
2339   }
2340   else                                 /* no saved-data; so reset the lot */
2341 #endif /* SKIPCHUNK_SAVE */
2342   {
2343 #if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
2344     pData->bHasglobalPLTE       = MNG_FALSE;
2345     pData->bHasglobalTRNS       = MNG_FALSE;
2346     pData->bHasglobalGAMA       = MNG_FALSE;
2347     pData->bHasglobalCHRM       = MNG_FALSE;
2348     pData->bHasglobalSRGB       = MNG_FALSE;
2349     pData->bHasglobalICCP       = MNG_FALSE;
2350     pData->bHasglobalBKGD       = MNG_FALSE;
2351 #endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
2352 
2353 #ifndef MNG_SKIPCHUNK_TERM
2354     if (!pData->bMisplacedTERM)        /* backward compatible ugliness !!! */
2355     {
2356       pData->iBACKred           = 0;
2357       pData->iBACKgreen         = 0;
2358       pData->iBACKblue          = 0;
2359       pData->iBACKmandatory     = 0;
2360       pData->iBACKimageid       = 0;
2361       pData->iBACKtile          = 0;
2362     }
2363 #endif
2364 
2365 #ifndef MNG_SKIPCHUNK_FRAM
2366     pData->iFRAMmode            = 1;
2367 /*    pData->iFRAMdelay           = 1; */
2368     pData->iFRAMtimeout         = 0x7fffffffl;
2369     pData->bFRAMclipping        = MNG_FALSE;
2370     pData->iFRAMclipl           = 0;
2371     pData->iFRAMclipr           = 0;
2372     pData->iFRAMclipt           = 0;
2373     pData->iFRAMclipb           = 0;
2374                                        /* NOOOOOOOOOOOO */
2375 /*    pData->iFramemode           = 1;
2376     pData->iFramedelay          = 1;
2377     pData->iFrametimeout        = 0x7fffffffl;
2378     pData->bFrameclipping       = MNG_FALSE;
2379     pData->iFrameclipl          = 0;
2380     pData->iFrameclipr          = 0;
2381     pData->iFrameclipt          = 0;
2382     pData->iFrameclipb          = 0; */
2383 
2384 /*    pData->iNextdelay           = 1; */
2385     pData->iNextdelay           = pData->iFramedelay;
2386 #endif
2387 
2388     pData->iGlobalPLTEcount     = 0;
2389 
2390     pData->iGlobalTRNSrawlen    = 0;
2391 
2392     pData->iGlobalGamma         = 0;
2393 
2394 #ifndef MNG_SKIPCHUNK_cHRM
2395     pData->iGlobalWhitepointx   = 0;
2396     pData->iGlobalWhitepointy   = 0;
2397     pData->iGlobalPrimaryredx   = 0;
2398     pData->iGlobalPrimaryredy   = 0;
2399     pData->iGlobalPrimarygreenx = 0;
2400     pData->iGlobalPrimarygreeny = 0;
2401     pData->iGlobalPrimarybluex  = 0;
2402     pData->iGlobalPrimarybluey  = 0;
2403 #endif
2404 
2405     pData->iGlobalRendintent    = 0;
2406 
2407 #ifndef MNG_SKIPCHUNK_iCCP
2408     if (pData->iGlobalProfilesize)     /* free a previous profile ? */
2409       MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
2410 
2411     pData->iGlobalProfilesize   = 0;
2412 #endif
2413 
2414 #ifndef MNG_SKIPCHUNK_bKGD
2415     pData->iGlobalBKGDred       = 0;
2416     pData->iGlobalBKGDgreen     = 0;
2417     pData->iGlobalBKGDblue      = 0;
2418 #endif
2419   }
2420 
2421 #ifndef MNG_SKIPCHUNK_TERM
2422   if (!pData->bMisplacedTERM)          /* backward compatible ugliness !!! */
2423   {
2424     pImage = (mng_imagep)pData->pFirstimgobj;
2425                                        /* drop un-frozen image objects */
2426     while (pImage)
2427     {
2428       mng_imagep pNext = (mng_imagep)pImage->sHeader.pNext;
2429 
2430       if (!pImage->bFrozen)            /* is it un-frozen ? */
2431       {
2432         mng_imagep pPrev = (mng_imagep)pImage->sHeader.pPrev;
2433 
2434         if (pPrev)                     /* unlink it */
2435           pPrev->sHeader.pNext = pNext;
2436         else
2437           pData->pFirstimgobj  = pNext;
2438 
2439         if (pNext)
2440           pNext->sHeader.pPrev = pPrev;
2441         else
2442           pData->pLastimgobj   = pPrev;
2443 
2444         if (pImage->pImgbuf->bFrozen)  /* buffer frozen ? */
2445         {
2446           if (pImage->pImgbuf->iRefcount < 2)
2447             MNG_ERROR (pData, MNG_INTERNALERROR);
2448                                        /* decrease ref counter */
2449           pImage->pImgbuf->iRefcount--;
2450                                        /* just cleanup the object then */
2451           MNG_FREEX (pData, pImage, sizeof (mng_image));
2452         }
2453         else
2454         {                              /* free the image buffer */
2455           iRetcode = mng_free_imagedataobject (pData, pImage->pImgbuf);
2456                                        /* and cleanup the object */
2457           MNG_FREEX (pData, pImage, sizeof (mng_image));
2458 
2459           if (iRetcode)                /* on error bail out */
2460             return iRetcode;
2461         }
2462       }
2463 
2464       pImage = pNext;                  /* neeeext */
2465     }
2466   }
2467 #endif
2468 
2469 #ifdef MNG_SUPPORT_TRACE
2470   MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_END);
2471 #endif
2472 
2473   return MNG_NOERROR;
2474 }
2475 
2476 /* ************************************************************************** */
2477 /* *                                                                        * */
2478 /* * General display processing routine                                     * */
2479 /* *                                                                        * */
2480 /* ************************************************************************** */
2481 
mng_process_display(mng_datap pData)2482 mng_retcode mng_process_display (mng_datap pData)
2483 {
2484   mng_retcode iRetcode = MNG_NOERROR;
2485 
2486 #ifdef MNG_SUPPORT_TRACE
2487   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_START);
2488 #endif
2489 
2490   if (!pData->iBreakpoint)             /* not broken previously ? */
2491   {
2492     if ((pData->iRequestframe) || (pData->iRequestlayer) || (pData->iRequesttime))
2493     {
2494       pData->bSearching = MNG_TRUE;    /* indicate we're searching */
2495 
2496       iRetcode = clear_canvas (pData); /* make the canvas virgin black ?!? */
2497 
2498       if (iRetcode)                    /* on error bail out */
2499         return iRetcode;
2500                                        /* let's start from the top, shall we */
2501       pData->pCurraniobj = pData->pFirstaniobj;
2502     }
2503   }
2504 
2505   do                                   /* process the objects */
2506   {
2507     if (pData->bSearching)             /* clear timer-flag when searching !!! */
2508       pData->bTimerset = MNG_FALSE;
2509                                        /* do we need to finish something first ? */
2510     if ((pData->iBreakpoint) && (pData->iBreakpoint < 99))
2511     {
2512       switch (pData->iBreakpoint)      /* return to broken display routine */
2513       {
2514 #ifndef MNG_SKIPCHUNK_FRAM
2515         case  1 : { iRetcode = mng_process_display_fram2 (pData); break; }
2516 #endif
2517 #ifndef MNG_SKIPCHUNK_SHOW
2518         case  3 : ;                    /* same as 4 !!! */
2519         case  4 : { iRetcode = mng_process_display_show  (pData); break; }
2520 #endif
2521 #ifndef MNG_SKIPCHUNK_CLON
2522         case  5 : { iRetcode = mng_process_display_clon2 (pData); break; }
2523 #endif
2524 #ifndef MNG_SKIPCHUNK_MAGN
2525         case  9 : { iRetcode = mng_process_display_magn2 (pData); break; }
2526         case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
2527 #endif
2528 #ifndef MNG_SKIPCHUNK_PAST
2529         case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
2530 #endif
2531         default : MNG_ERROR (pData, MNG_INTERNALERROR);
2532       }
2533     }
2534     else
2535     {
2536       if (pData->pCurraniobj)
2537         iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
2538     }
2539 
2540     if (!pData->bTimerset)             /* reset breakpoint flag ? */
2541       pData->iBreakpoint = 0;
2542                                        /* can we advance to next object ? */
2543     if ((!iRetcode) && (pData->pCurraniobj) &&
2544         (!pData->bTimerset) && (!pData->bSectionwait))
2545     {
2546       pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
2547                                        /* MEND processing to be done ? */
2548       if ((pData->eImagetype == mng_it_mng) && (!pData->pCurraniobj))
2549         iRetcode = mng_process_display_mend (pData);
2550 
2551       if (!pData->pCurraniobj)         /* refresh after last image ? */
2552         pData->bNeedrefresh = MNG_TRUE;
2553     }
2554 
2555     if (pData->bSearching)             /* are we looking for something ? */
2556     {
2557       if ((pData->iRequestframe) && (pData->iRequestframe <= pData->iFrameseq))
2558       {
2559         pData->iRequestframe = 0;      /* found the frame ! */
2560         pData->bSearching    = MNG_FALSE;
2561       }
2562       else
2563       if ((pData->iRequestlayer) && (pData->iRequestlayer <= pData->iLayerseq))
2564       {
2565         pData->iRequestlayer = 0;      /* found the layer ! */
2566         pData->bSearching    = MNG_FALSE;
2567       }
2568       else
2569       if ((pData->iRequesttime) && (pData->iRequesttime <= pData->iFrametime))
2570       {
2571         pData->iRequesttime  = 0;      /* found the playtime ! */
2572         pData->bSearching    = MNG_FALSE;
2573       }
2574     }
2575   }                                    /* until error or a break or no more objects */
2576   while ((!iRetcode) && (pData->pCurraniobj) &&
2577          (((pData->bRunning) && (!pData->bTimerset)) || (pData->bSearching)) &&
2578          (!pData->bSectionwait) && (!pData->bFreezing));
2579 
2580   if (iRetcode)                        /* on error bail out */
2581     return iRetcode;
2582                                        /* refresh needed ? */
2583   if ((!pData->bTimerset) && (pData->bNeedrefresh))
2584   {
2585     iRetcode = mng_display_progressive_refresh (pData, 1);
2586 
2587     if (iRetcode)                      /* on error bail out */
2588       return iRetcode;
2589   }
2590                                        /* timer break ? */
2591   if ((pData->bTimerset) && (!pData->iBreakpoint))
2592     pData->iBreakpoint = 99;
2593   else
2594   if (!pData->bTimerset)
2595     pData->iBreakpoint = 0;            /* reset if no timer break */
2596 
2597   if ((!pData->bTimerset) && (!pData->pCurraniobj))
2598     pData->bRunning = MNG_FALSE;       /* all done now ! */
2599 
2600 #ifdef MNG_SUPPORT_TRACE
2601   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_END);
2602 #endif
2603 
2604   return MNG_NOERROR;
2605 }
2606 
2607 /* ************************************************************************** */
2608 /* *                                                                        * */
2609 /* * Chunk display processing routines                                      * */
2610 /* *                                                                        * */
2611 /* ************************************************************************** */
2612 
2613 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
mng_png_imgtype(mng_uint8 colortype,mng_uint8 bitdepth)2614 png_imgtype mng_png_imgtype(mng_uint8 colortype, mng_uint8 bitdepth)
2615 {
2616   png_imgtype ret;
2617   switch (bitdepth)
2618   {
2619 #ifndef MNG_NO_1_2_4BIT_SUPPORT
2620     case 1:
2621     {
2622       png_imgtype imgtype[]={png_g1,png_none,png_none,png_idx1};
2623       ret=imgtype[colortype];
2624       break;
2625     }
2626     case 2:
2627     {
2628       png_imgtype imgtype[]={png_g2,png_none,png_none,png_idx2};
2629       ret=imgtype[colortype];
2630       break;
2631     }
2632     case 4:
2633     {
2634       png_imgtype imgtype[]={png_g4,png_none,png_none,png_idx4};
2635       ret=imgtype[colortype];
2636       break;
2637     }
2638 #endif
2639     case 8:
2640     {
2641       png_imgtype imgtype[]={png_g8,png_none,png_rgb8,png_idx8,png_ga8,
2642           png_none,png_rgba8};
2643       ret=imgtype[colortype];
2644       break;
2645     }
2646 #ifndef MNG_NO_16BIT_SUPPORT
2647     case 16:
2648     {
2649       png_imgtype imgtype[]={png_g16,png_none,png_rgb16,png_none,png_ga16,
2650           png_none,png_rgba16};
2651       ret=imgtype[colortype];
2652       break;
2653     }
2654 #endif
2655     default:
2656       ret=png_none;
2657       break;
2658   }
2659   return (ret);
2660 }
2661 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
2662 
2663 /* ************************************************************************** */
2664 
mng_process_display_ihdr(mng_datap pData)2665 mng_retcode mng_process_display_ihdr (mng_datap pData)
2666 {                                      /* address the current "object" if any */
2667   mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
2668 
2669 #ifdef MNG_SUPPORT_TRACE
2670   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_START);
2671 #endif
2672 
2673   if (!pData->bHasDHDR)
2674   {
2675     pData->fInitrowproc = MNG_NULL;    /* do nothing by default */
2676     pData->fDisplayrow  = MNG_NULL;
2677     pData->fCorrectrow  = MNG_NULL;
2678     pData->fStorerow    = MNG_NULL;
2679     pData->fProcessrow  = MNG_NULL;
2680     pData->fDifferrow   = MNG_NULL;
2681     pData->pStoreobj    = MNG_NULL;
2682   }
2683 
2684   if (!pData->iBreakpoint)             /* not previously broken ? */
2685   {
2686     mng_retcode iRetcode = MNG_NOERROR;
2687 
2688 #ifndef MNG_NO_DELTA_PNG
2689     if (pData->bHasDHDR)               /* is a delta-image ? */
2690     {
2691       if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
2692         iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
2693                                              pData->iDatawidth, pData->iDataheight,
2694                                              pData->iBitdepth, pData->iColortype,
2695                                              pData->iCompression, pData->iFilter,
2696                                              pData->iInterlace, MNG_TRUE);
2697       else
2698       if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
2699           (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
2700       {
2701         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
2702         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
2703       }
2704       else
2705       if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
2706           (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
2707         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
2708       else
2709       if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
2710           (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
2711         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
2712 
2713       if (!iRetcode)
2714       {                                /* process immediately if bitdepth & colortype are equal */
2715         pData->bDeltaimmediate =
2716           (mng_bool)((pData->iBitdepth  == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
2717                      (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype)    );
2718                                        /* be sure to reset object 0 */
2719         iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
2720                                              pData->iDatawidth, pData->iDataheight,
2721                                              pData->iBitdepth, pData->iColortype,
2722                                              pData->iCompression, pData->iFilter,
2723                                              pData->iInterlace, MNG_TRUE);
2724       }
2725     }
2726     else
2727 #endif
2728     {
2729       if (pImage)                      /* update object buffer ? */
2730         iRetcode = mng_reset_object_details (pData, pImage,
2731                                              pData->iDatawidth, pData->iDataheight,
2732                                              pData->iBitdepth, pData->iColortype,
2733                                              pData->iCompression, pData->iFilter,
2734                                              pData->iInterlace, MNG_TRUE);
2735       else
2736         iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
2737                                              pData->iDatawidth, pData->iDataheight,
2738                                              pData->iBitdepth, pData->iColortype,
2739                                              pData->iCompression, pData->iFilter,
2740                                              pData->iInterlace, MNG_TRUE);
2741     }
2742 
2743     if (iRetcode)                      /* on error bail out */
2744       return iRetcode;
2745   }
2746 
2747 #ifndef MNG_NO_DELTA_PNG
2748   if (!pData->bHasDHDR)
2749 #endif
2750   {
2751     if (pImage)                        /* real object ? */
2752       pData->pStoreobj = pImage;       /* tell the row routines */
2753     else                               /* otherwise use object 0 */
2754       pData->pStoreobj = pData->pObjzero;
2755 
2756 #if !defined(MNG_INCLUDE_MPNG_PROPOSAL) && !defined(MNG_INCLUDE_ANG_PROPOSAL)
2757     if (                               /* display "on-the-fly" ? */
2758 #ifndef MNG_SKIPCHUNK_MAGN
2759          (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
2760          (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
2761 #endif
2762          ( (pData->eImagetype == mng_it_png         ) ||
2763            (((mng_imagep)pData->pStoreobj)->bVisible)    )       )
2764     {
2765       next_layer (pData);              /* that's a new layer then ! */
2766 
2767       if (pData->bTimerset)            /* timer break ? */
2768         pData->iBreakpoint = 2;
2769       else
2770       {
2771         pData->iBreakpoint = 0;
2772                                        /* anything to display ? */
2773         if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
2774           set_display_routine (pData); /* then determine display routine */
2775       }
2776     }
2777 #endif
2778   }
2779 
2780   if (!pData->bTimerset)               /* no timer break ? */
2781   {
2782 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
2783     pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
2784     pData->ePng_imgtype=mng_png_imgtype(pData->iColortype,pData->iBitdepth);
2785 #else
2786     switch (pData->iColortype)         /* determine row initialization routine */
2787     {
2788       case 0 : {                       /* gray */
2789                  switch (pData->iBitdepth)
2790                  {
2791 #ifndef MNG_NO_1_2_4BIT_SUPPORT
2792                    case  1 : {
2793                                if (!pData->iInterlace)
2794                                  pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
2795                                else
2796                                  pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
2797 
2798                                break;
2799                              }
2800                    case  2 : {
2801                                if (!pData->iInterlace)
2802                                  pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
2803                                else
2804                                  pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
2805 
2806                                break;
2807                              }
2808                    case  4 : {
2809                                if (!pData->iInterlace)
2810                                  pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
2811                                else
2812                                  pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
2813                                break;
2814                              }
2815 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
2816                    case  8 : {
2817                                if (!pData->iInterlace)
2818                                  pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
2819                                else
2820                                  pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
2821 
2822                                break;
2823                              }
2824 #ifndef MNG_NO_16BIT_SUPPORT
2825                    case 16 : {
2826                                if (!pData->iInterlace)
2827                                  pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
2828                                else
2829                                  pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
2830 
2831                                break;
2832                              }
2833 #endif
2834                  }
2835 
2836                  break;
2837                }
2838       case 2 : {                       /* rgb */
2839                  switch (pData->iBitdepth)
2840                  {
2841                    case  8 : {
2842                                if (!pData->iInterlace)
2843                                  pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
2844                                else
2845                                  pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
2846                                break;
2847                              }
2848 #ifndef MNG_NO_16BIT_SUPPORT
2849                    case 16 : {
2850                                if (!pData->iInterlace)
2851                                  pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
2852                                else
2853                                  pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
2854 
2855                                break;
2856                              }
2857 #endif
2858                  }
2859 
2860                  break;
2861                }
2862       case 3 : {                       /* indexed */
2863                  switch (pData->iBitdepth)
2864                  {
2865 #ifndef MNG_NO_1_2_4BIT_SUPPORT
2866                    case  1 : {
2867                                if (!pData->iInterlace)
2868                                  pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
2869                                else
2870                                  pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
2871 
2872                                break;
2873                              }
2874                    case  2 : {
2875                                if (!pData->iInterlace)
2876                                  pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
2877                                else
2878                                  pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
2879 
2880                                break;
2881                              }
2882                    case  4 : {
2883                                if (!pData->iInterlace)
2884                                  pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
2885                                else
2886                                  pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
2887 
2888                                break;
2889                              }
2890 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
2891                    case  8 : {
2892                                if (!pData->iInterlace)
2893                                  pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
2894                                else
2895                                  pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
2896 
2897                                break;
2898                              }
2899                  }
2900 
2901                  break;
2902                }
2903       case 4 : {                       /* gray+alpha */
2904                  switch (pData->iBitdepth)
2905                  {
2906                    case  8 : {
2907                                if (!pData->iInterlace)
2908                                  pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
2909                                else
2910                                  pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
2911 
2912                                break;
2913                              }
2914 #ifndef MNG_NO_16BIT_SUPPORT
2915                    case 16 : {
2916                                if (!pData->iInterlace)
2917                                  pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
2918                                else
2919                                  pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
2920                                break;
2921                              }
2922 #endif
2923                  }
2924 
2925                  break;
2926                }
2927       case 6 : {                       /* rgb+alpha */
2928                  switch (pData->iBitdepth)
2929                  {
2930                    case  8 : {
2931                                if (!pData->iInterlace)
2932                                  pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
2933                                else
2934                                  pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
2935 
2936                                break;
2937                              }
2938 #ifndef MNG_NO_16BIT_SUPPORT
2939                    case 16 : {
2940                                if (!pData->iInterlace)
2941                                  pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
2942                                else
2943                                  pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
2944 
2945                                break;
2946                              }
2947 #endif
2948                  }
2949 
2950                  break;
2951                }
2952     }
2953 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
2954 
2955     pData->iFilterofs = 0;             /* determine filter characteristics */
2956     pData->iLevel0    = 0;             /* default levels */
2957     pData->iLevel1    = 0;
2958     pData->iLevel2    = 0;
2959     pData->iLevel3    = 0;
2960 
2961 #ifdef FILTER192                       /* leveling & differing ? */
2962     if (pData->iFilter == MNG_FILTER_DIFFERING)
2963     {
2964       switch (pData->iColortype)
2965       {
2966         case 0 : {
2967                    if (pData->iBitdepth <= 8)
2968                      pData->iFilterofs = 1;
2969                    else
2970                      pData->iFilterofs = 2;
2971 
2972                    break;
2973                  }
2974         case 2 : {
2975                    if (pData->iBitdepth <= 8)
2976                      pData->iFilterofs = 3;
2977                    else
2978                      pData->iFilterofs = 6;
2979 
2980                    break;
2981                  }
2982         case 3 : {
2983                    pData->iFilterofs = 1;
2984                    break;
2985                  }
2986         case 4 : {
2987                    if (pData->iBitdepth <= 8)
2988                      pData->iFilterofs = 2;
2989                    else
2990                      pData->iFilterofs = 4;
2991 
2992                    break;
2993                  }
2994         case 6 : {
2995                    if (pData->iBitdepth <= 8)
2996                      pData->iFilterofs = 4;
2997                    else
2998                      pData->iFilterofs = 8;
2999 
3000                    break;
3001                  }
3002       }
3003     }
3004 #endif
3005 
3006 #ifdef FILTER193                       /* no adaptive filtering ? */
3007     if (pData->iFilter == MNG_FILTER_NOFILTER)
3008       pData->iPixelofs = pData->iFilterofs;
3009     else
3010 #endif
3011       pData->iPixelofs = pData->iFilterofs + 1;
3012 
3013   }
3014 
3015 #ifdef MNG_SUPPORT_TRACE
3016   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_END);
3017 #endif
3018 
3019   return MNG_NOERROR;
3020 }
3021 
3022 /* ************************************************************************** */
3023 
3024 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
mng_process_display_mpng(mng_datap pData)3025 mng_retcode mng_process_display_mpng (mng_datap pData)
3026 {
3027 #ifdef MNG_SUPPORT_TRACE
3028   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MPNG, MNG_LC_START);
3029 #endif
3030 
3031   pData->iAlphadepth = 8;              /* assume transparency !! */
3032 
3033   if (pData->fProcessheader)           /* inform the app (creating the output canvas) ? */
3034   {
3035     pData->iWidth  = ((mng_mpng_objp)pData->pMPNG)->iFramewidth;
3036     pData->iHeight = ((mng_mpng_objp)pData->pMPNG)->iFrameheight;
3037 
3038     if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
3039       MNG_ERROR (pData, MNG_APPMISCERROR);
3040   }
3041 
3042   next_layer (pData);                  /* first mPNG layer then ! */
3043   pData->bTimerset   = MNG_FALSE;
3044   pData->iBreakpoint = 0;
3045 
3046   if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
3047     set_display_routine (pData);       /* then determine display routine */
3048 
3049 #ifdef MNG_SUPPORT_TRACE
3050   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MPNG, MNG_LC_END);
3051 #endif
3052 
3053   return MNG_NOERROR;
3054 }
3055 #endif
3056 
3057 /* ************************************************************************** */
3058 
3059 #ifdef MNG_INCLUDE_ANG_PROPOSAL
mng_process_display_ang(mng_datap pData)3060 mng_retcode mng_process_display_ang (mng_datap pData)
3061 {
3062 #ifdef MNG_SUPPORT_TRACE
3063   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_ANG, MNG_LC_START);
3064 #endif
3065 
3066   if (pData->fProcessheader)           /* inform the app (creating the output canvas) ? */
3067   {
3068     if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
3069       MNG_ERROR (pData, MNG_APPMISCERROR);
3070   }
3071 
3072   next_layer (pData);                  /* first mPNG layer then ! */
3073   pData->bTimerset   = MNG_FALSE;
3074   pData->iBreakpoint = 0;
3075 
3076   if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
3077     set_display_routine (pData);       /* then determine display routine */
3078 
3079 #ifdef MNG_SUPPORT_TRACE
3080   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_ANG, MNG_LC_END);
3081 #endif
3082 
3083   return MNG_NOERROR;
3084 }
3085 #endif
3086 
3087 /* ************************************************************************** */
3088 
3089 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_idat(mng_datap pData,mng_uint32 iRawlen,mng_uint8p pRawdata)3090 mng_retcode mng_process_display_idat (mng_datap  pData,
3091                                       mng_uint32 iRawlen,
3092                                       mng_uint8p pRawdata)
3093 #else
3094 mng_retcode mng_process_display_idat (mng_datap  pData)
3095 #endif
3096 {
3097   mng_retcode iRetcode = MNG_NOERROR;
3098 
3099 #ifdef MNG_SUPPORT_TRACE
3100   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_START);
3101 #endif
3102 
3103 #if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
3104   if ((pData->eImagetype == mng_it_png) && (pData->iLayerseq <= 0))
3105   {
3106     if (pData->fProcessheader)         /* inform the app (creating the output canvas) ? */
3107       if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
3108         MNG_ERROR (pData, MNG_APPMISCERROR);
3109 
3110     next_layer (pData);                /* first regular PNG layer then ! */
3111     pData->bTimerset   = MNG_FALSE;
3112     pData->iBreakpoint = 0;
3113 
3114     if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
3115       set_display_routine (pData);     /* then determine display routine */
3116   }
3117 #endif
3118 
3119   if (pData->bRestorebkgd)             /* need to restore the background ? */
3120   {
3121     pData->bRestorebkgd = MNG_FALSE;
3122     iRetcode            = load_bkgdlayer (pData);
3123 
3124     if (iRetcode)                      /* on error bail out */
3125       return iRetcode;
3126 
3127     pData->iLayerseq++;                /* and it counts as a layer then ! */
3128   }
3129 
3130   if (pData->fInitrowproc)             /* need to initialize row processing? */
3131   {
3132     iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
3133     pData->fInitrowproc = MNG_NULL;    /* only call this once !!! */
3134   }
3135 
3136   if ((!iRetcode) && (!pData->bInflating))
3137                                        /* initialize inflate */
3138     iRetcode = mngzlib_inflateinit (pData);
3139 
3140   if (!iRetcode)                       /* all ok? then inflate, my man */
3141 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3142     iRetcode = mngzlib_inflaterows (pData, iRawlen, pRawdata);
3143 #else
3144     iRetcode = mngzlib_inflaterows (pData, pData->iRawlen, pData->pRawdata);
3145 #endif
3146 
3147   if (iRetcode)                        /* on error bail out */
3148     return iRetcode;
3149 
3150 #ifdef MNG_SUPPORT_TRACE
3151   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_END);
3152 #endif
3153 
3154   return MNG_NOERROR;
3155 }
3156 
3157 /* ************************************************************************** */
3158 
mng_process_display_iend(mng_datap pData)3159 mng_retcode mng_process_display_iend (mng_datap pData)
3160 {
3161   mng_retcode iRetcode, iRetcode2;
3162   mng_bool bDodisplay = MNG_FALSE;
3163   mng_bool bMagnify   = MNG_FALSE;
3164   mng_bool bCleanup   = (mng_bool)(pData->iBreakpoint != 0);
3165 
3166 #ifdef MNG_SUPPORT_TRACE
3167   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_START);
3168 #endif
3169 
3170 #ifdef MNG_INCLUDE_JNG                 /* progressive+alpha JNG can be displayed now */
3171   if ( (pData->bHasJHDR                                         ) &&
3172        ( (pData->bJPEGprogressive) || (pData->bJPEGprogressive2)) &&
3173        ( (pData->eImagetype == mng_it_jng         ) ||
3174          (((mng_imagep)pData->pStoreobj)->bVisible)             ) &&
3175        ( (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
3176          (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )    )
3177     bDodisplay = MNG_TRUE;
3178 #endif
3179 
3180 #ifndef MNG_SKIPCHUNK_MAGN
3181   if ( (pData->pStoreobj) &&           /* on-the-fly magnification ? */
3182        ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX) ||
3183          (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY)    ) )
3184     bMagnify = MNG_TRUE;
3185 #endif
3186 
3187   if ((pData->bHasBASI) ||             /* was it a BASI stream */
3188       (bDodisplay)      ||             /* or should we display the JNG */
3189 #ifndef MNG_SKIPCHUNK_MAGN
3190       (bMagnify)        ||             /* or should we magnify it */
3191 #endif
3192                                        /* or did we get broken here last time ? */
3193       ((pData->iBreakpoint) && (pData->iBreakpoint != 8)))
3194   {
3195     mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
3196 
3197     if (!pImage)                       /* or was it object 0 ? */
3198       pImage = (mng_imagep)pData->pObjzero;
3199                                        /* display it now then ? */
3200     if ((pImage->bVisible) && (pImage->bViewable))
3201     {                                  /* ok, so do it */
3202       iRetcode = mng_display_image (pData, pImage, bDodisplay);
3203 
3204       if (iRetcode)                    /* on error bail out */
3205         return iRetcode;
3206 
3207       if (pData->bTimerset)            /* timer break ? */
3208         pData->iBreakpoint = 6;
3209     }
3210   }
3211 #ifndef MNG_NO_DELTA_PNG
3212   else
3213   if ((pData->bHasDHDR) ||             /* was it a DHDR stream */
3214       (pData->iBreakpoint == 8))       /* or did we get broken here last time ? */
3215   {
3216     mng_imagep pImage = (mng_imagep)pData->pDeltaImage;
3217 
3218     if (!pData->iBreakpoint)
3219     {                                  /* perform the delta operations needed */
3220       iRetcode = mng_execute_delta_image (pData, pImage, (mng_imagep)pData->pObjzero);
3221 
3222       if (iRetcode)                    /* on error bail out */
3223         return iRetcode;
3224     }
3225                                        /* display it now then ? */
3226     if ((pImage->bVisible) && (pImage->bViewable))
3227     {                                  /* ok, so do it */
3228       iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
3229 
3230       if (iRetcode)                    /* on error bail out */
3231         return iRetcode;
3232 
3233       if (pData->bTimerset)            /* timer break ? */
3234         pData->iBreakpoint = 8;
3235     }
3236   }
3237 #endif
3238 
3239   if (!pData->bTimerset)               /* can we continue ? */
3240   {
3241     pData->iBreakpoint = 0;            /* clear this flag now ! */
3242 
3243 
3244 #ifdef MNG_INCLUDE_MPNG_PROPOSAL
3245     if (pData->eImagetype == mng_it_mpng)
3246     {
3247       pData->pCurraniobj = pData->pFirstaniobj;
3248     } else
3249 #endif
3250 #ifdef MNG_INCLUDE_ANG_PROPOSAL
3251     if (pData->eImagetype == mng_it_ang)
3252     {
3253       pData->pCurraniobj = pData->pFirstaniobj;
3254     } else
3255 #endif
3256     {                                  /* cleanup object 0 */
3257       mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
3258                                 0, 0, 0, 0, 0, 0, 0, MNG_TRUE);
3259     }
3260 
3261     if (pData->bInflating)             /* if we've been inflating */
3262     {                                  /* cleanup row-processing, */
3263       iRetcode  = mng_cleanup_rowproc (pData);
3264                                        /* also cleanup inflate! */
3265       iRetcode2 = mngzlib_inflatefree (pData);
3266 
3267       if (iRetcode)                    /* on error bail out */
3268         return iRetcode;
3269       if (iRetcode2)
3270         return iRetcode2;
3271     }
3272 
3273 #ifdef MNG_INCLUDE_JNG
3274     if (pData->bJPEGdecompress)        /* if we've been decompressing JDAT */
3275     {                                  /* cleanup row-processing, */
3276       iRetcode  = mng_cleanup_rowproc (pData);
3277                                        /* also cleanup decompress! */
3278       iRetcode2 = mngjpeg_decompressfree (pData);
3279 
3280       if (iRetcode)                    /* on error bail out */
3281         return iRetcode;
3282       if (iRetcode2)
3283         return iRetcode2;
3284     }
3285 
3286     if (pData->bJPEGdecompress2)       /* if we've been decompressing JDAA */
3287     {                                  /* cleanup row-processing, */
3288       iRetcode  = mng_cleanup_rowproc (pData);
3289                                        /* also cleanup decompress! */
3290       iRetcode2 = mngjpeg_decompressfree2 (pData);
3291 
3292       if (iRetcode)                    /* on error bail out */
3293         return iRetcode;
3294       if (iRetcode2)
3295         return iRetcode2;
3296     }
3297 #endif
3298 
3299     if (bCleanup)                      /* if we got broken last time we need to cleanup */
3300     {
3301       pData->bHasIHDR = MNG_FALSE;     /* IEND signals the end for most ... */
3302       pData->bHasBASI = MNG_FALSE;
3303       pData->bHasDHDR = MNG_FALSE;
3304 #ifdef MNG_INCLUDE_JNG
3305       pData->bHasJHDR = MNG_FALSE;
3306       pData->bHasJSEP = MNG_FALSE;
3307       pData->bHasJDAA = MNG_FALSE;
3308       pData->bHasJDAT = MNG_FALSE;
3309 #endif
3310       pData->bHasPLTE = MNG_FALSE;
3311       pData->bHasTRNS = MNG_FALSE;
3312       pData->bHasGAMA = MNG_FALSE;
3313       pData->bHasCHRM = MNG_FALSE;
3314       pData->bHasSRGB = MNG_FALSE;
3315       pData->bHasICCP = MNG_FALSE;
3316       pData->bHasBKGD = MNG_FALSE;
3317       pData->bHasIDAT = MNG_FALSE;
3318     }
3319                                        /* if the image was displayed on the fly, */
3320                                        /* we'll have to make the app refresh */
3321     if ((pData->eImagetype != mng_it_mng) && (pData->fDisplayrow))
3322       pData->bNeedrefresh = MNG_TRUE;
3323 
3324   }
3325 
3326 #ifdef MNG_SUPPORT_TRACE
3327   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_END);
3328 #endif
3329 
3330   return MNG_NOERROR;
3331 }
3332 
3333 /* ************************************************************************** */
3334 
3335 /* change in the MNG spec with regards to TERM delay & interframe_delay
3336    as proposed by Adam M. Costello (option 4) and finalized by official vote
3337    during december 2002 / check the 'mng-list' archives for more details */
3338 
mng_process_display_mend(mng_datap pData)3339 mng_retcode mng_process_display_mend (mng_datap pData)
3340 {
3341 #ifdef MNG_SUPPORT_TRACE
3342   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START);
3343 #endif
3344 
3345   pData->bForcedelay = pData->iAccumdelay ? MNG_FALSE : MNG_TRUE;
3346   pData->iAccumdelay = 0;
3347 
3348 #ifdef MNG_SUPPORT_DYNAMICMNG
3349   if (pData->bStopafterseek)           /* need to stop after this ? */
3350   {
3351     pData->bFreezing      = MNG_TRUE;  /* stop processing on this one */
3352     pData->bRunningevent  = MNG_FALSE;
3353     pData->bStopafterseek = MNG_FALSE;
3354     pData->bNeedrefresh   = MNG_TRUE;  /* make sure the last bit is displayed ! */
3355   }
3356 #endif
3357 
3358 #ifndef MNG_SKIPCHUNK_TERM
3359                                        /* TERM processed ? */
3360   if ((pData->bDisplaying) && (pData->bRunning) &&
3361       (pData->bHasTERM) && (pData->pTermaniobj))
3362   {
3363     mng_retcode   iRetcode;
3364     mng_ani_termp pTERM;
3365                                        /* get the right animation object ! */
3366     pTERM = (mng_ani_termp)pData->pTermaniobj;
3367 
3368     pData->iIterations++;              /* increase iteration count */
3369 
3370     switch (pTERM->iTermaction)        /* determine what to do! */
3371     {
3372       case 0 : {                       /* show last frame indefinitly */
3373                  break;                /* piece of cake, that is... */
3374                }
3375 
3376       case 1 : {                       /* cease displaying anything */
3377                                        /* max(1, TERM delay, interframe_delay) */
3378 #ifndef MNG_SKIPCHUNK_FRAM
3379                  if (pTERM->iDelay > pData->iFramedelay)
3380                    pData->iFramedelay = pTERM->iDelay;
3381                  if (!pData->iFramedelay)
3382                    pData->iFramedelay = 1;
3383 #endif
3384 
3385                  iRetcode = interframe_delay (pData);
3386                                        /* no interframe_delay? then fake it */
3387                  if ((!iRetcode) && (!pData->bTimerset))
3388                    iRetcode = set_delay (pData, 1);
3389 
3390                  if (iRetcode)
3391                    return iRetcode;
3392 
3393                  pData->iBreakpoint = 10;
3394                  break;
3395                }
3396 
3397       case 2 : {                       /* show first image after TERM */
3398                  iRetcode = restore_state (pData);
3399 
3400                  if (iRetcode)         /* on error bail out */
3401                    return iRetcode;
3402                                        /* notify the app ? */
3403                  if (pData->fProcessmend)
3404                    if (!pData->fProcessmend ((mng_handle)pData, pData->iIterations, 0))
3405                      MNG_ERROR (pData, MNG_APPMISCERROR);
3406 
3407                                        /* show first frame after TERM chunk */
3408                  pData->pCurraniobj      = pTERM;
3409                  pData->bOnlyfirstframe  = MNG_TRUE;
3410                  pData->iFramesafterTERM = 0;
3411 
3412                                        /* max(1, TERM delay, interframe_delay) */
3413 #ifndef MNG_SKIPCHUNK_FRAM
3414                  if (pTERM->iDelay > pData->iFramedelay)
3415                    pData->iFramedelay = pTERM->iDelay;
3416                  if (!pData->iFramedelay)
3417                    pData->iFramedelay = 1;
3418 #endif
3419 
3420                  break;
3421                }
3422 
3423       case 3 : {                       /* repeat */
3424                  if ((pTERM->iItermax) && (pTERM->iItermax < 0x7FFFFFFF))
3425                    pTERM->iItermax--;
3426 
3427                  if (pTERM->iItermax)  /* go back to TERM ? */
3428                  {                     /* restore to initial or SAVE state */
3429                    iRetcode = restore_state (pData);
3430 
3431                    if (iRetcode)       /* on error bail out */
3432                      return iRetcode;
3433                                        /* notify the app ? */
3434                    if (pData->fProcessmend)
3435                      if (!pData->fProcessmend ((mng_handle)pData,
3436                                                pData->iIterations, pTERM->iItermax))
3437                        MNG_ERROR (pData, MNG_APPMISCERROR);
3438 
3439                                        /* restart from TERM chunk */
3440                    pData->pCurraniobj = pTERM;
3441 
3442                    if (pTERM->iDelay)  /* set the delay (?) */
3443                    {
3444                                        /* max(1, TERM delay, interframe_delay) */
3445 #ifndef MNG_SKIPCHUNK_FRAM
3446                      if (pTERM->iDelay > pData->iFramedelay)
3447                        pData->iFramedelay = pTERM->iDelay;
3448                      if (!pData->iFramedelay)
3449                        pData->iFramedelay = 1;
3450 #endif
3451 
3452                      pData->bNeedrefresh = MNG_TRUE;
3453                    }
3454                  }
3455                  else
3456                  {
3457                    switch (pTERM->iIteraction)
3458                    {
3459                      case 0 : {        /* show last frame indefinitly */
3460                                 break; /* piece of cake, that is... */
3461                               }
3462 
3463                      case 1 : {        /* cease displaying anything */
3464                                        /* max(1, TERM delay, interframe_delay) */
3465 #ifndef MNG_SKIPCHUNK_FRAM
3466                                 if (pTERM->iDelay > pData->iFramedelay)
3467                                   pData->iFramedelay = pTERM->iDelay;
3468                                 if (!pData->iFramedelay)
3469                                   pData->iFramedelay = 1;
3470 #endif
3471 
3472                                 iRetcode = interframe_delay (pData);
3473                                        /* no interframe_delay? then fake it */
3474                                 if ((!iRetcode) && (!pData->bTimerset))
3475                                   iRetcode = set_delay (pData, 1);
3476 
3477                                 if (iRetcode)
3478                                   return iRetcode;
3479 
3480                                 pData->iBreakpoint = 10;
3481                                 break;
3482                               }
3483 
3484                      case 2 : {        /* show first image after TERM */
3485                                 iRetcode = restore_state (pData);
3486                                        /* on error bail out */
3487                                 if (iRetcode)
3488                                   return iRetcode;
3489                                        /* notify the app ? */
3490                                 if (pData->fProcessmend)
3491                                   if (!pData->fProcessmend ((mng_handle)pData,
3492                                                             pData->iIterations, 0))
3493                                     MNG_ERROR (pData, MNG_APPMISCERROR);
3494 
3495                                        /* show first frame after TERM chunk */
3496                                 pData->pCurraniobj      = pTERM;
3497                                 pData->bOnlyfirstframe  = MNG_TRUE;
3498                                 pData->iFramesafterTERM = 0;
3499                                        /* max(1, TERM delay, interframe_delay) */
3500 #ifndef MNG_SKIPCHUNK_FRAM
3501                                 if (pTERM->iDelay > pData->iFramedelay)
3502                                   pData->iFramedelay = pTERM->iDelay;
3503                                 if (!pData->iFramedelay)
3504                                   pData->iFramedelay = 1;
3505 #endif
3506 
3507                                 break;
3508                               }
3509                    }
3510                  }
3511 
3512                  break;
3513                }
3514     }
3515   }
3516 #endif /* MNG_SKIPCHUNK_TERM */
3517                                        /* just reading ? */
3518   if ((!pData->bDisplaying) && (pData->bReading))
3519     if (pData->fProcessmend)           /* inform the app ? */
3520       if (!pData->fProcessmend ((mng_handle)pData, 0, 0))
3521         MNG_ERROR (pData, MNG_APPMISCERROR);
3522 
3523   if (!pData->pCurraniobj)             /* always let the app refresh at the end ! */
3524     pData->bNeedrefresh = MNG_TRUE;
3525 
3526 #ifdef MNG_SUPPORT_TRACE
3527   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END);
3528 #endif
3529 
3530   return MNG_NOERROR;
3531 }
3532 
3533 /* ************************************************************************** */
3534 
mng_process_display_mend2(mng_datap pData)3535 mng_retcode mng_process_display_mend2 (mng_datap pData)
3536 {
3537 #ifdef MNG_SUPPORT_TRACE
3538   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START);
3539 #endif
3540 
3541 #ifndef MNG_SKIPCHUNK_FRAM
3542   pData->bFrameclipping = MNG_FALSE;   /* nothing to do but restore the app background */
3543 #endif
3544   load_bkgdlayer (pData);
3545 
3546 #ifdef MNG_SUPPORT_TRACE
3547   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END);
3548 #endif
3549 
3550   return MNG_NOERROR;
3551 }
3552 
3553 /* ************************************************************************** */
3554 
3555 #ifndef MNG_SKIPCHUNK_DEFI
mng_process_display_defi(mng_datap pData)3556 mng_retcode mng_process_display_defi (mng_datap pData)
3557 {
3558   mng_imagep pImage;
3559 
3560 #ifdef MNG_SUPPORT_TRACE
3561   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_START);
3562 #endif
3563 
3564   if (!pData->iDEFIobjectid)           /* object id=0 ? */
3565   {
3566     pImage             = (mng_imagep)pData->pObjzero;
3567 
3568     if (pData->bDEFIhasdonotshow)
3569       pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
3570 
3571     if (pData->bDEFIhasloca)
3572     {
3573       pImage->iPosx    = pData->iDEFIlocax;
3574       pImage->iPosy    = pData->iDEFIlocay;
3575     }
3576 
3577     if (pData->bDEFIhasclip)
3578     {
3579       pImage->bClipped = pData->bDEFIhasclip;
3580       pImage->iClipl   = pData->iDEFIclipl;
3581       pImage->iClipr   = pData->iDEFIclipr;
3582       pImage->iClipt   = pData->iDEFIclipt;
3583       pImage->iClipb   = pData->iDEFIclipb;
3584     }
3585 
3586     pData->pCurrentobj = 0;            /* not a real object ! */
3587   }
3588   else
3589   {                                    /* already exists ? */
3590     pImage = (mng_imagep)mng_find_imageobject (pData, pData->iDEFIobjectid);
3591 
3592     if (!pImage)                       /* if not; create new */
3593     {
3594       mng_retcode iRetcode = mng_create_imageobject (pData, pData->iDEFIobjectid,
3595                                                      (mng_bool)(pData->iDEFIconcrete == 1),
3596                                                      (mng_bool)(pData->iDEFIdonotshow == 0),
3597                                                      MNG_FALSE, 0, 0, 0, 0, 0, 0, 0,
3598                                                      pData->iDEFIlocax, pData->iDEFIlocay,
3599                                                      pData->bDEFIhasclip,
3600                                                      pData->iDEFIclipl, pData->iDEFIclipr,
3601                                                      pData->iDEFIclipt, pData->iDEFIclipb,
3602                                                      &pImage);
3603 
3604       if (iRetcode)                    /* on error bail out */
3605         return iRetcode;
3606     }
3607     else
3608     {                                  /* exists; then set new info */
3609       if (pData->bDEFIhasdonotshow)
3610         pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
3611 
3612       pImage->bViewable  = MNG_FALSE;
3613 
3614       if (pData->bDEFIhasloca)
3615       {
3616         pImage->iPosx    = pData->iDEFIlocax;
3617         pImage->iPosy    = pData->iDEFIlocay;
3618       }
3619 
3620       if (pData->bDEFIhasclip)
3621       {
3622         pImage->bClipped = pData->bDEFIhasclip;
3623         pImage->iClipl   = pData->iDEFIclipl;
3624         pImage->iClipr   = pData->iDEFIclipr;
3625         pImage->iClipt   = pData->iDEFIclipt;
3626         pImage->iClipb   = pData->iDEFIclipb;
3627       }
3628 
3629       if (pData->bDEFIhasconcrete)
3630         pImage->pImgbuf->bConcrete = (mng_bool)(pData->iDEFIconcrete == 1);
3631     }
3632 
3633     pData->pCurrentobj = pImage;       /* others may want to know this */
3634   }
3635 
3636 #ifdef MNG_SUPPORT_TRACE
3637   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_END);
3638 #endif
3639 
3640   return MNG_NOERROR;
3641 }
3642 #endif
3643 
3644 /* ************************************************************************** */
3645 
3646 #ifndef MNG_SKIPCHUNK_BASI
3647 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_basi(mng_datap pData,mng_uint16 iRed,mng_uint16 iGreen,mng_uint16 iBlue,mng_bool bHasalpha,mng_uint16 iAlpha,mng_uint8 iViewable)3648 mng_retcode mng_process_display_basi (mng_datap  pData,
3649                                       mng_uint16 iRed,
3650                                       mng_uint16 iGreen,
3651                                       mng_uint16 iBlue,
3652                                       mng_bool   bHasalpha,
3653                                       mng_uint16 iAlpha,
3654                                       mng_uint8  iViewable)
3655 #else
3656 mng_retcode mng_process_display_basi (mng_datap  pData)
3657 #endif
3658 {                                      /* address the current "object" if any */
3659   mng_imagep     pImage = (mng_imagep)pData->pCurrentobj;
3660   mng_uint8p     pWork;
3661   mng_uint32     iX;
3662   mng_imagedatap pBuf;
3663   mng_retcode    iRetcode;
3664 
3665 #ifdef MNG_SUPPORT_TRACE
3666   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_START);
3667 #endif
3668 
3669   if (!pImage)                         /* or is it an "on-the-fly" image ? */
3670     pImage = (mng_imagep)pData->pObjzero;
3671                                        /* address the object-buffer */
3672   pBuf               = pImage->pImgbuf;
3673 
3674   pData->fDisplayrow = MNG_NULL;       /* do nothing by default */
3675   pData->fCorrectrow = MNG_NULL;
3676   pData->fStorerow   = MNG_NULL;
3677   pData->fProcessrow = MNG_NULL;
3678                                        /* set parms now that they're known */
3679   iRetcode = mng_reset_object_details (pData, pImage, pData->iDatawidth,
3680                                        pData->iDataheight, pData->iBitdepth,
3681                                        pData->iColortype, pData->iCompression,
3682                                        pData->iFilter, pData->iInterlace, MNG_FALSE);
3683   if (iRetcode)                        /* on error bail out */
3684     return iRetcode;
3685                                        /* save the viewable flag */
3686 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3687   pImage->bViewable = (mng_bool)(iViewable == 1);
3688 #else
3689   pImage->bViewable = (mng_bool)(pData->iBASIviewable == 1);
3690 #endif
3691   pBuf->bViewable   = pImage->bViewable;
3692   pData->pStoreobj  = pImage;          /* let row-routines know which object */
3693 
3694   pWork = pBuf->pImgdata;              /* fill the object-buffer with the specified
3695                                           "color" sample */
3696   switch (pData->iColortype)           /* depending on color_type & bit_depth */
3697   {
3698     case 0 : {                         /* gray */
3699 #ifndef MNG_NO_16BIT_SUPPORT
3700                if (pData->iBitdepth == 16)
3701                {
3702 #ifdef MNG_DECREMENT_LOOPS
3703                  for (iX = pData->iDatawidth * pData->iDataheight;
3704                     iX > 0;iX--)
3705 #else
3706                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3707 #endif
3708                  {
3709 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3710                    mng_put_uint16 (pWork, iRed);
3711 #else
3712                    mng_put_uint16 (pWork, pData->iBASIred);
3713 #endif
3714                    pWork += 2;
3715                  }
3716                }
3717                else
3718 #endif
3719                {
3720 #ifdef MNG_DECREMENT_LOOPS
3721                  for (iX = pData->iDatawidth * pData->iDataheight;
3722                     iX > 0;iX--)
3723 #else
3724                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3725 #endif
3726                  {
3727 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3728                    *pWork = (mng_uint8)iRed;
3729 #else
3730                    *pWork = (mng_uint8)pData->iBASIred;
3731 #endif
3732                    pWork++;
3733                  }
3734                }
3735                                        /* force tRNS ? */
3736 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3737                if ((bHasalpha) && (!iAlpha))
3738 #else
3739                if ((pData->bBASIhasalpha) && (!pData->iBASIalpha))
3740 #endif
3741                {
3742                  pBuf->bHasTRNS  = MNG_TRUE;
3743 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3744                  pBuf->iTRNSgray = iRed;
3745 #else
3746                  pBuf->iTRNSgray = pData->iBASIred;
3747 #endif
3748                }
3749 
3750                break;
3751              }
3752 
3753     case 2 : {                         /* rgb */
3754 #ifndef MNG_NO_16BIT_SUPPORT
3755                if (pData->iBitdepth == 16)
3756                {
3757 #ifdef MNG_DECREMENT_LOOPS
3758                  for (iX = pData->iDatawidth * pData->iDataheight;
3759                     iX > 0;iX--)
3760 #else
3761                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3762 #endif
3763                  {
3764 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3765                    mng_put_uint16 (pWork,   iRed  );
3766                    mng_put_uint16 (pWork+2, iGreen);
3767                    mng_put_uint16 (pWork+4, iBlue );
3768 #else
3769                    mng_put_uint16 (pWork,   pData->iBASIred  );
3770                    mng_put_uint16 (pWork+2, pData->iBASIgreen);
3771                    mng_put_uint16 (pWork+4, pData->iBASIblue );
3772 #endif
3773                    pWork += 6;
3774                  }
3775                }
3776                else
3777 #endif
3778                {
3779 #ifdef MNG_DECREMENT_LOOPS
3780                  for (iX = pData->iDatawidth * pData->iDataheight;
3781                     iX > 0;iX--)
3782 #else
3783                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3784 #endif
3785                  {
3786 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3787                    *pWork     = (mng_uint8)iRed;
3788                    *(pWork+1) = (mng_uint8)iGreen;
3789                    *(pWork+2) = (mng_uint8)iBlue;
3790 #else
3791                    *pWork     = (mng_uint8)pData->iBASIred;
3792                    *(pWork+1) = (mng_uint8)pData->iBASIgreen;
3793                    *(pWork+2) = (mng_uint8)pData->iBASIblue;
3794 #endif
3795                    pWork += 3;
3796                  }
3797                }
3798                                        /* force tRNS ? */
3799 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3800                if ((bHasalpha) && (!iAlpha))
3801 #else
3802                if ((pData->bBASIhasalpha) && (!pData->iBASIalpha))
3803 #endif
3804                {
3805                  pBuf->bHasTRNS   = MNG_TRUE;
3806 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3807                  pBuf->iTRNSred   = iRed;
3808                  pBuf->iTRNSgreen = iGreen;
3809                  pBuf->iTRNSblue  = iBlue;
3810 #else
3811                  pBuf->iTRNSred   = pData->iBASIred;
3812                  pBuf->iTRNSgreen = pData->iBASIgreen;
3813                  pBuf->iTRNSblue  = pData->iBASIblue;
3814 #endif
3815                }
3816 
3817                break;
3818              }
3819 
3820     case 3 : {                         /* indexed */
3821                pBuf->bHasPLTE = MNG_TRUE;
3822 
3823                switch (pData->iBitdepth)
3824                {
3825                  case 1  : { pBuf->iPLTEcount =   2; break; }
3826                  case 2  : { pBuf->iPLTEcount =   4; break; }
3827                  case 4  : { pBuf->iPLTEcount =  16; break; }
3828                  case 8  : { pBuf->iPLTEcount = 256; break; }
3829                  default : { pBuf->iPLTEcount =   1; break; }
3830                }
3831 
3832 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3833                pBuf->aPLTEentries [0].iRed   = (mng_uint8)iRed;
3834                pBuf->aPLTEentries [0].iGreen = (mng_uint8)iGreen;
3835                pBuf->aPLTEentries [0].iBlue  = (mng_uint8)iBlue;
3836 #else
3837                pBuf->aPLTEentries [0].iRed   = (mng_uint8)pData->iBASIred;
3838                pBuf->aPLTEentries [0].iGreen = (mng_uint8)pData->iBASIgreen;
3839                pBuf->aPLTEentries [0].iBlue  = (mng_uint8)pData->iBASIblue;
3840 #endif
3841 
3842                for (iX = 1; iX < pBuf->iPLTEcount; iX++)
3843                {
3844                  pBuf->aPLTEentries [iX].iRed   = 0;
3845                  pBuf->aPLTEentries [iX].iGreen = 0;
3846                  pBuf->aPLTEentries [iX].iBlue  = 0;
3847                }
3848                                        /* force tRNS ? */
3849 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3850                if ((bHasalpha) && (iAlpha < 255))
3851 #else
3852                if ((pData->bBASIhasalpha) && (pData->iBASIalpha < 255))
3853 #endif
3854                {
3855                  pBuf->bHasTRNS         = MNG_TRUE;
3856                  pBuf->iTRNScount       = 1;
3857 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3858                  pBuf->aTRNSentries [0] = (mng_uint8)iAlpha;
3859 #else
3860                  pBuf->aTRNSentries [0] = (mng_uint8)pData->iBASIalpha;
3861 #endif
3862                }
3863 
3864                break;
3865              }
3866 
3867     case 4 : {                         /* gray+alpha */
3868 #ifndef MNG_NO_16BIT_SUPPORT
3869                if (pData->iBitdepth == 16)
3870                {
3871 #ifdef MNG_DECREMENT_LOOPS
3872                  for (iX = pData->iDatawidth * pData->iDataheight;
3873                     iX > 0;iX--)
3874 #else
3875                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3876 #endif
3877                  {
3878 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3879                    mng_put_uint16 (pWork,   iRed);
3880                    mng_put_uint16 (pWork+2, iAlpha);
3881 #else
3882                    mng_put_uint16 (pWork,   pData->iBASIred);
3883                    mng_put_uint16 (pWork+2, pData->iBASIalpha);
3884 #endif
3885                    pWork += 4;
3886                  }
3887                }
3888                else
3889 #endif
3890                {
3891 #ifdef MNG_DECREMENT_LOOPS
3892                  for (iX = pData->iDatawidth * pData->iDataheight;
3893                     iX > 0;iX--)
3894 #else
3895                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3896 #endif
3897                  {
3898 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3899                    *pWork     = (mng_uint8)iRed;
3900                    *(pWork+1) = (mng_uint8)iAlpha;
3901 #else
3902                    *pWork     = (mng_uint8)pData->iBASIred;
3903                    *(pWork+1) = (mng_uint8)pData->iBASIalpha;
3904 #endif
3905                    pWork += 2;
3906                  }
3907                }
3908 
3909                break;
3910              }
3911 
3912     case 6 : {                         /* rgb+alpha */
3913 #ifndef MNG_NO_16BIT_SUPPORT
3914                if (pData->iBitdepth == 16)
3915                {
3916 #ifdef MNG_DECREMENT_LOOPS
3917                  for (iX = pData->iDatawidth * pData->iDataheight;
3918                     iX > 0;iX--)
3919 #else
3920                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3921 #endif
3922                  {
3923 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3924                    mng_put_uint16 (pWork,   iRed);
3925                    mng_put_uint16 (pWork+2, iGreen);
3926                    mng_put_uint16 (pWork+4, iBlue);
3927                    mng_put_uint16 (pWork+6, iAlpha);
3928 #else
3929                    mng_put_uint16 (pWork,   pData->iBASIred);
3930                    mng_put_uint16 (pWork+2, pData->iBASIgreen);
3931                    mng_put_uint16 (pWork+4, pData->iBASIblue);
3932                    mng_put_uint16 (pWork+6, pData->iBASIalpha);
3933 #endif
3934                    pWork += 8;
3935                  }
3936                }
3937                else
3938 #endif
3939                {
3940 #ifdef MNG_DECREMENT_LOOPS
3941                  for (iX = pData->iDatawidth * pData->iDataheight;
3942                     iX > 0;iX--)
3943 #else
3944                  for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
3945 #endif
3946                  {
3947 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
3948                    *pWork     = (mng_uint8)iRed;
3949                    *(pWork+1) = (mng_uint8)iGreen;
3950                    *(pWork+2) = (mng_uint8)iBlue;
3951                    *(pWork+3) = (mng_uint8)iAlpha;
3952 #else
3953                    *pWork     = (mng_uint8)pData->iBASIred;
3954                    *(pWork+1) = (mng_uint8)pData->iBASIgreen;
3955                    *(pWork+2) = (mng_uint8)pData->iBASIblue;
3956                    *(pWork+3) = (mng_uint8)pData->iBASIalpha;
3957 #endif
3958                    pWork += 4;
3959                  }
3960                }
3961 
3962                break;
3963              }
3964 
3965   }
3966 
3967 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
3968   pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
3969   pData->ePng_imgtype=mng_png_imgtype(pData->iColortype,pData->iBitdepth);
3970 #else
3971   switch (pData->iColortype)           /* determine row initialization routine */
3972   {                                    /* just to accomodate IDAT if it arrives */
3973     case 0 : {                         /* gray */
3974                switch (pData->iBitdepth)
3975                {
3976 #ifndef MNG_NO_1_2_4BIT_SUPPORT
3977                  case  1 : {
3978                              if (!pData->iInterlace)
3979                                pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
3980                              else
3981                                pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
3982 
3983                              break;
3984                            }
3985                  case  2 : {
3986                              if (!pData->iInterlace)
3987                                pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
3988                              else
3989                                pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
3990 
3991                              break;
3992                            }
3993                  case  4 : {
3994                              if (!pData->iInterlace)
3995                                pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
3996                              else
3997                                pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
3998 
3999                              break;
4000                            }
4001 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
4002                  case  8 : {
4003                              if (!pData->iInterlace)
4004                                pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
4005                              else
4006                                pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
4007 
4008                              break;
4009                            }
4010 #ifndef MNG_NO_16BIT_SUPPORT
4011                  case 16 : {
4012                              if (!pData->iInterlace)
4013                                pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
4014                              else
4015                                pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
4016 
4017                              break;
4018                            }
4019 #endif
4020                }
4021 
4022                break;
4023              }
4024     case 2 : {                         /* rgb */
4025                switch (pData->iBitdepth)
4026                {
4027                  case  8 : {
4028                              if (!pData->iInterlace)
4029                                pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
4030                              else
4031                                pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
4032 
4033                              break;
4034                            }
4035 #ifndef MNG_NO_16BIT_SUPPORT
4036                  case 16 : {
4037                              if (!pData->iInterlace)
4038                                pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
4039                              else
4040                                pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
4041 
4042                              break;
4043                            }
4044 #endif
4045                }
4046 
4047                break;
4048              }
4049     case 3 : {                         /* indexed */
4050                switch (pData->iBitdepth)
4051                {
4052 #ifndef MNG_NO_1_2_4BIT_SUPPORT
4053                  case  1 : {
4054                              if (!pData->iInterlace)
4055                                pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
4056                              else
4057                                pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
4058 
4059                              break;
4060                            }
4061                  case  2 : {
4062                              if (!pData->iInterlace)
4063                                pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
4064                              else
4065                                pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
4066 
4067                              break;
4068                            }
4069                  case  4 : {
4070                              if (!pData->iInterlace)
4071                                pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
4072                              else
4073                                pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
4074 
4075                              break;
4076                            }
4077 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
4078                  case  8 : {
4079                              if (!pData->iInterlace)
4080                                pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
4081                              else
4082                                pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
4083 
4084                              break;
4085                            }
4086                }
4087 
4088                break;
4089              }
4090     case 4 : {                         /* gray+alpha */
4091                switch (pData->iBitdepth)
4092                {
4093                  case  8 : {
4094                              if (!pData->iInterlace)
4095                                pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
4096                              else
4097                                pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
4098 
4099                              break;
4100                            }
4101 #ifndef MNG_NO_16BIT_SUPPORT
4102                  case 16 : {
4103                              if (!pData->iInterlace)
4104                                pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
4105                              else
4106                                pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
4107 
4108                              break;
4109                            }
4110 #endif
4111                }
4112 
4113                break;
4114              }
4115     case 6 : {                         /* rgb+alpha */
4116                switch (pData->iBitdepth)
4117                {
4118                  case  8 : {
4119                              if (!pData->iInterlace)
4120                                pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
4121                              else
4122                                pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
4123 
4124                              break;
4125                            }
4126 #ifndef MNG_NO_16BIT_SUPPORT
4127                  case 16 : {
4128                              if (!pData->iInterlace)
4129                                pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
4130                              else
4131                                pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
4132 
4133                              break;
4134                            }
4135 #endif
4136                }
4137 
4138                break;
4139              }
4140   }
4141 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
4142 
4143   pData->iFilterofs = 0;               /* determine filter characteristics */
4144   pData->iLevel0    = 0;               /* default levels */
4145   pData->iLevel1    = 0;
4146   pData->iLevel2    = 0;
4147   pData->iLevel3    = 0;
4148 
4149 #ifdef FILTER192
4150   if (pData->iFilter == 0xC0)          /* leveling & differing ? */
4151   {
4152     switch (pData->iColortype)
4153     {
4154       case 0 : {
4155 #ifndef MNG_NO_16BIT_SUPPORT
4156                  if (pData->iBitdepth <= 8)
4157 #endif
4158                    pData->iFilterofs = 1;
4159 #ifndef MNG_NO_16BIT_SUPPORT
4160                  else
4161                    pData->iFilterofs = 2;
4162 #endif
4163 
4164                  break;
4165                }
4166       case 2 : {
4167 #ifndef MNG_NO_16BIT_SUPPORT
4168                  if (pData->iBitdepth <= 8)
4169 #endif
4170                    pData->iFilterofs = 3;
4171 #ifndef MNG_NO_16BIT_SUPPORT
4172                  else
4173                    pData->iFilterofs = 6;
4174 #endif
4175 
4176                  break;
4177                }
4178       case 3 : {
4179                  pData->iFilterofs = 1;
4180                  break;
4181                }
4182       case 4 : {
4183 #ifndef MNG_NO_16BIT_SUPPORT
4184                  if (pData->iBitdepth <= 8)
4185 #endif
4186                    pData->iFilterofs = 2;
4187 #ifndef MNG_NO_16BIT_SUPPORT
4188                  else
4189                    pData->iFilterofs = 4;
4190 #endif
4191 
4192                  break;
4193                }
4194       case 6 : {
4195 #ifndef MNG_NO_16BIT_SUPPORT
4196                  if (pData->iBitdepth <= 8)
4197 #endif
4198                    pData->iFilterofs = 4;
4199 #ifndef MNG_NO_16BIT_SUPPORT
4200                  else
4201                    pData->iFilterofs = 8;
4202 #endif
4203 
4204                  break;
4205                }
4206     }
4207   }
4208 #endif
4209 
4210 #ifdef FILTER193
4211   if (pData->iFilter == 0xC1)          /* no adaptive filtering ? */
4212     pData->iPixelofs = pData->iFilterofs;
4213   else
4214 #endif
4215     pData->iPixelofs = pData->iFilterofs + 1;
4216 
4217 #ifdef MNG_SUPPORT_TRACE
4218   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_END);
4219 #endif
4220 
4221   return MNG_NOERROR;
4222 }
4223 #endif
4224 
4225 /* ************************************************************************** */
4226 
4227 #ifndef MNG_SKIPCHUNK_CLON
4228 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_clon(mng_datap pData,mng_uint16 iSourceid,mng_uint16 iCloneid,mng_uint8 iClonetype,mng_bool bHasdonotshow,mng_uint8 iDonotshow,mng_uint8 iConcrete,mng_bool bHasloca,mng_uint8 iLocationtype,mng_int32 iLocationx,mng_int32 iLocationy)4229 mng_retcode mng_process_display_clon (mng_datap  pData,
4230                                       mng_uint16 iSourceid,
4231                                       mng_uint16 iCloneid,
4232                                       mng_uint8  iClonetype,
4233                                       mng_bool   bHasdonotshow,
4234                                       mng_uint8  iDonotshow,
4235                                       mng_uint8  iConcrete,
4236                                       mng_bool   bHasloca,
4237                                       mng_uint8  iLocationtype,
4238                                       mng_int32  iLocationx,
4239                                       mng_int32  iLocationy)
4240 #else
4241 mng_retcode mng_process_display_clon (mng_datap  pData)
4242 #endif
4243 {
4244   mng_imagep  pSource, pClone;
4245   mng_bool    bVisible, bAbstract;
4246   mng_retcode iRetcode = MNG_NOERROR;
4247 
4248 #ifdef MNG_SUPPORT_TRACE
4249   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START);
4250 #endif
4251 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4252                                        /* locate the source object first */
4253   pSource = mng_find_imageobject (pData, iSourceid);
4254                                        /* check if the clone exists */
4255   pClone  = mng_find_imageobject (pData, iCloneid);
4256 #else
4257                                        /* locate the source object first */
4258   pSource = mng_find_imageobject (pData, pData->iCLONsourceid);
4259                                        /* check if the clone exists */
4260   pClone  = mng_find_imageobject (pData, pData->iCLONcloneid);
4261 #endif
4262 
4263   if (!pSource)                        /* source must exist ! */
4264     MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
4265 
4266   if (pClone)                          /* clone must not exist ! */
4267     MNG_ERROR (pData, MNG_OBJECTEXISTS);
4268 
4269 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4270   if (bHasdonotshow)                   /* DoNotShow flag filled ? */
4271     bVisible = (mng_bool)(iDonotshow == 0);
4272   else
4273     bVisible = pSource->bVisible;
4274 #else
4275   if (pData->bCLONhasdonotshow)        /* DoNotShow flag filled ? */
4276     bVisible = (mng_bool)(pData->iCLONdonotshow == 0);
4277   else
4278     bVisible = pSource->bVisible;
4279 #endif
4280 
4281 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4282   bAbstract  = (mng_bool)(iConcrete == 1);
4283 #else
4284   bAbstract  = (mng_bool)(pData->iCLONconcrete == 1);
4285 #endif
4286 
4287 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4288   switch (iClonetype)                  /* determine action to take */
4289   {
4290     case 0 : {                         /* full clone */
4291                iRetcode = mng_clone_imageobject (pData, iCloneid, MNG_FALSE,
4292                                                  bVisible, bAbstract, bHasloca,
4293                                                  iLocationtype, iLocationx, iLocationy,
4294                                                  pSource, &pClone);
4295                break;
4296              }
4297 
4298     case 1 : {                         /* partial clone */
4299                iRetcode = mng_clone_imageobject (pData, iCloneid, MNG_TRUE,
4300                                                  bVisible, bAbstract, bHasloca,
4301                                                  iLocationtype, iLocationx, iLocationy,
4302                                                  pSource, &pClone);
4303                break;
4304              }
4305 
4306     case 2 : {                         /* renumber object */
4307                iRetcode = mng_renum_imageobject (pData, pSource, iCloneid,
4308                                                  bVisible, bAbstract, bHasloca,
4309                                                  iLocationtype, iLocationx, iLocationy);
4310                pClone   = pSource;
4311                break;
4312              }
4313 
4314   }
4315 #else
4316   switch (pData->iCLONclonetype)       /* determine action to take */
4317   {
4318     case 0 : {                         /* full clone */
4319                iRetcode = mng_clone_imageobject (pData, pData->iCLONcloneid, MNG_FALSE,
4320                                                  bVisible, bAbstract,
4321                                                  pData->bCLONhasloca, pData->iCLONlocationtype,
4322                                                  pData->iCLONlocationx, pData->iCLONlocationy,
4323                                                  pSource, &pClone);
4324                break;
4325              }
4326 
4327     case 1 : {                         /* partial clone */
4328                iRetcode = mng_clone_imageobject (pData, pData->iCLONcloneid, MNG_TRUE,
4329                                                  bVisible, bAbstract,
4330                                                  pData->bCLONhasloca, pData->iCLONlocationtype,
4331                                                  pData->iCLONlocationx, pData->iCLONlocationy,
4332                                                  pSource, &pClone);
4333                break;
4334              }
4335 
4336     case 2 : {                         /* renumber object */
4337                iRetcode = mng_renum_imageobject (pData, pSource, pData->iCLONcloneid,
4338                                                  bVisible, bAbstract,
4339                                                  pData->bCLONhasloca, pData->iCLONlocationtype,
4340                                                  pData->iCLONlocationx, pData->iCLONlocationy);
4341                pClone   = pSource;
4342                break;
4343              }
4344 
4345   }
4346 #endif
4347 
4348   if (iRetcode)                        /* on error bail out */
4349     return iRetcode;
4350 
4351                                        /* display on the fly ? */
4352   if ((pClone->bViewable) && (pClone->bVisible))
4353   {
4354     pData->pLastclone = pClone;        /* remember in case of timer break ! */
4355                                        /* display it */
4356     mng_display_image (pData, pClone, MNG_FALSE);
4357 
4358     if (pData->bTimerset)              /* timer break ? */
4359       pData->iBreakpoint = 5;
4360   }
4361 
4362 #ifdef MNG_SUPPORT_TRACE
4363   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END);
4364 #endif
4365 
4366   return MNG_NOERROR;
4367 }
4368 
4369 /* ************************************************************************** */
4370 
mng_process_display_clon2(mng_datap pData)4371 mng_retcode mng_process_display_clon2 (mng_datap pData)
4372 {
4373 #ifdef MNG_SUPPORT_TRACE
4374   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START);
4375 #endif
4376                                        /* only called after timer break ! */
4377   mng_display_image (pData, (mng_imagep)pData->pLastclone, MNG_FALSE);
4378   pData->iBreakpoint = 0;
4379 
4380 #ifdef MNG_SUPPORT_TRACE
4381   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END);
4382 #endif
4383 
4384   return MNG_NOERROR;
4385 }
4386 #endif
4387 
4388 /* ************************************************************************** */
4389 
4390 #ifndef MNG_SKIPCHUNK_DISC
4391 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_disc(mng_datap pData,mng_uint32 iCount,mng_uint16p pIds)4392 mng_retcode mng_process_display_disc (mng_datap   pData,
4393                                       mng_uint32  iCount,
4394                                       mng_uint16p pIds)
4395 #else
4396 mng_retcode mng_process_display_disc (mng_datap   pData)
4397 #endif
4398 {
4399   mng_uint32 iX;
4400   mng_imagep pImage;
4401   mng_uint32 iRetcode;
4402 #ifdef MNG_SUPPORT_TRACE
4403   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_START);
4404 #endif
4405 
4406 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4407   if (iCount)                          /* specific list ? */
4408 #else
4409   if (pData->iDISCcount)               /* specific list ? */
4410 #endif
4411   {
4412 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4413     mng_uint16p pWork = pIds;
4414 #else
4415     mng_uint16p pWork = pData->pDISCids;
4416 #endif
4417 
4418 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4419 #ifdef MNG_DECREMENT_LOOPS             /* iterate the list */
4420     for (iX = iCount; iX > 0; iX--)
4421 #else
4422     for (iX = 0; iX < iCount; iX++)
4423 #endif
4424 #else
4425 #ifdef MNG_DECREMENT_LOOPS             /* iterate the list */
4426     for (iX = pData->iDISCcount; iX > 0; iX--)
4427 #else
4428     for (iX = 0; iX < pData->iDISCcount; iX++)
4429 #endif
4430 #endif
4431     {
4432       pImage = mng_find_imageobject (pData, *pWork++);
4433 
4434       if (pImage)                      /* found the object ? */
4435       {                                /* then drop it */
4436         iRetcode = mng_free_imageobject (pData, pImage);
4437 
4438         if (iRetcode)                  /* on error bail out */
4439           return iRetcode;
4440       }
4441     }
4442   }
4443   else                                 /* empty: drop all un-frozen objects */
4444   {
4445     mng_imagep pNext = (mng_imagep)pData->pFirstimgobj;
4446 
4447     while (pNext)                      /* any left ? */
4448     {
4449       pImage = pNext;
4450       pNext  = pImage->sHeader.pNext;
4451 
4452       if (!pImage->bFrozen)            /* not frozen ? */
4453       {                                /* then drop it */
4454         iRetcode = mng_free_imageobject (pData, pImage);
4455 
4456         if (iRetcode)                  /* on error bail out */
4457           return iRetcode;
4458       }
4459     }
4460   }
4461 
4462 #ifdef MNG_SUPPORT_TRACE
4463   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_END);
4464 #endif
4465 
4466   return MNG_NOERROR;
4467 }
4468 #endif
4469 
4470 /* ************************************************************************** */
4471 
4472 #ifndef MNG_SKIPCHUNK_FRAM
4473 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_fram(mng_datap pData,mng_uint8 iFramemode,mng_uint8 iChangedelay,mng_uint32 iDelay,mng_uint8 iChangetimeout,mng_uint32 iTimeout,mng_uint8 iChangeclipping,mng_uint8 iCliptype,mng_int32 iClipl,mng_int32 iClipr,mng_int32 iClipt,mng_int32 iClipb)4474 mng_retcode mng_process_display_fram (mng_datap  pData,
4475                                       mng_uint8  iFramemode,
4476                                       mng_uint8  iChangedelay,
4477                                       mng_uint32 iDelay,
4478                                       mng_uint8  iChangetimeout,
4479                                       mng_uint32 iTimeout,
4480                                       mng_uint8  iChangeclipping,
4481                                       mng_uint8  iCliptype,
4482                                       mng_int32  iClipl,
4483                                       mng_int32  iClipr,
4484                                       mng_int32  iClipt,
4485                                       mng_int32  iClipb)
4486 #else
4487 mng_retcode mng_process_display_fram (mng_datap  pData)
4488 #endif
4489 {
4490   mng_retcode iRetcode;
4491 
4492 #ifdef MNG_SUPPORT_TRACE
4493   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START);
4494 #endif
4495                                        /* advance a frame then */
4496 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4497   iRetcode = next_frame (pData, iFramemode, iChangedelay, iDelay,
4498                          iChangetimeout, iTimeout, iChangeclipping,
4499                          iCliptype, iClipl, iClipr, iClipt, iClipb);
4500 #else
4501   iRetcode = next_frame (pData, pData->iTempFramemode, pData->iTempChangedelay,
4502                          pData->iTempDelay, pData->iTempChangetimeout,
4503                          pData->iTempTimeout, pData->iTempChangeclipping,
4504                          pData->iTempCliptype, pData->iTempClipl, pData->iTempClipr,
4505                          pData->iTempClipt, pData->iTempClipb);
4506 #endif
4507 
4508   if (pData->bTimerset)                /* timer break ? */
4509     pData->iBreakpoint = 1;
4510 
4511 #ifdef MNG_SUPPORT_TRACE
4512   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END);
4513 #endif
4514 
4515   return iRetcode;
4516 }
4517 
4518 /* ************************************************************************** */
4519 
mng_process_display_fram2(mng_datap pData)4520 mng_retcode mng_process_display_fram2 (mng_datap pData)
4521 {
4522   mng_retcode iRetcode;
4523 
4524 #ifdef MNG_SUPPORT_TRACE
4525   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START);
4526 #endif
4527                                        /* again; after the break */
4528   iRetcode = next_frame (pData, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
4529   pData->iBreakpoint = 0;              /* not again! */
4530 
4531 #ifdef MNG_SUPPORT_TRACE
4532   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END);
4533 #endif
4534 
4535   return iRetcode;
4536 }
4537 #endif
4538 
4539 /* ************************************************************************** */
4540 
4541 #ifndef MNG_SKIPCHUNK_MOVE
4542 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_move(mng_datap pData,mng_uint16 iFromid,mng_uint16 iToid,mng_uint8 iMovetype,mng_int32 iMovex,mng_int32 iMovey)4543 mng_retcode mng_process_display_move (mng_datap  pData,
4544                                       mng_uint16 iFromid,
4545                                       mng_uint16 iToid,
4546                                       mng_uint8  iMovetype,
4547                                       mng_int32  iMovex,
4548                                       mng_int32  iMovey)
4549 #else
4550 mng_retcode mng_process_display_move (mng_datap  pData)
4551 #endif
4552 {
4553   mng_uint16 iX;
4554   mng_imagep pImage;
4555 
4556 #ifdef MNG_SUPPORT_TRACE
4557   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_START);
4558 #endif
4559                                        /* iterate the list */
4560 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4561   for (iX = iFromid; iX <= iToid; iX++)
4562 #else
4563   for (iX = pData->iMOVEfromid; iX <= pData->iMOVEtoid; iX++)
4564 #endif
4565   {
4566     if (!iX)                           /* object id=0 ? */
4567       pImage = (mng_imagep)pData->pObjzero;
4568     else
4569       pImage = mng_find_imageobject (pData, iX);
4570 
4571     if (pImage)                        /* object exists ? */
4572     {
4573 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4574       switch (iMovetype)
4575 #else
4576       switch (pData->iMOVEmovetype)
4577 #endif
4578       {
4579         case 0 : {                     /* absolute */
4580 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4581                    pImage->iPosx = iMovex;
4582                    pImage->iPosy = iMovey;
4583 #else
4584                    pImage->iPosx = pData->iMOVEmovex;
4585                    pImage->iPosy = pData->iMOVEmovey;
4586 #endif
4587                    break;
4588                  }
4589         case 1 : {                     /* relative */
4590 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4591                    pImage->iPosx = pImage->iPosx + iMovex;
4592                    pImage->iPosy = pImage->iPosy + iMovey;
4593 #else
4594                    pImage->iPosx = pImage->iPosx + pData->iMOVEmovex;
4595                    pImage->iPosy = pImage->iPosy + pData->iMOVEmovey;
4596 #endif
4597                    break;
4598                  }
4599       }
4600     }
4601   }
4602 
4603 #ifdef MNG_SUPPORT_TRACE
4604   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_END);
4605 #endif
4606 
4607   return MNG_NOERROR;
4608 }
4609 #endif
4610 
4611 /* ************************************************************************** */
4612 
4613 #ifndef MNG_SKIPCHUNK_CLIP
4614 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_clip(mng_datap pData,mng_uint16 iFromid,mng_uint16 iToid,mng_uint8 iCliptype,mng_int32 iClipl,mng_int32 iClipr,mng_int32 iClipt,mng_int32 iClipb)4615 mng_retcode mng_process_display_clip (mng_datap  pData,
4616                                       mng_uint16 iFromid,
4617                                       mng_uint16 iToid,
4618                                       mng_uint8  iCliptype,
4619                                       mng_int32  iClipl,
4620                                       mng_int32  iClipr,
4621                                       mng_int32  iClipt,
4622                                       mng_int32  iClipb)
4623 #else
4624 mng_retcode mng_process_display_clip (mng_datap  pData)
4625 #endif
4626 {
4627   mng_uint16 iX;
4628   mng_imagep pImage;
4629 
4630 #ifdef MNG_SUPPORT_TRACE
4631   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_START);
4632 #endif
4633                                        /* iterate the list */
4634 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4635   for (iX = iFromid; iX <= iToid; iX++)
4636 #else
4637   for (iX = pData->iCLIPfromid; iX <= pData->iCLIPtoid; iX++)
4638 #endif
4639   {
4640     if (!iX)                           /* object id=0 ? */
4641       pImage = (mng_imagep)pData->pObjzero;
4642     else
4643       pImage = mng_find_imageobject (pData, iX);
4644 
4645     if (pImage)                        /* object exists ? */
4646     {
4647 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4648       switch (iCliptype)
4649 #else
4650       switch (pData->iCLIPcliptype)
4651 #endif
4652       {
4653         case 0 : {                     /* absolute */
4654                    pImage->bClipped = MNG_TRUE;
4655 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4656                    pImage->iClipl   = iClipl;
4657                    pImage->iClipr   = iClipr;
4658                    pImage->iClipt   = iClipt;
4659                    pImage->iClipb   = iClipb;
4660 #else
4661                    pImage->iClipl   = pData->iCLIPclipl;
4662                    pImage->iClipr   = pData->iCLIPclipr;
4663                    pImage->iClipt   = pData->iCLIPclipt;
4664                    pImage->iClipb   = pData->iCLIPclipb;
4665 #endif
4666                    break;
4667                  }
4668         case 1 : {                    /* relative */
4669                    pImage->bClipped = MNG_TRUE;
4670 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
4671                    pImage->iClipl   = pImage->iClipl + iClipl;
4672                    pImage->iClipr   = pImage->iClipr + iClipr;
4673                    pImage->iClipt   = pImage->iClipt + iClipt;
4674                    pImage->iClipb   = pImage->iClipb + iClipb;
4675 #else
4676                    pImage->iClipl   = pImage->iClipl + pData->iCLIPclipl;
4677                    pImage->iClipr   = pImage->iClipr + pData->iCLIPclipr;
4678                    pImage->iClipt   = pImage->iClipt + pData->iCLIPclipt;
4679                    pImage->iClipb   = pImage->iClipb + pData->iCLIPclipb;
4680 #endif
4681                    break;
4682                  }
4683       }
4684     }
4685   }
4686 
4687 #ifdef MNG_SUPPORT_TRACE
4688   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_END);
4689 #endif
4690 
4691   return MNG_NOERROR;
4692 }
4693 #endif
4694 
4695 /* ************************************************************************** */
4696 
4697 #ifndef MNG_SKIPCHUNK_SHOW
mng_process_display_show(mng_datap pData)4698 mng_retcode mng_process_display_show (mng_datap pData)
4699 {
4700   mng_int16  iX, iS, iFrom, iTo;
4701   mng_imagep pImage;
4702 
4703 #ifdef MNG_SUPPORT_TRACE
4704   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_START);
4705 #endif
4706 
4707   /* TODO: optimization for the cases where "abs (iTo - iFrom)" is rather high;
4708      especially where ((iFrom==1) && (iTo==65535)); eg. an empty SHOW !!! */
4709 
4710   if (pData->iBreakpoint == 3)         /* previously broken during cycle-mode ? */
4711   {
4712     pImage = mng_find_imageobject (pData, pData->iSHOWnextid);
4713 
4714     if (pImage)                        /* still there ? */
4715       mng_display_image (pData, pImage, MNG_FALSE);
4716 
4717     pData->iBreakpoint = 0;            /* let's not go through this again! */
4718   }
4719   else
4720   {
4721     if (pData->iBreakpoint)            /* previously broken at other point ? */
4722     {                                  /* restore last parms */
4723       iFrom = (mng_int16)pData->iSHOWfromid;
4724       iTo   = (mng_int16)pData->iSHOWtoid;
4725       iX    = (mng_int16)pData->iSHOWnextid;
4726       iS    = (mng_int16)pData->iSHOWskip;
4727     }
4728     else
4729     {                                  /* regular sequence ? */
4730       if (pData->iSHOWtoid >= pData->iSHOWfromid)
4731         iS  = 1;
4732       else                             /* reverse sequence ! */
4733         iS  = -1;
4734 
4735       iFrom = (mng_int16)pData->iSHOWfromid;
4736       iTo   = (mng_int16)pData->iSHOWtoid;
4737       iX    = iFrom;
4738 
4739       pData->iSHOWfromid = (mng_uint16)iFrom;
4740       pData->iSHOWtoid   = (mng_uint16)iTo;
4741       pData->iSHOWskip   = iS;
4742     }
4743                                        /* cycle mode ? */
4744     if ((pData->iSHOWmode == 6) || (pData->iSHOWmode == 7))
4745     {
4746       mng_uint16 iTrigger = 0;
4747       mng_uint16 iFound   = 0;
4748       mng_uint16 iPass    = 0;
4749       mng_imagep pFound   = 0;
4750 
4751       do
4752       {
4753         iPass++;                       /* lets prevent endless loops when there
4754                                           are no potential candidates in the list! */
4755 
4756         if (iS > 0)                    /* forward ? */
4757         {
4758           for (iX = iFrom; iX <= iTo; iX += iS)
4759           {
4760             pImage = mng_find_imageobject (pData, (mng_uint16)iX);
4761 
4762             if (pImage)                /* object exists ? */
4763             {
4764               if (iFound)              /* already found a candidate ? */
4765                 pImage->bVisible = MNG_FALSE;
4766               else
4767               if (iTrigger)            /* found the trigger ? */
4768               {
4769                 pImage->bVisible = MNG_TRUE;
4770                 iFound           = iX;
4771                 pFound           = pImage;
4772               }
4773               else
4774               if (pImage->bVisible)    /* ok, this is the trigger */
4775               {
4776                 pImage->bVisible = MNG_FALSE;
4777                 iTrigger         = iX;
4778               }
4779             }
4780           }
4781         }
4782         else
4783         {
4784           for (iX = iFrom; iX >= iTo; iX += iS)
4785           {
4786             pImage = mng_find_imageobject (pData, (mng_uint16)iX);
4787 
4788             if (pImage)                /* object exists ? */
4789             {
4790               if (iFound)              /* already found a candidate ? */
4791                 pImage->bVisible = MNG_FALSE;
4792               else
4793               if (iTrigger)            /* found the trigger ? */
4794               {
4795                 pImage->bVisible = MNG_TRUE;
4796                 iFound           = iX;
4797                 pFound           = pImage;
4798               }
4799               else
4800               if (pImage->bVisible)    /* ok, this is the trigger */
4801               {
4802                 pImage->bVisible = MNG_FALSE;
4803                 iTrigger         = iX;
4804               }
4805             }
4806           }
4807         }
4808 
4809         if (!iTrigger)                 /* did not find a trigger ? */
4810           iTrigger = 1;                /* then fake it so the first image
4811                                           gets nominated */
4812       }                                /* cycle back to beginning ? */
4813       while ((iPass < 2) && (iTrigger) && (!iFound));
4814 
4815       pData->iBreakpoint = 0;          /* just a sanity precaution */
4816                                        /* display it ? */
4817       if ((pData->iSHOWmode == 6) && (pFound))
4818       {
4819         mng_display_image (pData, pFound, MNG_FALSE);
4820 
4821         if (pData->bTimerset)          /* timer set ? */
4822         {
4823           pData->iBreakpoint = 3;
4824           pData->iSHOWnextid = iFound; /* save it for after the break */
4825         }
4826       }
4827     }
4828     else
4829     {
4830       do
4831       {
4832         pImage = mng_find_imageobject (pData, iX);
4833 
4834         if (pImage)                    /* object exists ? */
4835         {
4836           if (pData->iBreakpoint)      /* did we get broken last time ? */
4837           {                            /* could only happen in the display routine */
4838             mng_display_image (pData, pImage, MNG_FALSE);
4839             pData->iBreakpoint = 0;    /* only once inside this loop please ! */
4840           }
4841           else
4842           {
4843             switch (pData->iSHOWmode)  /* do what ? */
4844             {
4845               case 0 : {
4846                          pImage->bVisible = MNG_TRUE;
4847                          mng_display_image (pData, pImage, MNG_FALSE);
4848                          break;
4849                        }
4850               case 1 : {
4851                          pImage->bVisible = MNG_FALSE;
4852                          break;
4853                        }
4854               case 2 : {
4855                          if (pImage->bVisible)
4856                            mng_display_image (pData, pImage, MNG_FALSE);
4857                          break;
4858                        }
4859               case 3 : {
4860                          pImage->bVisible = MNG_TRUE;
4861                          break;
4862                        }
4863               case 4 : {
4864                          pImage->bVisible = (mng_bool)(!pImage->bVisible);
4865                          if (pImage->bVisible)
4866                            mng_display_image (pData, pImage, MNG_FALSE);
4867                          break;
4868                        }
4869               case 5 : {
4870                          pImage->bVisible = (mng_bool)(!pImage->bVisible);
4871                        }
4872             }
4873           }
4874         }
4875 
4876         if (!pData->bTimerset)         /* next ? */
4877           iX += iS;
4878 
4879       }                                /* continue ? */
4880       while ((!pData->bTimerset) && (((iS > 0) && (iX <= iTo)) ||
4881                                      ((iS < 0) && (iX >= iTo))    ));
4882 
4883       if (pData->bTimerset)            /* timer set ? */
4884       {
4885         pData->iBreakpoint = 4;
4886         pData->iSHOWnextid = iX;       /* save for next time */
4887       }
4888       else
4889         pData->iBreakpoint = 0;
4890 
4891     }
4892   }
4893 
4894 #ifdef MNG_SUPPORT_TRACE
4895   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_END);
4896 #endif
4897 
4898   return MNG_NOERROR;
4899 }
4900 #endif
4901 
4902 /* ************************************************************************** */
4903 
4904 #ifndef MNG_SKIPCHUNK_SAVE
mng_process_display_save(mng_datap pData)4905 mng_retcode mng_process_display_save (mng_datap pData)
4906 {
4907   mng_retcode iRetcode;
4908 
4909 #ifdef MNG_SUPPORT_TRACE
4910   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_START);
4911 #endif
4912 
4913   iRetcode = save_state (pData);       /* save the current state */
4914 
4915   if (iRetcode)                        /* on error bail out */
4916     return iRetcode;
4917 
4918 #ifdef MNG_SUPPORT_TRACE
4919   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_END);
4920 #endif
4921 
4922   return MNG_NOERROR;
4923 }
4924 #endif
4925 
4926 /* ************************************************************************** */
4927 
4928 #ifndef MNG_SKIPCHUNK_SEEK
mng_process_display_seek(mng_datap pData)4929 mng_retcode mng_process_display_seek (mng_datap pData)
4930 {
4931 #ifdef MNG_SUPPORT_TRACE
4932   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_START);
4933 #endif
4934 
4935 #ifdef MNG_SUPPORT_DYNAMICMNG
4936   if (pData->bStopafterseek)           /* need to stop after this SEEK ? */
4937   {
4938     pData->bFreezing      = MNG_TRUE;  /* stop processing on this one */
4939     pData->bRunningevent  = MNG_FALSE;
4940     pData->bStopafterseek = MNG_FALSE;
4941     pData->bNeedrefresh   = MNG_TRUE;  /* make sure the last bit is displayed ! */
4942   }
4943   else
4944 #endif
4945   {                                    /* restore the initial or SAVE state */
4946     mng_retcode iRetcode = restore_state (pData);
4947 
4948     if (iRetcode)                      /* on error bail out */
4949       return iRetcode;
4950 
4951 #ifdef MNG_SUPPORT_DYNAMICMNG
4952                                        /* stop after next SEEK ? */
4953     if ((pData->bDynamic) || (pData->bRunningevent))
4954       pData->bStopafterseek = MNG_TRUE;
4955 #endif
4956   }
4957 
4958 #ifdef MNG_SUPPORT_TRACE
4959   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_END);
4960 #endif
4961 
4962   return MNG_NOERROR;
4963 }
4964 #endif
4965 
4966 /* ************************************************************************** */
4967 
4968 #ifdef MNG_INCLUDE_JNG
mng_process_display_jhdr(mng_datap pData)4969 mng_retcode mng_process_display_jhdr (mng_datap pData)
4970 {                                      /* address the current "object" if any */
4971   mng_imagep  pImage   = (mng_imagep)pData->pCurrentobj;
4972   mng_retcode iRetcode = MNG_NOERROR;
4973 
4974 #ifdef MNG_SUPPORT_TRACE
4975   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_START);
4976 #endif
4977 
4978   if (!pData->bHasDHDR)
4979   {
4980     pData->fInitrowproc  = MNG_NULL;   /* do nothing by default */
4981     pData->fDisplayrow   = MNG_NULL;
4982     pData->fCorrectrow   = MNG_NULL;
4983     pData->fStorerow     = MNG_NULL;
4984     pData->fProcessrow   = MNG_NULL;
4985     pData->fDifferrow    = MNG_NULL;
4986     pData->fStorerow2    = MNG_NULL;
4987     pData->fStorerow3    = MNG_NULL;
4988 
4989     pData->pStoreobj     = MNG_NULL;   /* initialize important work-parms */
4990 
4991     pData->iJPEGrow      = 0;
4992     pData->iJPEGalpharow = 0;
4993     pData->iJPEGrgbrow   = 0;
4994     pData->iRowmax       = 0;          /* so init_rowproc does the right thing ! */
4995   }
4996 
4997   if (!pData->iBreakpoint)             /* not previously broken ? */
4998   {
4999 #ifndef MNG_NO_DELTA_PNG
5000     if (pData->bHasDHDR)               /* delta-image ? */
5001     {
5002       if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
5003       {
5004         iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
5005                                              pData->iDatawidth, pData->iDataheight,
5006                                              pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
5007                                              pData->iJHDRalphacompression, pData->iJHDRalphafilter,
5008                                              pData->iJHDRalphainterlace, MNG_TRUE);
5009 
5010         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
5011         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
5012         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
5013         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
5014       }
5015       else
5016       if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
5017           (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
5018       {
5019         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
5020         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
5021       }
5022       else
5023       if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
5024           (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
5025         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
5026       else
5027       if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
5028           (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
5029         ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
5030 
5031     }
5032     else
5033 #endif /* MNG_NO_DELTA_PNG */
5034     {
5035       if (pImage)                      /* update object buffer ? */
5036       {
5037         iRetcode = mng_reset_object_details (pData, pImage,
5038                                              pData->iDatawidth, pData->iDataheight,
5039                                              pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
5040                                              pData->iJHDRalphacompression, pData->iJHDRalphafilter,
5041                                              pData->iJHDRalphainterlace, MNG_TRUE);
5042 
5043         pImage->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
5044         pImage->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
5045         pImage->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
5046         pImage->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
5047       }
5048       else                             /* update object 0 */
5049       {
5050         iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
5051                                              pData->iDatawidth, pData->iDataheight,
5052                                              pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
5053                                              pData->iJHDRalphacompression, pData->iJHDRalphafilter,
5054                                              pData->iJHDRalphainterlace, MNG_TRUE);
5055 
5056         ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphabitdepth    = pData->iJHDRalphabitdepth;
5057         ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRcompression  = pData->iJHDRimgcompression;
5058         ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRinterlace    = pData->iJHDRimginterlace;
5059         ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
5060       }
5061     }
5062 
5063     if (iRetcode)                      /* on error bail out */
5064       return iRetcode;
5065   }
5066 
5067   if (!pData->bHasDHDR)
5068   {                                    /* we're always storing a JPEG */
5069     if (pImage)                        /* real object ? */
5070       pData->pStoreobj = pImage;       /* tell the row routines */
5071     else                               /* otherwise use object 0 */
5072       pData->pStoreobj = pData->pObjzero;
5073                                        /* display "on-the-fly" ? */
5074     if (
5075 #ifndef MNG_SKIPCHUNK_MAGN
5076          ( ((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
5077          ( ((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
5078 #endif
5079          ( (pData->eImagetype == mng_it_jng         ) ||
5080            (((mng_imagep)pData->pStoreobj)->bVisible)    )       )
5081     {
5082       next_layer (pData);              /* that's a new layer then ! */
5083 
5084       pData->iBreakpoint = 0;
5085 
5086       if (pData->bTimerset)            /* timer break ? */
5087         pData->iBreakpoint = 7;
5088       else
5089       if (pData->bRunning)             /* still running ? */
5090       {                                /* anything to display ? */
5091         if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
5092         {
5093           set_display_routine (pData); /* then determine display routine */
5094                                        /* display from the object we store in */
5095           pData->pRetrieveobj = pData->pStoreobj;
5096         }
5097       }
5098     }
5099   }
5100 
5101   if (!pData->bTimerset)               /* no timer break ? */
5102   {                                    /* default row initialization ! */
5103 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5104     pData->ePng_imgtype=png_none;
5105 #endif
5106     pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
5107 
5108     if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_REPLACE))
5109     {                                  /* 8-bit JPEG ? */
5110       if (pData->iJHDRimgbitdepth == 8)
5111       {                                /* intermediate row is 8-bit deep */
5112         pData->bIsRGBA16   = MNG_FALSE;
5113         pData->iRowsamples = pData->iDatawidth;
5114 
5115         switch (pData->iJHDRcolortype) /* determine pixel processing routines */
5116         {
5117           case MNG_COLORTYPE_JPEGGRAY :
5118                {
5119                  pData->fStorerow2   = (mng_fptr)mng_store_jpeg_g8;
5120                  pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
5121                  pData->bIsOpaque    = MNG_TRUE;
5122                  break;
5123                }
5124           case MNG_COLORTYPE_JPEGCOLOR :
5125                {
5126                  pData->fStorerow2   = (mng_fptr)mng_store_jpeg_rgb8;
5127                  pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
5128                  pData->bIsOpaque    = MNG_TRUE;
5129                  break;
5130                }
5131           case MNG_COLORTYPE_JPEGGRAYA :
5132                {
5133                  pData->fStorerow2   = (mng_fptr)mng_store_jpeg_ga8;
5134                  pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
5135                  pData->bIsOpaque    = MNG_FALSE;
5136                  break;
5137                }
5138           case MNG_COLORTYPE_JPEGCOLORA :
5139                {
5140                  pData->fStorerow2   = (mng_fptr)mng_store_jpeg_rgba8;
5141                  pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
5142                  pData->bIsOpaque    = MNG_FALSE;
5143                  break;
5144                }
5145         }
5146       }
5147 #ifndef MNG_NO_16BIT_SUPPORT
5148       else
5149       {
5150         pData->bIsRGBA16 = MNG_TRUE;   /* intermediate row is 16-bit deep */
5151 
5152         /* TODO: 12-bit JPEG */
5153         /* TODO: 8- + 12-bit JPEG (eg. type=20) */
5154 
5155       }
5156 #endif
5157                                        /* possible IDAT alpha-channel ? */
5158       if (pData->iJHDRalphacompression == MNG_COMPRESSION_DEFLATE)
5159       {
5160                                        /* determine alpha processing routine */
5161 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5162         pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
5163 #endif
5164         switch (pData->iJHDRalphabitdepth)
5165         {
5166 #ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
5167 #ifndef MNG_NO_1_2_4BIT_SUPPORT
5168           case  1 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a1_ni;  break; }
5169           case  2 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a2_ni;  break; }
5170           case  4 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a4_ni;  break; }
5171 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
5172           case  8 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a8_ni;  break; }
5173 #ifndef MNG_NO_16BIT_SUPPORT
5174           case 16 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a16_ni; break; }
5175 #endif
5176 #else
5177 #ifndef MNG_NO_1_2_4BIT_SUPPORT
5178           case  1 : { pData->ePng_imgtype = png_jpeg_a1;  break; }
5179           case  2 : { pData->ePng_imgtype = png_jpeg_a2;  break; }
5180           case  4 : { pData->ePng_imgtype = png_jpeg_a4;  break; }
5181 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
5182           case  8 : { pData->ePng_imgtype = png_jpeg_a8;  break; }
5183 #ifndef MNG_NO_16BIT_SUPPORT
5184           case 16 : { pData->ePng_imgtype = png_jpeg_a16; break; }
5185 #endif
5186 #endif
5187         }
5188       }
5189       else                             /* possible JDAA alpha-channel ? */
5190       if (pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG)
5191       {                                /* 8-bit JPEG ? */
5192         if (pData->iJHDRimgbitdepth == 8)
5193         {
5194           if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)
5195             pData->fStorerow3 = (mng_fptr)mng_store_jpeg_g8_alpha;
5196           else
5197           if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)
5198             pData->fStorerow3 = (mng_fptr)mng_store_jpeg_rgb8_alpha;
5199         }
5200         else
5201         {
5202           /* TODO: 12-bit JPEG with 8-bit JDAA */
5203         }
5204       }
5205                                        /* initialize JPEG library */
5206       iRetcode = mngjpeg_initialize (pData);
5207 
5208       if (iRetcode)                    /* on error bail out */
5209         return iRetcode;
5210     }
5211     else
5212     {                                  /* must be alpha add/replace !! */
5213       if ((pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAADD    ) &&
5214           (pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
5215         MNG_ERROR (pData, MNG_INVDELTATYPE);
5216                                        /* determine alpha processing routine */
5217 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5218         pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
5219 #endif
5220       switch (pData->iJHDRalphabitdepth)
5221       {
5222 #ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
5223 #ifndef MNG_NO_1_2_4BIT_SUPPORT
5224         case  1 : { pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;  break; }
5225         case  2 : { pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;  break; }
5226         case  4 : { pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;  break; }
5227 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
5228         case  8 : { pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;  break; }
5229 #ifndef MNG_NO_16BIT_SUPPORT
5230         case 16 : { pData->fInitrowproc = (mng_fptr)mng_init_g16_ni; break; }
5231 #endif
5232 #else
5233 #ifndef MNG_NO_1_2_4BIT_SUPPORT
5234         case  1 : { pData->ePng_imgtype = png_jpeg_a1;  break; }
5235         case  2 : { pData->ePng_imgtype = png_jpeg_a2;  break; }
5236         case  4 : { pData->ePng_imgtype = png_jpeg_a4;  break; }
5237 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
5238         case  8 : { pData->ePng_imgtype = png_jpeg_a8;  break; }
5239 #ifndef MNG_NO_16BIT_SUPPORT
5240         case 16 : { pData->ePng_imgtype = png_jpeg_a16; break; }
5241 #endif
5242 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
5243       }
5244     }
5245 
5246     pData->iFilterofs = 0;             /* determine filter characteristics */
5247     pData->iLevel0    = 0;             /* default levels */
5248     pData->iLevel1    = 0;
5249     pData->iLevel2    = 0;
5250     pData->iLevel3    = 0;
5251 
5252 #ifdef FILTER192                       /* leveling & differing ? */
5253     if (pData->iJHDRalphafilter == 0xC0)
5254     {
5255        if (pData->iJHDRalphabitdepth <= 8)
5256          pData->iFilterofs = 1;
5257        else
5258          pData->iFilterofs = 2;
5259 
5260     }
5261 #endif
5262 #ifdef FILTER193                       /* no adaptive filtering ? */
5263     if (pData->iJHDRalphafilter == 0xC1)
5264       pData->iPixelofs = pData->iFilterofs;
5265     else
5266 #endif
5267       pData->iPixelofs = pData->iFilterofs + 1;
5268 
5269   }
5270 
5271 #ifdef MNG_SUPPORT_TRACE
5272   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_END);
5273 #endif
5274 
5275   return MNG_NOERROR;
5276 }
5277 #endif /* MNG_INCLUDE_JNG */
5278 
5279 /* ************************************************************************** */
5280 
5281 #ifdef MNG_INCLUDE_JNG
5282 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_jdaa(mng_datap pData,mng_uint32 iRawlen,mng_uint8p pRawdata)5283 mng_retcode mng_process_display_jdaa (mng_datap  pData,
5284                                       mng_uint32 iRawlen,
5285                                       mng_uint8p pRawdata)
5286 #else
5287 mng_retcode mng_process_display_jdaa (mng_datap  pData)
5288 #endif
5289 {
5290   mng_retcode iRetcode = MNG_NOERROR;
5291 
5292 #ifdef MNG_SUPPORT_TRACE
5293   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_START);
5294 #endif
5295 
5296   if (!pData->bJPEGdecompress2)        /* if we're not decompressing already */
5297   {
5298     if (pData->fInitrowproc)           /* initialize row-processing? */
5299     {
5300       iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
5301       pData->fInitrowproc = MNG_NULL;  /* only call this once !!! */
5302     }
5303 
5304     if (!iRetcode)                     /* initialize decompress */
5305       iRetcode = mngjpeg_decompressinit2 (pData);
5306   }
5307 
5308   if (!iRetcode)                       /* all ok? then decompress, my man */
5309 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5310     iRetcode = mngjpeg_decompressdata2 (pData, iRawlen, pRawdata);
5311 #else
5312     iRetcode = mngjpeg_decompressdata2 (pData, pData->iRawlen, pData->pRawdata);
5313 #endif
5314 
5315   if (iRetcode)
5316     return iRetcode;
5317 
5318 #ifdef MNG_SUPPORT_TRACE
5319   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_END);
5320 #endif
5321 
5322   return MNG_NOERROR;
5323 }
5324 #endif /* MNG_INCLUDE_JNG */
5325 
5326 /* ************************************************************************** */
5327 
5328 #ifdef MNG_INCLUDE_JNG
5329 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_jdat(mng_datap pData,mng_uint32 iRawlen,mng_uint8p pRawdata)5330 mng_retcode mng_process_display_jdat (mng_datap  pData,
5331                                       mng_uint32 iRawlen,
5332                                       mng_uint8p pRawdata)
5333 #else
5334 mng_retcode mng_process_display_jdat (mng_datap  pData)
5335 #endif
5336 {
5337   mng_retcode iRetcode = MNG_NOERROR;
5338 
5339 #ifdef MNG_SUPPORT_TRACE
5340   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_START);
5341 #endif
5342 
5343   if (pData->bRestorebkgd)             /* need to restore the background ? */
5344   {
5345     pData->bRestorebkgd = MNG_FALSE;
5346     iRetcode            = load_bkgdlayer (pData);
5347 
5348     pData->iLayerseq++;                /* and it counts as a layer then ! */
5349 
5350     if (iRetcode)                      /* on error bail out */
5351       return iRetcode;
5352   }
5353 
5354   if (!pData->bJPEGdecompress)         /* if we're not decompressing already */
5355   {
5356     if (pData->fInitrowproc)           /* initialize row-processing? */
5357     {
5358       iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
5359       pData->fInitrowproc = MNG_NULL;  /* only call this once !!! */
5360     }
5361 
5362     if (!iRetcode)                     /* initialize decompress */
5363       iRetcode = mngjpeg_decompressinit (pData);
5364   }
5365 
5366   if (!iRetcode)                       /* all ok? then decompress, my man */
5367 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5368     iRetcode = mngjpeg_decompressdata (pData, iRawlen, pRawdata);
5369 #else
5370     iRetcode = mngjpeg_decompressdata (pData, pData->iRawlen, pData->pRawdata);
5371 #endif
5372 
5373   if (iRetcode)
5374     return iRetcode;
5375 
5376 #ifdef MNG_SUPPORT_TRACE
5377   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_END);
5378 #endif
5379 
5380   return MNG_NOERROR;
5381 }
5382 #endif /* MNG_INCLUDE_JNG */
5383 
5384 /* ************************************************************************** */
5385 
5386 #ifndef MNG_NO_DELTA_PNG
5387 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_dhdr(mng_datap pData,mng_uint16 iObjectid,mng_uint8 iImagetype,mng_uint8 iDeltatype,mng_uint32 iBlockwidth,mng_uint32 iBlockheight,mng_uint32 iBlockx,mng_uint32 iBlocky)5388 mng_retcode mng_process_display_dhdr (mng_datap  pData,
5389                                       mng_uint16 iObjectid,
5390                                       mng_uint8  iImagetype,
5391                                       mng_uint8  iDeltatype,
5392                                       mng_uint32 iBlockwidth,
5393                                       mng_uint32 iBlockheight,
5394                                       mng_uint32 iBlockx,
5395                                       mng_uint32 iBlocky)
5396 #else
5397 mng_retcode mng_process_display_dhdr (mng_datap  pData)
5398 #endif
5399 {
5400   mng_imagep  pImage;
5401   mng_retcode iRetcode;
5402 
5403 #ifdef MNG_SUPPORT_TRACE
5404   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_START);
5405 #endif
5406 
5407   pData->fInitrowproc     = MNG_NULL;  /* do nothing by default */
5408   pData->fDisplayrow      = MNG_NULL;
5409   pData->fCorrectrow      = MNG_NULL;
5410   pData->fStorerow        = MNG_NULL;
5411   pData->fProcessrow      = MNG_NULL;
5412   pData->pStoreobj        = MNG_NULL;
5413 
5414   pData->fDeltagetrow     = MNG_NULL;
5415   pData->fDeltaaddrow     = MNG_NULL;
5416   pData->fDeltareplacerow = MNG_NULL;
5417   pData->fDeltaputrow     = MNG_NULL;
5418 
5419 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5420   pImage = mng_find_imageobject (pData, iObjectid);
5421 #else
5422   pImage = mng_find_imageobject (pData, pData->iDHDRobjectid);
5423 #endif
5424 
5425   if (pImage)                          /* object exists ? */
5426   {
5427     if (pImage->pImgbuf->bConcrete)    /* is it concrete ? */
5428     {                                  /* previous magnification to be done ? */
5429 #ifndef MNG_SKIPCHUNK_MAGN
5430       if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
5431       {
5432         iRetcode = mng_magnify_imageobject (pData, pImage);
5433 
5434         if (iRetcode)                  /* on error bail out */
5435           return iRetcode;
5436       }
5437 #endif
5438                                        /* save delta fields */
5439       pData->pDeltaImage           = (mng_ptr)pImage;
5440 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5441       pData->iDeltaImagetype       = iImagetype;
5442       pData->iDeltatype            = iDeltatype;
5443       pData->iDeltaBlockwidth      = iBlockwidth;
5444       pData->iDeltaBlockheight     = iBlockheight;
5445       pData->iDeltaBlockx          = iBlockx;
5446       pData->iDeltaBlocky          = iBlocky;
5447 #else
5448       pData->iDeltaImagetype       = pData->iDHDRimagetype;
5449       pData->iDeltatype            = pData->iDHDRdeltatype;
5450       pData->iDeltaBlockwidth      = pData->iDHDRblockwidth;
5451       pData->iDeltaBlockheight     = pData->iDHDRblockheight;
5452       pData->iDeltaBlockx          = pData->iDHDRblockx;
5453       pData->iDeltaBlocky          = pData->iDHDRblocky;
5454 #endif
5455                                        /* restore target-object fields */
5456       pData->iDatawidth            = pImage->pImgbuf->iWidth;
5457       pData->iDataheight           = pImage->pImgbuf->iHeight;
5458       pData->iBitdepth             = pImage->pImgbuf->iBitdepth;
5459       pData->iColortype            = pImage->pImgbuf->iColortype;
5460       pData->iCompression          = pImage->pImgbuf->iCompression;
5461       pData->iFilter               = pImage->pImgbuf->iFilter;
5462       pData->iInterlace            = pImage->pImgbuf->iInterlace;
5463 
5464 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5465       if ((iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
5466           (iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
5467         pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
5468       else
5469       if ((iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
5470           (iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
5471         pData->iBitdepth           = pImage->pImgbuf->iAlphasampledepth;
5472       else
5473       if ((iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
5474           (iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
5475         pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
5476 #else
5477       if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKPIXELADD    ) ||
5478           (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)    )
5479         pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
5480       else
5481       if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKALPHAADD    ) ||
5482           (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE)    )
5483         pData->iBitdepth           = pImage->pImgbuf->iAlphasampledepth;
5484       else
5485       if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKCOLORADD    ) ||
5486           (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE)    )
5487         pData->iBitdepth           = pImage->pImgbuf->iPixelsampledepth;
5488 #endif
5489 
5490 #ifdef MNG_INCLUDE_JNG
5491       pData->iJHDRimgbitdepth      = pImage->pImgbuf->iBitdepth;
5492       pData->iJHDRcolortype        = pImage->pImgbuf->iColortype;
5493       pData->iJHDRimgcompression   = pImage->pImgbuf->iJHDRcompression;
5494       pData->iJHDRimginterlace     = pImage->pImgbuf->iJHDRinterlace;
5495       pData->iJHDRalphacompression = pImage->pImgbuf->iCompression;
5496       pData->iJHDRalphafilter      = pImage->pImgbuf->iFilter;
5497       pData->iJHDRalphainterlace   = pImage->pImgbuf->iInterlace;
5498       pData->iJHDRalphabitdepth    = pImage->pImgbuf->iAlphabitdepth;
5499 #endif
5500 
5501 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5502                                        /* block size specified ? */
5503       if (iDeltatype != MNG_DELTATYPE_NOCHANGE)
5504       {                                /* block entirely within target ? */
5505         if (iDeltatype != MNG_DELTATYPE_REPLACE)
5506         {
5507           if (((iBlockx + iBlockwidth ) > pData->iDatawidth ) ||
5508               ((iBlocky + iBlockheight) > pData->iDataheight)    )
5509             MNG_ERROR (pData, MNG_INVALIDBLOCK);
5510         }
5511 
5512         pData->iDatawidth          = iBlockwidth;
5513         pData->iDataheight         = iBlockheight;
5514       }
5515 #else
5516                                        /* block size specified ? */
5517       if (pData->iDHDRdeltatype != MNG_DELTATYPE_NOCHANGE)
5518       {                                /* block entirely within target ? */
5519         if (pData->iDHDRdeltatype != MNG_DELTATYPE_REPLACE)
5520         {
5521           if (((pData->iDHDRblockx + pData->iDHDRblockwidth ) > pData->iDatawidth ) ||
5522               ((pData->iDHDRblocky + pData->iDHDRblockheight) > pData->iDataheight)    )
5523             MNG_ERROR (pData, MNG_INVALIDBLOCK);
5524         }
5525 
5526         pData->iDatawidth          = pData->iDHDRblockwidth;
5527         pData->iDataheight         = pData->iDHDRblockheight;
5528       }
5529 #endif
5530 
5531 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5532       switch (iDeltatype)              /* determine nr of delta-channels */
5533 #else
5534       switch (pData->iDHDRdeltatype)   /* determine nr of delta-channels */
5535 #endif
5536       {
5537          case MNG_DELTATYPE_BLOCKALPHAADD : ;
5538          case MNG_DELTATYPE_BLOCKALPHAREPLACE :
5539               {
5540 #ifdef MNG_INCLUDE_JNG
5541                 if ((pData->iColortype     == MNG_COLORTYPE_GRAYA    ) ||
5542                     (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    )
5543                 {
5544                   pData->iColortype     = MNG_COLORTYPE_GRAY;
5545                   pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
5546                 }
5547                 else
5548                 if ((pData->iColortype     == MNG_COLORTYPE_RGBA      ) ||
5549                     (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
5550                 {
5551                   pData->iColortype     = MNG_COLORTYPE_GRAY;
5552                   pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
5553                 }
5554 #else
5555                 if (pData->iColortype      == MNG_COLORTYPE_GRAYA)
5556                   pData->iColortype     = MNG_COLORTYPE_GRAY;
5557                 else
5558                 if (pData->iColortype      == MNG_COLORTYPE_RGBA)
5559                   pData->iColortype     = MNG_COLORTYPE_GRAY;
5560 #endif
5561                 else                   /* target has no alpha; that sucks! */
5562                   MNG_ERROR (pData, MNG_TARGETNOALPHA);
5563 
5564                 break;
5565               }
5566 
5567          case MNG_DELTATYPE_BLOCKCOLORADD : ;
5568          case MNG_DELTATYPE_BLOCKCOLORREPLACE :
5569               {
5570 #ifdef MNG_INCLUDE_JNG
5571                 if ((pData->iColortype     == MNG_COLORTYPE_GRAYA    ) ||
5572                     (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)    )
5573                 {
5574                   pData->iColortype     = MNG_COLORTYPE_GRAY;
5575                   pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
5576                 }
5577                 else
5578                 if ((pData->iColortype     == MNG_COLORTYPE_RGBA      ) ||
5579                     (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)    )
5580                 {
5581                   pData->iColortype     = MNG_COLORTYPE_RGB;
5582                   pData->iJHDRcolortype = MNG_COLORTYPE_JPEGCOLOR;
5583                 }
5584 #else
5585                 if (pData->iColortype == MNG_COLORTYPE_GRAYA)
5586                   pData->iColortype = MNG_COLORTYPE_GRAY;
5587                 else
5588                 if (pData->iColortype == MNG_COLORTYPE_RGBA)
5589                   pData->iColortype = MNG_COLORTYPE_RGB;
5590 #endif
5591                 else                   /* target has no alpha; that sucks! */
5592                   MNG_ERROR (pData, MNG_TARGETNOALPHA);
5593 
5594                 break;
5595               }
5596 
5597       }
5598                                        /* full image replace ? */
5599 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5600       if (iDeltatype == MNG_DELTATYPE_REPLACE)
5601 #else
5602       if (pData->iDHDRdeltatype == MNG_DELTATYPE_REPLACE)
5603 #endif
5604       {
5605         iRetcode = mng_reset_object_details (pData, pImage,
5606                                              pData->iDatawidth, pData->iDataheight,
5607                                              pData->iBitdepth, pData->iColortype,
5608                                              pData->iCompression, pData->iFilter,
5609                                              pData->iInterlace, MNG_FALSE);
5610 
5611         if (iRetcode)                  /* on error bail out */
5612           return iRetcode;
5613 
5614         pData->pStoreobj = pImage;     /* and store straight into this object */
5615       }
5616       else
5617       {
5618         mng_imagedatap pBufzero, pBuf;
5619                                        /* we store in object 0 and process it later */
5620         pData->pStoreobj = pData->pObjzero;
5621                                        /* make sure to initialize object 0 then */
5622         iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
5623                                              pData->iDatawidth, pData->iDataheight,
5624                                              pData->iBitdepth, pData->iColortype,
5625                                              pData->iCompression, pData->iFilter,
5626                                              pData->iInterlace, MNG_TRUE);
5627 
5628         if (iRetcode)                  /* on error bail out */
5629           return iRetcode;
5630 
5631         pBuf     = pImage->pImgbuf;    /* copy possible palette & cheap transparency */
5632         pBufzero = ((mng_imagep)pData->pObjzero)->pImgbuf;
5633 
5634         pBufzero->bHasPLTE = pBuf->bHasPLTE;
5635         pBufzero->bHasTRNS = pBuf->bHasTRNS;
5636 
5637         if (pBufzero->bHasPLTE)        /* copy palette ? */
5638         {
5639           mng_uint32 iX;
5640 
5641           pBufzero->iPLTEcount = pBuf->iPLTEcount;
5642 
5643           for (iX = 0; iX < pBuf->iPLTEcount; iX++)
5644           {
5645             pBufzero->aPLTEentries [iX].iRed   = pBuf->aPLTEentries [iX].iRed;
5646             pBufzero->aPLTEentries [iX].iGreen = pBuf->aPLTEentries [iX].iGreen;
5647             pBufzero->aPLTEentries [iX].iBlue  = pBuf->aPLTEentries [iX].iBlue;
5648           }
5649         }
5650 
5651         if (pBufzero->bHasTRNS)        /* copy cheap transparency ? */
5652         {
5653           pBufzero->iTRNSgray  = pBuf->iTRNSgray;
5654           pBufzero->iTRNSred   = pBuf->iTRNSred;
5655           pBufzero->iTRNSgreen = pBuf->iTRNSgreen;
5656           pBufzero->iTRNSblue  = pBuf->iTRNSblue;
5657           pBufzero->iTRNScount = pBuf->iTRNScount;
5658 
5659           MNG_COPY (pBufzero->aTRNSentries, pBuf->aTRNSentries,
5660                     sizeof (pBufzero->aTRNSentries));
5661         }
5662                                        /* process immediately if bitdepth & colortype are equal */
5663         pData->bDeltaimmediate =
5664           (mng_bool)((pData->bDisplaying) && (!pData->bSkipping) &&
5665                      ((pData->bRunning) || (pData->bSearching)) &&
5666                      (pData->iBitdepth  == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
5667                      (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype)    );
5668       }
5669 
5670 #ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5671   pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
5672   pData->ePng_imgtype = mng_png_imgtype (pData->iColortype, pData->iBitdepth);
5673 #else
5674       switch (pData->iColortype)       /* determine row initialization routine */
5675       {
5676         case 0 : {                     /* gray */
5677                    switch (pData->iBitdepth)
5678                    {
5679 #ifndef MNG_NO_1_2_4BIT_SUPPORT
5680                      case  1 : {
5681                                  if (!pData->iInterlace)
5682                                    pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
5683                                  else
5684                                    pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
5685 
5686                                  break;
5687                                }
5688                      case  2 : {
5689                                  if (!pData->iInterlace)
5690                                    pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
5691                                  else
5692                                    pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
5693 
5694                                  break;
5695                                }
5696                      case  4 : {
5697                                  if (!pData->iInterlace)
5698                                    pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
5699                                  else
5700                                    pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
5701 
5702                                  break;
5703                                }
5704 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
5705                      case  8 : {
5706                                  if (!pData->iInterlace)
5707                                    pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
5708                                  else
5709                                    pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
5710 
5711                                  break;
5712                                }
5713 #ifndef MNG_NO_16BIT_SUPPORT
5714                      case 16 : {
5715                                  if (!pData->iInterlace)
5716                                    pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
5717                                  else
5718                                    pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
5719 
5720                                  break;
5721                                }
5722 #endif
5723                    }
5724 
5725                    break;
5726                  }
5727         case 2 : {                     /* rgb */
5728                    switch (pData->iBitdepth)
5729                    {
5730                      case  8 : {
5731                                  if (!pData->iInterlace)
5732                                    pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
5733                                  else
5734                                    pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
5735 
5736                                  break;
5737                                }
5738 #ifndef MNG_NO_16BIT_SUPPORT
5739                      case 16 : {
5740                                  if (!pData->iInterlace)
5741                                    pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
5742                                  else
5743                                    pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
5744 
5745                                  break;
5746                                }
5747 #endif
5748                    }
5749 
5750                    break;
5751                  }
5752         case 3 : {                     /* indexed */
5753                    switch (pData->iBitdepth)
5754                    {
5755 #ifndef MNG_NO_1_2_4BIT_SUPPORT
5756                      case  1 : {
5757                                  if (!pData->iInterlace)
5758                                    pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
5759                                  else
5760                                    pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
5761 
5762                                  break;
5763                                }
5764                      case  2 : {
5765                                  if (!pData->iInterlace)
5766                                    pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
5767                                  else
5768                                    pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
5769 
5770                                  break;
5771                                }
5772                      case  4 : {
5773                                  if (!pData->iInterlace)
5774                                    pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
5775                                  else
5776                                    pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
5777 
5778                                  break;
5779                                }
5780 #endif /* MNG_NO_1_2_4BIT_SUPPORT */
5781                      case  8 : {
5782                                  if (!pData->iInterlace)
5783                                    pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
5784                                  else
5785                                    pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
5786 
5787                                  break;
5788                                }
5789                    }
5790 
5791                    break;
5792                  }
5793         case 4 : {                     /* gray+alpha */
5794                    switch (pData->iBitdepth)
5795                    {
5796                      case  8 : {
5797                                  if (!pData->iInterlace)
5798                                    pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
5799                                  else
5800                                    pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
5801 
5802                                  break;
5803                                }
5804 #ifndef MNG_NO_16BIT_SUPPORT
5805                      case 16 : {
5806                                  if (!pData->iInterlace)
5807                                    pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
5808                                  else
5809                                    pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
5810 
5811                                  break;
5812                                }
5813 #endif
5814                    }
5815 
5816                    break;
5817                  }
5818         case 6 : {                     /* rgb+alpha */
5819                    switch (pData->iBitdepth)
5820                    {
5821                      case  8 : {
5822                                  if (!pData->iInterlace)
5823                                    pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
5824                                  else
5825                                    pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
5826 
5827                                  break;
5828                                }
5829 #ifndef MNG_NO_16BIT_SUPPORT
5830                      case 16 : {
5831                                  if (!pData->iInterlace)
5832                                    pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
5833                                  else
5834                                    pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
5835 
5836                                  break;
5837                                }
5838 #endif
5839                    }
5840 
5841                    break;
5842                  }
5843       }
5844 #endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
5845     }
5846     else
5847       MNG_ERROR (pData, MNG_OBJNOTCONCRETE);
5848 
5849   }
5850   else
5851     MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
5852 
5853 #ifdef MNG_SUPPORT_TRACE
5854   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_END);
5855 #endif
5856 
5857   return MNG_NOERROR;
5858 }
5859 #endif
5860 
5861 /* ************************************************************************** */
5862 
5863 #ifndef MNG_NO_DELTA_PNG
5864 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_prom(mng_datap pData,mng_uint8 iBitdepth,mng_uint8 iColortype,mng_uint8 iFilltype)5865 mng_retcode mng_process_display_prom (mng_datap  pData,
5866                                       mng_uint8  iBitdepth,
5867                                       mng_uint8  iColortype,
5868                                       mng_uint8  iFilltype)
5869 #else
5870 mng_retcode mng_process_display_prom (mng_datap  pData)
5871 #endif
5872 {
5873   mng_imagep     pImage;
5874   mng_imagedatap pBuf;
5875   mng_retcode    iRetcode;
5876 
5877 #ifdef MNG_SUPPORT_TRACE
5878   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_START);
5879 #endif
5880 
5881   if (!pData->pDeltaImage)             /* gotta have this now! */
5882     MNG_ERROR (pData, MNG_INVALIDDELTA);
5883 
5884   pImage = (mng_imagep)pData->pDeltaImage;
5885   pBuf   = pImage->pImgbuf;
5886                                        /* can't demote bitdepth! */
5887 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
5888   if (iBitdepth < pBuf->iBitdepth)
5889     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
5890 
5891   if ( ((pBuf->iColortype == MNG_COLORTYPE_GRAY      ) &&
5892         (iColortype       != MNG_COLORTYPE_GRAY      ) &&
5893         (iColortype       != MNG_COLORTYPE_GRAYA     ) &&
5894         (iColortype       != MNG_COLORTYPE_RGB       ) &&
5895         (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
5896        ((pBuf->iColortype == MNG_COLORTYPE_GRAYA     ) &&
5897         (iColortype       != MNG_COLORTYPE_GRAYA     ) &&
5898         (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
5899        ((pBuf->iColortype == MNG_COLORTYPE_RGB       ) &&
5900         (iColortype       != MNG_COLORTYPE_RGB       ) &&
5901         (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
5902        ((pBuf->iColortype == MNG_COLORTYPE_RGBA      ) &&
5903         (iColortype       != MNG_COLORTYPE_RGBA      )    ) ||
5904 #ifdef MNG_INCLUDE_JNG
5905        ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY  ) &&
5906         (iColortype       != MNG_COLORTYPE_JPEGGRAY  ) &&
5907         (iColortype       != MNG_COLORTYPE_JPEGCOLOR ) &&
5908         (iColortype       != MNG_COLORTYPE_JPEGGRAYA ) &&
5909         (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5910        ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR ) &&
5911         (iColortype       != MNG_COLORTYPE_JPEGCOLOR ) &&
5912         (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5913        ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA ) &&
5914         (iColortype       != MNG_COLORTYPE_JPEGGRAYA ) &&
5915         (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5916        ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) &&
5917         (iColortype       != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5918 #endif
5919        ((pBuf->iColortype == MNG_COLORTYPE_INDEXED   ) &&
5920         (iColortype       != MNG_COLORTYPE_INDEXED   ) &&
5921         (iColortype       != MNG_COLORTYPE_RGB       ) &&
5922         (iColortype       != MNG_COLORTYPE_RGBA      )    )    )
5923     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
5924 
5925   iRetcode = mng_promote_imageobject (pData, pImage, iBitdepth, iColortype, iFilltype);
5926 #else
5927   if (pData->iPROMbitdepth < pBuf->iBitdepth)
5928     MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
5929 
5930   if ( ((pBuf->iColortype      == MNG_COLORTYPE_GRAY      ) &&
5931         (pData->iPROMcolortype != MNG_COLORTYPE_GRAY      ) &&
5932         (pData->iPROMcolortype != MNG_COLORTYPE_GRAYA     ) &&
5933         (pData->iPROMcolortype != MNG_COLORTYPE_RGB       ) &&
5934         (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
5935        ((pBuf->iColortype      == MNG_COLORTYPE_GRAYA     ) &&
5936         (pData->iPROMcolortype != MNG_COLORTYPE_GRAYA     ) &&
5937         (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
5938        ((pBuf->iColortype      == MNG_COLORTYPE_RGB       ) &&
5939         (pData->iPROMcolortype != MNG_COLORTYPE_RGB       ) &&
5940         (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
5941        ((pBuf->iColortype      == MNG_COLORTYPE_RGBA      ) &&
5942         (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    ) ||
5943 #ifdef MNG_INCLUDE_JNG
5944        ((pBuf->iColortype      == MNG_COLORTYPE_JPEGGRAY  ) &&
5945         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAY  ) &&
5946         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
5947         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
5948         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5949        ((pBuf->iColortype      == MNG_COLORTYPE_JPEGCOLOR ) &&
5950         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
5951         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5952        ((pBuf->iColortype      == MNG_COLORTYPE_JPEGGRAYA ) &&
5953         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
5954         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5955        ((pBuf->iColortype      == MNG_COLORTYPE_JPEGCOLORA) &&
5956         (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA)    ) ||
5957 #endif
5958        ((pBuf->iColortype      == MNG_COLORTYPE_INDEXED   ) &&
5959         (pData->iPROMcolortype != MNG_COLORTYPE_INDEXED   ) &&
5960         (pData->iPROMcolortype != MNG_COLORTYPE_RGB       ) &&
5961         (pData->iPROMcolortype != MNG_COLORTYPE_RGBA      )    )    )
5962     MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
5963 
5964   iRetcode = mng_promote_imageobject (pData, pImage, pData->iPROMbitdepth,
5965                                       pData->iPROMcolortype, pData->iPROMfilltype);
5966 #endif
5967 
5968   if (iRetcode)                        /* on error bail out */
5969     return iRetcode;
5970 
5971 #ifdef MNG_SUPPORT_TRACE
5972   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_END);
5973 #endif
5974 
5975   return MNG_NOERROR;
5976 }
5977 #endif
5978 
5979 /* ************************************************************************** */
5980 
5981 #ifndef MNG_NO_DELTA_PNG
mng_process_display_ipng(mng_datap pData)5982 mng_retcode mng_process_display_ipng (mng_datap pData)
5983 {
5984 #ifdef MNG_SUPPORT_TRACE
5985   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_START);
5986 #endif
5987                                        /* indicate it for what it is now */
5988   pData->iDeltaImagetype = MNG_IMAGETYPE_PNG;
5989 
5990 #ifdef MNG_SUPPORT_TRACE
5991   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_END);
5992 #endif
5993 
5994   return MNG_NOERROR;
5995 }
5996 #endif
5997 
5998 /* ************************************************************************** */
5999 
6000 #ifndef MNG_NO_DELTA_PNG
6001 #ifdef MNG_INCLUDE_JNG
mng_process_display_ijng(mng_datap pData)6002 mng_retcode mng_process_display_ijng (mng_datap pData)
6003 {
6004 #ifdef MNG_SUPPORT_TRACE
6005   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_START);
6006 #endif
6007                                        /* indicate it for what it is now */
6008   pData->iDeltaImagetype = MNG_IMAGETYPE_JNG;
6009 
6010 #ifdef MNG_SUPPORT_TRACE
6011   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_END);
6012 #endif
6013 
6014   return MNG_NOERROR;
6015 }
6016 #endif
6017 #endif
6018 
6019 /* ************************************************************************** */
6020 
6021 #ifndef MNG_NO_DELTA_PNG
6022 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_pplt(mng_datap pData,mng_uint8 iType,mng_uint32 iCount,mng_palette8ep paIndexentries,mng_uint8p paAlphaentries,mng_uint8p paUsedentries)6023 mng_retcode mng_process_display_pplt (mng_datap      pData,
6024                                       mng_uint8      iType,
6025                                       mng_uint32     iCount,
6026                                       mng_palette8ep paIndexentries,
6027                                       mng_uint8p     paAlphaentries,
6028                                       mng_uint8p     paUsedentries)
6029 #else
6030 mng_retcode mng_process_display_pplt (mng_datap      pData)
6031 #endif
6032 {
6033   mng_uint32     iX;
6034   mng_imagep     pImage = (mng_imagep)pData->pObjzero;
6035   mng_imagedatap pBuf   = pImage->pImgbuf;
6036 
6037 #ifdef MNG_SUPPORT_TRACE
6038   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_START);
6039 #endif
6040 
6041 #ifdef MNG_DECREMENT_LOOPS
6042 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6043   iX = iCount;
6044 #else
6045   iX = pData->iPPLTcount;
6046 #endif
6047 #endif
6048 
6049 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6050   switch (iType)
6051 #else
6052   switch (pData->iPPLTtype)
6053 #endif
6054   {
6055     case MNG_DELTATYPE_REPLACERGB :
6056       {
6057 #ifdef MNG_DECREMENT_LOOPS
6058         for (; iX > 0;iX--)
6059 #else
6060 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6061         for (iX = 0; iX < iCount; iX++)
6062 #else
6063         for (iX = 0; iX < pData->iPPLTcount; iX++)
6064 #endif
6065 #endif
6066         {
6067 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6068           if (paUsedentries [iX])
6069           {
6070             pBuf->aPLTEentries [iX].iRed   = paIndexentries [iX].iRed;
6071             pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
6072             pBuf->aPLTEentries [iX].iBlue  = paIndexentries [iX].iBlue;
6073           }
6074 #else
6075           if (pData->paPPLTusedentries [iX])
6076           {
6077             pBuf->aPLTEentries [iX].iRed   = pData->paPPLTindexentries [iX].iRed;
6078             pBuf->aPLTEentries [iX].iGreen = pData->paPPLTindexentries [iX].iGreen;
6079             pBuf->aPLTEentries [iX].iBlue  = pData->paPPLTindexentries [iX].iBlue;
6080           }
6081 #endif
6082         }
6083 
6084         break;
6085       }
6086     case MNG_DELTATYPE_DELTARGB :
6087       {
6088 #ifdef MNG_DECREMENT_LOOPS
6089         for (; iX > 0;iX--)
6090 #else
6091 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6092         for (iX = 0; iX < iCount; iX++)
6093 #else
6094         for (iX = 0; iX < pData->iPPLTcount; iX++)
6095 #endif
6096 #endif
6097         {
6098 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6099           if (paUsedentries [iX])
6100           {
6101             pBuf->aPLTEentries [iX].iRed   =
6102                                (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
6103                                            paIndexentries [iX].iRed  );
6104             pBuf->aPLTEentries [iX].iGreen =
6105                                (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
6106                                            paIndexentries [iX].iGreen);
6107             pBuf->aPLTEentries [iX].iBlue  =
6108                                (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
6109                                            paIndexentries [iX].iBlue );
6110           }
6111 #else
6112           if (pData->paPPLTusedentries [iX])
6113           {
6114             pBuf->aPLTEentries [iX].iRed   =
6115                                (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
6116                                            pData->paPPLTindexentries [iX].iRed  );
6117             pBuf->aPLTEentries [iX].iGreen =
6118                                (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
6119                                            pData->paPPLTindexentries [iX].iGreen);
6120             pBuf->aPLTEentries [iX].iBlue  =
6121                                (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
6122                                            pData->paPPLTindexentries [iX].iBlue );
6123           }
6124 #endif
6125         }
6126 
6127         break;
6128       }
6129     case MNG_DELTATYPE_REPLACEALPHA :
6130       {
6131 #ifdef MNG_DECREMENT_LOOPS
6132         for (; iX > 0;iX--)
6133 #else
6134 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6135         for (iX = 0; iX < iCount; iX++)
6136 #else
6137         for (iX = 0; iX < pData->iPPLTcount; iX++)
6138 #endif
6139 #endif
6140         {
6141 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6142           if (paUsedentries [iX])
6143             pBuf->aTRNSentries [iX] = paAlphaentries [iX];
6144         }
6145 #else
6146           if (pData->paPPLTusedentries [iX])
6147             pBuf->aTRNSentries [iX] = pData->paPPLTalphaentries [iX];
6148         }
6149 #endif
6150 
6151         break;
6152       }
6153     case MNG_DELTATYPE_DELTAALPHA :
6154       {
6155 #ifdef MNG_DECREMENT_LOOPS
6156         for (; iX > 0;iX--)
6157 #else
6158 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6159         for (iX = 0; iX < iCount; iX++)
6160 #else
6161         for (iX = 0; iX < pData->iPPLTcount; iX++)
6162 #endif
6163 #endif
6164         {
6165 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6166           if (paUsedentries [iX])
6167             pBuf->aTRNSentries [iX] =
6168                                (mng_uint8)(pBuf->aTRNSentries [iX] +
6169                                            paAlphaentries [iX]);
6170 #else
6171           if (pData->paPPLTusedentries [iX])
6172             pBuf->aTRNSentries [iX] =
6173                                (mng_uint8)(pBuf->aTRNSentries [iX] +
6174                                            pData->paPPLTalphaentries [iX]);
6175 #endif
6176         }
6177 
6178         break;
6179       }
6180     case MNG_DELTATYPE_REPLACERGBA :
6181       {
6182 #ifdef MNG_DECREMENT_LOOPS
6183         for (; iX > 0;iX--)
6184 #else
6185 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6186         for (iX = 0; iX < iCount; iX++)
6187 #else
6188         for (iX = 0; iX < pData->iPPLTcount; iX++)
6189 #endif
6190 #endif
6191         {
6192 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6193           if (paUsedentries [iX])
6194           {
6195             pBuf->aPLTEentries [iX].iRed   = paIndexentries [iX].iRed;
6196             pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
6197             pBuf->aPLTEentries [iX].iBlue  = paIndexentries [iX].iBlue;
6198             pBuf->aTRNSentries [iX]        = paAlphaentries [iX];
6199           }
6200 #else
6201           if (pData->paPPLTusedentries [iX])
6202           {
6203             pBuf->aPLTEentries [iX].iRed   = pData->paPPLTindexentries [iX].iRed;
6204             pBuf->aPLTEentries [iX].iGreen = pData->paPPLTindexentries [iX].iGreen;
6205             pBuf->aPLTEentries [iX].iBlue  = pData->paPPLTindexentries [iX].iBlue;
6206             pBuf->aTRNSentries [iX]        = pData->paPPLTalphaentries [iX];
6207           }
6208 #endif
6209         }
6210 
6211         break;
6212       }
6213     case MNG_DELTATYPE_DELTARGBA :
6214       {
6215 #ifdef MNG_DECREMENT_LOOPS
6216         for (; iX > 0;iX--)
6217 #else
6218 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6219         for (iX = 0; iX < iCount; iX++)
6220 #else
6221         for (iX = 0; iX < pData->iPPLTcount; iX++)
6222 #endif
6223 #endif
6224         {
6225 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6226           if (paUsedentries [iX])
6227           {
6228             pBuf->aPLTEentries [iX].iRed   =
6229                                (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
6230                                            paIndexentries [iX].iRed  );
6231             pBuf->aPLTEentries [iX].iGreen =
6232                                (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
6233                                            paIndexentries [iX].iGreen);
6234             pBuf->aPLTEentries [iX].iBlue  =
6235                                (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
6236                                            paIndexentries [iX].iBlue );
6237             pBuf->aTRNSentries [iX] =
6238                                (mng_uint8)(pBuf->aTRNSentries [iX] +
6239                                            paAlphaentries [iX]);
6240           }
6241 #else
6242           if (pData->paPPLTusedentries [iX])
6243           {
6244             pBuf->aPLTEentries [iX].iRed   =
6245                                (mng_uint8)(pBuf->aPLTEentries [iX].iRed   +
6246                                            pData->paPPLTindexentries [iX].iRed  );
6247             pBuf->aPLTEentries [iX].iGreen =
6248                                (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
6249                                            pData->paPPLTindexentries [iX].iGreen);
6250             pBuf->aPLTEentries [iX].iBlue  =
6251                                (mng_uint8)(pBuf->aPLTEentries [iX].iBlue  +
6252                                            pData->paPPLTindexentries [iX].iBlue );
6253             pBuf->aTRNSentries [iX] =
6254                                (mng_uint8)(pBuf->aTRNSentries [iX] +
6255                                            pData->paPPLTalphaentries [iX]);
6256           }
6257 #endif
6258         }
6259 
6260         break;
6261       }
6262   }
6263 
6264 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6265   if ((iType != MNG_DELTATYPE_REPLACERGB) && (iType != MNG_DELTATYPE_DELTARGB))
6266 #else
6267   if ((pData->iPPLTtype != MNG_DELTATYPE_REPLACERGB) &&
6268       (pData->iPPLTtype != MNG_DELTATYPE_DELTARGB  )    )
6269 #endif
6270   {
6271     if (pBuf->bHasTRNS)
6272     {
6273 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6274       if (iCount > pBuf->iTRNScount)
6275         pBuf->iTRNScount = iCount;
6276 #else
6277       if (pData->iPPLTcount > pBuf->iTRNScount)
6278         pBuf->iTRNScount = pData->iPPLTcount;
6279 #endif
6280     }
6281     else
6282     {
6283 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6284       pBuf->iTRNScount = iCount;
6285       pBuf->bHasTRNS   = MNG_TRUE;
6286 #else
6287       pBuf->iTRNScount = pData->iPPLTcount;
6288       pBuf->bHasTRNS   = MNG_TRUE;
6289 #endif
6290     }
6291   }
6292 
6293 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6294   if ((iType != MNG_DELTATYPE_REPLACEALPHA) && (iType != MNG_DELTATYPE_DELTAALPHA))
6295 #else
6296   if ((pData->iPPLTtype != MNG_DELTATYPE_REPLACEALPHA) &&
6297       (pData->iPPLTtype != MNG_DELTATYPE_DELTAALPHA  )    )
6298 #endif
6299   {
6300 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6301     if (iCount > pBuf->iPLTEcount)
6302       pBuf->iPLTEcount = iCount;
6303 #else
6304     if (pData->iPPLTcount > pBuf->iPLTEcount)
6305       pBuf->iPLTEcount = pData->iPPLTcount;
6306 #endif
6307   }
6308 
6309 #ifdef MNG_SUPPORT_TRACE
6310   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_END);
6311 #endif
6312 
6313   return MNG_NOERROR;
6314 }
6315 #endif
6316 
6317 /* ************************************************************************** */
6318 
6319 #ifndef MNG_SKIPCHUNK_MAGN
6320 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_magn(mng_datap pData,mng_uint16 iFirstid,mng_uint16 iLastid,mng_uint8 iMethodX,mng_uint16 iMX,mng_uint16 iMY,mng_uint16 iML,mng_uint16 iMR,mng_uint16 iMT,mng_uint16 iMB,mng_uint8 iMethodY)6321 mng_retcode mng_process_display_magn (mng_datap  pData,
6322                                       mng_uint16 iFirstid,
6323                                       mng_uint16 iLastid,
6324                                       mng_uint8  iMethodX,
6325                                       mng_uint16 iMX,
6326                                       mng_uint16 iMY,
6327                                       mng_uint16 iML,
6328                                       mng_uint16 iMR,
6329                                       mng_uint16 iMT,
6330                                       mng_uint16 iMB,
6331                                       mng_uint8  iMethodY)
6332 #else
6333 mng_retcode mng_process_display_magn (mng_datap  pData)
6334 #endif
6335 {
6336   mng_uint16 iX;
6337   mng_imagep pImage;
6338 
6339 #ifdef MNG_SUPPORT_TRACE
6340   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START);
6341 #endif
6342                                        /* iterate the object-ids */
6343 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6344   for (iX = iFirstid; iX <= iLastid; iX++)
6345 #else
6346   for (iX = pData->iMAGNfirstid; iX <= pData->iMAGNlastid; iX++)
6347 #endif
6348   {
6349     if (iX == 0)                       /* process object 0 ? */
6350     {
6351       pImage = (mng_imagep)pData->pObjzero;
6352 
6353 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6354       pImage->iMAGN_MethodX = iMethodX;
6355       pImage->iMAGN_MethodY = iMethodY;
6356       pImage->iMAGN_MX      = iMX;
6357       pImage->iMAGN_MY      = iMY;
6358       pImage->iMAGN_ML      = iML;
6359       pImage->iMAGN_MR      = iMR;
6360       pImage->iMAGN_MT      = iMT;
6361       pImage->iMAGN_MB      = iMB;
6362 #else
6363       pImage->iMAGN_MethodX = pData->iMAGNmethodX;
6364       pImage->iMAGN_MethodY = pData->iMAGNmethodY;
6365       pImage->iMAGN_MX      = pData->iMAGNmX;
6366       pImage->iMAGN_MY      = pData->iMAGNmY;
6367       pImage->iMAGN_ML      = pData->iMAGNmL;
6368       pImage->iMAGN_MR      = pData->iMAGNmR;
6369       pImage->iMAGN_MT      = pData->iMAGNmT;
6370       pImage->iMAGN_MB      = pData->iMAGNmB;
6371 #endif
6372     }
6373     else
6374     {
6375       pImage = mng_find_imageobject (pData, iX);
6376                                        /* object exists & is not frozen ? */
6377       if ((pImage) && (!pImage->bFrozen))
6378       {                                /* previous magnification to be done ? */
6379         if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
6380         {
6381           mng_retcode iRetcode = mng_magnify_imageobject (pData, pImage);
6382           if (iRetcode)                /* on error bail out */
6383             return iRetcode;
6384         }
6385 
6386 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6387         pImage->iMAGN_MethodX = iMethodX;
6388         pImage->iMAGN_MethodY = iMethodY;
6389         pImage->iMAGN_MX      = iMX;
6390         pImage->iMAGN_MY      = iMY;
6391         pImage->iMAGN_ML      = iML;
6392         pImage->iMAGN_MR      = iMR;
6393         pImage->iMAGN_MT      = iMT;
6394         pImage->iMAGN_MB      = iMB;
6395 #else
6396         pImage->iMAGN_MethodX = pData->iMAGNmethodX;
6397         pImage->iMAGN_MethodY = pData->iMAGNmethodY;
6398         pImage->iMAGN_MX      = pData->iMAGNmX;
6399         pImage->iMAGN_MY      = pData->iMAGNmY;
6400         pImage->iMAGN_ML      = pData->iMAGNmL;
6401         pImage->iMAGN_MR      = pData->iMAGNmR;
6402         pImage->iMAGN_MT      = pData->iMAGNmT;
6403         pImage->iMAGN_MB      = pData->iMAGNmB;
6404 #endif
6405       }
6406     }
6407   }
6408 
6409 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6410   pData->iMAGNfromid = iFirstid;
6411   pData->iMAGNtoid   = iLastid;
6412   iX                 = iFirstid;
6413 #else
6414   pData->iMAGNfromid = pData->iMAGNfirstid;
6415   pData->iMAGNtoid   = pData->iMAGNlastid;
6416   iX                 = pData->iMAGNfirstid;
6417 #endif
6418                                        /* iterate again for showing */
6419 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6420   while ((iX <= iLastid) && (!pData->bTimerset))
6421 #else
6422   while ((iX <= pData->iMAGNlastid) && (!pData->bTimerset))
6423 #endif
6424   {
6425     pData->iMAGNcurrentid = iX;
6426 
6427     if (iX)                            /* only real objects ! */
6428     {
6429       pImage = mng_find_imageobject (pData, iX);
6430                                        /* object exists & is not frozen  &
6431                                           is visible & is viewable ? */
6432       if ((pImage) && (!pImage->bFrozen) &&
6433           (pImage->bVisible) && (pImage->bViewable))
6434       {
6435         mng_retcode iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
6436         if (iRetcode)
6437           return iRetcode;
6438       }
6439     }
6440 
6441     iX++;
6442   }
6443 
6444   if (pData->bTimerset)                /* broken ? */
6445     pData->iBreakpoint = 9;
6446 
6447 #ifdef MNG_SUPPORT_TRACE
6448   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END);
6449 #endif
6450 
6451   return MNG_NOERROR;
6452 }
6453 
6454 /* ************************************************************************** */
6455 
mng_process_display_magn2(mng_datap pData)6456 mng_retcode mng_process_display_magn2 (mng_datap pData)
6457 {
6458   mng_uint16 iX;
6459   mng_imagep pImage;
6460 
6461 #ifdef MNG_SUPPORT_TRACE
6462   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START);
6463 #endif
6464 
6465   iX = pData->iMAGNcurrentid;
6466                                        /* iterate again for showing */
6467   while ((iX <= pData->iMAGNtoid) && (!pData->bTimerset))
6468   {
6469     pData->iMAGNcurrentid = iX;
6470 
6471     if (iX)                            /* only real objects ! */
6472     {
6473       pImage = mng_find_imageobject (pData, iX);
6474                                        /* object exists & is not frozen  &
6475                                           is visible & is viewable ? */
6476       if ((pImage) && (!pImage->bFrozen) &&
6477           (pImage->bVisible) && (pImage->bViewable))
6478       {
6479         mng_retcode iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
6480         if (iRetcode)
6481           return iRetcode;
6482       }
6483     }
6484 
6485     iX++;
6486   }
6487 
6488   if (pData->bTimerset)                /* broken ? */
6489     pData->iBreakpoint = 9;
6490   else
6491     pData->iBreakpoint = 0;            /* not again ! */
6492 
6493 #ifdef MNG_SUPPORT_TRACE
6494   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END);
6495 #endif
6496 
6497   return MNG_NOERROR;
6498 }
6499 #endif
6500 
6501 /* ************************************************************************** */
6502 
6503 #ifndef MNG_SKIPCHUNK_PAST
6504 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
mng_process_display_past(mng_datap pData,mng_uint16 iTargetid,mng_uint8 iTargettype,mng_int32 iTargetx,mng_int32 iTargety,mng_uint32 iCount,mng_ptr pSources)6505 mng_retcode mng_process_display_past (mng_datap  pData,
6506                                       mng_uint16 iTargetid,
6507                                       mng_uint8  iTargettype,
6508                                       mng_int32  iTargetx,
6509                                       mng_int32  iTargety,
6510                                       mng_uint32 iCount,
6511                                       mng_ptr    pSources)
6512 #else
6513 mng_retcode mng_process_display_past (mng_datap  pData)
6514 #endif
6515 {
6516   mng_retcode      iRetcode = MNG_NOERROR;
6517   mng_imagep       pTargetimg;
6518   mng_imagep       pSourceimg;
6519 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6520   mng_past_sourcep pSource = (mng_past_sourcep)pSources;
6521 #else
6522   mng_past_sourcep pSource = (mng_past_sourcep)pData->pPASTsources;
6523 #endif
6524   mng_uint32       iX      = 0;
6525 
6526 #ifdef MNG_SUPPORT_TRACE
6527   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_START);
6528 #endif
6529 
6530 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6531   if (iTargetid)                       /* a real destination object ? */
6532 #else
6533   if (pData->iPASTtargetid)            /* a real destination object ? */
6534 #endif
6535   {                                    /* let's find it then */
6536 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6537     pTargetimg = (mng_imagep)mng_find_imageobject (pData, iTargetid);
6538 #else
6539     pTargetimg = (mng_imagep)mng_find_imageobject (pData, pData->iPASTtargetid);
6540 #endif
6541 
6542     if (!pTargetimg)                   /* if it doesn't exists; do a barf */
6543       MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
6544                                        /* it's gotta be abstract !!! */
6545     if (pTargetimg->pImgbuf->bConcrete)
6546       MNG_ERROR (pData, MNG_OBJNOTABSTRACT);
6547                                        /* we want 32-/64-bit RGBA to play with ! */
6548     if ((pTargetimg->pImgbuf->iBitdepth <= MNG_BITDEPTH_8)          ||
6549         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAY)    ||
6550         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_RGB)     ||
6551         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_INDEXED) ||
6552         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAYA)      )
6553       iRetcode = mng_promote_imageobject (pData, pTargetimg, MNG_BITDEPTH_8,
6554                                           MNG_COLORTYPE_RGBA,
6555                                           MNG_FILLMETHOD_LEFTBITREPLICATE);
6556     else
6557     if ((pTargetimg->pImgbuf->iBitdepth > MNG_BITDEPTH_8)              &&
6558         ((pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAY)  ||
6559          (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_RGB)   ||
6560          (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_GRAYA)    )   )
6561       iRetcode = mng_promote_imageobject (pData, pTargetimg, MNG_BITDEPTH_16,
6562                                           MNG_COLORTYPE_RGBA,
6563                                           MNG_FILLMETHOD_LEFTBITREPLICATE);
6564 #ifdef MNG_INCLUDE_JNG
6565     else
6566     if ((pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_JPEGGRAY)  ||
6567         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_JPEGCOLOR) ||
6568         (pTargetimg->pImgbuf->iColortype ==  MNG_COLORTYPE_JPEGGRAYA)    )
6569       iRetcode = mng_promote_imageobject (pData, pTargetimg,
6570                                           pTargetimg->pImgbuf->iBitdepth,
6571                                           MNG_COLORTYPE_JPEGCOLORA,
6572                                           MNG_FILLMETHOD_LEFTBITREPLICATE);
6573 #endif
6574 
6575     if (iRetcode)                      /* on error bail out */
6576       return iRetcode;
6577                                        /* make it really abstract ? */
6578     if (!pTargetimg->pImgbuf->bCorrected)
6579     {
6580       iRetcode = mng_colorcorrect_object (pData, pTargetimg);
6581 
6582       if (iRetcode)                    /* on error bail out */
6583         return iRetcode;
6584     }
6585   }
6586   else
6587   {                                    /* pasting into object 0 !!! */
6588     pTargetimg = (mng_imagep)pData->pObjzero;
6589                                        /* is it usable ??? */
6590     if ((pTargetimg->bClipped) &&
6591         (pTargetimg->iClipr > pTargetimg->iPosx) &&
6592         (pTargetimg->iClipb > pTargetimg->iPosy))
6593     {
6594                                        /* make it 32-bit RGBA please !!! */
6595       iRetcode = mng_reset_object_details (pData, pTargetimg,
6596                                            pTargetimg->iClipr - pTargetimg->iPosx,
6597                                            pTargetimg->iClipb - pTargetimg->iPosy,
6598                                            MNG_BITDEPTH_8, MNG_COLORTYPE_RGBA,
6599                                            0, 0, 0, MNG_FALSE);
6600 
6601       if (iRetcode)                    /* on error bail out */
6602         return iRetcode;
6603     }
6604     else
6605       pTargetimg = MNG_NULL;           /* clipped beyond visibility ! */
6606   }
6607 
6608   if (pTargetimg)                      /* usable destination ? */
6609   {
6610     mng_int32      iSourceY;
6611     mng_int32      iSourceYinc;
6612     mng_int32      iSourcerowsize;
6613     mng_int32      iSourcesamples;
6614     mng_bool       bSourceRGBA16;
6615     mng_int32      iTargetY;
6616     mng_int32      iTargetrowsize;
6617     mng_int32      iTargetsamples;
6618     mng_bool       bTargetRGBA16 = MNG_FALSE;
6619     mng_int32      iTemprowsize;
6620     mng_imagedatap pBuf;
6621 #ifndef MNG_SKIPCHUNK_MAGN
6622                                        /* needs magnification ? */
6623     if ((pTargetimg->iMAGN_MethodX) || (pTargetimg->iMAGN_MethodY))
6624       iRetcode = mng_magnify_imageobject (pData, pTargetimg);
6625 #endif
6626 
6627     if (!iRetcode)                     /* still ok ? */
6628     {
6629       bTargetRGBA16 = (mng_bool)(pTargetimg->pImgbuf->iBitdepth > 8);
6630 
6631 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6632       switch (iTargettype)             /* determine target x/y */
6633 #else
6634       switch (pData->iPASTtargettype)  /* determine target x/y */
6635 #endif
6636       {
6637         case 0 : {
6638 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6639                    pData->iPastx = iTargetx;
6640                    pData->iPasty = iTargety;
6641 #else
6642                    pData->iPastx = pData->iPASTtargetx;
6643                    pData->iPasty = pData->iPASTtargety;
6644 #endif
6645                    break;
6646                  }
6647 
6648         case 1 : {
6649 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6650                    pData->iPastx = pTargetimg->iPastx + iTargetx;
6651                    pData->iPasty = pTargetimg->iPasty + iTargety;
6652 #else
6653                    pData->iPastx = pTargetimg->iPastx + pData->iPASTtargetx;
6654                    pData->iPasty = pTargetimg->iPasty + pData->iPASTtargety;
6655 #endif
6656                    break;
6657                  }
6658 
6659         case 2 : {
6660 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6661                    pData->iPastx += iTargetx;
6662                    pData->iPasty += iTargety;
6663 #else
6664                    pData->iPastx += pData->iPASTtargetx;
6665                    pData->iPasty += pData->iPASTtargety;
6666 #endif
6667                    break;
6668                  }
6669       }
6670                                        /* save for next time ... */
6671       pTargetimg->iPastx      = pData->iPastx;
6672       pTargetimg->iPasty      = pData->iPasty;
6673                                        /* address destination for row-routines */
6674       pData->pStoreobj        = (mng_objectp)pTargetimg;
6675       pData->pStorebuf        = (mng_objectp)pTargetimg->pImgbuf;
6676     }
6677                                        /* process the sources one by one */
6678 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
6679     while ((!iRetcode) && (iX < iCount))
6680 #else
6681     while ((!iRetcode) && (iX < pData->iPASTcount))
6682 #endif
6683     {                                  /* find the little bastards first */
6684       pSourceimg              = (mng_imagep)mng_find_imageobject (pData, pSource->iSourceid);
6685                                        /* exists and viewable? */
6686       if ((pSourceimg) && (pSourceimg->bViewable))
6687       {                                /* needs magnification ? */
6688 #ifndef MNG_SKIPCHUNK_MAGN
6689         if ((pSourceimg->iMAGN_MethodX) || (pSourceimg->iMAGN_MethodY))
6690           iRetcode = mng_magnify_imageobject (pData, pSourceimg);
6691 #endif
6692 
6693         if (!iRetcode)                 /* still ok ? */
6694         {
6695           pBuf                = (mng_imagedatap)pSourceimg->pImgbuf;
6696                                        /* address source for row-routines */
6697           pData->pRetrieveobj = (mng_objectp)pSourceimg;
6698 
6699           pData->iPass        = -1;    /* init row-processing variables */
6700           pData->iRowinc      = 1;
6701           pData->iColinc      = 1;
6702           pData->iPixelofs    = 0;
6703           iSourcesamples      = (mng_int32)pBuf->iWidth;
6704           iSourcerowsize      = pBuf->iRowsize;
6705           bSourceRGBA16       = (mng_bool)(pBuf->iBitdepth > 8);
6706                                        /* make sure the delta-routines do the right thing */
6707           pData->iDeltatype   = MNG_DELTATYPE_BLOCKPIXELREPLACE;
6708 
6709           switch (pBuf->iColortype)
6710           {
6711             case  0 : {
6712 #ifndef MNG_NO_16BIT_SUPPORT
6713                          if (bSourceRGBA16)
6714                           pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
6715                         else
6716 #endif
6717                           pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
6718 
6719                         pData->bIsOpaque      = (mng_bool)(!pBuf->bHasTRNS);
6720                         break;
6721                       }
6722 
6723             case  2 : {
6724 #ifndef MNG_NO_16BIT_SUPPORT
6725                         if (bSourceRGBA16)
6726                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
6727                         else
6728 #endif
6729                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
6730 
6731                         pData->bIsOpaque      = (mng_bool)(!pBuf->bHasTRNS);
6732                         break;
6733                       }
6734 
6735 
6736             case  3 : { pData->fRetrieverow   = (mng_fptr)mng_retrieve_idx8;
6737                         pData->bIsOpaque      = (mng_bool)(!pBuf->bHasTRNS);
6738                         break;
6739                       }
6740 
6741 
6742             case  4 : {
6743 #ifndef MNG_NO_16BIT_SUPPORT
6744                         if (bSourceRGBA16)
6745                           pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
6746                         else
6747 #endif
6748                           pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
6749 
6750                         pData->bIsOpaque      = MNG_FALSE;
6751                         break;
6752                       }
6753 
6754 
6755             case  6 : {
6756 #ifndef MNG_NO_16BIT_SUPPORT
6757                          if (bSourceRGBA16)
6758                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
6759                         else
6760 #endif
6761                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
6762 
6763                         pData->bIsOpaque      = MNG_FALSE;
6764                         break;
6765                       }
6766 
6767             case  8 : {
6768 #ifndef MNG_NO_16BIT_SUPPORT
6769                          if (bSourceRGBA16)
6770                           pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
6771                         else
6772 #endif
6773                           pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
6774 
6775                         pData->bIsOpaque      = MNG_TRUE;
6776                         break;
6777                       }
6778 
6779             case 10 : {
6780 #ifndef MNG_NO_16BIT_SUPPORT
6781                          if (bSourceRGBA16)
6782                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
6783                         else
6784 #endif
6785                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
6786 
6787                         pData->bIsOpaque      = MNG_TRUE;
6788                         break;
6789                       }
6790 
6791 
6792             case 12 : {
6793 #ifndef MNG_NO_16BIT_SUPPORT
6794                          if (bSourceRGBA16)
6795                           pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
6796                         else
6797 #endif
6798                           pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
6799 
6800                         pData->bIsOpaque      = MNG_FALSE;
6801                         break;
6802                       }
6803 
6804 
6805             case 14 : {
6806 #ifndef MNG_NO_16BIT_SUPPORT
6807                          if (bSourceRGBA16)
6808                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
6809                         else
6810 #endif
6811                           pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
6812 
6813                         pData->bIsOpaque      = MNG_FALSE;
6814                         break;
6815                       }
6816           }
6817                                        /* determine scaling */
6818 #ifndef MNG_NO_16BIT_SUPPORT
6819 #ifndef MNG_NO_DELTA_PNG
6820           if ((!bSourceRGBA16) && (bTargetRGBA16))
6821             pData->fScalerow = (mng_fptr)mng_scale_rgba8_rgba16;
6822           else
6823           if ((bSourceRGBA16) && (!bTargetRGBA16))
6824             pData->fScalerow = (mng_fptr)mng_scale_rgba16_rgba8;
6825           else
6826 #endif
6827 #endif
6828             pData->fScalerow = MNG_NULL;
6829 
6830                                        /* default no color-correction */
6831           pData->fCorrectrow = MNG_NULL;
6832 
6833 #if defined(MNG_FULL_CMS)              /* determine color-management routine */
6834           iRetcode = mng_init_full_cms   (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
6835 #elif defined(MNG_GAMMA_ONLY)
6836           iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
6837 #elif defined(MNG_APP_CMS)
6838           iRetcode = mng_init_app_cms    (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
6839 #endif
6840         }
6841 
6842         if (!iRetcode)                 /* still ok ? */
6843         {
6844           pData->fFliprow = MNG_NULL;  /* no flipping or tiling by default */
6845           pData->fTilerow = MNG_NULL;
6846                                        /* but perhaps we do have to ... */
6847           switch (pSource->iOrientation)
6848           {
6849             case 2 : ;
6850             case 4 : {
6851 #ifndef MNG_NO_16BIT_SUPPORT
6852                        if (bTargetRGBA16)
6853                          pData->fFliprow = (mng_fptr)mng_flip_rgba16;
6854                        else
6855 #endif
6856                          pData->fFliprow = (mng_fptr)mng_flip_rgba8;
6857                        break;
6858                      }
6859 
6860             case 8 : {
6861 #ifndef MNG_NO_16BIT_SUPPORT
6862                        if (bTargetRGBA16)
6863                          pData->fTilerow = (mng_fptr)mng_tile_rgba16;
6864                        else
6865 #endif
6866                          pData->fTilerow = (mng_fptr)mng_tile_rgba8;
6867                        break;
6868                      }
6869           }
6870                                        /* determine composition routine */
6871                                        /* note that we're abusing the delta-routine setup !!! */
6872           switch (pSource->iComposition)
6873           {
6874             case 0 : {                 /* composite over */
6875 #ifndef MNG_NO_16BIT_SUPPORT
6876                        if (bTargetRGBA16)
6877                          pData->fDeltarow = (mng_fptr)mng_composeover_rgba16;
6878                        else
6879 #endif
6880                          pData->fDeltarow = (mng_fptr)mng_composeover_rgba8;
6881                        break;
6882                      }
6883 
6884             case 1 : {                 /* replace */
6885 #ifndef MNG_NO_16BIT_SUPPORT
6886                        if (bTargetRGBA16)
6887                          pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgba16;
6888                        else
6889 #endif
6890                          pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgba8;
6891                        break;
6892                      }
6893 
6894             case 2 : {                 /* composite under */
6895 #ifndef MNG_NO_16BIT_SUPPORT
6896                        if (bTargetRGBA16)
6897                          pData->fDeltarow = (mng_fptr)mng_composeunder_rgba16;
6898                        else
6899 #endif
6900                          pData->fDeltarow = (mng_fptr)mng_composeunder_rgba8;
6901                        break;
6902                      }
6903           }
6904                                        /* determine offsets & clipping */
6905           if (pSource->iOffsettype == 1)
6906           {
6907             pData->iDestl          = pData->iPastx + pSource->iOffsetx;
6908             pData->iDestt          = pData->iPasty + pSource->iOffsety;
6909           }
6910           else
6911           {
6912             pData->iDestl          = pSource->iOffsetx;
6913             pData->iDestt          = pSource->iOffsety;
6914           }
6915 
6916           pData->iDestr            = (mng_int32)pTargetimg->pImgbuf->iWidth;
6917           pData->iDestb            = (mng_int32)pTargetimg->pImgbuf->iHeight;
6918                                        /* take the source dimension into account ? */
6919           if (pSource->iOrientation != 8)
6920           {
6921             pData->iDestr          = MIN_COORD (pData->iDestr, pData->iDestl + (mng_int32)pBuf->iWidth);
6922             pData->iDestb          = MIN_COORD (pData->iDestb, pData->iDestt + (mng_int32)pBuf->iHeight);
6923           }
6924                                        /* source clipping */
6925           if (pSource->iBoundarytype == 1)
6926           {
6927             if (pData->iDestl < pData->iPastx + pSource->iBoundaryl)
6928               pData->iSourcel      = pData->iPastx + pSource->iBoundaryl - pData->iDestl;
6929             else
6930               pData->iSourcel      = 0;
6931 
6932             if (pData->iDestt < pData->iPasty + pSource->iBoundaryt)
6933               pData->iSourcet      = pData->iPasty + pSource->iBoundaryt - pData->iDestt;
6934             else
6935               pData->iSourcet      = 0;
6936 
6937             pData->iDestl          = MAX_COORD (pData->iDestl, pData->iPastx + pSource->iBoundaryl);
6938             pData->iDestt          = MAX_COORD (pData->iDestt, pData->iPasty + pSource->iBoundaryt);
6939             pData->iDestr          = MIN_COORD (pData->iDestr, pData->iPastx + pSource->iBoundaryr);
6940             pData->iDestb          = MIN_COORD (pData->iDestb, pData->iPasty + pSource->iBoundaryb);
6941           }
6942           else
6943           {
6944             if (pData->iDestl < pSource->iBoundaryl)
6945               pData->iSourcel      = pSource->iBoundaryl - pData->iDestl;
6946             else
6947               pData->iSourcel      = 0;
6948 
6949             if (pData->iDestt < pSource->iBoundaryt)
6950               pData->iSourcet      = pSource->iBoundaryt - pData->iDestt;
6951             else
6952               pData->iSourcet      = 0;
6953 
6954             pData->iDestl          = MAX_COORD (pData->iDestl, pSource->iBoundaryl);
6955             pData->iDestt          = MAX_COORD (pData->iDestt, pSource->iBoundaryt);
6956             pData->iDestr          = MIN_COORD (pData->iDestr, pSource->iBoundaryr);
6957             pData->iDestb          = MIN_COORD (pData->iDestb, pSource->iBoundaryb);
6958           }
6959 
6960           if (pData->iSourcel)         /* indent source ? */
6961           {
6962 #ifndef MNG_NO_16BIT_SUPPORT
6963              if (bTargetRGBA16)        /* abuse tiling routine to shift source-pixels */
6964                pData->fTilerow = (mng_fptr)mng_tile_rgba16;
6965              else
6966 #endif
6967                pData->fTilerow = (mng_fptr)mng_tile_rgba8;
6968           }
6969                                        /* anything to display ? */
6970           if ((pData->iDestl <= pData->iDestr) && (pData->iDestt <= pData->iDestb))
6971           {                            /* init variables for the loop */
6972             if ((pSource->iOrientation == 2) || (pSource->iOrientation == 6))
6973             {
6974               iSourceY             = (mng_int32)pBuf->iHeight - 1 - pData->iSourcet;
6975               iSourceYinc          = -1;
6976             }
6977             else
6978             {
6979               iSourceY             = pData->iSourcet;
6980               iSourceYinc          = 1;
6981             }
6982 
6983             iTargetY               = pData->iDestt;
6984             pData->iCol            = pData->iDestl;
6985 
6986             iTargetsamples         = pData->iDestr - pData->iDestl;
6987 
6988 #ifndef MNG_NO_16BIT_SUPPORT
6989             if (bTargetRGBA16)
6990               iTargetrowsize       = (iTargetsamples << 3);
6991             else
6992 #endif
6993               iTargetrowsize       = (iTargetsamples << 2);
6994 
6995                                        /* get temporary work-buffers */
6996             if (iSourcerowsize > iTargetrowsize)
6997               iTemprowsize         = iSourcerowsize << 1;
6998             else
6999               iTemprowsize         = iTargetrowsize << 1;
7000             MNG_ALLOC (pData, pData->pRGBArow, iTemprowsize);
7001             MNG_ALLOC (pData, pData->pWorkrow, iTemprowsize);
7002 
7003             while ((!iRetcode) && (iTargetY < pData->iDestb))
7004             {                          /* get a row */
7005               pData->iRow          = iSourceY;
7006               pData->iRowsamples   = iSourcesamples;
7007               pData->iRowsize      = iSourcerowsize;
7008               pData->bIsRGBA16     = bSourceRGBA16;
7009               iRetcode             = ((mng_retrieverow)pData->fRetrieverow) (pData);
7010                                        /* scale it (if necessary) */
7011               if ((!iRetcode) && (pData->fScalerow))
7012                 iRetcode           = ((mng_scalerow)pData->fScalerow) (pData);
7013 
7014               pData->bIsRGBA16     = bTargetRGBA16;
7015                                        /* color correction (if necessary) */
7016               if ((!iRetcode) && (pData->fCorrectrow))
7017                 iRetcode           = ((mng_correctrow)pData->fCorrectrow) (pData);
7018                                        /* flipping (if necessary) */
7019               if ((!iRetcode) && (pData->fFliprow))
7020                 iRetcode           = ((mng_fliprow)pData->fFliprow) (pData);
7021                                        /* tiling (if necessary) */
7022               if ((!iRetcode) && (pData->fTilerow))
7023                 iRetcode           = ((mng_tilerow)pData->fTilerow) (pData);
7024 
7025               if (!iRetcode)           /* and paste..... */
7026               {
7027                 pData->iRow        = iTargetY;
7028                 pData->iRowsamples = iTargetsamples;
7029                 pData->iRowsize    = iTargetrowsize;
7030                 iRetcode           = ((mng_deltarow)pData->fDeltarow) (pData);
7031               }
7032 
7033               iSourceY += iSourceYinc; /* and next line */
7034 
7035               if (iSourceY < 0)
7036                 iSourceY = (mng_int32)pBuf->iHeight - 1;
7037               else
7038               if (iSourceY >= (mng_int32)pBuf->iHeight)
7039                 iSourceY = 0;
7040 
7041               iTargetY++;
7042             }
7043                                        /* drop the temporary row-buffer */
7044             MNG_FREEX (pData, pData->pWorkrow, iTemprowsize);
7045             MNG_FREEX (pData, pData->pRGBArow, iTemprowsize);
7046           }
7047 
7048 #if defined(MNG_FULL_CMS)              /* cleanup cms stuff */
7049           if (!iRetcode)
7050             iRetcode = mng_clear_cms (pData);
7051 #endif
7052         }
7053 
7054         pSource++;                     /* neeeeext */
7055         iX++;
7056       }
7057     }
7058 
7059     if (iRetcode)                      /* on error bail out */
7060       return iRetcode;
7061 
7062 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
7063     if (!iTargetid)                    /* did we paste into object 0 ? */
7064 #else
7065     if (!pData->iPASTtargetid)         /* did we paste into object 0 ? */
7066 #endif
7067     {                                  /* display it then ! */
7068       iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
7069       if (iRetcode)                    /* on error bail out */
7070         return iRetcode;
7071     }
7072     else
7073     {                                  /* target is visible & viewable ? */
7074       if ((pTargetimg->bVisible) && (pTargetimg->bViewable))
7075       {
7076         iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
7077         if (iRetcode)
7078           return iRetcode;
7079       }
7080     }
7081   }
7082 
7083   if (pData->bTimerset)                /* broken ? */
7084   {
7085 #ifndef MNG_OPTIMIZE_DISPLAYCALLS
7086     pData->iPASTid     = iTargetid;
7087 #else
7088     pData->iPASTid     = pData->iPASTtargetid;
7089 #endif
7090     pData->iBreakpoint = 11;
7091   }
7092 
7093 #ifdef MNG_SUPPORT_TRACE
7094   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_END);
7095 #endif
7096 
7097   return MNG_NOERROR;
7098 }
7099 #endif /* MNG_SKIPCHUNK_PAST */
7100 
7101 /* ************************************************************************** */
7102 
7103 #ifndef MNG_SKIPCHUNK_PAST
mng_process_display_past2(mng_datap pData)7104 mng_retcode mng_process_display_past2 (mng_datap pData)
7105 {
7106   mng_retcode iRetcode;
7107   mng_imagep  pTargetimg;
7108 
7109 #ifdef MNG_SUPPORT_TRACE
7110   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_START);
7111 #endif
7112 
7113   if (pData->iPASTid)                  /* a real destination object ? */
7114     pTargetimg = (mng_imagep)mng_find_imageobject (pData, pData->iPASTid);
7115   else                                 /* otherwise object 0 */
7116     pTargetimg = (mng_imagep)pData->pObjzero;
7117 
7118   iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
7119   if (iRetcode)
7120     return iRetcode;
7121 
7122   pData->iBreakpoint = 0;              /* only once */
7123 
7124 #ifdef MNG_SUPPORT_TRACE
7125   MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_END);
7126 #endif
7127 
7128   return MNG_NOERROR;
7129 }
7130 #endif /* MNG_SKIPCHUNK_PAST */
7131 
7132 /* ************************************************************************** */
7133 
7134 #endif /* MNG_INCLUDE_DISPLAY_PROCS */
7135 
7136 /* ************************************************************************** */
7137 /* * end of file                                                            * */
7138 /* ************************************************************************** */
7139 
7140 
7141