source: trunk/src/3rdparty/libmng/libmng_display.c

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 182.5 KB
Line 
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 G.Juyn * */
8/* * version : 1.0.2 * */
9/* * * */
10/* * purpose : Display management (implementation) * */
11/* * * */
12/* * author : G.Juyn * */
13/* * web : http://www.3-t.com * */
14/* * email : mailto:info@3-t.com * */
15/* * * */
16/* * comment : implementation of the display management routines * */
17/* * * */
18/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
19/* * - changed strict-ANSI stuff * */
20/* * 0.5.1 - 05/11/2000 - G.Juyn * */
21/* * - added callback error-reporting support * */
22/* * - fixed frame_delay misalignment * */
23/* * 0.5.1 - 05/12/2000 - G.Juyn * */
24/* * - added sanity check for frozen status * */
25/* * - changed trace to macro for callback error-reporting * */
26/* * 0.5.1 - 05/13/2000 - G.Juyn * */
27/* * - changed display_mend to reset state to initial or SAVE * */
28/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
29/* * - added TERM animation object pointer (easier reference) * */
30/* * - added process_save & process_seek routines * */
31/* * 0.5.1 - 05/14/2000 - G.Juyn * */
32/* * - added save_state and restore_state for SAVE/SEEK/TERM * */
33/* * processing * */
34/* * * */
35/* * 0.5.2 - 05/20/2000 - G.Juyn * */
36/* * - added JNG support (JHDR/JDAT) * */
37/* * 0.5.2 - 05/23/2000 - G.Juyn * */
38/* * - fixed problem with DEFI clipping * */
39/* * 0.5.2 - 05/30/2000 - G.Juyn * */
40/* * - added delta-image support (DHDR,PROM,IPNG,IJNG) * */
41/* * 0.5.2 - 05/31/2000 - G.Juyn * */
42/* * - fixed pointer confusion (contributed by Tim Rowley) * */
43/* * 0.5.2 - 06/03/2000 - G.Juyn * */
44/* * - fixed makeup for Linux gcc compile * */
45/* * 0.5.2 - 06/05/2000 - G.Juyn * */
46/* * - added support for RGB8_A8 canvasstyle * */
47/* * 0.5.2 - 06/09/2000 - G.Juyn * */
48/* * - fixed timer-handling to run with Mozilla (Tim Rowley) * */
49/* * 0.5.2 - 06/10/2000 - G.Juyn * */
50/* * - fixed some compilation-warnings (contrib Jason Morris) * */
51/* * * */
52/* * 0.5.3 - 06/12/2000 - G.Juyn * */
53/* * - fixed display of stored JNG images * */
54/* * 0.5.3 - 06/13/2000 - G.Juyn * */
55/* * - fixed problem with BASI-IEND as object 0 * */
56/* * 0.5.3 - 06/16/2000 - G.Juyn * */
57/* * - changed progressive-display processing * */
58/* * 0.5.3 - 06/17/2000 - G.Juyn * */
59/* * - changed delta-image processing * */
60/* * 0.5.3 - 06/20/2000 - G.Juyn * */
61/* * - fixed some minor stuff * */
62/* * 0.5.3 - 06/21/2000 - G.Juyn * */
63/* * - added speed-modifier to timing routine * */
64/* * 0.5.3 - 06/22/2000 - G.Juyn * */
65/* * - added support for PPLT chunk processing * */
66/* * 0.5.3 - 06/29/2000 - G.Juyn * */
67/* * - swapped refresh parameters * */
68/* * * */
69/* * 0.9.0 - 06/30/2000 - G.Juyn * */
70/* * - changed refresh parameters to 'x,y,width,height' * */
71/* * * */
72/* * 0.9.1 - 07/07/2000 - G.Juyn * */
73/* * - implemented support for freeze/reset/resume & go_xxxx * */
74/* * 0.9.1 - 07/08/2000 - G.Juyn * */
75/* * - added support for improved timing * */
76/* * 0.9.1 - 07/14/2000 - G.Juyn * */
77/* * - changed EOF processing behavior * */
78/* * - fixed TERM delay processing * */
79/* * 0.9.1 - 07/15/2000 - G.Juyn * */
80/* * - fixed freeze & reset processing * */
81/* * 0.9.1 - 07/16/2000 - G.Juyn * */
82/* * - fixed storage of images during mng_read() * */
83/* * - fixed support for mng_display() after mng_read() * */
84/* * 0.9.1 - 07/24/2000 - G.Juyn * */
85/* * - fixed reading of still-images * */
86/* * * */
87/* * 0.9.2 - 08/05/2000 - G.Juyn * */
88/* * - changed file-prefixes * */
89/* * * */
90/* * 0.9.3 - 08/07/2000 - G.Juyn * */
91/* * - B111300 - fixup for improved portability * */
92/* * 0.9.3 - 08/21/2000 - G.Juyn * */
93/* * - fixed TERM processing delay of 0 msecs * */
94/* * 0.9.3 - 08/26/2000 - G.Juyn * */
95/* * - added MAGN chunk * */
96/* * 0.9.3 - 09/10/2000 - G.Juyn * */
97/* * - fixed problem with no refresh after TERM * */
98/* * - fixed DEFI behavior * */
99/* * 0.9.3 - 09/16/2000 - G.Juyn * */
100/* * - fixed timing & refresh behavior for single PNG/JNG * */
101/* * 0.9.3 - 09/19/2000 - G.Juyn * */
102/* * - refixed timing & refresh behavior for single PNG/JNG * */
103/* * 0.9.3 - 10/02/2000 - G.Juyn * */
104/* * - fixed timing again (this is getting boring...) * */
105/* * - refixed problem with no refresh after TERM * */
106/* * 0.9.3 - 10/16/2000 - G.Juyn * */
107/* * - added JDAA chunk * */
108/* * 0.9.3 - 10/17/2000 - G.Juyn * */
109/* * - fixed support for bKGD * */
110/* * 0.9.3 - 10/18/2000 - G.Juyn * */
111/* * - fixed delta-processing behavior * */
112/* * 0.9.3 - 10/19/2000 - G.Juyn * */
113/* * - added storage for pixel-/alpha-sampledepth for delta's * */
114/* * 0.9.3 - 10/27/2000 - G.Juyn * */
115/* * - fixed seperate read() & display() processing * */
116/* * * */
117/* * 0.9.4 - 10/31/2000 - G.Juyn * */
118/* * - fixed possible loop in display_resume() (Thanks Vova!) * */
119/* * 0.9.4 - 11/20/2000 - G.Juyn * */
120/* * - fixed unwanted repetition in mng_readdisplay() * */
121/* * 0.9.4 - 11/24/2000 - G.Juyn * */
122/* * - moved restore of object 0 to libmng_display * */
123/* * - added restore of object 0 to TERM processing !!! * */
124/* * - fixed TERM delay processing * */
125/* * - fixed TERM end processing (count = 0) * */
126/* * 0.9.4 - 12/16/2000 - G.Juyn * */
127/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
128/* * 0.9.4 - 1/18/2001 - G.Juyn * */
129/* * - removed test filter-methods 1 & 65 * */
130/* * - set default level-set for filtertype=64 to all zeroes * */
131/* * * */
132/* * 0.9.5 - 1/20/2001 - G.Juyn * */
133/* * - fixed compiler-warnings Mozilla (thanks Tim) * */
134/* * 0.9.5 - 1/23/2001 - G.Juyn * */
135/* * - fixed timing-problem with switching framing_modes * */
136/* * * */
137/* * 1.0.1 - 02/08/2001 - G.Juyn * */
138/* * - added MEND processing callback * */
139/* * 1.0.1 - 02/13/2001 - G.Juyn * */
140/* * - fixed first FRAM_MODE=4 timing problem * */
141/* * 1.0.1 - 04/21/2001 - G.Juyn * */
142/* * - fixed memory-leak for JNGs with alpha (Thanks Gregg!) * */
143/* * - added BGRA8 canvas with premultiplied alpha * */
144/* * * */
145/* * 1.0.2 - 06/25/2001 - G.Juyn * */
146/* * - fixed memory-leak with delta-images (Thanks Michael!) * */
147/* * * */
148/* ************************************************************************** */
149
150#include "libmng.h"
151#include "libmng_data.h"
152#include "libmng_error.h"
153#include "libmng_trace.h"
154#ifdef __BORLANDC__
155#pragma hdrstop
156#endif
157#include "libmng_objects.h"
158#include "libmng_object_prc.h"
159#include "libmng_memory.h"
160#include "libmng_zlib.h"
161#include "libmng_jpeg.h"
162#include "libmng_cms.h"
163#include "libmng_pixels.h"
164#include "libmng_display.h"
165
166#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
167#pragma option -A /* force ANSI-C */
168#endif
169
170/* ************************************************************************** */
171
172#ifdef MNG_INCLUDE_DISPLAY_PROCS
173
174/* ************************************************************************** */
175
176mng_retcode set_delay (mng_datap pData,
177 mng_uint32 iInterval)
178{
179 if (!iInterval) /* at least 1 msec please! */
180 iInterval = 1;
181
182 if (!pData->fSettimer ((mng_handle)pData, iInterval))
183 MNG_ERROR (pData, MNG_APPTIMERERROR)
184
185 pData->bTimerset = MNG_TRUE; /* and indicate so */
186
187 return MNG_NOERROR;
188}
189
190/* ************************************************************************** */
191/* * * */
192/* * Progressive display refresh - does the call to the refresh callback * */
193/* * and sets the timer to allow the app to perform the actual refresh to * */
194/* * the screen (eg. process its main message-loop) * */
195/* * * */
196/* ************************************************************************** */
197
198mng_retcode display_progressive_refresh (mng_datap pData,
199 mng_uint32 iInterval)
200{
201 if (!pData->bSearching) /* we mustn't be searching !!! */
202 {
203 if ((pData->bRunning) && /* let the app refresh first ? */
204 (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
205 {
206 if (!pData->fRefresh (((mng_handle)pData),
207 pData->iUpdateleft, pData->iUpdatetop,
208 pData->iUpdateright - pData->iUpdateleft,
209 pData->iUpdatebottom - pData->iUpdatetop))
210 MNG_ERROR (pData, MNG_APPMISCERROR)
211
212 pData->iUpdateleft = 0; /* reset update-region */
213 pData->iUpdateright = 0;
214 pData->iUpdatetop = 0;
215 pData->iUpdatebottom = 0; /* reset refreshneeded indicator */
216 pData->bNeedrefresh = MNG_FALSE;
217 /* interval requested ? */
218 if ((!pData->bFreezing) && (iInterval))
219 { /* setup the timer */
220 mng_retcode iRetcode = set_delay (pData, iInterval);
221
222 if (iRetcode) /* on error bail out */
223 return iRetcode;
224 }
225 }
226 }
227
228 return MNG_NOERROR;
229}
230
231/* ************************************************************************** */
232/* * * */
233/* * Generic display routines * */
234/* * * */
235/* ************************************************************************** */
236
237mng_retcode interframe_delay (mng_datap pData)
238{
239 mng_uint32 iWaitfor = 0;
240 mng_uint32 iInterval;
241 mng_uint32 iRuninterval;
242 mng_retcode iRetcode;
243
244#ifdef MNG_SUPPORT_TRACE
245 MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_START)
246#endif
247
248 if (!pData->bSearching) /* we mustn't be searching !!! */
249 {
250 if (pData->iFramedelay > 0) /* real delay ? */
251 {
252 if ((pData->bRunning) && /* let the app refresh first ? */
253 (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
254 if (!pData->fRefresh (((mng_handle)pData),
255 pData->iUpdateleft, pData->iUpdatetop,
256 pData->iUpdateright - pData->iUpdateleft,
257 pData->iUpdatebottom - pData->iUpdatetop))
258 MNG_ERROR (pData, MNG_APPMISCERROR)
259
260 pData->iUpdateleft = 0; /* reset update-region */
261 pData->iUpdateright = 0;
262 pData->iUpdatetop = 0;
263 pData->iUpdatebottom = 0; /* reset refreshneeded indicator */
264 pData->bNeedrefresh = MNG_FALSE;
265 /* get current tickcount */
266 pData->iRuntime = pData->fGettickcount ((mng_handle)pData);
267 /* calculate interval since last sync-point */
268 if (pData->iRuntime < pData->iSynctime)
269 iRuninterval = pData->iRuntime + ~pData->iSynctime + 1;
270 else
271 iRuninterval = pData->iRuntime - pData->iSynctime;
272 /* calculate actual run-time */
273 if (pData->iRuntime < pData->iStarttime)
274 pData->iRuntime = pData->iRuntime + ~pData->iStarttime + 1;
275 else
276 pData->iRuntime = pData->iRuntime - pData->iStarttime;
277
278 if (pData->iTicks) /* what are we aiming for */
279 {
280 switch (pData->iSpeed) /* honor speed modifier */
281 {
282 case mng_st_fast :
283 {
284 iWaitfor = (mng_uint32)(( 500 * pData->iFramedelay) / pData->iTicks);
285 break;
286 }
287 case mng_st_slow :
288 {
289 iWaitfor = (mng_uint32)((3000 * pData->iFramedelay) / pData->iTicks);
290 break;
291 }
292 case mng_st_slowest :
293 {
294 iWaitfor = (mng_uint32)((8000 * pData->iFramedelay) / pData->iTicks);
295 break;
296 }
297 default :
298 {
299 iWaitfor = (mng_uint32)((1000 * pData->iFramedelay) / pData->iTicks);
300 }
301 }
302 }
303 else
304 {
305 if (pData->eImagetype == mng_it_mng)
306 iWaitfor = 1000;
307 else
308 iWaitfor = 1;
309 }
310
311 if (iWaitfor > iRuninterval) /* delay necessary ? */
312 iInterval = iWaitfor - iRuninterval;
313 else
314 iInterval = 1; /* force app to process messageloop */
315
316 if (pData->bRunning) /* set the timer ? */
317 {
318 iRetcode = set_delay (pData, iInterval);
319
320 if (iRetcode) /* on error bail out */
321 return iRetcode;
322 }
323 }
324
325 if (pData->bRunning) /* increase frametime in advance */
326 pData->iFrametime = pData->iFrametime + iWaitfor;
327 /* setup for next delay */
328 pData->iFramedelay = pData->iNextdelay;
329 }
330
331#ifdef MNG_SUPPORT_TRACE
332 MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_END)
333#endif
334
335 return MNG_NOERROR;
336}
337
338/* ************************************************************************** */
339
340void set_display_routine (mng_datap pData)
341{ /* actively running ? */
342 if ((pData->bRunning) && (!pData->bFreezing))
343 {
344 switch (pData->iCanvasstyle) /* determine display routine */
345 {
346 case MNG_CANVAS_RGB8 : { pData->fDisplayrow = (mng_fptr)display_rgb8; break; }
347 case MNG_CANVAS_RGBA8 : { pData->fDisplayrow = (mng_fptr)display_rgba8; break; }
348 case MNG_CANVAS_ARGB8 : { pData->fDisplayrow = (mng_fptr)display_argb8; break; }
349 case MNG_CANVAS_RGB8_A8 : { pData->fDisplayrow = (mng_fptr)display_rgb8_a8; break; }
350 case MNG_CANVAS_BGR8 : { pData->fDisplayrow = (mng_fptr)display_bgr8; break; }
351 case MNG_CANVAS_BGRA8 : { pData->fDisplayrow = (mng_fptr)display_bgra8; break; }
352 case MNG_CANVAS_BGRA8PM : { pData->fDisplayrow = (mng_fptr)display_bgra8_pm; break; }
353 case MNG_CANVAS_ABGR8 : { pData->fDisplayrow = (mng_fptr)display_abgr8; break; }
354/* case MNG_CANVAS_RGB16 : { pData->fDisplayrow = (mng_fptr)display_rgb16; break; } */
355/* case MNG_CANVAS_RGBA16 : { pData->fDisplayrow = (mng_fptr)display_rgba16; break; } */
356/* case MNG_CANVAS_ARGB16 : { pData->fDisplayrow = (mng_fptr)display_argb16; break; } */
357/* case MNG_CANVAS_BGR16 : { pData->fDisplayrow = (mng_fptr)display_bgr16; break; } */
358/* case MNG_CANVAS_BGRA16 : { pData->fDisplayrow = (mng_fptr)display_bgra16; break; } */
359/* case MNG_CANVAS_ABGR16 : { pData->fDisplayrow = (mng_fptr)display_abgr16; break; } */
360/* case MNG_CANVAS_INDEX8 : { pData->fDisplayrow = (mng_fptr)display_index8; break; } */
361/* case MNG_CANVAS_INDEXA8 : { pData->fDisplayrow = (mng_fptr)display_indexa8; break; } */
362/* case MNG_CANVAS_AINDEX8 : { pData->fDisplayrow = (mng_fptr)display_aindex8; break; } */
363/* case MNG_CANVAS_GRAY8 : { pData->fDisplayrow = (mng_fptr)display_gray8; break; } */
364/* case MNG_CANVAS_GRAY16 : { pData->fDisplayrow = (mng_fptr)display_gray16; break; } */
365/* case MNG_CANVAS_GRAYA8 : { pData->fDisplayrow = (mng_fptr)display_graya8; break; } */
366/* case MNG_CANVAS_GRAYA16 : { pData->fDisplayrow = (mng_fptr)display_graya16; break; } */
367/* case MNG_CANVAS_AGRAY8 : { pData->fDisplayrow = (mng_fptr)display_agray8; break; } */
368/* case MNG_CANVAS_AGRAY16 : { pData->fDisplayrow = (mng_fptr)display_agray16; break; } */
369/* case MNG_CANVAS_DX15 : { pData->fDisplayrow = (mng_fptr)display_dx15; break; } */
370/* case MNG_CANVAS_DX16 : { pData->fDisplayrow = (mng_fptr)display_dx16; break; } */
371 }
372 }
373
374 return;
375}
376
377/* ************************************************************************** */
378
379mng_retcode load_bkgdlayer (mng_datap pData)
380{
381#ifdef MNG_SUPPORT_TRACE
382 MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_START)
383#endif
384 /* actively running ? */
385 if ((pData->bRunning) && (!pData->bFreezing))
386 {
387 mng_int32 iY;
388 mng_retcode iRetcode; /* save values */
389 mng_int32 iDestl = pData->iDestl;
390 mng_int32 iDestr = pData->iDestr;
391 mng_int32 iDestt = pData->iDestt;
392 mng_int32 iDestb = pData->iDestb;
393 mng_int32 iSourcel = pData->iSourcel;
394 mng_int32 iSourcer = pData->iSourcer;
395 mng_int32 iSourcet = pData->iSourcet;
396 mng_int32 iSourceb = pData->iSourceb;
397 mng_int8 iPass = pData->iPass;
398 mng_int32 iRow = pData->iRow;
399 mng_int32 iRowinc = pData->iRowinc;
400 mng_int32 iCol = pData->iCol;
401 mng_int32 iColinc = pData->iColinc;
402 mng_int32 iRowsamples = pData->iRowsamples;
403 mng_int32 iRowsize = pData->iRowsize;
404 mng_bool bIsRGBA16 = pData->bIsRGBA16;
405 mng_bool bIsOpaque = pData->bIsOpaque;
406 mng_fptr fCorrectrow = pData->fCorrectrow;
407
408 pData->iDestl = 0; /* determine clipping region */
409 pData->iDestt = 0;
410 pData->iDestr = pData->iWidth;
411 pData->iDestb = pData->iHeight;
412
413 if (pData->bFrameclipping) /* frame clipping specified ? */
414 {
415 pData->iDestl = MAX_COORD (pData->iDestl, pData->iFrameclipl);
416 pData->iDestt = MAX_COORD (pData->iDestt, pData->iFrameclipt);
417 pData->iDestr = MIN_COORD (pData->iDestr, pData->iFrameclipr);
418 pData->iDestb = MIN_COORD (pData->iDestb, pData->iFrameclipb);
419 }
420 /* anything to clear ? */
421 if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
422 {
423 pData->iPass = -1; /* these are the object's dimensions now */
424 pData->iRow = 0;
425 pData->iRowinc = 1;
426 pData->iCol = 0;
427 pData->iColinc = 1;
428 pData->iRowsamples = pData->iWidth;
429 pData->iRowsize = pData->iRowsamples << 2;
430 pData->bIsRGBA16 = MNG_FALSE; /* let's keep it simple ! */
431 pData->bIsOpaque = MNG_TRUE;
432
433 pData->iSourcel = 0; /* source relative to destination */
434 pData->iSourcer = pData->iDestr - pData->iDestl;
435 pData->iSourcet = 0;
436 pData->iSourceb = pData->iDestb - pData->iDestt;
437
438 set_display_routine (pData); /* determine display routine */
439 /* default restore using preset BG color */
440 pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgcolor;
441
442 if (((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng)) &&
443 (pData->bUseBKGD))
444 { /* prefer bKGD in PNG/JNG */
445 mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
446
447 if (!pImage)
448 pImage = (mng_imagep)pData->pObjzero;
449
450 if (pImage->pImgbuf->bHasBKGD)
451 pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bkgd;
452 }
453
454 if (pData->fGetbkgdline) /* background-canvas-access callback set ? */
455 {
456 switch (pData->iBkgdstyle)
457 {
458 case MNG_CANVAS_RGB8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_rgb8; break; }
459 case MNG_CANVAS_BGR8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgr8; break; }
460 /* case MNG_CANVAS_RGB16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_rgb16; break; } */
461 /* case MNG_CANVAS_BGR16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgr16; break; } */
462 /* case MNG_CANVAS_INDEX8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_index8; break; } */
463 /* case MNG_CANVAS_GRAY8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_gray8; break; } */
464 /* case MNG_CANVAS_GRAY16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_gray16; break; } */
465 /* case MNG_CANVAS_DX15 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_dx15; break; } */
466 /* case MNG_CANVAS_DX16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_dx16; break; } */
467 }
468 }
469
470 if (pData->bHasBACK)
471 { /* background image ? */
472 if ((pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
473 pData->fRestbkgdrow = (mng_fptr)restore_bkgd_backimage;
474 else /* background color ? */
475 if (pData->iBACKmandatory & 0x01)
476 pData->fRestbkgdrow = (mng_fptr)restore_bkgd_backcolor;
477
478 }
479
480 pData->fCorrectrow = MNG_NULL; /* default no color-correction */
481
482
483 /* TODO: determine color correction; this is tricky;
484 the BACK color is treated differently as the image;
485 it probably requires a rewrite of the logic here... */
486
487
488 /* get a temporary row-buffer */
489 MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
490
491 iY = pData->iDestt; /* this is where we start */
492 iRetcode = MNG_NOERROR; /* so far, so good */
493
494 while ((!iRetcode) && (iY < pData->iDestb))
495 { /* restore a background row */
496 iRetcode = ((mng_restbkgdrow)pData->fRestbkgdrow) (pData);
497 /* color correction ? */
498 if ((!iRetcode) && (pData->fCorrectrow))
499 iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
500
501 if (!iRetcode) /* so... display it */
502 iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
503
504 if (!iRetcode)
505 iRetcode = next_row (pData); /* adjust variables for next row */
506
507 iY++; /* and next line */
508 }
509 /* drop the temporary row-buffer */
510 MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
511
512 if (iRetcode) /* on error bail out */
513 return iRetcode;
514
515 }
516
517 pData->iDestl = iDestl; /* restore values */
518 pData->iDestr = iDestr;
519 pData->iDestt = iDestt;
520 pData->iDestb = iDestb;
521 pData->iSourcel = iSourcel;
522 pData->iSourcer = iSourcer;
523 pData->iSourcet = iSourcet;
524 pData->iSourceb = iSourceb;
525 pData->iPass = iPass;
526 pData->iRow = iRow;
527 pData->iRowinc = iRowinc;
528 pData->iCol = iCol;
529 pData->iColinc = iColinc;
530 pData->iRowsamples = iRowsamples;
531 pData->iRowsize = iRowsize;
532 pData->bIsRGBA16 = bIsRGBA16;
533 pData->bIsOpaque = bIsOpaque;
534 pData->fCorrectrow = fCorrectrow;
535 }
536
537#ifdef MNG_SUPPORT_TRACE
538 MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_END)
539#endif
540
541 return MNG_NOERROR;
542}
543
544/* ************************************************************************** */
545
546mng_retcode clear_canvas (mng_datap pData)
547{
548 mng_int32 iY;
549 mng_retcode iRetcode;
550
551#ifdef MNG_SUPPORT_TRACE
552 MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_START)
553#endif
554
555 pData->iDestl = 0; /* clipping region is full canvas! */
556 pData->iDestt = 0;
557 pData->iDestr = pData->iWidth;
558 pData->iDestb = pData->iHeight;
559
560 pData->iSourcel = 0; /* source is same as destination */
561 pData->iSourcer = pData->iWidth;
562 pData->iSourcet = 0;
563 pData->iSourceb = pData->iHeight;
564
565 pData->iPass = -1; /* these are the object's dimensions now */
566 pData->iRow = 0;
567 pData->iRowinc = 1;
568 pData->iCol = 0;
569 pData->iColinc = 1;
570 pData->iRowsamples = pData->iWidth;
571 pData->iRowsize = pData->iRowsamples << 2;
572 pData->bIsRGBA16 = MNG_FALSE; /* let's keep it simple ! */
573 pData->bIsOpaque = MNG_TRUE;
574
575 set_display_routine (pData); /* determine display routine */
576 /* get a temporary row-buffer */
577 /* it's transparent black by default!! */
578 MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
579
580 iY = pData->iDestt; /* this is where we start */
581 iRetcode = MNG_NOERROR; /* so far, so good */
582
583 while ((!iRetcode) && (iY < pData->iDestb))
584 { /* clear a row then */
585 iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
586
587 if (!iRetcode)
588 iRetcode = next_row (pData); /* adjust variables for next row */
589
590 iY++; /* and next line */
591 }
592 /* drop the temporary row-buffer */
593 MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
594
595 if (iRetcode) /* on error bail out */
596 return iRetcode;
597
598#ifdef MNG_SUPPORT_TRACE
599 MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_END)
600#endif
601
602 return MNG_NOERROR;
603}
604
605/* ************************************************************************** */
606
607mng_retcode next_frame (mng_datap pData,
608 mng_uint8 iFramemode,
609 mng_uint8 iChangedelay,
610 mng_uint32 iDelay,
611 mng_uint8 iChangetimeout,
612 mng_uint32 iTimeout,
613 mng_uint8 iChangeclipping,
614 mng_uint8 iCliptype,
615 mng_int32 iClipl,
616 mng_int32 iClipr,
617 mng_int32 iClipt,
618 mng_int32 iClipb)
619{
620 mng_retcode iRetcode = MNG_NOERROR;
621
622#ifdef MNG_SUPPORT_TRACE
623 MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_START)
624#endif
625
626 if (!pData->iBreakpoint) /* no previous break here ? */
627 {
628 mng_uint8 iOldmode = pData->iFramemode;
629 /* interframe delay required ? */
630 if ((iOldmode == 2) || (iOldmode == 4))
631 {
632/* changed here because FRAM 1/3 will delay themselves before each image */
633 if ((pData->iFrameseq) && (iFramemode != 1) && (iFramemode != 3))
634 iRetcode = interframe_delay (pData);
635 else
636 pData->iFramedelay = pData->iNextdelay;
637 }
638 else
639 { /* delay before inserting background layer? */
640 if ((pData->bFramedone) && (iFramemode == 4))
641 iRetcode = interframe_delay (pData);
642 }
643
644 if (iRetcode) /* on error bail out */
645 return iRetcode;
646 /* now we'll assume we're in the next frame! */
647 if (iFramemode) /* save the new framing mode ? */
648 {
649 pData->iFRAMmode = iFramemode;
650 pData->iFramemode = iFramemode;
651 }
652 else /* reload default */
653 pData->iFramemode = pData->iFRAMmode;
654
655 if (iChangedelay) /* delay changed ? */
656 {
657 pData->iNextdelay = iDelay; /* for *after* next subframe */
658
659 if ((iOldmode == 2) || (iOldmode == 4))
660/* pData->iFramedelay = iDelay; */
661 pData->iFramedelay = pData->iFRAMdelay;
662
663 if (iChangedelay == 2) /* also overall ? */
664 pData->iFRAMdelay = iDelay;
665 }
666 else
667 { /* reload default */
668 pData->iNextdelay = pData->iFRAMdelay;
669
670/* if ((iOldmode == 2) || (iOldmode == 4))
671 pData->iFramedelay = pData->iNextdelay; */
672 }
673
674 if (iChangetimeout) /* timeout changed ? */
675 { /* for next subframe */
676 pData->iFrametimeout = iTimeout;
677
678 if ((iChangetimeout == 2) || /* also overall ? */
679 (iChangetimeout == 4) ||
680 (iChangetimeout == 6) ||
681 (iChangetimeout == 8))
682 pData->iFRAMtimeout = iTimeout;
683 }
684 else /* reload default */
685 pData->iFrametimeout = pData->iFRAMtimeout;
686
687 if (iChangeclipping) /* clipping changed ? */
688 {
689 pData->bFrameclipping = MNG_TRUE;
690
691 if (!iCliptype) /* absolute ? */
692 {
693 pData->iFrameclipl = iClipl;
694 pData->iFrameclipr = iClipr;
695 pData->iFrameclipt = iClipt;
696 pData->iFrameclipb = iClipb;
697 }
698 else /* relative */
699 {
700 pData->iFrameclipl = pData->iFrameclipl + iClipl;
701 pData->iFrameclipr = pData->iFrameclipr + iClipr;
702 pData->iFrameclipt = pData->iFrameclipt + iClipt;
703 pData->iFrameclipb = pData->iFrameclipb + iClipb;
704 }
705
706 if (iChangeclipping == 2) /* also overall ? */
707 {
708 pData->bFRAMclipping = MNG_TRUE;
709
710 if (!iCliptype) /* absolute ? */
711 {
712 pData->iFRAMclipl = iClipl;
713 pData->iFRAMclipr = iClipr;
714 pData->iFRAMclipt = iClipt;
715 pData->iFRAMclipb = iClipb;
716 }
717 else /* relative */
718 {
719 pData->iFRAMclipl = pData->iFRAMclipl + iClipl;
720 pData->iFRAMclipr = pData->iFRAMclipr + iClipr;
721 pData->iFRAMclipt = pData->iFRAMclipt + iClipt;
722 pData->iFRAMclipb = pData->iFRAMclipb + iClipb;
723 }
724 }
725 }
726 else
727 { /* reload defaults */
728 pData->bFrameclipping = pData->bFRAMclipping;
729 pData->iFrameclipl = pData->iFRAMclipl;
730 pData->iFrameclipr = pData->iFRAMclipr;
731 pData->iFrameclipt = pData->iFRAMclipt;
732 pData->iFrameclipb = pData->iFRAMclipb;
733 }
734 }
735
736 if (!pData->bTimerset) /* timer still off ? */
737 {
738 if ((pData->iFramemode == 4) || /* insert background layer after a new frame */
739 (!pData->iLayerseq)) /* and certainly before the very first layer */
740 iRetcode = load_bkgdlayer (pData);
741
742 if (iRetcode) /* on error bail out */
743 return iRetcode;
744
745 if ((pData->bDisplaying) && (pData->bRunning))
746 {
747 pData->iFrameseq++; /* count the frame ! */
748 pData->bFramedone = MNG_TRUE; /* and indicate we've done one */
749 }
750 }
751
752#ifdef MNG_SUPPORT_TRACE
753 MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_END)
754#endif
755
756 return MNG_NOERROR;
757}
758
759/* ************************************************************************** */
760
761mng_retcode next_layer (mng_datap pData)
762{
763 mng_imagep pImage;
764 mng_retcode iRetcode = MNG_NOERROR;
765
766#ifdef MNG_SUPPORT_TRACE
767 MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_START)
768#endif
769
770 if (!pData->iBreakpoint) /* no previous break here ? */
771 { /* interframe delay required ? */
772 if ((pData->eImagetype == mng_it_mng) && (pData->iLayerseq) &&
773 ((pData->iFramemode == 1) || (pData->iFramemode == 3)))
774 iRetcode = interframe_delay (pData);
775 else
776 pData->iFramedelay = pData->iNextdelay;
777
778 if (iRetcode) /* on error bail out */
779 return iRetcode;
780 }
781
782 if (!pData->bTimerset) /* timer still off ? */
783 {
784 if (!pData->iLayerseq) /* restore background for the very first layer ? */
785 { /* wait till IDAT/JDAT for PNGs & JNGs !!! */
786 if ((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng))
787 pData->bRestorebkgd = MNG_TRUE;
788 else
789 { /* for MNG we do it right away */
790 iRetcode = load_bkgdlayer (pData);
791
792 if (pData->bRunning)
793 pData->iLayerseq++; /* and it counts as a layer then ! */
794 }
795 }
796 else
797 if (pData->iFramemode == 3) /* restore background for each layer ? */
798 iRetcode = load_bkgdlayer (pData);
799
800 if (iRetcode) /* on error bail out */
801 return iRetcode;
802
803 if (pData->bHasDHDR) /* processing a delta-image ? */
804 pImage = (mng_imagep)pData->pDeltaImage;
805 else
806 pImage = (mng_imagep)pData->pCurrentobj;
807
808 if (!pImage) /* not an active object ? */
809 pImage = (mng_imagep)pData->pObjzero;
810 /* determine display rectangle */
811 pData->iDestl = MAX_COORD ((mng_int32)0, pImage->iPosx);
812 pData->iDestt = MAX_COORD ((mng_int32)0, pImage->iPosy);
813 /* is it a valid buffer ? */
814 if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
815 {
816 pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
817 pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth );
818 pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
819 pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight);
820 }
821 else /* it's a single image ! */
822 {
823 pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
824 (mng_int32)pData->iDatawidth );
825 pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
826 (mng_int32)pData->iDataheight);
827 }
828
829 if (pData->bFrameclipping) /* frame clipping specified ? */
830 {
831 pData->iDestl = MAX_COORD (pData->iDestl, pData->iFrameclipl);
832 pData->iDestt = MAX_COORD (pData->iDestt, pData->iFrameclipt);
833 pData->iDestr = MIN_COORD (pData->iDestr, pData->iFrameclipr);
834 pData->iDestb = MIN_COORD (pData->iDestb, pData->iFrameclipb);
835 }
836
837 if (pImage->bClipped) /* is the image clipped itself ? */
838 {
839 pData->iDestl = MAX_COORD (pData->iDestl, pImage->iClipl);
840 pData->iDestt = MAX_COORD (pData->iDestt, pImage->iClipt);
841 pData->iDestr = MIN_COORD (pData->iDestr, pImage->iClipr);
842 pData->iDestb = MIN_COORD (pData->iDestb, pImage->iClipb);
843 }
844 /* determine source starting point */
845 pData->iSourcel = MAX_COORD ((mng_int32)0, pData->iDestl - pImage->iPosx);
846 pData->iSourcet = MAX_COORD ((mng_int32)0, pData->iDestt - pImage->iPosy);
847
848 if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
849 { /* and maximum size */
850 pData->iSourcer = MIN_COORD ((mng_int32)pImage->pImgbuf->iWidth,
851 pData->iSourcel + pData->iDestr - pData->iDestl);
852 pData->iSourceb = MIN_COORD ((mng_int32)pImage->pImgbuf->iHeight,
853 pData->iSourcet + pData->iDestb - pData->iDestt);
854 }
855 else /* it's a single image ! */
856 {
857 pData->iSourcer = pData->iSourcel + pData->iDestr - pData->iDestl;
858 pData->iSourceb = pData->iSourcet + pData->iDestb - pData->iDestt;
859 }
860
861 if (pData->bRunning)
862 pData->iLayerseq++; /* count the layer ! */
863 }
864
865#ifdef MNG_SUPPORT_TRACE
866 MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_END)
867#endif
868
869 return MNG_NOERROR;
870}
871
872/* ************************************************************************** */
873
874mng_retcode display_image (mng_datap pData,
875 mng_imagep pImage,
876 mng_bool bLayeradvanced)
877{
878 mng_retcode iRetcode;
879
880#ifdef MNG_SUPPORT_TRACE
881 MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_START)
882#endif
883 /* actively running ? */
884 if ((pData->bRunning) && (!pData->bFreezing))
885 {
886 if ( (!pData->iBreakpoint) && /* needs magnification ? */
887 ( (pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY) ) )
888 {
889 iRetcode = magnify_imageobject (pData, pImage);
890
891 if (iRetcode) /* on error bail out */
892 return iRetcode;
893 }
894 }
895
896 pData->pRetrieveobj = pImage; /* so retrieve-row and color-correction can find it */
897
898 if (!bLayeradvanced) /* need to advance the layer ? */
899 {
900 mng_imagep pSave = pData->pCurrentobj;
901 pData->pCurrentobj = pImage;
902 next_layer (pData); /* advance to next layer */
903 pData->pCurrentobj = pSave;
904 }
905 /* need to restore the background ? */
906 if ((!pData->bTimerset) && (pData->bRestorebkgd))
907 {
908 mng_imagep pSave = pData->pCurrentobj;
909 pData->pCurrentobj = pImage;
910 pData->bRestorebkgd = MNG_FALSE;
911 iRetcode = load_bkgdlayer (pData);
912 pData->pCurrentobj = pSave;
913
914 if (iRetcode) /* on error bail out */
915 return iRetcode;
916
917 if (pData->bRunning)
918 pData->iLayerseq++; /* and it counts as a layer then ! */
919 }
920 /* actively running ? */
921 if ((pData->bRunning) && (!pData->bFreezing))
922 {
923 if (!pData->bTimerset) /* all systems still go ? */
924 {
925 pData->iBreakpoint = 0; /* let's make absolutely sure... */
926 /* anything to display ? */
927 if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
928 {
929 mng_int32 iY;
930
931 set_display_routine (pData); /* determine display routine */
932 /* and image-buffer retrieval routine */
933 switch (pImage->pImgbuf->iColortype)
934 {
935 case 0 : { if (pImage->pImgbuf->iBitdepth > 8)
936 pData->fRetrieverow = (mng_fptr)retrieve_g16;
937 else
938 pData->fRetrieverow = (mng_fptr)retrieve_g8;
939
940 pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
941 break;
942 }
943
944 case 2 : { if (pImage->pImgbuf->iBitdepth > 8)
945 pData->fRetrieverow = (mng_fptr)retrieve_rgb16;
946 else
947 pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
948
949 pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
950 break;
951 }
952
953
954 case 3 : { pData->fRetrieverow = (mng_fptr)retrieve_idx8;
955 pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
956 break;
957 }
958
959
960 case 4 : { if (pImage->pImgbuf->iBitdepth > 8)
961 pData->fRetrieverow = (mng_fptr)retrieve_ga16;
962 else
963 pData->fRetrieverow = (mng_fptr)retrieve_ga8;
964
965 pData->bIsOpaque = MNG_FALSE;
966 break;
967 }
968
969
970 case 6 : { if (pImage->pImgbuf->iBitdepth > 8)
971 pData->fRetrieverow = (mng_fptr)retrieve_rgba16;
972 else
973 pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
974
975 pData->bIsOpaque = MNG_FALSE;
976 break;
977 }
978
979 case 8 : { if (pImage->pImgbuf->iBitdepth > 8)
980 pData->fRetrieverow = (mng_fptr)retrieve_g16;
981 else
982 pData->fRetrieverow = (mng_fptr)retrieve_g8;
983
984 pData->bIsOpaque = MNG_TRUE;
985 break;
986 }
987
988 case 10 : { if (pImage->pImgbuf->iBitdepth > 8)
989 pData->fRetrieverow = (mng_fptr)retrieve_rgb16;
990 else
991 pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
992
993 pData->bIsOpaque = MNG_TRUE;
994 break;
995 }
996
997
998 case 12 : { if (pImage->pImgbuf->iBitdepth > 8)
999 pData->fRetrieverow = (mng_fptr)retrieve_ga16;
1000 else
1001 pData->fRetrieverow = (mng_fptr)retrieve_ga8;
1002
1003 pData->bIsOpaque = MNG_FALSE;
1004 break;
1005 }
1006
1007
1008 case 14 : { if (pImage->pImgbuf->iBitdepth > 8)
1009 pData->fRetrieverow = (mng_fptr)retrieve_rgba16;
1010 else
1011 pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
1012
1013 pData->bIsOpaque = MNG_FALSE;
1014 break;
1015 }
1016
1017 }
1018
1019 pData->iPass = -1; /* these are the object's dimensions now */
1020 pData->iRow = pData->iSourcet;
1021 pData->iRowinc = 1;
1022 pData->iCol = 0;
1023 pData->iColinc = 1;
1024 pData->iRowsamples = pImage->pImgbuf->iWidth;
1025 pData->iRowsize = pData->iRowsamples << 2;
1026 pData->bIsRGBA16 = MNG_FALSE;
1027 /* adjust for 16-bit object ? */
1028 if (pImage->pImgbuf->iBitdepth > 8)
1029 {
1030 pData->bIsRGBA16 = MNG_TRUE;
1031 pData->iRowsize = pData->iRowsamples << 3;
1032 }
1033
1034 pData->fCorrectrow = MNG_NULL; /* default no color-correction */
1035
1036#ifdef MNG_NO_CMS
1037 iRetcode = MNG_NOERROR;
1038#else
1039#if defined(MNG_FULL_CMS) /* determine color-management routine */
1040 iRetcode = init_full_cms_object (pData);
1041#elif defined(MNG_GAMMA_ONLY)
1042 iRetcode = init_gamma_only_object (pData);
1043#elif defined(MNG_APP_CMS)
1044 iRetcode = init_app_cms_object (pData);
1045#endif
1046 if (iRetcode) /* on error bail out */
1047 return iRetcode;
1048#endif /* MNG_NO_CMS */
1049 /* get a temporary row-buffer */
1050 MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
1051
1052 iY = pData->iSourcet; /* this is where we start */
1053
1054 while ((!iRetcode) && (iY < pData->iSourceb))
1055 { /* get a row */
1056 iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
1057 /* color correction ? */
1058 if ((!iRetcode) && (pData->fCorrectrow))
1059 iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
1060
1061 if (!iRetcode) /* so... display it */
1062 iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
1063
1064 if (!iRetcode) /* adjust variables for next row */
1065 iRetcode = next_row (pData);
1066
1067 iY++; /* and next line */
1068 }
1069 /* drop the temporary row-buffer */
1070 MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
1071
1072 if (iRetcode) /* on error bail out */
1073 return iRetcode;
1074
1075#if defined(MNG_INCLUDE_LCMS) /* cleanup cms stuff */
1076 iRetcode = mng_clear_cms (pData);
1077
1078 if (iRetcode) /* on error bail out */
1079 return iRetcode;
1080#endif
1081 }
1082 }
1083 }
1084
1085#ifdef MNG_SUPPORT_TRACE
1086 MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_END)
1087#endif
1088
1089 return MNG_NOERROR; /* whehehe, this is good ! */
1090}
1091
1092/* ************************************************************************** */
1093
1094mng_retcode execute_delta_image (mng_datap pData,
1095 mng_imagep pTarget,
1096 mng_imagep pDelta)
1097{
1098 mng_imagedatap pBuftarget = pTarget->pImgbuf;
1099 mng_imagedatap pBufdelta = pDelta->pImgbuf;
1100 mng_uint32 iY;
1101 mng_retcode iRetcode;
1102
1103#ifdef MNG_SUPPORT_TRACE
1104 MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_START)
1105#endif
1106 /* actively running ? */
1107 if ((pData->bRunning) && (!pData->bFreezing))
1108 {
1109 if (pBufdelta->bHasPLTE) /* palette in delta ? */
1110 {
1111 mng_uint32 iX;
1112 /* new palette larger than old one ? */
1113 if ((!pBuftarget->bHasPLTE) || (pBuftarget->iPLTEcount < pBufdelta->iPLTEcount))
1114 pBuftarget->iPLTEcount = pBufdelta->iPLTEcount;
1115 /* it's definitely got a PLTE now */
1116 pBuftarget->bHasPLTE = MNG_TRUE;
1117
1118 for (iX = 0; iX < pBufdelta->iPLTEcount; iX++)
1119 {
1120 pBuftarget->aPLTEentries[iX].iRed = pBufdelta->aPLTEentries[iX].iRed;
1121 pBuftarget->aPLTEentries[iX].iGreen = pBufdelta->aPLTEentries[iX].iGreen;
1122 pBuftarget->aPLTEentries[iX].iBlue = pBufdelta->aPLTEentries[iX].iBlue;
1123 }
1124 }
1125
1126 if (pBufdelta->bHasTRNS) /* cheap transparency in delta ? */
1127 {
1128 switch (pData->iColortype) /* drop it into the target */
1129 {
1130 case 0: { /* gray */
1131 pBuftarget->iTRNSgray = pBufdelta->iTRNSgray;
1132 pBuftarget->iTRNSred = 0;
1133 pBuftarget->iTRNSgreen = 0;
1134 pBuftarget->iTRNSblue = 0;
1135 pBuftarget->iTRNScount = 0;
1136 break;
1137 }
1138 case 2: { /* rgb */
1139 pBuftarget->iTRNSgray = 0;
1140 pBuftarget->iTRNSred = pBufdelta->iTRNSred;
1141 pBuftarget->iTRNSgreen = pBufdelta->iTRNSgreen;
1142 pBuftarget->iTRNSblue = pBufdelta->iTRNSblue;
1143 pBuftarget->iTRNScount = 0;
1144 break;
1145 }
1146 case 3: { /* indexed */
1147 pBuftarget->iTRNSgray = 0;
1148 pBuftarget->iTRNSred = 0;
1149 pBuftarget->iTRNSgreen = 0;
1150 pBuftarget->iTRNSblue = 0;
1151 /* existing range smaller than new one ? */
1152 if ((!pBuftarget->bHasTRNS) || (pBuftarget->iTRNScount < pBufdelta->iTRNScount))
1153 pBuftarget->iTRNScount = pBufdelta->iTRNScount;
1154
1155 MNG_COPY (pBuftarget->aTRNSentries, pBufdelta->aTRNSentries, pBufdelta->iTRNScount)
1156 break;
1157 }
1158 }
1159
1160 pBuftarget->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
1161 }
1162
1163 if (pBufdelta->bHasBKGD) /* bkgd in source ? */
1164 { /* drop it onto the target */
1165 pBuftarget->bHasBKGD = MNG_TRUE;
1166 pBuftarget->iBKGDindex = pBufdelta->iBKGDindex;
1167 pBuftarget->iBKGDgray = pBufdelta->iBKGDgray;
1168 pBuftarget->iBKGDred = pBufdelta->iBKGDred;
1169 pBuftarget->iBKGDgreen = pBufdelta->iBKGDgreen;
1170 pBuftarget->iBKGDblue = pBufdelta->iBKGDblue;
1171 }
1172
1173 if (pBufdelta->bHasGAMA) /* gamma in source ? */
1174 {
1175 pBuftarget->bHasGAMA = MNG_TRUE; /* drop it onto the target */
1176 pBuftarget->iGamma = pBufdelta->iGamma;
1177 }
1178
1179 if (pBufdelta->bHasCHRM) /* chroma in delta ? */
1180 { /* drop it onto the target */
1181 pBuftarget->bHasCHRM = MNG_TRUE;
1182 pBuftarget->iWhitepointx = pBufdelta->iWhitepointx;
1183 pBuftarget->iWhitepointy = pBufdelta->iWhitepointy;
1184 pBuftarget->iPrimaryredx = pBufdelta->iPrimaryredx;
1185 pBuftarget->iPrimaryredy = pBufdelta->iPrimaryredy;
1186 pBuftarget->iPrimarygreenx = pBufdelta->iPrimarygreenx;
1187 pBuftarget->iPrimarygreeny = pBufdelta->iPrimarygreeny;
1188 pBuftarget->iPrimarybluex = pBufdelta->iPrimarybluex;
1189 pBuftarget->iPrimarybluey = pBufdelta->iPrimarybluey;
1190 }
1191
1192 if (pBufdelta->bHasSRGB) /* sRGB in delta ? */
1193 { /* drop it onto the target */
1194 pBuftarget->bHasSRGB = MNG_TRUE;
1195 pBuftarget->iRenderingintent = pBufdelta->iRenderingintent;
1196 }
1197
1198 if (pBufdelta->bHasICCP) /* ICC profile in delta ? */
1199 {
1200 pBuftarget->bHasICCP = MNG_TRUE; /* drop it onto the target */
1201
1202 if (pBuftarget->pProfile) /* profile existed ? */
1203 MNG_FREEX (pData, pBuftarget->pProfile, pBuftarget->iProfilesize)
1204 /* allocate a buffer & copy it */
1205 MNG_ALLOC (pData, pBuftarget->pProfile, pBufdelta->iProfilesize)
1206 MNG_COPY (pBuftarget->pProfile, pBufdelta->pProfile, pBufdelta->iProfilesize)
1207 /* store it's length as well */
1208 pBuftarget->iProfilesize = pBufdelta->iProfilesize;
1209 }
1210 /* need to execute delta pixels ? */
1211 if ((!pData->bDeltaimmediate) && (pData->iDeltatype != MNG_DELTATYPE_NOCHANGE))
1212 {
1213 pData->fScalerow = MNG_NULL; /* not needed by default */
1214
1215 switch (pBuftarget->iBitdepth) /* determine scaling routine */
1216 {
1217
1218
1219 }
1220
1221 pData->fDeltarow = MNG_NULL; /* let's assume there's nothing to do */
1222
1223 switch (pBuftarget->iColortype) /* determine delta processing routine */
1224 {
1225 case 0 : ;
1226 case 8 : { /* gray */
1227 if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
1228 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
1229 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
1230 {
1231 if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
1232 (pBufdelta->iColortype == 8))
1233 {
1234 switch (pBuftarget->iBitdepth)
1235 {
1236 case 1 : { pData->fDeltarow = (mng_fptr)delta_g1_g1; break; }
1237 case 2 : { pData->fDeltarow = (mng_fptr)delta_g2_g2; break; }
1238 case 4 : { pData->fDeltarow = (mng_fptr)delta_g4_g4; break; }
1239 case 8 : { pData->fDeltarow = (mng_fptr)delta_g8_g8; break; }
1240 case 16 : { pData->fDeltarow = (mng_fptr)delta_g16_g16; break; }
1241 }
1242 }
1243 }
1244
1245 break;
1246 }
1247
1248 case 2 : ;
1249 case 10 : { /* rgb */
1250 if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
1251 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
1252 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
1253 {
1254 if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
1255 {
1256 switch (pBuftarget->iBitdepth)
1257 {
1258 case 8 : { pData->fDeltarow = (mng_fptr)delta_rgb8_rgb8; break; }
1259 case 16 : { pData->fDeltarow = (mng_fptr)delta_rgb16_rgb16; break; }
1260 }
1261 }
1262 }
1263
1264 break;
1265 }
1266
1267 case 3 : { /* indexed; abuse gray routines */
1268 if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
1269 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
1270 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
1271 {
1272 if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1273 {
1274 switch (pBuftarget->iBitdepth)
1275 {
1276 case 1 : { pData->fDeltarow = (mng_fptr)delta_g1_g1; break; }
1277 case 2 : { pData->fDeltarow = (mng_fptr)delta_g2_g2; break; }
1278 case 4 : { pData->fDeltarow = (mng_fptr)delta_g4_g4; break; }
1279 case 8 : { pData->fDeltarow = (mng_fptr)delta_g8_g8; break; }
1280 }
1281 }
1282 }
1283
1284 break;
1285 }
1286
1287 case 4 : ;
1288 case 12 : { /* gray + alpha */
1289 if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
1290 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
1291 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
1292 {
1293 if ((pBufdelta->iColortype == 4) || (pBufdelta->iColortype == 12))
1294 {
1295 switch (pBuftarget->iBitdepth)
1296 {
1297 case 8 : { pData->fDeltarow = (mng_fptr)delta_ga8_ga8; break; }
1298 case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_ga16; break; }
1299 }
1300 }
1301 }
1302 else
1303 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
1304 (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
1305 {
1306 if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
1307 (pBufdelta->iColortype == 8))
1308 {
1309 switch (pBuftarget->iBitdepth)
1310 {
1311 case 8 : { pData->fDeltarow = (mng_fptr)delta_ga8_g8; break; }
1312 case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_g16; break; }
1313 }
1314 }
1315 }
1316 else
1317 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
1318 (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
1319 {
1320 if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1321 {
1322 switch (pBuftarget->iBitdepth)
1323 {
1324 case 8 : { pData->fDeltarow = (mng_fptr)delta_ga8_a8; break; }
1325 case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_a16; break; }
1326 }
1327 }
1328 }
1329
1330 break;
1331 }
1332
1333 case 6 : ;
1334 case 14 : { /* rgb + alpha */
1335 if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
1336 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
1337 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
1338 {
1339 if ((pBufdelta->iColortype == 6) || (pBufdelta->iColortype == 14))
1340 {
1341 switch (pBuftarget->iBitdepth)
1342 {
1343 case 8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_rgba8; break; }
1344 case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_rgba16; break; }
1345 }
1346 }
1347 }
1348 else
1349 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
1350 (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
1351 {
1352 if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
1353 {
1354 switch (pBuftarget->iBitdepth)
1355 {
1356 case 8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_rgb8; break; }
1357 case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_rgb16; break; }
1358 }
1359 }
1360 }
1361 else
1362 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
1363 (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
1364 {
1365 if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
1366 {
1367 switch (pBuftarget->iBitdepth)
1368 {
1369 case 8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_a8; break; }
1370 case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_a16; break; }
1371 }
1372 }
1373 }
1374
1375 break;
1376 }
1377
1378 }
1379
1380 if (pData->fDeltarow) /* do we need to take action ? */
1381 {
1382 pData->iPass = -1; /* setup row dimensions and stuff */
1383 pData->iRow = pData->iDeltaBlocky;
1384 pData->iRowinc = 1;
1385 pData->iCol = pData->iDeltaBlockx;
1386 pData->iColinc = 1;
1387 pData->iRowsamples = pBufdelta->iWidth;
1388 pData->iRowsize = pBuftarget->iRowsize;
1389 /* indicate where to retrieve & where to store */
1390 pData->pRetrieveobj = (mng_objectp)pDelta;
1391 pData->pStoreobj = (mng_objectp)pTarget;
1392
1393 if (pData->pRGBArow) /* prevent duplicate allocation! */
1394 MNG_FREE (pData, pData->pRGBArow, (pData->iDatawidth << 3))
1395 /* get a temporary row-buffer */
1396 MNG_ALLOC (pData, pData->pRGBArow, pBufdelta->iRowsize)
1397
1398 iY = 0; /* this is where we start */
1399 iRetcode = MNG_NOERROR; /* still oke for now */
1400
1401 while ((!iRetcode) && (iY < pBufdelta->iHeight))
1402 { /* get a row */
1403 mng_uint8p pWork = pBufdelta->pImgdata + (iY * pBufdelta->iRowsize);
1404
1405 MNG_COPY (pData->pRGBArow, pWork, pBufdelta->iRowsize);
1406
1407 if (pData->fScalerow) /* scale it (if necessary) */
1408 iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
1409
1410 if (!iRetcode) /* and... execute it */
1411 iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
1412
1413 if (!iRetcode) /* adjust variables for next row */
1414 iRetcode = next_row (pData);
1415
1416 iY++; /* and next line */
1417 }
1418 /* drop the temporary row-buffer */
1419 MNG_FREE (pData, pData->pRGBArow, pBufdelta->iRowsize)
1420
1421 if (iRetcode) /* on error bail out */
1422 return iRetcode;
1423
1424 }
1425 else
1426 MNG_ERROR (pData, MNG_INVALIDDELTA)
1427
1428 }
1429 }
1430
1431#ifdef MNG_SUPPORT_TRACE
1432 MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_END)
1433#endif
1434
1435 return MNG_NOERROR;
1436}
1437
1438/* ************************************************************************** */
1439
1440mng_retcode save_state (mng_datap pData)
1441{
1442 mng_savedatap pSave;
1443 mng_imagep pImage;
1444
1445#ifdef MNG_SUPPORT_TRACE
1446 MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_START)
1447#endif
1448
1449 if (pData->pSavedata) /* sanity check */
1450 MNG_ERROR (pData, MNG_INTERNALERROR)
1451 /* get a buffer for saving */
1452 MNG_ALLOC (pData, pData->pSavedata, sizeof (mng_savedata))
1453
1454 pSave = pData->pSavedata; /* address it more directly */
1455 /* and copy global data from the main struct */
1456#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1457 pSave->bHasglobalPLTE = pData->bHasglobalPLTE;
1458 pSave->bHasglobalTRNS = pData->bHasglobalTRNS;
1459 pSave->bHasglobalGAMA = pData->bHasglobalGAMA;
1460 pSave->bHasglobalCHRM = pData->bHasglobalCHRM;
1461 pSave->bHasglobalSRGB = pData->bHasglobalSRGB;
1462 pSave->bHasglobalICCP = pData->bHasglobalICCP;
1463 pSave->bHasglobalBKGD = pData->bHasglobalBKGD;
1464#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1465
1466 pSave->iBACKred = pData->iBACKred;
1467 pSave->iBACKgreen = pData->iBACKgreen;
1468 pSave->iBACKblue = pData->iBACKblue;
1469 pSave->iBACKmandatory = pData->iBACKmandatory;
1470 pSave->iBACKimageid = pData->iBACKimageid;
1471 pSave->iBACKtile = pData->iBACKtile;
1472
1473 pSave->iFRAMmode = pData->iFRAMmode;
1474 pSave->iFRAMdelay = pData->iFRAMdelay;
1475 pSave->iFRAMtimeout = pData->iFRAMtimeout;
1476 pSave->bFRAMclipping = pData->bFRAMclipping;
1477 pSave->iFRAMclipl = pData->iFRAMclipl;
1478 pSave->iFRAMclipr = pData->iFRAMclipr;
1479 pSave->iFRAMclipt = pData->iFRAMclipt;
1480 pSave->iFRAMclipb = pData->iFRAMclipb;
1481
1482 pSave->iGlobalPLTEcount = pData->iGlobalPLTEcount;
1483
1484 MNG_COPY (pSave->aGlobalPLTEentries, pData->aGlobalPLTEentries, sizeof (mng_rgbpaltab))
1485
1486 pSave->iGlobalTRNSrawlen = pData->iGlobalTRNSrawlen;
1487 MNG_COPY (pSave->aGlobalTRNSrawdata, pData->aGlobalTRNSrawdata, 256)
1488
1489 pSave->iGlobalGamma = pData->iGlobalGamma;
1490
1491 pSave->iGlobalWhitepointx = pData->iGlobalWhitepointx;
1492 pSave->iGlobalWhitepointy = pData->iGlobalWhitepointy;
1493 pSave->iGlobalPrimaryredx = pData->iGlobalPrimaryredx;
1494 pSave->iGlobalPrimaryredy = pData->iGlobalPrimaryredy;
1495 pSave->iGlobalPrimarygreenx = pData->iGlobalPrimarygreenx;
1496 pSave->iGlobalPrimarygreeny = pData->iGlobalPrimarygreeny;
1497 pSave->iGlobalPrimarybluex = pData->iGlobalPrimarybluex;
1498 pSave->iGlobalPrimarybluey = pData->iGlobalPrimarybluey;
1499
1500 pSave->iGlobalRendintent = pData->iGlobalRendintent;
1501
1502 pSave->iGlobalProfilesize = pData->iGlobalProfilesize;
1503
1504 if (pSave->iGlobalProfilesize) /* has a profile ? */
1505 { /* then copy that ! */
1506 MNG_ALLOC (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize)
1507 MNG_COPY (pSave->pGlobalProfile, pData->pGlobalProfile, pSave->iGlobalProfilesize)
1508 }
1509
1510 pSave->iGlobalBKGDred = pData->iGlobalBKGDred;
1511 pSave->iGlobalBKGDgreen = pData->iGlobalBKGDgreen;
1512 pSave->iGlobalBKGDblue = pData->iGlobalBKGDblue;
1513
1514 /* freeze current image objects */
1515 pImage = (mng_imagep)pData->pFirstimgobj;
1516
1517 while (pImage)
1518 { /* freeze the object AND it's buffer */
1519 pImage->bFrozen = MNG_TRUE;
1520 pImage->pImgbuf->bFrozen = MNG_TRUE;
1521 /* neeeext */
1522 pImage = (mng_imagep)pImage->sHeader.pNext;
1523 }
1524
1525#ifdef MNG_SUPPORT_TRACE
1526 MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_END)
1527#endif
1528
1529 return MNG_NOERROR;
1530}
1531
1532/* ************************************************************************** */
1533
1534mng_retcode mng_reset_objzero (mng_datap pData)
1535{
1536 mng_imagep pImage = (mng_imagep)pData->pObjzero;
1537 mng_retcode iRetcode = reset_object_details (pData, pImage, 0, 0, 0,
1538 0, 0, 0, 0, MNG_TRUE);
1539
1540 if (iRetcode) /* on error bail out */
1541 return iRetcode;
1542
1543 pImage->bVisible = MNG_TRUE;
1544 pImage->bViewable = MNG_TRUE;
1545 pImage->iPosx = 0;
1546 pImage->iPosy = 0;
1547 pImage->bClipped = MNG_FALSE;
1548 pImage->iClipl = 0;
1549 pImage->iClipr = 0;
1550 pImage->iClipt = 0;
1551 pImage->iClipb = 0;
1552 pImage->iMAGN_MethodX = 0;
1553 pImage->iMAGN_MethodY = 0;
1554 pImage->iMAGN_MX = 0;
1555 pImage->iMAGN_MY = 0;
1556 pImage->iMAGN_ML = 0;
1557 pImage->iMAGN_MR = 0;
1558 pImage->iMAGN_MT = 0;
1559 pImage->iMAGN_MB = 0;
1560
1561 return MNG_NOERROR;
1562}
1563
1564/* ************************************************************************** */
1565
1566mng_retcode restore_state (mng_datap pData)
1567{
1568 mng_savedatap pSave;
1569 mng_imagep pImage;
1570 mng_retcode iRetcode;
1571
1572#ifdef MNG_SUPPORT_TRACE
1573 MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_START)
1574#endif
1575 /* restore object 0 status !!! */
1576 iRetcode = mng_reset_objzero (pData);
1577
1578 if (iRetcode) /* on error bail out */
1579 return iRetcode;
1580 /* fresh cycle; fake no frames done yet */
1581 pData->bFramedone = MNG_FALSE;
1582
1583 if (pData->pSavedata) /* do we have a saved state ? */
1584 {
1585 pSave = pData->pSavedata; /* address it more directly */
1586 /* and copy it back to the main struct */
1587#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1588 pData->bHasglobalPLTE = pSave->bHasglobalPLTE;
1589 pData->bHasglobalTRNS = pSave->bHasglobalTRNS;
1590 pData->bHasglobalGAMA = pSave->bHasglobalGAMA;
1591 pData->bHasglobalCHRM = pSave->bHasglobalCHRM;
1592 pData->bHasglobalSRGB = pSave->bHasglobalSRGB;
1593 pData->bHasglobalICCP = pSave->bHasglobalICCP;
1594 pData->bHasglobalBKGD = pSave->bHasglobalBKGD;
1595#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1596
1597 pData->iBACKred = pSave->iBACKred;
1598 pData->iBACKgreen = pSave->iBACKgreen;
1599 pData->iBACKblue = pSave->iBACKblue;
1600 pData->iBACKmandatory = pSave->iBACKmandatory;
1601 pData->iBACKimageid = pSave->iBACKimageid;
1602 pData->iBACKtile = pSave->iBACKtile;
1603
1604 pData->iFRAMmode = pSave->iFRAMmode;
1605 pData->iFRAMdelay = pSave->iFRAMdelay;
1606 pData->iFRAMtimeout = pSave->iFRAMtimeout;
1607 pData->bFRAMclipping = pSave->bFRAMclipping;
1608 pData->iFRAMclipl = pSave->iFRAMclipl;
1609 pData->iFRAMclipr = pSave->iFRAMclipr;
1610 pData->iFRAMclipt = pSave->iFRAMclipt;
1611 pData->iFRAMclipb = pSave->iFRAMclipb;
1612 /* also the next subframe parms */
1613 pData->iFramemode = pSave->iFRAMmode;
1614 pData->iFramedelay = pSave->iFRAMdelay;
1615 pData->iFrametimeout = pSave->iFRAMtimeout;
1616 pData->bFrameclipping = pSave->bFRAMclipping;
1617 pData->iFrameclipl = pSave->iFRAMclipl;
1618 pData->iFrameclipr = pSave->iFRAMclipr;
1619 pData->iFrameclipt = pSave->iFRAMclipt;
1620 pData->iFrameclipb = pSave->iFRAMclipb;
1621
1622 pData->iNextdelay = pSave->iFRAMdelay;
1623
1624 pData->iGlobalPLTEcount = pSave->iGlobalPLTEcount;
1625 MNG_COPY (pData->aGlobalPLTEentries, pSave->aGlobalPLTEentries, sizeof (mng_rgbpaltab))
1626
1627 pData->iGlobalTRNSrawlen = pSave->iGlobalTRNSrawlen;
1628 MNG_COPY (pData->aGlobalTRNSrawdata, pSave->aGlobalTRNSrawdata, 256)
1629
1630 pData->iGlobalGamma = pSave->iGlobalGamma;
1631
1632 pData->iGlobalWhitepointx = pSave->iGlobalWhitepointx;
1633 pData->iGlobalWhitepointy = pSave->iGlobalWhitepointy;
1634 pData->iGlobalPrimaryredx = pSave->iGlobalPrimaryredx;
1635 pData->iGlobalPrimaryredy = pSave->iGlobalPrimaryredy;
1636 pData->iGlobalPrimarygreenx = pSave->iGlobalPrimarygreenx;
1637 pData->iGlobalPrimarygreeny = pSave->iGlobalPrimarygreeny;
1638 pData->iGlobalPrimarybluex = pSave->iGlobalPrimarybluex;
1639 pData->iGlobalPrimarybluey = pSave->iGlobalPrimarybluey;
1640
1641 pData->iGlobalRendintent = pSave->iGlobalRendintent;
1642
1643 pData->iGlobalProfilesize = pSave->iGlobalProfilesize;
1644
1645 if (pData->iGlobalProfilesize) /* has a profile ? */
1646 { /* then copy that ! */
1647 MNG_ALLOC (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
1648 MNG_COPY (pData->pGlobalProfile, pSave->pGlobalProfile, pData->iGlobalProfilesize)
1649 }
1650
1651 pData->iGlobalBKGDred = pSave->iGlobalBKGDred;
1652 pData->iGlobalBKGDgreen = pSave->iGlobalBKGDgreen;
1653 pData->iGlobalBKGDblue = pSave->iGlobalBKGDblue;
1654 }
1655 else /* no saved-data; so reset the lot */
1656 {
1657#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
1658 pData->bHasglobalPLTE = MNG_FALSE;
1659 pData->bHasglobalTRNS = MNG_FALSE;
1660 pData->bHasglobalGAMA = MNG_FALSE;
1661 pData->bHasglobalCHRM = MNG_FALSE;
1662 pData->bHasglobalSRGB = MNG_FALSE;
1663 pData->bHasglobalICCP = MNG_FALSE;
1664 pData->bHasglobalBKGD = MNG_FALSE;
1665#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
1666
1667 if (!pData->bEMNGMAhack) /* TODO: remove line in 1.0.0 !!! */
1668 { /* TODO: remove line in 1.0.0 !!! */
1669 pData->iBACKred = 0;
1670 pData->iBACKgreen = 0;
1671 pData->iBACKblue = 0;
1672 pData->iBACKmandatory = 0;
1673 pData->iBACKimageid = 0;
1674 pData->iBACKtile = 0;
1675 } /* TODO: remove line in 1.0.0 !!! */
1676
1677 pData->iFRAMmode = 1;
1678 pData->iFRAMdelay = 1;
1679 pData->iFRAMtimeout = 0x7fffffffl;
1680 pData->bFRAMclipping = MNG_FALSE;
1681 pData->iFRAMclipl = 0;
1682 pData->iFRAMclipr = 0;
1683 pData->iFRAMclipt = 0;
1684 pData->iFRAMclipb = 0;
1685 /* also the next subframe parms */
1686 pData->iFramemode = 1;
1687 pData->iFramedelay = 1;
1688 pData->iFrametimeout = 0x7fffffffl;
1689 pData->bFrameclipping = MNG_FALSE;
1690 pData->iFrameclipl = 0;
1691 pData->iFrameclipr = 0;
1692 pData->iFrameclipt = 0;
1693 pData->iFrameclipb = 0;
1694
1695 pData->iNextdelay = 1;
1696
1697 pData->iGlobalPLTEcount = 0;
1698
1699 pData->iGlobalTRNSrawlen = 0;
1700
1701 pData->iGlobalGamma = 0;
1702
1703 pData->iGlobalWhitepointx = 0;
1704 pData->iGlobalWhitepointy = 0;
1705 pData->iGlobalPrimaryredx = 0;
1706 pData->iGlobalPrimaryredy = 0;
1707 pData->iGlobalPrimarygreenx = 0;
1708 pData->iGlobalPrimarygreeny = 0;
1709 pData->iGlobalPrimarybluex = 0;
1710 pData->iGlobalPrimarybluey = 0;
1711
1712 pData->iGlobalRendintent = 0;
1713
1714 if (pData->iGlobalProfilesize) /* free a previous profile ? */
1715 MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
1716
1717 pData->iGlobalProfilesize = 0;
1718
1719 pData->iGlobalBKGDred = 0;
1720 pData->iGlobalBKGDgreen = 0;
1721 pData->iGlobalBKGDblue = 0;
1722 }
1723
1724 if (!pData->bEMNGMAhack) /* TODO: remove line in 1.0.0 !!! */
1725 { /* TODO: remove line in 1.0.0 !!! */
1726 /* drop un-frozen image objects */
1727 pImage = (mng_imagep)pData->pFirstimgobj;
1728
1729 while (pImage)
1730 { /* is it un-frozen ? */
1731 if (!pImage->bFrozen)
1732 {
1733 mng_imagep pPrev = (mng_imagep)pImage->sHeader.pPrev;
1734 mng_imagep pNext = (mng_imagep)pImage->sHeader.pNext;
1735
1736 if (pPrev) /* unlink it */
1737 pPrev->sHeader.pNext = pNext;
1738 else
1739 pData->pFirstimgobj = pNext;
1740
1741 if (pNext)
1742 pNext->sHeader.pPrev = pPrev;
1743 else
1744 pData->pLastimgobj = pPrev;
1745
1746 if (pImage->pImgbuf->bFrozen) /* buffer frozen ? */
1747 {
1748 if (pImage->pImgbuf->iRefcount <= 2)
1749 MNG_ERROR (pData, MNG_INTERNALERROR)
1750 /* decrease ref counter */
1751 pImage->pImgbuf->iRefcount--;
1752 /* just cleanup the object then */
1753 MNG_FREEX (pData, pImage, sizeof (mng_image))
1754 }
1755 else
1756 { /* free the image buffer */
1757 iRetcode = free_imagedataobject (pData, pImage->pImgbuf);
1758 /* and cleanup the object */
1759 MNG_FREEX (pData, pImage, sizeof (mng_image))
1760
1761 if (iRetcode) /* on error bail out */
1762 return iRetcode;
1763 }
1764
1765 pImage = pNext; /* this is the next */
1766 }
1767 else /* neeeext */
1768 pImage = (mng_imagep)pImage->sHeader.pNext;
1769
1770 }
1771 } /* TODO: remove line in 1.0.0 !!! */
1772
1773#ifdef MNG_SUPPORT_TRACE
1774 MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_END)
1775#endif
1776
1777 return MNG_NOERROR;
1778}
1779
1780/* ************************************************************************** */
1781/* * * */
1782/* * General display processing routine * */
1783/* * * */
1784/* ************************************************************************** */
1785
1786mng_retcode process_display (mng_datap pData)
1787{
1788 mng_retcode iRetcode = MNG_NOERROR;
1789
1790#ifdef MNG_SUPPORT_TRACE
1791 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_START)
1792#endif
1793
1794 if (!pData->iBreakpoint) /* not broken previously ? */
1795 {
1796 if ((pData->iRequestframe) || (pData->iRequestlayer) || (pData->iRequesttime))
1797 {
1798 pData->bSearching = MNG_TRUE; /* indicate we're searching */
1799
1800 iRetcode = clear_canvas (pData); /* make the canvas virgin black ?!? */
1801
1802 if (iRetcode) /* on error bail out */
1803 return iRetcode;
1804 /* let's start from the top, shall we */
1805 pData->pCurraniobj = pData->pFirstaniobj;
1806 }
1807 }
1808
1809 do /* process the objects */
1810 {
1811 if (pData->bSearching) /* are we looking sor something ? */
1812 {
1813 if ((pData->iRequestframe) &&
1814 (pData->iRequestframe < ((mng_object_headerp)pData->pCurraniobj)->iFramenr))
1815 {
1816 pData->iRequestframe = 0; /* found the frame ! */
1817 pData->bSearching = MNG_FALSE;
1818 }
1819 else
1820 if ((pData->iRequestlayer) &&
1821 (pData->iRequestlayer < ((mng_object_headerp)pData->pCurraniobj)->iLayernr))
1822 {
1823 pData->iRequestlayer = 0; /* found the layer ! */
1824 pData->bSearching = MNG_FALSE;
1825 }
1826 else
1827 if ((pData->iRequesttime) &&
1828 (pData->iRequesttime < ((mng_object_headerp)pData->pCurraniobj)->iPlaytime))
1829 {
1830 pData->iRequesttime = 0; /* found the playtime ! */
1831 pData->bSearching = MNG_FALSE;
1832 }
1833 }
1834 /* do we need to finish something first ? */
1835 if ((pData->iBreakpoint) && (pData->iBreakpoint < 99))
1836 {
1837 switch (pData->iBreakpoint) /* return to broken display routine */
1838 {
1839 case 1 : { iRetcode = process_display_fram2 (pData); break; }
1840 case 3 : ; /* same as 4 !!! */
1841 case 4 : { iRetcode = process_display_show (pData); break; }
1842 case 5 : { iRetcode = process_display_clon2 (pData); break; }
1843 case 9 : { iRetcode = process_display_magn2 (pData); break; }
1844 default : MNG_ERROR (pData, MNG_INTERNALERROR)
1845 }
1846 }
1847 else
1848 {
1849 if (pData->pCurraniobj)
1850 iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
1851 }
1852
1853 if (!pData->bTimerset) /* reset breakpoint flag ? */
1854 pData->iBreakpoint = 0;
1855 /* can we advance to next object ? */
1856 if ((!iRetcode) && (pData->pCurraniobj) &&
1857 (!pData->bTimerset) && (!pData->bSectionwait))
1858 {
1859 pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
1860 /* MEND processing to be done ? */
1861 if ((pData->eImagetype == mng_it_mng) && (!pData->pCurraniobj))
1862 iRetcode = process_display_mend (pData);
1863
1864 if (!pData->pCurraniobj) /* refresh after last image ? */
1865 pData->bNeedrefresh = MNG_TRUE;
1866 }
1867 } /* until error or a break or no more objects */
1868 while ((!iRetcode) && (pData->pCurraniobj) &&
1869 (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
1870
1871 if (iRetcode) /* on error bail out */
1872 return iRetcode;
1873 /* refresh needed ? */
1874 if ((!pData->bTimerset) && (pData->bNeedrefresh))
1875 {
1876 iRetcode = display_progressive_refresh (pData, 1);
1877
1878 if (iRetcode) /* on error bail out */
1879 return iRetcode;
1880 }
1881 /* timer break ? */
1882 if ((pData->bTimerset) && (!pData->iBreakpoint))
1883 pData->iBreakpoint = 99;
1884 else
1885 if (!pData->bTimerset)
1886 pData->iBreakpoint = 0; /* reset if no timer break */
1887
1888 if ((!pData->bTimerset) && (!pData->pCurraniobj))
1889 pData->bRunning = MNG_FALSE; /* all done now ! */
1890
1891#ifdef MNG_SUPPORT_TRACE
1892 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_END)
1893#endif
1894
1895 return MNG_NOERROR;
1896}
1897
1898/* ************************************************************************** */
1899/* * * */
1900/* * Chunk display processing routines * */
1901/* * * */
1902/* ************************************************************************** */
1903
1904mng_retcode process_display_ihdr (mng_datap pData)
1905{ /* address the current "object" if any */
1906 mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
1907
1908#ifdef MNG_SUPPORT_TRACE
1909 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_START)
1910#endif
1911
1912 if (!pData->bHasDHDR)
1913 {
1914 pData->fInitrowproc = MNG_NULL; /* do nothing by default */
1915 pData->fDisplayrow = MNG_NULL;
1916 pData->fCorrectrow = MNG_NULL;
1917 pData->fStorerow = MNG_NULL;
1918 pData->fProcessrow = MNG_NULL;
1919 pData->fDifferrow = MNG_NULL;
1920 pData->pStoreobj = MNG_NULL;
1921 }
1922
1923 if (!pData->iBreakpoint) /* not previously broken ? */
1924 {
1925 mng_retcode iRetcode = MNG_NOERROR;
1926
1927 if (pData->bHasDHDR) /* is a delta-image ? */
1928 {
1929 if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
1930 iRetcode = reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
1931 pData->iDatawidth, pData->iDataheight,
1932 pData->iBitdepth, pData->iColortype,
1933 pData->iCompression, pData->iFilter,
1934 pData->iInterlace, MNG_TRUE);
1935 else
1936 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
1937 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
1938 {
1939 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
1940 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
1941 }
1942 else
1943 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
1944 (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
1945 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
1946 else
1947 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
1948 (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
1949 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
1950
1951 /* process immediatly if bitdepth & colortype are equal */
1952 pData->bDeltaimmediate =
1953 (mng_bool)((pData->iBitdepth == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
1954 (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype) );
1955 }
1956 else
1957 {
1958 if (pImage) /* update object buffer ? */
1959 iRetcode = reset_object_details (pData, pImage,
1960 pData->iDatawidth, pData->iDataheight,
1961 pData->iBitdepth, pData->iColortype,
1962 pData->iCompression, pData->iFilter,
1963 pData->iInterlace, MNG_TRUE);
1964 else
1965 iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
1966 pData->iDatawidth, pData->iDataheight,
1967 pData->iBitdepth, pData->iColortype,
1968 pData->iCompression, pData->iFilter,
1969 pData->iInterlace, MNG_TRUE);
1970 }
1971
1972 if (iRetcode) /* on error bail out */
1973 return iRetcode;
1974 }
1975
1976 if (!pData->bHasDHDR)
1977 {
1978 if (pImage) /* real object ? */
1979 pData->pStoreobj = pImage; /* tell the row routines */
1980 else /* otherwise use object 0 */
1981 pData->pStoreobj = pData->pObjzero;
1982 /* display "on-the-fly" ? */
1983 if ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
1984 (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
1985 ( (pData->eImagetype == mng_it_png ) ||
1986 (((mng_imagep)pData->pStoreobj)->bVisible) ) )
1987 {
1988 next_layer (pData); /* that's a new layer then ! */
1989
1990 if (pData->bTimerset) /* timer break ? */
1991 pData->iBreakpoint = 2;
1992 else
1993 {
1994 pData->iBreakpoint = 0;
1995 /* anything to display ? */
1996 if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
1997 set_display_routine (pData); /* then determine display routine */
1998 }
1999 }
2000 }
2001
2002 if (!pData->bTimerset) /* no timer break ? */
2003 {
2004 switch (pData->iColortype) /* determine row initialization routine */
2005 {
2006 case 0 : { /* gray */
2007 switch (pData->iBitdepth)
2008 {
2009 case 1 : {
2010 if (!pData->iInterlace)
2011 pData->fInitrowproc = (mng_fptr)init_g1_ni;
2012 else
2013 pData->fInitrowproc = (mng_fptr)init_g1_i;
2014
2015 break;
2016 }
2017 case 2 : {
2018 if (!pData->iInterlace)
2019 pData->fInitrowproc = (mng_fptr)init_g2_ni;
2020 else
2021 pData->fInitrowproc = (mng_fptr)init_g2_i;
2022
2023 break;
2024 }
2025 case 4 : {
2026 if (!pData->iInterlace)
2027 pData->fInitrowproc = (mng_fptr)init_g4_ni;
2028 else
2029 pData->fInitrowproc = (mng_fptr)init_g4_i;
2030
2031 break;
2032 }
2033 case 8 : {
2034 if (!pData->iInterlace)
2035 pData->fInitrowproc = (mng_fptr)init_g8_ni;
2036 else
2037 pData->fInitrowproc = (mng_fptr)init_g8_i;
2038
2039 break;
2040 }
2041 case 16 : {
2042 if (!pData->iInterlace)
2043 pData->fInitrowproc = (mng_fptr)init_g16_ni;
2044 else
2045 pData->fInitrowproc = (mng_fptr)init_g16_i;
2046
2047 break;
2048 }
2049 }
2050
2051 break;
2052 }
2053 case 2 : { /* rgb */
2054 switch (pData->iBitdepth)
2055 {
2056 case 8 : {
2057 if (!pData->iInterlace)
2058 pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
2059 else
2060 pData->fInitrowproc = (mng_fptr)init_rgb8_i;
2061
2062 break;
2063 }
2064 case 16 : {
2065 if (!pData->iInterlace)
2066 pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
2067 else
2068 pData->fInitrowproc = (mng_fptr)init_rgb16_i;
2069
2070 break;
2071 }
2072 }
2073
2074 break;
2075 }
2076 case 3 : { /* indexed */
2077 switch (pData->iBitdepth)
2078 {
2079 case 1 : {
2080 if (!pData->iInterlace)
2081 pData->fInitrowproc = (mng_fptr)init_idx1_ni;
2082 else
2083 pData->fInitrowproc = (mng_fptr)init_idx1_i;
2084
2085 break;
2086 }
2087 case 2 : {
2088 if (!pData->iInterlace)
2089 pData->fInitrowproc = (mng_fptr)init_idx2_ni;
2090 else
2091 pData->fInitrowproc = (mng_fptr)init_idx2_i;
2092
2093 break;
2094 }
2095 case 4 : {
2096 if (!pData->iInterlace)
2097 pData->fInitrowproc = (mng_fptr)init_idx4_ni;
2098 else
2099 pData->fInitrowproc = (mng_fptr)init_idx4_i;
2100
2101 break;
2102 }
2103 case 8 : {
2104 if (!pData->iInterlace)
2105 pData->fInitrowproc = (mng_fptr)init_idx8_ni;
2106 else
2107 pData->fInitrowproc = (mng_fptr)init_idx8_i;
2108
2109 break;
2110 }
2111 }
2112
2113 break;
2114 }
2115 case 4 : { /* gray+alpha */
2116 switch (pData->iBitdepth)
2117 {
2118 case 8 : {
2119 if (!pData->iInterlace)
2120 pData->fInitrowproc = (mng_fptr)init_ga8_ni;
2121 else
2122 pData->fInitrowproc = (mng_fptr)init_ga8_i;
2123
2124 break;
2125 }
2126 case 16 : {
2127 if (!pData->iInterlace)
2128 pData->fInitrowproc = (mng_fptr)init_ga16_ni;
2129 else
2130 pData->fInitrowproc = (mng_fptr)init_ga16_i;
2131
2132 break;
2133 }
2134 }
2135
2136 break;
2137 }
2138 case 6 : { /* rgb+alpha */
2139 switch (pData->iBitdepth)
2140 {
2141 case 8 : {
2142 if (!pData->iInterlace)
2143 pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
2144 else
2145 pData->fInitrowproc = (mng_fptr)init_rgba8_i;
2146
2147 break;
2148 }
2149 case 16 : {
2150 if (!pData->iInterlace)
2151 pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
2152 else
2153 pData->fInitrowproc = (mng_fptr)init_rgba16_i;
2154
2155 break;
2156 }
2157 }
2158
2159 break;
2160 }
2161 }
2162
2163 pData->iFilterofs = 0; /* determine filter characteristics */
2164 pData->iLevel0 = 0; /* default levels */
2165 pData->iLevel1 = 0;
2166 pData->iLevel2 = 0;
2167 pData->iLevel3 = 0;
2168 /* leveling & differing ? */
2169/* if (pData->iFilter & 0x40)
2170 {
2171 switch (pData->iColortype)
2172 {
2173 case 0 : {
2174 if (pData->iBitdepth <= 8)
2175 pData->iFilterofs = 1;
2176 else
2177 pData->iFilterofs = 2;
2178
2179 break;
2180 }
2181 case 2 : {
2182 if (pData->iBitdepth <= 8)
2183 pData->iFilterofs = 3;
2184 else
2185 pData->iFilterofs = 6;
2186
2187 break;
2188 }
2189 case 3 : {
2190 pData->iFilterofs = 1;
2191 break;
2192 }
2193 case 4 : {
2194 if (pData->iBitdepth <= 8)
2195 pData->iFilterofs = 2;
2196 else
2197 pData->iFilterofs = 4;
2198
2199 break;
2200 }
2201 case 6 : {
2202 if (pData->iBitdepth <= 8)
2203 pData->iPixelofs = 5;
2204 else
2205 pData->iFilterofs = 8;
2206
2207 break;
2208 }
2209 }
2210 } */
2211 /* no adaptive filtering ? */
2212/* if (pData->iFilter & 0x01)
2213 pData->iPixelofs = pData->iFilterofs;
2214 else */
2215 pData->iPixelofs = pData->iFilterofs + 1;
2216
2217 }
2218
2219#ifdef MNG_SUPPORT_TRACE
2220 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_END)
2221#endif
2222
2223 return MNG_NOERROR;
2224}
2225
2226/* ************************************************************************** */
2227
2228mng_retcode process_display_idat (mng_datap pData,
2229 mng_uint32 iRawlen,
2230 mng_uint8p pRawdata)
2231{
2232 mng_retcode iRetcode = MNG_NOERROR;
2233
2234#ifdef MNG_SUPPORT_TRACE
2235 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_START)
2236#endif
2237
2238 if (pData->bRestorebkgd) /* need to restore the background ? */
2239 {
2240 pData->bRestorebkgd = MNG_FALSE;
2241 iRetcode = load_bkgdlayer (pData);
2242
2243 if (iRetcode) /* on error bail out */
2244 return iRetcode;
2245
2246 if ((pData->bDisplaying) && (pData->bRunning))
2247 pData->iLayerseq++; /* and it counts as a layer then ! */
2248 }
2249
2250 if (pData->fInitrowproc) /* need to initialize row processing? */
2251 {
2252 iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
2253 pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
2254 }
2255
2256 if ((!iRetcode) && (!pData->bInflating))
2257 /* initialize inflate */
2258 iRetcode = mngzlib_inflateinit (pData);
2259
2260 if (!iRetcode) /* all ok? then inflate, my man */
2261 iRetcode = mngzlib_inflaterows (pData, iRawlen, pRawdata);
2262
2263 if (iRetcode) /* on error bail out */
2264 return iRetcode;
2265
2266#ifdef MNG_SUPPORT_TRACE
2267 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_END)
2268#endif
2269
2270 return MNG_NOERROR;
2271}
2272
2273/* ************************************************************************** */
2274
2275mng_retcode process_display_iend (mng_datap pData)
2276{
2277 mng_retcode iRetcode, iRetcode2;
2278 mng_bool bDodisplay = MNG_FALSE;
2279 mng_bool bMagnify = MNG_FALSE;
2280 mng_bool bCleanup = (mng_bool)(pData->iBreakpoint != 0);
2281
2282#ifdef MNG_SUPPORT_TRACE
2283 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_START)
2284#endif
2285
2286#ifdef MNG_INCLUDE_JNG /* progressive+alpha JNG can be displayed now */
2287 if ( (pData->bHasJHDR ) &&
2288 ( (pData->bJPEGprogressive) || (pData->bJPEGprogressive2)) &&
2289 ( (pData->eImagetype == mng_it_jng ) ||
2290 (((mng_imagep)pData->pStoreobj)->bVisible) ) &&
2291 ( (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
2292 (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) )
2293 bDodisplay = MNG_TRUE;
2294#endif
2295
2296 if ( (pData->pStoreobj) && /* on-the-fly magnification ? */
2297 ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX) ||
2298 (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY) ) )
2299 bMagnify = MNG_TRUE;
2300
2301 if ((pData->bHasBASI) || /* was it a BASI stream */
2302 (bDodisplay) || /* or should we display the JNG */
2303 (bMagnify) || /* or should we magnify it */
2304 /* or did we get broken here last time ? */
2305 ((pData->iBreakpoint) && (pData->iBreakpoint != 8)))
2306 {
2307 mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
2308
2309 if (!pImage) /* or was it object 0 ? */
2310 pImage = (mng_imagep)pData->pObjzero;
2311 /* display it now then ? */
2312 if ((pImage->bVisible) && (pImage->bViewable))
2313 { /* ok, so do it */
2314 iRetcode = display_image (pData, pImage, bDodisplay);
2315
2316 if (iRetcode) /* on error bail out */
2317 return iRetcode;
2318
2319 if (pData->bTimerset) /* timer break ? */
2320 pData->iBreakpoint = 6;
2321 }
2322 }
2323 else
2324 if ((pData->bHasDHDR) || /* was it a DHDR stream */
2325 (pData->iBreakpoint == 8)) /* or did we get broken here last time ? */
2326 {
2327 mng_imagep pImage = (mng_imagep)pData->pDeltaImage;
2328
2329 if (!pData->iBreakpoint)
2330 { /* perform the delta operations needed */
2331 iRetcode = execute_delta_image (pData, pImage, (mng_imagep)pData->pObjzero);
2332
2333 if (iRetcode) /* on error bail out */
2334 return iRetcode;
2335 }
2336 /* display it now then ? */
2337 if ((pImage->bVisible) && (pImage->bViewable))
2338 { /* ok, so do it */
2339 iRetcode = display_image (pData, pImage, MNG_FALSE);
2340
2341 if (iRetcode) /* on error bail out */
2342 return iRetcode;
2343
2344 if (pData->bTimerset) /* timer break ? */
2345 pData->iBreakpoint = 8;
2346 }
2347 }
2348
2349 if (!pData->bTimerset) /* can we continue ? */
2350 {
2351 pData->iBreakpoint = 0; /* clear this flag now ! */
2352 /* cleanup object 0 */
2353 reset_object_details (pData, (mng_imagep)pData->pObjzero,
2354 0, 0, 0, 0, 0, 0, 0, MNG_TRUE);
2355
2356 if (pData->bInflating) /* if we've been inflating */
2357 { /* cleanup row-processing, */
2358 iRetcode = cleanup_rowproc (pData);
2359 /* also cleanup inflate! */
2360 iRetcode2 = mngzlib_inflatefree (pData);
2361
2362 if (iRetcode) /* on error bail out */
2363 return iRetcode;
2364 if (iRetcode2)
2365 return iRetcode2;
2366 }
2367
2368#ifdef MNG_INCLUDE_JNG
2369 if (pData->bJPEGdecompress) /* if we've been decompressing JDAT */
2370 { /* cleanup row-processing, */
2371 iRetcode = cleanup_rowproc (pData);
2372 /* also cleanup decompress! */
2373 iRetcode2 = mngjpeg_decompressfree (pData);
2374
2375 if (iRetcode) /* on error bail out */
2376 return iRetcode;
2377 if (iRetcode2)
2378 return iRetcode2;
2379 }
2380
2381 if (pData->bJPEGdecompress2) /* if we've been decompressing JDAA */
2382 { /* cleanup row-processing, */
2383 iRetcode = cleanup_rowproc (pData);
2384 /* also cleanup decompress! */
2385 iRetcode2 = mngjpeg_decompressfree2 (pData);
2386
2387 if (iRetcode) /* on error bail out */
2388 return iRetcode;
2389 if (iRetcode2)
2390 return iRetcode2;
2391 }
2392#endif
2393
2394 if (bCleanup) /* if we got broken last time we need to cleanup */
2395 {
2396 pData->bHasIHDR = MNG_FALSE; /* IEND signals the end for most ... */
2397 pData->bHasBASI = MNG_FALSE;
2398 pData->bHasDHDR = MNG_FALSE;
2399#ifdef MNG_INCLUDE_JNG
2400 pData->bHasJHDR = MNG_FALSE;
2401 pData->bHasJSEP = MNG_FALSE;
2402 pData->bHasJDAA = MNG_FALSE;
2403 pData->bHasJDAT = MNG_FALSE;
2404#endif
2405 pData->bHasPLTE = MNG_FALSE;
2406 pData->bHasTRNS = MNG_FALSE;
2407 pData->bHasGAMA = MNG_FALSE;
2408 pData->bHasCHRM = MNG_FALSE;
2409 pData->bHasSRGB = MNG_FALSE;
2410 pData->bHasICCP = MNG_FALSE;
2411 pData->bHasBKGD = MNG_FALSE;
2412 pData->bHasIDAT = MNG_FALSE;
2413 }
2414 /* if the image was displayed on the fly, */
2415 /* we'll have to make the app refresh */
2416 if ((pData->eImagetype != mng_it_mng) && (pData->fDisplayrow))
2417 pData->bNeedrefresh = MNG_TRUE;
2418
2419 }
2420
2421#ifdef MNG_SUPPORT_TRACE
2422 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_END)
2423#endif
2424
2425 return MNG_NOERROR;
2426}
2427
2428/* ************************************************************************** */
2429
2430mng_retcode process_display_mend (mng_datap pData)
2431{
2432#ifdef MNG_SUPPORT_TRACE
2433 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START)
2434#endif
2435 /* TERM processed ? */
2436 if ((pData->bDisplaying) && (pData->bRunning) &&
2437 (pData->bHasTERM) && (pData->pTermaniobj))
2438 {
2439 mng_retcode iRetcode;
2440 mng_ani_termp pTERM;
2441 /* get the right animation object ! */
2442 pTERM = (mng_ani_termp)pData->pTermaniobj;
2443
2444 pData->iIterations++; /* increase iteration count */
2445
2446 switch (pTERM->iTermaction) /* determine what to do! */
2447 {
2448 case 0 : { /* show last frame indefinitly */
2449 break; /* piece of cake, that is... */
2450 }
2451
2452 case 1 : { /* cease displaying anything */
2453 pData->bFrameclipping = MNG_FALSE;
2454 load_bkgdlayer (pData);
2455 break;
2456 }
2457
2458 case 2 : { /* show first image after TERM */
2459
2460 /* TODO: something */
2461
2462 break;
2463 }
2464
2465 case 3 : { /* repeat */
2466 if ((pTERM->iItermax) && (pTERM->iItermax < 0x7FFFFFFF))
2467 pTERM->iItermax--;
2468
2469 if (pTERM->iItermax) /* go back to TERM ? */
2470 { /* restore to initial or SAVE state */
2471 iRetcode = restore_state (pData);
2472
2473 if (iRetcode) /* on error bail out */
2474 return iRetcode;
2475 /* notify the app ? */
2476 if (pData->fProcessmend)
2477 {
2478 mng_bool bOke = pData->fProcessmend ((mng_handle)pData,
2479 pData->iIterations,
2480 pTERM->iItermax);
2481 if (!bOke) /* stop here and now ? */
2482 break;
2483 }
2484 /* restart from TERM chunk */
2485 pData->pCurraniobj = pTERM;
2486
2487 if (pTERM->iDelay) /* set the delay (?) */
2488 {
2489 mng_uint32 iWaitfor = 1000;
2490 /* what are we aiming for */
2491 if (pData->iTicks)
2492 { /* honor speed modifier */
2493 switch (pData->iSpeed)
2494 {
2495 case mng_st_fast :
2496 {
2497 iWaitfor = (mng_uint32)(( 500 * pTERM->iDelay) / pData->iTicks);
2498 break;
2499 }
2500 case mng_st_slow :
2501 {
2502 iWaitfor = (mng_uint32)((3000 * pTERM->iDelay) / pData->iTicks);
2503 break;
2504 }
2505 case mng_st_slowest :
2506 {
2507 iWaitfor = (mng_uint32)((8000 * pTERM->iDelay) / pData->iTicks);
2508 break;
2509 }
2510 default :
2511 {
2512 iWaitfor = (mng_uint32)((1000 * pTERM->iDelay) / pData->iTicks);
2513 }
2514 }
2515 }
2516
2517 iRetcode = display_progressive_refresh (pData, iWaitfor);
2518
2519 if (iRetcode) /* on error bail out */
2520 return iRetcode;
2521 }
2522 }
2523 else
2524 {
2525 switch (pTERM->iIteraction)
2526 {
2527 case 0 : { /* show last frame indefinitly */
2528 break; /* piece of cake, that is... */
2529 }
2530
2531 case 1 : { /* cease displaying anything */
2532 pData->bFrameclipping = MNG_FALSE;
2533 load_bkgdlayer (pData);
2534 break;
2535 }
2536
2537 case 2 : { /* show first image after TERM */
2538
2539 /* TODO: something */
2540
2541 break;
2542 }
2543
2544 }
2545 }
2546
2547 break;
2548 }
2549
2550 }
2551 }
2552
2553 if (!pData->pCurraniobj) /* always let the app refresh at the end ! */
2554 pData->bNeedrefresh = MNG_TRUE;
2555
2556#ifdef MNG_SUPPORT_TRACE
2557 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END)
2558#endif
2559
2560 return MNG_NOERROR;
2561}
2562
2563/* ************************************************************************** */
2564
2565mng_retcode process_display_defi (mng_datap pData)
2566{
2567 mng_imagep pImage;
2568
2569#ifdef MNG_SUPPORT_TRACE
2570 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_START)
2571#endif
2572
2573 if (!pData->iDEFIobjectid) /* object id=0 ? */
2574 {
2575 pImage = (mng_imagep)pData->pObjzero;
2576
2577 if (pData->bDEFIhasdonotshow)
2578 pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
2579
2580 if (pData->bDEFIhasloca)
2581 {
2582 pImage->iPosx = pData->iDEFIlocax;
2583 pImage->iPosy = pData->iDEFIlocay;
2584 }
2585
2586 if (pData->bDEFIhasclip)
2587 {
2588 pImage->bClipped = pData->bDEFIhasclip;
2589 pImage->iClipl = pData->iDEFIclipl;
2590 pImage->iClipr = pData->iDEFIclipr;
2591 pImage->iClipt = pData->iDEFIclipt;
2592 pImage->iClipb = pData->iDEFIclipb;
2593 }
2594
2595 pData->pCurrentobj = 0; /* not a real object ! */
2596 }
2597 else
2598 { /* already exists ? */
2599 pImage = (mng_imagep)find_imageobject (pData, pData->iDEFIobjectid);
2600
2601 if (!pImage) /* if not; create new */
2602 {
2603 mng_retcode iRetcode = create_imageobject (pData, pData->iDEFIobjectid,
2604 (mng_bool)(pData->iDEFIconcrete == 1),
2605 (mng_bool)(pData->iDEFIdonotshow == 0),
2606 MNG_FALSE, 0, 0, 0, 0, 0, 0, 0,
2607 pData->iDEFIlocax, pData->iDEFIlocay,
2608 pData->bDEFIhasclip,
2609 pData->iDEFIclipl, pData->iDEFIclipr,
2610 pData->iDEFIclipt, pData->iDEFIclipb,
2611 &pImage);
2612
2613 if (iRetcode) /* on error bail out */
2614 return iRetcode;
2615 }
2616 else
2617 { /* exists; then set new info */
2618 if (pData->bDEFIhasdonotshow)
2619 pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
2620
2621 pImage->bViewable = MNG_FALSE;
2622
2623 if (pData->bDEFIhasloca)
2624 {
2625 pImage->iPosx = pData->iDEFIlocax;
2626 pImage->iPosy = pData->iDEFIlocay;
2627 }
2628
2629 if (pData->bDEFIhasclip)
2630 {
2631 pImage->bClipped = pData->bDEFIhasclip;
2632 pImage->iClipl = pData->iDEFIclipl;
2633 pImage->iClipr = pData->iDEFIclipr;
2634 pImage->iClipt = pData->iDEFIclipt;
2635 pImage->iClipb = pData->iDEFIclipb;
2636 }
2637
2638 if (pData->bDEFIhasconcrete)
2639 pImage->pImgbuf->bConcrete = (mng_bool)(pData->iDEFIconcrete == 1);
2640 }
2641
2642 pData->pCurrentobj = pImage; /* others may want to know this */
2643 }
2644
2645#ifdef MNG_SUPPORT_TRACE
2646 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_END)
2647#endif
2648
2649 return MNG_NOERROR;
2650}
2651
2652/* ************************************************************************** */
2653
2654mng_retcode process_display_basi (mng_datap pData,
2655 mng_uint16 iRed,
2656 mng_uint16 iGreen,
2657 mng_uint16 iBlue,
2658 mng_bool bHasalpha,
2659 mng_uint16 iAlpha,
2660 mng_uint8 iViewable)
2661{ /* address the current "object" if any */
2662 mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
2663 mng_uint8p pWork;
2664 mng_uint32 iX;
2665 mng_imagedatap pBuf;
2666 mng_retcode iRetcode;
2667
2668#ifdef MNG_SUPPORT_TRACE
2669 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_START)
2670#endif
2671
2672 if (!pImage) /* or is it an "on-the-fly" image ? */
2673 pImage = (mng_imagep)pData->pObjzero;
2674 /* address the object-buffer */
2675 pBuf = pImage->pImgbuf;
2676
2677 pData->fDisplayrow = MNG_NULL; /* do nothing by default */
2678 pData->fCorrectrow = MNG_NULL;
2679 pData->fStorerow = MNG_NULL;
2680 pData->fProcessrow = MNG_NULL;
2681 /* set parms now that they're known */
2682 iRetcode = reset_object_details (pData, pImage, pData->iDatawidth,
2683 pData->iDataheight, pData->iBitdepth,
2684 pData->iColortype, pData->iCompression,
2685 pData->iFilter, pData->iInterlace, MNG_FALSE);
2686 if (iRetcode) /* on error bail out */
2687 return iRetcode;
2688 /* save the viewable flag */
2689 pImage->bViewable = (mng_bool)(iViewable == 1);
2690 pBuf->bViewable = pImage->bViewable;
2691 pData->pStoreobj = pImage; /* let row-routines know which object */
2692
2693 pWork = pBuf->pImgdata; /* fill the object-buffer with the specified
2694 "color" sample */
2695 switch (pData->iColortype) /* depending on color_type & bit_depth */
2696 {
2697 case 0 : { /* gray */
2698 if (pData->iBitdepth == 16)
2699 {
2700 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2701 {
2702 mng_put_uint16 (pWork, iRed);
2703 pWork += 2;
2704 }
2705 }
2706 else
2707 {
2708 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2709 {
2710 *pWork = (mng_uint8)iRed;
2711 pWork++;
2712 }
2713 }
2714 /* force tRNS ? */
2715 if ((bHasalpha) && (!iAlpha))
2716 {
2717 pBuf->bHasTRNS = MNG_TRUE;
2718 pBuf->iTRNSgray = iRed;
2719 }
2720
2721 break;
2722 }
2723
2724 case 2 : { /* rgb */
2725 if (pData->iBitdepth == 16)
2726 {
2727 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2728 {
2729 mng_put_uint16 (pWork, iRed );
2730 mng_put_uint16 (pWork+2, iGreen);
2731 mng_put_uint16 (pWork+4, iBlue );
2732 pWork += 6;
2733 }
2734 }
2735 else
2736 {
2737 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2738 {
2739 *pWork = (mng_uint8)iRed;
2740 *(pWork+1) = (mng_uint8)iGreen;
2741 *(pWork+2) = (mng_uint8)iBlue;
2742 pWork += 3;
2743 }
2744 }
2745 /* force tRNS ? */
2746 if ((bHasalpha) && (!iAlpha))
2747 {
2748 pBuf->bHasTRNS = MNG_TRUE;
2749 pBuf->iTRNSred = iRed;
2750 pBuf->iTRNSgreen = iGreen;
2751 pBuf->iTRNSblue = iBlue;
2752 }
2753
2754 break;
2755 }
2756
2757 case 3 : { /* indexed */
2758 pBuf->bHasPLTE = MNG_TRUE;
2759
2760 switch (pData->iBitdepth)
2761 {
2762 case 1 : { pBuf->iPLTEcount = 2; break; }
2763 case 2 : { pBuf->iPLTEcount = 4; break; }
2764 case 4 : { pBuf->iPLTEcount = 16; break; }
2765 case 8 : { pBuf->iPLTEcount = 256; break; }
2766 default : { pBuf->iPLTEcount = 1; break; }
2767 }
2768
2769 pBuf->aPLTEentries [0].iRed = (mng_uint8)iRed;
2770 pBuf->aPLTEentries [0].iGreen = (mng_uint8)iGreen;
2771 pBuf->aPLTEentries [0].iBlue = (mng_uint8)iBlue;
2772
2773 for (iX = 1; iX < pBuf->iPLTEcount; iX++)
2774 {
2775 pBuf->aPLTEentries [iX].iRed = 0;
2776 pBuf->aPLTEentries [iX].iGreen = 0;
2777 pBuf->aPLTEentries [iX].iBlue = 0;
2778 }
2779 /* force tRNS ? */
2780 if ((bHasalpha) && (iAlpha < 255))
2781 {
2782 pBuf->bHasTRNS = MNG_TRUE;
2783 pBuf->iTRNScount = 1;
2784 pBuf->aTRNSentries [0] = (mng_uint8)iAlpha;
2785 }
2786
2787 break;
2788 }
2789
2790 case 4 : { /* gray+alpha */
2791 if (pData->iBitdepth == 16)
2792 {
2793 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2794 {
2795 mng_put_uint16 (pWork, iRed);
2796 mng_put_uint16 (pWork+2, iAlpha);
2797 pWork += 4;
2798 }
2799 }
2800 else
2801 {
2802 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2803 {
2804 *pWork = (mng_uint8)iRed;
2805 *(pWork+1) = (mng_uint8)iAlpha;
2806 pWork += 2;
2807 }
2808 }
2809
2810 break;
2811 }
2812
2813 case 6 : { /* rgb+alpha */
2814 if (pData->iBitdepth == 16)
2815 {
2816 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2817 {
2818 mng_put_uint16 (pWork, iRed);
2819 mng_put_uint16 (pWork+2, iGreen);
2820 mng_put_uint16 (pWork+4, iBlue);
2821 mng_put_uint16 (pWork+6, iAlpha);
2822 pWork += 8;
2823 }
2824 }
2825 else
2826 {
2827 for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
2828 {
2829 *pWork = (mng_uint8)iRed;
2830 *(pWork+1) = (mng_uint8)iGreen;
2831 *(pWork+2) = (mng_uint8)iBlue;
2832 *(pWork+3) = (mng_uint8)iAlpha;
2833 pWork += 4;
2834 }
2835 }
2836
2837 break;
2838 }
2839
2840 }
2841
2842 switch (pData->iColortype) /* determine row initialization routine */
2843 { /* just to accomodate IDAT if it arrives */
2844 case 0 : { /* gray */
2845 switch (pData->iBitdepth)
2846 {
2847 case 1 : {
2848 if (!pData->iInterlace)
2849 pData->fInitrowproc = (mng_fptr)init_g1_ni;
2850 else
2851 pData->fInitrowproc = (mng_fptr)init_g1_i;
2852
2853 break;
2854 }
2855 case 2 : {
2856 if (!pData->iInterlace)
2857 pData->fInitrowproc = (mng_fptr)init_g2_ni;
2858 else
2859 pData->fInitrowproc = (mng_fptr)init_g2_i;
2860
2861 break;
2862 }
2863 case 4 : {
2864 if (!pData->iInterlace)
2865 pData->fInitrowproc = (mng_fptr)init_g4_ni;
2866 else
2867 pData->fInitrowproc = (mng_fptr)init_g4_i;
2868
2869 break;
2870 }
2871 case 8 : {
2872 if (!pData->iInterlace)
2873 pData->fInitrowproc = (mng_fptr)init_g8_ni;
2874 else
2875 pData->fInitrowproc = (mng_fptr)init_g8_i;
2876
2877 break;
2878 }
2879 case 16 : {
2880 if (!pData->iInterlace)
2881 pData->fInitrowproc = (mng_fptr)init_g16_ni;
2882 else
2883 pData->fInitrowproc = (mng_fptr)init_g16_i;
2884
2885 break;
2886 }
2887 }
2888
2889 break;
2890 }
2891 case 2 : { /* rgb */
2892 switch (pData->iBitdepth)
2893 {
2894 case 8 : {
2895 if (!pData->iInterlace)
2896 pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
2897 else
2898 pData->fInitrowproc = (mng_fptr)init_rgb8_i;
2899
2900 break;
2901 }
2902 case 16 : {
2903 if (!pData->iInterlace)
2904 pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
2905 else
2906 pData->fInitrowproc = (mng_fptr)init_rgb16_i;
2907
2908 break;
2909 }
2910 }
2911
2912 break;
2913 }
2914 case 3 : { /* indexed */
2915 switch (pData->iBitdepth)
2916 {
2917 case 1 : {
2918 if (!pData->iInterlace)
2919 pData->fInitrowproc = (mng_fptr)init_idx1_ni;
2920 else
2921 pData->fInitrowproc = (mng_fptr)init_idx1_i;
2922
2923 break;
2924 }
2925 case 2 : {
2926 if (!pData->iInterlace)
2927 pData->fInitrowproc = (mng_fptr)init_idx2_ni;
2928 else
2929 pData->fInitrowproc = (mng_fptr)init_idx2_i;
2930
2931 break;
2932 }
2933 case 4 : {
2934 if (!pData->iInterlace)
2935 pData->fInitrowproc = (mng_fptr)init_idx4_ni;
2936 else
2937 pData->fInitrowproc = (mng_fptr)init_idx4_i;
2938
2939 break;
2940 }
2941 case 8 : {
2942 if (!pData->iInterlace)
2943 pData->fInitrowproc = (mng_fptr)init_idx8_ni;
2944 else
2945 pData->fInitrowproc = (mng_fptr)init_idx8_i;
2946
2947 break;
2948 }
2949 }
2950
2951 break;
2952 }
2953 case 4 : { /* gray+alpha */
2954 switch (pData->iBitdepth)
2955 {
2956 case 8 : {
2957 if (!pData->iInterlace)
2958 pData->fInitrowproc = (mng_fptr)init_ga8_ni;
2959 else
2960 pData->fInitrowproc = (mng_fptr)init_ga8_i;
2961
2962 break;
2963 }
2964 case 16 : {
2965 if (!pData->iInterlace)
2966 pData->fInitrowproc = (mng_fptr)init_ga16_ni;
2967 else
2968 pData->fInitrowproc = (mng_fptr)init_ga16_i;
2969
2970 break;
2971 }
2972 }
2973
2974 break;
2975 }
2976 case 6 : { /* rgb+alpha */
2977 switch (pData->iBitdepth)
2978 {
2979 case 8 : {
2980 if (!pData->iInterlace)
2981 pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
2982 else
2983 pData->fInitrowproc = (mng_fptr)init_rgba8_i;
2984
2985 break;
2986 }
2987 case 16 : {
2988 if (!pData->iInterlace)
2989 pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
2990 else
2991 pData->fInitrowproc = (mng_fptr)init_rgba16_i;
2992
2993 break;
2994 }
2995 }
2996
2997 break;
2998 }
2999 }
3000
3001 pData->iFilterofs = 0; /* determine filter characteristics */
3002 pData->iLevel0 = 0; /* default levels */
3003 pData->iLevel1 = 0;
3004 pData->iLevel2 = 0;
3005 pData->iLevel3 = 0;
3006 /* leveling & differing ? */
3007/* if (pData->iFilter & 0x40)
3008 {
3009 switch (pData->iColortype)
3010 {
3011 case 0 : {
3012 if (pData->iBitdepth <= 8)
3013 pData->iFilterofs = 1;
3014 else
3015 pData->iFilterofs = 2;
3016
3017 break;
3018 }
3019 case 2 : {
3020 if (pData->iBitdepth <= 8)
3021 pData->iFilterofs = 3;
3022 else
3023 pData->iFilterofs = 6;
3024
3025 break;
3026 }
3027 case 3 : {
3028 pData->iFilterofs = 1;
3029 break;
3030 }
3031 case 4 : {
3032 if (pData->iBitdepth <= 8)
3033 pData->iFilterofs = 2;
3034 else
3035 pData->iFilterofs = 4;
3036
3037 break;
3038 }
3039 case 6 : {
3040 if (pData->iBitdepth <= 8)
3041 pData->iPixelofs = 5;
3042 else
3043 pData->iFilterofs = 8;
3044
3045 break;
3046 }
3047 }
3048 } */
3049 /* no adaptive filtering ? */
3050/* if (pData->iFilter & 0x01)
3051 pData->iPixelofs = pData->iFilterofs;
3052 else */
3053 pData->iPixelofs = pData->iFilterofs + 1;
3054
3055#ifdef MNG_SUPPORT_TRACE
3056 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_END)
3057#endif
3058
3059 return MNG_NOERROR;
3060}
3061
3062/* ************************************************************************** */
3063
3064mng_retcode process_display_clon (mng_datap pData,
3065 mng_uint16 iSourceid,
3066 mng_uint16 iCloneid,
3067 mng_uint8 iClonetype,
3068 mng_bool bHasdonotshow,
3069 mng_uint8 iDonotshow,
3070 mng_uint8 iConcrete,
3071 mng_bool bHasloca,
3072 mng_uint8 iLocationtype,
3073 mng_int32 iLocationx,
3074 mng_int32 iLocationy)
3075{
3076 mng_imagep pSource, pClone;
3077 mng_bool bVisible, bAbstract;
3078 mng_retcode iRetcode = MNG_NOERROR;
3079
3080#ifdef MNG_SUPPORT_TRACE
3081 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START)
3082#endif
3083 /* locate the source object first */
3084 pSource = find_imageobject (pData, iSourceid);
3085 /* check if the clone exists */
3086 pClone = find_imageobject (pData, iCloneid);
3087
3088 if (!pSource) /* source must exist ! */
3089 MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
3090
3091 if (pClone) /* clone must not exist ! */
3092 MNG_ERROR (pData, MNG_OBJECTEXISTS);
3093
3094 if (bHasdonotshow) /* DoNotShow flag filled ? */
3095 bVisible = (mng_bool)(iDonotshow == 0);
3096 else
3097 bVisible = pSource->bVisible;
3098
3099 bAbstract = (mng_bool)(iConcrete == 1);
3100
3101 switch (iClonetype) /* determine action to take */
3102 {
3103 case 0 : { /* full clone */
3104 iRetcode = clone_imageobject (pData, iCloneid, MNG_FALSE,
3105 bVisible, bAbstract, bHasloca,
3106 iLocationtype, iLocationx, iLocationy,
3107 pSource, &pClone);
3108 break;
3109 }
3110
3111 case 1 : { /* partial clone */
3112 iRetcode = clone_imageobject (pData, iCloneid, MNG_TRUE,
3113 bVisible, bAbstract, bHasloca,
3114 iLocationtype, iLocationx, iLocationy,
3115 pSource, &pClone);
3116 break;
3117 }
3118
3119 case 2 : { /* renumber object */
3120 iRetcode = renum_imageobject (pData, pSource, iCloneid,
3121 bVisible, bAbstract, bHasloca,
3122 iLocationtype, iLocationx, iLocationy);
3123 pClone = pSource;
3124 break;
3125 }
3126
3127 }
3128
3129 if (iRetcode) /* on error bail out */
3130 return iRetcode;
3131
3132 /* display on the fly ? */
3133 if ((pClone->bViewable) && (pClone->bVisible))
3134 {
3135 pData->pLastclone = pClone; /* remember in case of timer break ! */
3136 /* display it */
3137 display_image (pData, pClone, MNG_FALSE);
3138
3139 if (pData->bTimerset) /* timer break ? */
3140 pData->iBreakpoint = 5;
3141 }
3142
3143#ifdef MNG_SUPPORT_TRACE
3144 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END)
3145#endif
3146
3147 return MNG_NOERROR;
3148}
3149
3150/* ************************************************************************** */
3151
3152mng_retcode process_display_clon2 (mng_datap pData)
3153{
3154#ifdef MNG_SUPPORT_TRACE
3155 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START)
3156#endif
3157 /* only called after timer break ! */
3158 display_image (pData, (mng_imagep)pData->pLastclone, MNG_FALSE);
3159 pData->iBreakpoint = 0;
3160
3161#ifdef MNG_SUPPORT_TRACE
3162 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END)
3163#endif
3164
3165 return MNG_NOERROR;
3166}
3167
3168/* ************************************************************************** */
3169
3170mng_retcode process_display_disc (mng_datap pData,
3171 mng_uint32 iCount,
3172 mng_uint16p pIds)
3173{
3174 mng_uint32 iX;
3175 mng_imagep pImage;
3176 mng_uint32 iRetcode;
3177#ifdef MNG_SUPPORT_TRACE
3178 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_START)
3179#endif
3180
3181 if (iCount) /* specific list ? */
3182 {
3183 mng_uint16p pWork = pIds;
3184
3185 for (iX = 0; iX < iCount; iX++) /* iterate the list */
3186 {
3187 pImage = find_imageobject (pData, *pWork++);
3188
3189 if (pImage) /* found the object ? */
3190 { /* then drop it */
3191 iRetcode = free_imageobject (pData, pImage);
3192
3193 if (iRetcode) /* on error bail out */
3194 return iRetcode;
3195 }
3196 }
3197 }
3198 else /* empty: drop all un-frozen objects */
3199 {
3200 mng_imagep pNext = (mng_imagep)pData->pFirstimgobj;
3201
3202 while (pNext) /* any left ? */
3203 {
3204 pImage = pNext;
3205 pNext = pImage->sHeader.pNext;
3206
3207 if (!pImage->bFrozen) /* not frozen ? */
3208 { /* then drop it */
3209 iRetcode = free_imageobject (pData, pImage);
3210
3211 if (iRetcode) /* on error bail out */
3212 return iRetcode;
3213 }
3214 }
3215 }
3216
3217#ifdef MNG_SUPPORT_TRACE
3218 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_END)
3219#endif
3220
3221 return MNG_NOERROR;
3222}
3223
3224/* ************************************************************************** */
3225
3226mng_retcode process_display_fram (mng_datap pData,
3227 mng_uint8 iFramemode,
3228 mng_uint8 iChangedelay,
3229 mng_uint32 iDelay,
3230 mng_uint8 iChangetimeout,
3231 mng_uint32 iTimeout,
3232 mng_uint8 iChangeclipping,
3233 mng_uint8 iCliptype,
3234 mng_int32 iClipl,
3235 mng_int32 iClipr,
3236 mng_int32 iClipt,
3237 mng_int32 iClipb)
3238{
3239 mng_retcode iRetcode;
3240
3241#ifdef MNG_SUPPORT_TRACE
3242 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START)
3243#endif
3244 /* advance a frame then */
3245 iRetcode = next_frame (pData, iFramemode, iChangedelay, iDelay,
3246 iChangetimeout, iTimeout, iChangeclipping,
3247 iCliptype, iClipl, iClipr, iClipt, iClipb);
3248
3249 if (pData->bTimerset) /* timer break ? */
3250 pData->iBreakpoint = 1;
3251
3252#ifdef MNG_SUPPORT_TRACE
3253 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END)
3254#endif
3255
3256 return iRetcode;
3257}
3258
3259/* ************************************************************************** */
3260
3261mng_retcode process_display_fram2 (mng_datap pData)
3262{
3263 mng_retcode iRetcode;
3264
3265#ifdef MNG_SUPPORT_TRACE
3266 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START)
3267#endif
3268 /* again; after the break */
3269 iRetcode = next_frame (pData, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
3270 pData->iBreakpoint = 0; /* not again! */
3271
3272#ifdef MNG_SUPPORT_TRACE
3273 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END)
3274#endif
3275
3276 return iRetcode;
3277}
3278
3279/* ************************************************************************** */
3280
3281mng_retcode process_display_move (mng_datap pData,
3282 mng_uint16 iFromid,
3283 mng_uint16 iToid,
3284 mng_uint8 iMovetype,
3285 mng_int32 iMovex,
3286 mng_int32 iMovey)
3287{
3288 mng_uint16 iX;
3289 mng_imagep pImage;
3290
3291#ifdef MNG_SUPPORT_TRACE
3292 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_START)
3293#endif
3294 /* iterate the list */
3295 for (iX = iFromid; iX <= iToid; iX++)
3296 {
3297 if (!iX) /* object id=0 ? */
3298 pImage = (mng_imagep)pData->pObjzero;
3299 else
3300 pImage = find_imageobject (pData, iX);
3301
3302 if (pImage) /* object exists ? */
3303 {
3304 switch (iMovetype)
3305 {
3306 case 0 : { /* absolute */
3307 pImage->iPosx = iMovex;
3308 pImage->iPosy = iMovey;
3309 break;
3310 }
3311 case 1 : { /* relative */
3312 pImage->iPosx = pImage->iPosx + iMovex;
3313 pImage->iPosy = pImage->iPosy + iMovey;
3314 break;
3315 }
3316 }
3317 }
3318 }
3319
3320#ifdef MNG_SUPPORT_TRACE
3321 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_END)
3322#endif
3323
3324 return MNG_NOERROR;
3325}
3326
3327/* ************************************************************************** */
3328
3329mng_retcode process_display_clip (mng_datap pData,
3330 mng_uint16 iFromid,
3331 mng_uint16 iToid,
3332 mng_uint8 iCliptype,
3333 mng_int32 iClipl,
3334 mng_int32 iClipr,
3335 mng_int32 iClipt,
3336 mng_int32 iClipb)
3337{
3338 mng_uint16 iX;
3339 mng_imagep pImage;
3340
3341#ifdef MNG_SUPPORT_TRACE
3342 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_START)
3343#endif
3344 /* iterate the list */
3345 for (iX = iFromid; iX <= iToid; iX++)
3346 {
3347 if (!iX) /* object id=0 ? */
3348 pImage = (mng_imagep)pData->pObjzero;
3349 else
3350 pImage = find_imageobject (pData, iX);
3351
3352 if (pImage) /* object exists ? */
3353 {
3354 switch (iCliptype)
3355 {
3356 case 0 : { /* absolute */
3357 pImage->bClipped = MNG_TRUE;
3358 pImage->iClipl = iClipl;
3359 pImage->iClipr = iClipr;
3360 pImage->iClipt = iClipt;
3361 pImage->iClipb = iClipb;
3362 break;
3363 }
3364 case 1 : { /* relative */
3365 pImage->bClipped = MNG_TRUE;
3366 pImage->iClipl = pImage->iClipl + iClipl;
3367 pImage->iClipr = pImage->iClipr + iClipr;
3368 pImage->iClipt = pImage->iClipt + iClipt;
3369 pImage->iClipb = pImage->iClipb + iClipb;
3370 break;
3371 }
3372 }
3373 }
3374 }
3375
3376#ifdef MNG_SUPPORT_TRACE
3377 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_END)
3378#endif
3379
3380 return MNG_NOERROR;
3381}
3382
3383/* ************************************************************************** */
3384
3385mng_retcode process_display_show (mng_datap pData)
3386{
3387 mng_int16 iX, iS, iFrom, iTo;
3388 mng_imagep pImage;
3389
3390#ifdef MNG_SUPPORT_TRACE
3391 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_START)
3392#endif
3393
3394 /* TODO: optimization for the cases where "abs (iTo - iFrom)" is rather high;
3395 especially where ((iFrom==1) && (iTo==65535)); eg. an empty SHOW !!! */
3396
3397 if (pData->iBreakpoint == 3) /* previously broken during cycle-mode ? */
3398 {
3399 pImage = find_imageobject (pData, pData->iSHOWnextid);
3400
3401 if (pImage) /* still there ? */
3402 display_image (pData, pImage, MNG_FALSE);
3403
3404 pData->iBreakpoint = 0; /* let's not go through this again! */
3405 }
3406 else
3407 {
3408 if (pData->iBreakpoint) /* previously broken at other point ? */
3409 { /* restore last parms */
3410 iFrom = (mng_int16)pData->iSHOWfromid;
3411 iTo = (mng_int16)pData->iSHOWtoid;
3412 iX = (mng_int16)pData->iSHOWnextid;
3413 iS = (mng_int16)pData->iSHOWskip;
3414 }
3415 else
3416 { /* regular sequence ? */
3417 if (pData->iSHOWtoid >= pData->iSHOWfromid)
3418 iS = 1;
3419 else /* reverse sequence ! */
3420 iS = -1;
3421
3422 iFrom = (mng_int16)pData->iSHOWfromid;
3423 iTo = (mng_int16)pData->iSHOWtoid;
3424 iX = iFrom;
3425
3426 pData->iSHOWfromid = (mng_uint16)iFrom;
3427 pData->iSHOWtoid = (mng_uint16)iTo;
3428 pData->iSHOWskip = iS;
3429 }
3430 /* cycle mode ? */
3431 if ((pData->iSHOWmode == 6) || (pData->iSHOWmode == 7))
3432 {
3433 mng_uint16 iTrigger = 0;
3434 mng_uint16 iFound = 0;
3435 mng_uint16 iPass = 0;
3436 mng_imagep pFound = 0;
3437
3438 do
3439 {
3440 iPass++; /* lets prevent endless loops when there
3441 are no potential candidates in the list! */
3442
3443 if (iS > 0) /* forward ? */
3444 {
3445 for (iX = iFrom; iX <= iTo; iX += iS)
3446 {
3447 pImage = find_imageobject (pData, (mng_uint16)iX);
3448
3449 if (pImage) /* object exists ? */
3450 {
3451 if (iFound) /* already found a candidate ? */
3452 pImage->bVisible = MNG_FALSE;
3453 else
3454 if (iTrigger) /* found the trigger ? */
3455 {
3456 pImage->bVisible = MNG_TRUE;
3457 iFound = iX;
3458 pFound = pImage;
3459 }
3460 else
3461 if (pImage->bVisible) /* ok, this is the trigger */
3462 {
3463 pImage->bVisible = MNG_FALSE;
3464 iTrigger = iX;
3465 }
3466 }
3467 }
3468 }
3469 else
3470 {
3471 for (iX = iFrom; iX >= iTo; iX += iS)
3472 {
3473 pImage = find_imageobject (pData, (mng_uint16)iX);
3474
3475 if (pImage) /* object exists ? */
3476 {
3477 if (iFound) /* already found a candidate ? */
3478 pImage->bVisible = MNG_FALSE;
3479 else
3480 if (iTrigger) /* found the trigger ? */
3481 {
3482 pImage->bVisible = MNG_TRUE;
3483 iFound = iX;
3484 pFound = pImage;
3485 }
3486 else
3487 if (pImage->bVisible) /* ok, this is the trigger */
3488 {
3489 pImage->bVisible = MNG_FALSE;
3490 iTrigger = iX;
3491 }
3492 }
3493 }
3494 }
3495
3496 if (!iTrigger) /* did not find a trigger ? */
3497 iTrigger = 1; /* then fake it so the first image
3498 gets nominated */
3499 } /* cycle back to beginning ? */
3500 while ((iPass < 2) && (iTrigger) && (!iFound));
3501
3502 pData->iBreakpoint = 0; /* just a sanity precaution */
3503 /* display it ? */
3504 if ((pData->iSHOWmode == 6) && (pFound))
3505 {
3506 display_image (pData, pFound, MNG_FALSE);
3507
3508 if (pData->bTimerset) /* timer set ? */
3509 {
3510 pData->iBreakpoint = 3;
3511 pData->iSHOWnextid = iFound; /* save it for after the break */
3512 }
3513 }
3514 }
3515 else
3516 {
3517 do
3518 {
3519 pImage = find_imageobject (pData, iX);
3520
3521 if (pImage) /* object exists ? */
3522 {
3523 if (pData->iBreakpoint) /* did we get broken last time ? */
3524 { /* could only happen in the display routine */
3525 display_image (pData, pImage, MNG_FALSE);
3526 pData->iBreakpoint = 0; /* only once inside this loop please ! */
3527 }
3528 else
3529 {
3530 switch (pData->iSHOWmode) /* do what ? */
3531 {
3532 case 0 : {
3533 pImage->bVisible = MNG_TRUE;
3534 display_image (pData, pImage, MNG_FALSE);
3535 break;
3536 }
3537 case 1 : {
3538 pImage->bVisible = MNG_FALSE;
3539 break;
3540 }
3541 case 2 : {
3542 if (pImage->bVisible)
3543 display_image (pData, pImage, MNG_FALSE);
3544 break;
3545 }
3546 case 3 : {
3547 pImage->bVisible = MNG_TRUE;
3548 break;
3549 }
3550 case 4 : {
3551 pImage->bVisible = (mng_bool)(!pImage->bVisible);
3552 if (pImage->bVisible)
3553 display_image (pData, pImage, MNG_FALSE);
3554 break;
3555 }
3556 case 5 : {
3557 pImage->bVisible = (mng_bool)(!pImage->bVisible);
3558 }
3559 }
3560 }
3561 }
3562
3563 if (!pData->bTimerset) /* next ? */
3564 iX += iS;
3565
3566 } /* continue ? */
3567 while ((!pData->bTimerset) && (((iS > 0) && (iX <= iTo)) ||
3568 ((iS < 0) && (iX >= iTo)) ));
3569
3570 if (pData->bTimerset) /* timer set ? */
3571 {
3572 pData->iBreakpoint = 4;
3573 pData->iSHOWnextid = iX; /* save for next time */
3574 }
3575 else
3576 pData->iBreakpoint = 0;
3577
3578 }
3579 }
3580
3581#ifdef MNG_SUPPORT_TRACE
3582 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_END)
3583#endif
3584
3585 return MNG_NOERROR;
3586}
3587
3588/* ************************************************************************** */
3589
3590mng_retcode process_display_save (mng_datap pData)
3591{
3592 mng_retcode iRetcode;
3593
3594#ifdef MNG_SUPPORT_TRACE
3595 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_START)
3596#endif
3597
3598 iRetcode = save_state (pData); /* save the current state */
3599
3600 if (iRetcode) /* on error bail out */
3601 return iRetcode;
3602
3603#ifdef MNG_SUPPORT_TRACE
3604 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_END)
3605#endif
3606
3607 return MNG_NOERROR;
3608}
3609
3610/* ************************************************************************** */
3611
3612mng_retcode process_display_seek (mng_datap pData)
3613{
3614 mng_retcode iRetcode;
3615
3616#ifdef MNG_SUPPORT_TRACE
3617 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_START)
3618#endif
3619
3620 iRetcode = restore_state (pData); /* restore the initial or SAVE state */
3621
3622 if (iRetcode) /* on error bail out */
3623 return iRetcode;
3624
3625#ifdef MNG_SUPPORT_TRACE
3626 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_END)
3627#endif
3628
3629 return MNG_NOERROR;
3630}
3631
3632/* ************************************************************************** */
3633
3634#ifdef MNG_INCLUDE_JNG
3635mng_retcode process_display_jhdr (mng_datap pData)
3636{ /* address the current "object" if any */
3637 mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
3638 mng_retcode iRetcode = MNG_NOERROR;
3639
3640#ifdef MNG_SUPPORT_TRACE
3641 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_START)
3642#endif
3643
3644 if (!pData->bHasDHDR)
3645 {
3646 pData->fInitrowproc = MNG_NULL; /* do nothing by default */
3647 pData->fDisplayrow = MNG_NULL;
3648 pData->fCorrectrow = MNG_NULL;
3649 pData->fStorerow = MNG_NULL;
3650 pData->fProcessrow = MNG_NULL;
3651 pData->fDifferrow = MNG_NULL;
3652 pData->fStorerow2 = MNG_NULL;
3653 pData->fStorerow3 = MNG_NULL;
3654
3655 pData->pStoreobj = MNG_NULL; /* initialize important work-parms */
3656
3657 pData->iJPEGrow = 0;
3658 pData->iJPEGalpharow = 0;
3659 pData->iJPEGrgbrow = 0;
3660 pData->iRowmax = 0; /* so init_rowproc does the right thing ! */
3661 }
3662
3663 if (!pData->iBreakpoint) /* not previously broken ? */
3664 {
3665 if (pData->bHasDHDR) /* delta-image ? */
3666 {
3667 if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
3668 {
3669 iRetcode = reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
3670 pData->iDatawidth, pData->iDataheight,
3671 pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
3672 pData->iJHDRalphacompression, pData->iJHDRalphafilter,
3673 pData->iJHDRalphainterlace, MNG_TRUE);
3674
3675 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
3676 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
3677 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
3678 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3679 }
3680 else
3681 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
3682 (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
3683 {
3684 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
3685 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3686 }
3687 else
3688 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
3689 (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
3690 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3691 else
3692 if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
3693 (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
3694 ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
3695
3696 }
3697 else
3698 {
3699 if (pImage) /* update object buffer ? */
3700 {
3701 iRetcode = reset_object_details (pData, pImage,
3702 pData->iDatawidth, pData->iDataheight,
3703 pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
3704 pData->iJHDRalphacompression, pData->iJHDRalphafilter,
3705 pData->iJHDRalphainterlace, MNG_TRUE);
3706
3707 pImage->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
3708 pImage->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
3709 pImage->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
3710 pImage->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3711 }
3712 else /* update object 0 */
3713 {
3714 iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
3715 pData->iDatawidth, pData->iDataheight,
3716 pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
3717 pData->iJHDRalphacompression, pData->iJHDRalphafilter,
3718 pData->iJHDRalphainterlace, MNG_TRUE);
3719
3720 ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
3721 ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
3722 ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
3723 ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
3724 }
3725 }
3726
3727 if (iRetcode) /* on error bail out */
3728 return iRetcode;
3729 }
3730
3731 if (!pData->bHasDHDR)
3732 { /* we're always storing a JPEG */
3733 if (pImage) /* real object ? */
3734 pData->pStoreobj = pImage; /* tell the row routines */
3735 else /* otherwise use object 0 */
3736 pData->pStoreobj = pData->pObjzero;
3737 /* display "on-the-fly" ? */
3738 if ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
3739 (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
3740 ( (pData->eImagetype == mng_it_jng ) ||
3741 (((mng_imagep)pData->pStoreobj)->bVisible) ) )
3742 {
3743 next_layer (pData); /* that's a new layer then ! */
3744
3745 if (pData->bTimerset) /* timer break ? */
3746 pData->iBreakpoint = 7;
3747 else
3748 {
3749 pData->iBreakpoint = 0;
3750 /* anything to display ? */
3751 if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
3752 {
3753 set_display_routine (pData); /* then determine display routine */
3754 /* display from the object we store in */
3755 pData->pRetrieveobj = pData->pStoreobj;
3756 }
3757 }
3758 }
3759 }
3760
3761 if (!pData->bTimerset) /* no timer break ? */
3762 { /* default row initialization ! */
3763 pData->fInitrowproc = (mng_fptr)init_rowproc;
3764
3765 if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_REPLACE))
3766 { /* 8-bit JPEG ? */
3767 if (pData->iJHDRimgbitdepth == 8)
3768 { /* intermediate row is 8-bit deep */
3769 pData->bIsRGBA16 = MNG_FALSE;
3770 pData->iRowsamples = pData->iDatawidth;
3771
3772 switch (pData->iJHDRcolortype) /* determine pixel processing routines */
3773 {
3774 case MNG_COLORTYPE_JPEGGRAY :
3775 {
3776 pData->fStorerow2 = (mng_fptr)store_jpeg_g8;
3777 pData->fRetrieverow = (mng_fptr)retrieve_g8;
3778 pData->bIsOpaque = MNG_TRUE;
3779 break;
3780 }
3781 case MNG_COLORTYPE_JPEGCOLOR :
3782 {
3783 pData->fStorerow2 = (mng_fptr)store_jpeg_rgb8;
3784 pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
3785 pData->bIsOpaque = MNG_TRUE;
3786 break;
3787 }
3788 case MNG_COLORTYPE_JPEGGRAYA :
3789 {
3790 pData->fStorerow2 = (mng_fptr)store_jpeg_ga8;
3791 pData->fRetrieverow = (mng_fptr)retrieve_ga8;
3792 pData->bIsOpaque = MNG_FALSE;
3793 break;
3794 }
3795 case MNG_COLORTYPE_JPEGCOLORA :
3796 {
3797 pData->fStorerow2 = (mng_fptr)store_jpeg_rgba8;
3798 pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
3799 pData->bIsOpaque = MNG_FALSE;
3800 break;
3801 }
3802 }
3803 }
3804 else
3805 {
3806 pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
3807
3808 /* TODO: 12-bit JPEG */
3809 /* TODO: 8- + 12-bit JPEG (eg. type=20) */
3810
3811 }
3812 /* possible IDAT alpha-channel ? */
3813 if (pData->iJHDRalphacompression == MNG_COMPRESSION_DEFLATE)
3814 {
3815 /* determine alpha processing routine */
3816 switch (pData->iJHDRalphabitdepth)
3817 {
3818 case 1 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a1_ni; break; }
3819 case 2 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a2_ni; break; }
3820 case 4 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a4_ni; break; }
3821 case 8 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a8_ni; break; }
3822 case 16 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a16_ni; break; }
3823 }
3824 }
3825 else /* possible JDAA alpha-channel ? */
3826 if (pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG)
3827 { /* 8-bit JPEG ? */
3828 if (pData->iJHDRimgbitdepth == 8)
3829 {
3830 if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)
3831 pData->fStorerow3 = (mng_fptr)store_jpeg_g8_alpha;
3832 else
3833 if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)
3834 pData->fStorerow3 = (mng_fptr)store_jpeg_rgb8_alpha;
3835 }
3836 else
3837 {
3838 /* TODO: 12-bit JPEG with 8-bit JDAA */
3839 }
3840 }
3841 /* initialize JPEG library */
3842 iRetcode = mngjpeg_initialize (pData);
3843
3844 if (iRetcode) /* on error bail out */
3845 return iRetcode;
3846 }
3847 else
3848 { /* must be alpha add/replace !! */
3849 if ((pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAADD ) &&
3850 (pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAREPLACE) )
3851 MNG_ERROR (pData, MNG_INVDELTATYPE)
3852 /* determine alpha processing routine */
3853 switch (pData->iJHDRalphabitdepth)
3854 {
3855 case 1 : { pData->fInitrowproc = (mng_fptr)init_g1_ni; break; }
3856 case 2 : { pData->fInitrowproc = (mng_fptr)init_g2_ni; break; }
3857 case 4 : { pData->fInitrowproc = (mng_fptr)init_g4_ni; break; }
3858 case 8 : { pData->fInitrowproc = (mng_fptr)init_g8_ni; break; }
3859 case 16 : { pData->fInitrowproc = (mng_fptr)init_g16_ni; break; }
3860 }
3861 }
3862
3863 pData->iFilterofs = 0; /* determine filter characteristics */
3864 pData->iLevel0 = 0; /* default levels */
3865 pData->iLevel1 = 0;
3866 pData->iLevel2 = 0;
3867 pData->iLevel3 = 0;
3868 /* leveling & differing ? */
3869/* if (pData->iJHDRalphafilter & 0x40)
3870 {
3871 if (pData->iJHDRalphabitdepth <= 8)
3872 pData->iFilterofs = 1;
3873 else
3874 pData->iFilterofs = 2;
3875
3876 } */
3877 /* no adaptive filtering ? */
3878/* if (pData->iJHDRalphafilter & 0x01)
3879 pData->iPixelofs = pData->iFilterofs;
3880 else */
3881 pData->iPixelofs = pData->iFilterofs + 1;
3882
3883 }
3884
3885#ifdef MNG_SUPPORT_TRACE
3886 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_END)
3887#endif
3888
3889 return MNG_NOERROR;
3890}
3891#endif /* MNG_INCLUDE_JNG */
3892
3893/* ************************************************************************** */
3894
3895#ifdef MNG_INCLUDE_JNG
3896mng_retcode process_display_jdaa (mng_datap pData,
3897 mng_uint32 iRawlen,
3898 mng_uint8p pRawdata)
3899{
3900 mng_retcode iRetcode = MNG_NOERROR;
3901
3902#ifdef MNG_SUPPORT_TRACE
3903 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_START)
3904#endif
3905
3906 if (!pData->bJPEGdecompress2) /* if we're not decompressing already */
3907 {
3908 if (pData->fInitrowproc) /* initialize row-processing? */
3909 {
3910 iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
3911 pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
3912 }
3913
3914 if (!iRetcode) /* initialize decompress */
3915 iRetcode = mngjpeg_decompressinit2 (pData);
3916 }
3917
3918 if (!iRetcode) /* all ok? then decompress, my man */
3919 iRetcode = mngjpeg_decompressdata2 (pData, iRawlen, pRawdata);
3920
3921 if (iRetcode)
3922 return iRetcode;
3923
3924#ifdef MNG_SUPPORT_TRACE
3925 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_END)
3926#endif
3927
3928 return MNG_NOERROR;
3929}
3930#endif /* MNG_INCLUDE_JNG */
3931
3932/* ************************************************************************** */
3933
3934#ifdef MNG_INCLUDE_JNG
3935mng_retcode process_display_jdat (mng_datap pData,
3936 mng_uint32 iRawlen,
3937 mng_uint8p pRawdata)
3938{
3939 mng_retcode iRetcode = MNG_NOERROR;
3940
3941#ifdef MNG_SUPPORT_TRACE
3942 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_START)
3943#endif
3944
3945 if (pData->bRestorebkgd) /* need to restore the background ? */
3946 {
3947 pData->bRestorebkgd = MNG_FALSE;
3948 iRetcode = load_bkgdlayer (pData);
3949
3950 if ((pData->bDisplaying) && (pData->bRunning))
3951 pData->iLayerseq++; /* and it counts as a layer then ! */
3952
3953 if (iRetcode) /* on error bail out */
3954 return iRetcode;
3955 }
3956
3957 if (!pData->bJPEGdecompress) /* if we're not decompressing already */
3958 {
3959 if (pData->fInitrowproc) /* initialize row-processing? */
3960 {
3961 iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
3962 pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
3963 }
3964
3965 if (!iRetcode) /* initialize decompress */
3966 iRetcode = mngjpeg_decompressinit (pData);
3967 }
3968
3969 if (!iRetcode) /* all ok? then decompress, my man */
3970 iRetcode = mngjpeg_decompressdata (pData, iRawlen, pRawdata);
3971
3972 if (iRetcode)
3973 return iRetcode;
3974
3975#ifdef MNG_SUPPORT_TRACE
3976 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_END)
3977#endif
3978
3979 return MNG_NOERROR;
3980}
3981#endif /* MNG_INCLUDE_JNG */
3982
3983/* ************************************************************************** */
3984
3985mng_retcode process_display_dhdr (mng_datap pData,
3986 mng_uint16 iObjectid,
3987 mng_uint8 iImagetype,
3988 mng_uint8 iDeltatype,
3989 mng_uint32 iBlockwidth,
3990 mng_uint32 iBlockheight,
3991 mng_uint32 iBlockx,
3992 mng_uint32 iBlocky)
3993{
3994 mng_imagep pImage;
3995 mng_retcode iRetcode;
3996
3997#ifdef MNG_SUPPORT_TRACE
3998 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_START)
3999#endif
4000
4001 pData->fInitrowproc = MNG_NULL; /* do nothing by default */
4002 pData->fDisplayrow = MNG_NULL;
4003 pData->fCorrectrow = MNG_NULL;
4004 pData->fStorerow = MNG_NULL;
4005 pData->fProcessrow = MNG_NULL;
4006 pData->pStoreobj = MNG_NULL;
4007
4008 pData->fDeltagetrow = MNG_NULL;
4009 pData->fDeltaaddrow = MNG_NULL;
4010 pData->fDeltareplacerow = MNG_NULL;
4011 pData->fDeltaputrow = MNG_NULL;
4012
4013 pImage = find_imageobject (pData, iObjectid);
4014
4015 if (pImage) /* object exists ? */
4016 {
4017 if (pImage->pImgbuf->bConcrete) /* is it concrete ? */
4018 { /* previous magnification to be done ? */
4019 if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
4020 {
4021 iRetcode = magnify_imageobject (pData, pImage);
4022
4023 if (iRetcode) /* on error bail out */
4024 return iRetcode;
4025 }
4026 /* save delta fields */
4027 pData->pDeltaImage = (mng_ptr)pImage;
4028 pData->iDeltaImagetype = iImagetype;
4029 pData->iDeltatype = iDeltatype;
4030 pData->iDeltaBlockwidth = iBlockwidth;
4031 pData->iDeltaBlockheight = iBlockheight;
4032 pData->iDeltaBlockx = iBlockx;
4033 pData->iDeltaBlocky = iBlocky;
4034 /* restore target-object fields */
4035 pData->iDatawidth = pImage->pImgbuf->iWidth;
4036 pData->iDataheight = pImage->pImgbuf->iHeight;
4037 pData->iBitdepth = pImage->pImgbuf->iBitdepth;
4038 pData->iColortype = pImage->pImgbuf->iColortype;
4039 pData->iCompression = pImage->pImgbuf->iCompression;
4040 pData->iFilter = pImage->pImgbuf->iFilter;
4041 pData->iInterlace = pImage->pImgbuf->iInterlace;
4042
4043#ifdef MNG_INCLUDE_JNG
4044 pData->iJHDRimgbitdepth = pImage->pImgbuf->iBitdepth;
4045 pData->iJHDRcolortype = pImage->pImgbuf->iColortype;
4046 pData->iJHDRimgcompression = pImage->pImgbuf->iJHDRcompression;
4047 pData->iJHDRimginterlace = pImage->pImgbuf->iJHDRinterlace;
4048 pData->iJHDRalphacompression = pImage->pImgbuf->iCompression;
4049 pData->iJHDRalphafilter = pImage->pImgbuf->iFilter;
4050 pData->iJHDRalphainterlace = pImage->pImgbuf->iInterlace;
4051 pData->iJHDRalphabitdepth = pImage->pImgbuf->iAlphabitdepth;
4052#endif
4053 /* block size specified ? */
4054 if (iDeltatype != MNG_DELTATYPE_NOCHANGE)
4055 {
4056 pData->iDatawidth = iBlockwidth;
4057 pData->iDataheight = iBlockheight;
4058 }
4059
4060 switch (iDeltatype) /* determine nr of delta-channels */
4061 {
4062 case MNG_DELTATYPE_BLOCKALPHAADD : ;
4063 case MNG_DELTATYPE_BLOCKALPHAREPLACE :
4064 {
4065#ifdef MNG_INCLUDE_JNG
4066 if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
4067 (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) )
4068 {
4069 pData->iColortype = MNG_COLORTYPE_GRAY;
4070 pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
4071 }
4072 else
4073 if ((pData->iColortype == MNG_COLORTYPE_RGBA ) ||
4074 (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
4075 {
4076 pData->iColortype = MNG_COLORTYPE_GRAY;
4077 pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
4078 }
4079#else
4080 if (pData->iColortype == MNG_COLORTYPE_GRAYA)
4081 pData->iColortype = MNG_COLORTYPE_GRAY;
4082 else
4083 if (pData->iColortype == MNG_COLORTYPE_RGBA)
4084 pData->iColortype = MNG_COLORTYPE_GRAY;
4085#endif
4086 else /* target has no alpha; that sucks! */
4087 MNG_ERROR (pData, MNG_TARGETNOALPHA)
4088
4089 break;
4090 }
4091
4092 case MNG_DELTATYPE_BLOCKCOLORADD : ;
4093 case MNG_DELTATYPE_BLOCKCOLORREPLACE :
4094 {
4095#ifdef MNG_INCLUDE_JNG
4096 if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
4097 (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) )
4098 {
4099 pData->iColortype = MNG_COLORTYPE_GRAY;
4100 pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
4101 }
4102 else
4103 if ((pData->iColortype == MNG_COLORTYPE_RGBA ) ||
4104 (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
4105 {
4106 pData->iColortype = MNG_COLORTYPE_RGB;
4107 pData->iJHDRcolortype = MNG_COLORTYPE_JPEGCOLOR;
4108 }
4109#else
4110 if (pData->iColortype == MNG_COLORTYPE_GRAYA)
4111 pData->iColortype = MNG_COLORTYPE_GRAY;
4112 else
4113 if (pData->iColortype == MNG_COLORTYPE_RGBA)
4114 pData->iColortype = MNG_COLORTYPE_RGB;
4115#endif
4116 else /* target has no alpha; that sucks! */
4117 MNG_ERROR (pData, MNG_TARGETNOALPHA)
4118
4119 break;
4120 }
4121
4122 }
4123 /* full image replace ? */
4124 if (iDeltatype == MNG_DELTATYPE_REPLACE)
4125 {
4126 iRetcode = reset_object_details (pData, pImage,
4127 pData->iDatawidth, pData->iDataheight,
4128 pData->iBitdepth, pData->iColortype,
4129 pData->iCompression, pData->iFilter,
4130 pData->iInterlace, MNG_FALSE);
4131
4132 if (iRetcode) /* on error bail out */
4133 return iRetcode;
4134
4135 pData->pStoreobj = pImage; /* and store straight into this object */
4136 }
4137 else
4138 {
4139 mng_imagedatap pBufzero, pBuf;
4140 /* we store in object 0 and process it later */
4141 pData->pStoreobj = pData->pObjzero;
4142 /* make sure to initialize object 0 then */
4143 iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
4144 pData->iDatawidth, pData->iDataheight,
4145 pData->iBitdepth, pData->iColortype,
4146 pData->iCompression, pData->iFilter,
4147 pData->iInterlace, MNG_TRUE);
4148
4149 if (iRetcode) /* on error bail out */
4150 return iRetcode;
4151
4152 pBuf = pImage->pImgbuf; /* copy possible palette & cheap transparency */
4153 pBufzero = ((mng_imagep)pData->pObjzero)->pImgbuf;
4154
4155 pBufzero->bHasPLTE = pBuf->bHasPLTE;
4156 pBufzero->bHasTRNS = pBuf->bHasTRNS;
4157
4158 if (pBufzero->bHasPLTE) /* copy palette ? */
4159 {
4160 mng_uint32 iX;
4161
4162 pBufzero->iPLTEcount = pBuf->iPLTEcount;
4163
4164 for (iX = 0; iX < pBuf->iPLTEcount; iX++)
4165 {
4166 pBufzero->aPLTEentries [iX].iRed = pBuf->aPLTEentries [iX].iRed;
4167 pBufzero->aPLTEentries [iX].iGreen = pBuf->aPLTEentries [iX].iGreen;
4168 pBufzero->aPLTEentries [iX].iBlue = pBuf->aPLTEentries [iX].iBlue;
4169 }
4170 }
4171
4172 if (pBufzero->bHasTRNS) /* copy cheap transparency ? */
4173 {
4174 pBufzero->iTRNSgray = pBuf->iTRNSgray;
4175 pBufzero->iTRNSred = pBuf->iTRNSred;
4176 pBufzero->iTRNSgreen = pBuf->iTRNSgreen;
4177 pBufzero->iTRNSblue = pBuf->iTRNSblue;
4178 pBufzero->iTRNScount = pBuf->iTRNScount;
4179
4180 MNG_COPY (pBufzero->aTRNSentries, pBuf->aTRNSentries,
4181 sizeof (pBufzero->aTRNSentries))
4182 }
4183 /* process immediatly if bitdepth & colortype are equal */
4184 pData->bDeltaimmediate =
4185 (mng_bool)((pData->bDisplaying) && (pData->bRunning) &&
4186 (pData->iBitdepth == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
4187 (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype) );
4188 }
4189
4190 switch (pData->iColortype) /* determine row initialization routine */
4191 {
4192 case 0 : { /* gray */
4193 switch (pData->iBitdepth)
4194 {
4195 case 1 : {
4196 if (!pData->iInterlace)
4197 pData->fInitrowproc = (mng_fptr)init_g1_ni;
4198 else
4199 pData->fInitrowproc = (mng_fptr)init_g1_i;
4200
4201 break;
4202 }
4203 case 2 : {
4204 if (!pData->iInterlace)
4205 pData->fInitrowproc = (mng_fptr)init_g2_ni;
4206 else
4207 pData->fInitrowproc = (mng_fptr)init_g2_i;
4208
4209 break;
4210 }
4211 case 4 : {
4212 if (!pData->iInterlace)
4213 pData->fInitrowproc = (mng_fptr)init_g4_ni;
4214 else
4215 pData->fInitrowproc = (mng_fptr)init_g4_i;
4216
4217 break;
4218 }
4219 case 8 : {
4220 if (!pData->iInterlace)
4221 pData->fInitrowproc = (mng_fptr)init_g8_ni;
4222 else
4223 pData->fInitrowproc = (mng_fptr)init_g8_i;
4224
4225 break;
4226 }
4227 case 16 : {
4228 if (!pData->iInterlace)
4229 pData->fInitrowproc = (mng_fptr)init_g16_ni;
4230 else
4231 pData->fInitrowproc = (mng_fptr)init_g16_i;
4232
4233 break;
4234 }
4235 }
4236
4237 break;
4238 }
4239 case 2 : { /* rgb */
4240 switch (pData->iBitdepth)
4241 {
4242 case 8 : {
4243 if (!pData->iInterlace)
4244 pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
4245 else
4246 pData->fInitrowproc = (mng_fptr)init_rgb8_i;
4247
4248 break;
4249 }
4250 case 16 : {
4251 if (!pData->iInterlace)
4252 pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
4253 else
4254 pData->fInitrowproc = (mng_fptr)init_rgb16_i;
4255
4256 break;
4257 }
4258 }
4259
4260 break;
4261 }
4262 case 3 : { /* indexed */
4263 switch (pData->iBitdepth)
4264 {
4265 case 1 : {
4266 if (!pData->iInterlace)
4267 pData->fInitrowproc = (mng_fptr)init_idx1_ni;
4268 else
4269 pData->fInitrowproc = (mng_fptr)init_idx1_i;
4270
4271 break;
4272 }
4273 case 2 : {
4274 if (!pData->iInterlace)
4275 pData->fInitrowproc = (mng_fptr)init_idx2_ni;
4276 else
4277 pData->fInitrowproc = (mng_fptr)init_idx2_i;
4278
4279 break;
4280 }
4281 case 4 : {
4282 if (!pData->iInterlace)
4283 pData->fInitrowproc = (mng_fptr)init_idx4_ni;
4284 else
4285 pData->fInitrowproc = (mng_fptr)init_idx4_i;
4286
4287 break;
4288 }
4289 case 8 : {
4290 if (!pData->iInterlace)
4291 pData->fInitrowproc = (mng_fptr)init_idx8_ni;
4292 else
4293 pData->fInitrowproc = (mng_fptr)init_idx8_i;
4294
4295 break;
4296 }
4297 }
4298
4299 break;
4300 }
4301 case 4 : { /* gray+alpha */
4302 switch (pData->iBitdepth)
4303 {
4304 case 8 : {
4305 if (!pData->iInterlace)
4306 pData->fInitrowproc = (mng_fptr)init_ga8_ni;
4307 else
4308 pData->fInitrowproc = (mng_fptr)init_ga8_i;
4309
4310 break;
4311 }
4312 case 16 : {
4313 if (!pData->iInterlace)
4314 pData->fInitrowproc = (mng_fptr)init_ga16_ni;
4315 else
4316 pData->fInitrowproc = (mng_fptr)init_ga16_i;
4317
4318 break;
4319 }
4320 }
4321
4322 break;
4323 }
4324 case 6 : { /* rgb+alpha */
4325 switch (pData->iBitdepth)
4326 {
4327 case 8 : {
4328 if (!pData->iInterlace)
4329 pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
4330 else
4331 pData->fInitrowproc = (mng_fptr)init_rgba8_i;
4332
4333 break;
4334 }
4335 case 16 : {
4336 if (!pData->iInterlace)
4337 pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
4338 else
4339 pData->fInitrowproc = (mng_fptr)init_rgba16_i;
4340
4341 break;
4342 }
4343 }
4344
4345 break;
4346 }
4347 }
4348 }
4349 else
4350 MNG_ERROR (pData, MNG_OBJNOTCONCRETE)
4351
4352 }
4353 else
4354 MNG_ERROR (pData, MNG_OBJECTUNKNOWN)
4355
4356#ifdef MNG_SUPPORT_TRACE
4357 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_END)
4358#endif
4359
4360 return MNG_NOERROR;
4361}
4362
4363/* ************************************************************************** */
4364
4365mng_retcode process_display_prom (mng_datap pData,
4366 mng_uint8 iBitdepth,
4367 mng_uint8 iColortype,
4368 mng_uint8 iFilltype)
4369{
4370#ifdef MNG_SUPPORT_TRACE
4371 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_START)
4372#endif
4373
4374
4375 /* TODO: everything */
4376
4377
4378#ifdef MNG_SUPPORT_TRACE
4379 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_END)
4380#endif
4381
4382 return MNG_NOERROR;
4383}
4384
4385/* ************************************************************************** */
4386
4387mng_retcode process_display_ipng (mng_datap pData)
4388{
4389#ifdef MNG_SUPPORT_TRACE
4390 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_START)
4391#endif
4392 /* indicate it for what it is now */
4393 pData->iDeltaImagetype = MNG_IMAGETYPE_PNG;
4394
4395#ifdef MNG_SUPPORT_TRACE
4396 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_END)
4397#endif
4398
4399 return MNG_NOERROR;
4400}
4401
4402/* ************************************************************************** */
4403
4404mng_retcode process_display_ijng (mng_datap pData)
4405{
4406#ifdef MNG_SUPPORT_TRACE
4407 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_START)
4408#endif
4409 /* indicate it for what it is now */
4410 pData->iDeltaImagetype = MNG_IMAGETYPE_JNG;
4411
4412#ifdef MNG_SUPPORT_TRACE
4413 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_END)
4414#endif
4415
4416 return MNG_NOERROR;
4417}
4418
4419/* ************************************************************************** */
4420
4421mng_retcode process_display_pplt (mng_datap pData,
4422 mng_uint8 iType,
4423 mng_uint32 iCount,
4424 mng_palette8ep paIndexentries,
4425 mng_uint8p paAlphaentries,
4426 mng_uint8p paUsedentries)
4427{
4428 mng_uint32 iX;
4429 mng_imagep pImage = (mng_imagep)pData->pObjzero;
4430 mng_imagedatap pBuf = pImage->pImgbuf;
4431
4432#ifdef MNG_SUPPORT_TRACE
4433 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_START)
4434#endif
4435
4436 switch (iType)
4437 {
4438 case MNG_DELTATYPE_REPLACERGB :
4439 {
4440 for (iX = 0; iX < iCount; iX++)
4441 {
4442 if (paUsedentries [iX])
4443 {
4444 pBuf->aPLTEentries [iX].iRed = paIndexentries [iX].iRed;
4445 pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
4446 pBuf->aPLTEentries [iX].iBlue = paIndexentries [iX].iBlue;
4447 }
4448 }
4449
4450 break;
4451 }
4452 case MNG_DELTATYPE_DELTARGB :
4453 {
4454 for (iX = 0; iX < iCount; iX++)
4455 {
4456 if (paUsedentries [iX])
4457 {
4458 pBuf->aPLTEentries [iX].iRed =
4459 (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
4460 paIndexentries [iX].iRed );
4461 pBuf->aPLTEentries [iX].iGreen =
4462 (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
4463 paIndexentries [iX].iGreen);
4464 pBuf->aPLTEentries [iX].iBlue =
4465 (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
4466 paIndexentries [iX].iBlue );
4467 }
4468 }
4469
4470 break;
4471 }
4472 case MNG_DELTATYPE_REPLACEALPHA :
4473 {
4474 for (iX = 0; iX < iCount; iX++)
4475 {
4476 if (paUsedentries [iX])
4477 pBuf->aTRNSentries [iX] = paAlphaentries [iX];
4478 }
4479
4480 break;
4481 }
4482 case MNG_DELTATYPE_DELTAALPHA :
4483 {
4484 for (iX = 0; iX < iCount; iX++)
4485 {
4486 if (paUsedentries [iX])
4487 pBuf->aTRNSentries [iX] =
4488 (mng_uint8)(pBuf->aTRNSentries [iX] +
4489 paAlphaentries [iX]);
4490 }
4491
4492 break;
4493 }
4494 case MNG_DELTATYPE_REPLACERGBA :
4495 {
4496 for (iX = 0; iX < iCount; iX++)
4497 {
4498 if (paUsedentries [iX])
4499 {
4500 pBuf->aPLTEentries [iX].iRed = paIndexentries [iX].iRed;
4501 pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
4502 pBuf->aPLTEentries [iX].iBlue = paIndexentries [iX].iBlue;
4503 pBuf->aTRNSentries [iX] = paAlphaentries [iX];
4504 }
4505 }
4506
4507 break;
4508 }
4509 case MNG_DELTATYPE_DELTARGBA :
4510 {
4511 for (iX = 0; iX < iCount; iX++)
4512 {
4513 if (paUsedentries [iX])
4514 {
4515 pBuf->aPLTEentries [iX].iRed =
4516 (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
4517 paIndexentries [iX].iRed );
4518 pBuf->aPLTEentries [iX].iGreen =
4519 (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
4520 paIndexentries [iX].iGreen);
4521 pBuf->aPLTEentries [iX].iBlue =
4522 (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
4523 paIndexentries [iX].iBlue );
4524 pBuf->aTRNSentries [iX] =
4525 (mng_uint8)(pBuf->aTRNSentries [iX] +
4526 paAlphaentries [iX]);
4527 }
4528 }
4529
4530 break;
4531 }
4532 }
4533
4534 if ((iType != MNG_DELTATYPE_REPLACERGB) && (iType != MNG_DELTATYPE_DELTARGB))
4535 {
4536 if (pBuf->bHasTRNS)
4537 {
4538 if (iCount > pBuf->iTRNScount)
4539 pBuf->iTRNScount = iCount;
4540 }
4541 else
4542 {
4543 pBuf->iTRNScount = iCount;
4544 pBuf->bHasTRNS = MNG_TRUE;
4545 }
4546 }
4547
4548 if ((iType != MNG_DELTATYPE_REPLACEALPHA) && (iType != MNG_DELTATYPE_DELTAALPHA))
4549 {
4550 if (iCount > pBuf->iPLTEcount)
4551 pBuf->iPLTEcount = iCount;
4552 }
4553
4554#ifdef MNG_SUPPORT_TRACE
4555 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_END)
4556#endif
4557
4558 return MNG_NOERROR;
4559}
4560
4561/* ************************************************************************** */
4562
4563mng_retcode process_display_magn (mng_datap pData,
4564 mng_uint16 iFirstid,
4565 mng_uint16 iLastid,
4566 mng_uint16 iMethodX,
4567 mng_uint16 iMX,
4568 mng_uint16 iMY,
4569 mng_uint16 iML,
4570 mng_uint16 iMR,
4571 mng_uint16 iMT,
4572 mng_uint16 iMB,
4573 mng_uint16 iMethodY)
4574{
4575 mng_uint16 iX;
4576 mng_imagep pImage;
4577
4578#ifdef MNG_SUPPORT_TRACE
4579 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START)
4580#endif
4581 /* iterate the object-ids */
4582 for (iX = iFirstid; iX <= iLastid; iX++)
4583 {
4584 if (iX == 0) /* process object 0 ? */
4585 {
4586 pImage = (mng_imagep)pData->pObjzero;
4587
4588 pImage->iMAGN_MethodX = iMethodX;
4589 pImage->iMAGN_MethodY = iMethodY;
4590 pImage->iMAGN_MX = iMX;
4591 pImage->iMAGN_MY = iMY;
4592 pImage->iMAGN_ML = iML;
4593 pImage->iMAGN_MR = iMR;
4594 pImage->iMAGN_MT = iMT;
4595 pImage->iMAGN_MB = iMB;
4596 }
4597 else
4598 {
4599 pImage = find_imageobject (pData, iX);
4600 /* object exists & is not frozen ? */
4601 if ((pImage) && (!pImage->bFrozen))
4602 { /* previous magnification to be done ? */
4603 if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
4604 {
4605 mng_retcode iRetcode = magnify_imageobject (pData, pImage);
4606
4607 if (iRetcode) /* on error bail out */
4608 return iRetcode;
4609 }
4610
4611 pImage->iMAGN_MethodX = iMethodX;
4612 pImage->iMAGN_MethodY = iMethodY;
4613 pImage->iMAGN_MX = iMX;
4614 pImage->iMAGN_MY = iMY;
4615 pImage->iMAGN_ML = iML;
4616 pImage->iMAGN_MR = iMR;
4617 pImage->iMAGN_MT = iMT;
4618 pImage->iMAGN_MB = iMB;
4619 }
4620 }
4621 }
4622
4623 iX = iFirstid;
4624 /* iterate again for showing */
4625 while ((iX <= iLastid) && (!pData->bTimerset))
4626 {
4627 if (iX) /* only real objects ! */
4628 {
4629 pImage = find_imageobject (pData, iX);
4630 /* object exists & is not frozen &
4631 is visible & is viewable ? */
4632 if ((pImage) && (!pImage->bFrozen) &&
4633 (pImage->bVisible) && (pImage->bViewable))
4634 display_image (pData, pImage, MNG_FALSE);
4635 }
4636
4637 iX++;
4638 }
4639
4640 if (pData->bTimerset) /* broken ? */
4641 {
4642 pData->iMAGNfromid = iFirstid;
4643 pData->iMAGNtoid = iLastid;
4644 pData->iBreakpoint = 9;
4645 }
4646
4647#ifdef MNG_SUPPORT_TRACE
4648 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END)
4649#endif
4650
4651 return MNG_NOERROR;
4652}
4653
4654/* ************************************************************************** */
4655
4656mng_retcode process_display_magn2 (mng_datap pData)
4657{
4658 mng_uint16 iX;
4659 mng_imagep pImage;
4660
4661#ifdef MNG_SUPPORT_TRACE
4662 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START)
4663#endif
4664
4665 iX = pData->iMAGNfromid;
4666 /* iterate again for showing */
4667 while ((iX <= pData->iMAGNtoid) && (!pData->bTimerset))
4668 {
4669 if (iX) /* only real objects ! */
4670 {
4671 pImage = find_imageobject (pData, iX);
4672 /* object exists & is not frozen &
4673 is visible & is viewable ? */
4674 if ((pImage) && (!pImage->bFrozen) &&
4675 (pImage->bVisible) && (pImage->bViewable))
4676 display_image (pData, pImage, MNG_FALSE);
4677 }
4678
4679 iX++;
4680 }
4681
4682 if (pData->bTimerset) /* broken ? */
4683 pData->iBreakpoint = 9;
4684
4685#ifdef MNG_SUPPORT_TRACE
4686 MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END)
4687#endif
4688
4689 return MNG_NOERROR;
4690}
4691
4692/* ************************************************************************** */
4693
4694#endif /* MNG_INCLUDE_DISPLAY_PROCS */
4695
4696/* ************************************************************************** */
4697/* * end of file * */
4698/* ************************************************************************** */
4699
Note: See TracBrowser for help on using the repository browser.