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