summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libmng/libmng_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libmng/libmng_display.c')
-rw-r--r--src/3rdparty/libmng/libmng_display.c7140
1 files changed, 7140 insertions, 0 deletions
diff --git a/src/3rdparty/libmng/libmng_display.c b/src/3rdparty/libmng/libmng_display.c
new file mode 100644
index 0000000000..81c2484b54
--- /dev/null
+++ b/src/3rdparty/libmng/libmng_display.c
@@ -0,0 +1,7140 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_display.c copyright (c) 2000-2007 G.Juyn * */
+/* * version : 1.0.10 * */
+/* * * */
+/* * purpose : Display management (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * * */
+/* * comment : implementation of the display management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * - fixed frame_delay misalignment * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - added sanity check for frozen status * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * 0.5.1 - 05/13/2000 - G.Juyn * */
+/* * - changed display_mend to reset state to initial or SAVE * */
+/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
+/* * - added TERM animation object pointer (easier reference) * */
+/* * - added process_save & process_seek routines * */
+/* * 0.5.1 - 05/14/2000 - G.Juyn * */
+/* * - added save_state and restore_state for SAVE/SEEK/TERM * */
+/* * processing * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - added JNG support (JHDR/JDAT) * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - fixed problem with DEFI clipping * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added delta-image support (DHDR,PROM,IPNG,IJNG) * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed pointer confusion (contributed by Tim Rowley) * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - fixed makeup for Linux gcc compile * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - added support for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/09/2000 - G.Juyn * */
+/* * - fixed timer-handling to run with Mozilla (Tim Rowley) * */
+/* * 0.5.2 - 06/10/2000 - G.Juyn * */
+/* * - fixed some compilation-warnings (contrib Jason Morris) * */
+/* * * */
+/* * 0.5.3 - 06/12/2000 - G.Juyn * */
+/* * - fixed display of stored JNG images * */
+/* * 0.5.3 - 06/13/2000 - G.Juyn * */
+/* * - fixed problem with BASI-IEND as object 0 * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed delta-image processing * */
+/* * 0.5.3 - 06/20/2000 - G.Juyn * */
+/* * - fixed some minor stuff * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added speed-modifier to timing routine * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added support for PPLT chunk processing * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - swapped refresh parameters * */
+/* * * */
+/* * 0.9.0 - 06/30/2000 - G.Juyn * */
+/* * - changed refresh parameters to 'x,y,width,height' * */
+/* * * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - implemented support for freeze/reset/resume & go_xxxx * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added support for improved timing * */
+/* * 0.9.1 - 07/14/2000 - G.Juyn * */
+/* * - changed EOF processing behavior * */
+/* * - fixed TERM delay processing * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - fixed freeze & reset processing * */
+/* * 0.9.1 - 07/16/2000 - G.Juyn * */
+/* * - fixed storage of images during mng_read() * */
+/* * - fixed support for mng_display() after mng_read() * */
+/* * 0.9.1 - 07/24/2000 - G.Juyn * */
+/* * - fixed reading of still-images * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/21/2000 - G.Juyn * */
+/* * - fixed TERM processing delay of 0 msecs * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed problem with no refresh after TERM * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 09/16/2000 - G.Juyn * */
+/* * - fixed timing & refresh behavior for single PNG/JNG * */
+/* * 0.9.3 - 09/19/2000 - G.Juyn * */
+/* * - refixed timing & refresh behavior for single PNG/JNG * */
+/* * 0.9.3 - 10/02/2000 - G.Juyn * */
+/* * - fixed timing again (this is getting boring...) * */
+/* * - refixed problem with no refresh after TERM * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added JDAA chunk * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - fixed support for bKGD * */
+/* * 0.9.3 - 10/18/2000 - G.Juyn * */
+/* * - fixed delta-processing behavior * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - added storage for pixel-/alpha-sampledepth for delta's * */
+/* * 0.9.3 - 10/27/2000 - G.Juyn * */
+/* * - fixed separate read() & display() processing * */
+/* * * */
+/* * 0.9.4 - 10/31/2000 - G.Juyn * */
+/* * - fixed possible loop in display_resume() (Thanks Vova!) * */
+/* * 0.9.4 - 11/20/2000 - G.Juyn * */
+/* * - fixed unwanted repetition in mng_readdisplay() * */
+/* * 0.9.4 - 11/24/2000 - G.Juyn * */
+/* * - moved restore of object 0 to libmng_display * */
+/* * - added restore of object 0 to TERM processing !!! * */
+/* * - fixed TERM delay processing * */
+/* * - fixed TERM end processing (count = 0) * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - removed test filter-methods 1 & 65 * */
+/* * - set default level-set for filtertype=64 to all zeroes * */
+/* * * */
+/* * 0.9.5 - 1/20/2001 - G.Juyn * */
+/* * - fixed compiler-warnings Mozilla (thanks Tim) * */
+/* * 0.9.5 - 1/23/2001 - G.Juyn * */
+/* * - fixed timing-problem with switching framing_modes * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 02/13/2001 - G.Juyn * */
+/* * - fixed first FRAM_MODE=4 timing problem * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn * */
+/* * - fixed memory-leak for JNGs with alpha (Thanks Gregg!) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - fixed memory-leak with delta-images (Thanks Michael!) * */
+/* * * */
+/* * 1.0.5 - 08/15/2002 - G.Juyn * */
+/* * - completed PROM support * */
+/* * - completed delta-image support * */
+/* * 1.0.5 - 08/19/2002 - G.Juyn * */
+/* * - B597134 - libmng pollutes the linker namespace * */
+/* * 1.0.5 - 09/13/2002 - G.Juyn * */
+/* * - fixed read/write of MAGN chunk * */
+/* * 1.0.5 - 09/15/2002 - G.Juyn * */
+/* * - fixed LOOP iteration=0 special case * */
+/* * 1.0.5 - 09/19/2002 - G.Juyn * */
+/* * - fixed color-correction for restore-background handling * */
+/* * - optimized restore-background for bKGD cases * */
+/* * - cleaned up some old stuff * */
+/* * 1.0.5 - 09/20/2002 - G.Juyn * */
+/* * - finished support for BACK image & tiling * */
+/* * - added support for PAST * */
+/* * 1.0.5 - 09/22/2002 - G.Juyn * */
+/* * - added bgrx8 canvas (filler byte) * */
+/* * 1.0.5 - 10/05/2002 - G.Juyn * */
+/* * - fixed dropping mix of frozen/unfrozen objects * */
+/* * 1.0.5 - 10/07/2002 - G.Juyn * */
+/* * - added proposed change in handling of TERM- & if-delay * */
+/* * - added another fix for misplaced TERM chunk * */
+/* * - completed support for condition=2 in TERM chunk * */
+/* * 1.0.5 - 10/18/2002 - G.Juyn * */
+/* * - fixed clipping-problem with BACK tiling (Thanks Sakura!) * */
+/* * 1.0.5 - 10/20/2002 - G.Juyn * */
+/* * - fixed processing for multiple objects in MAGN * */
+/* * - fixed display of visible target of PAST operation * */
+/* * 1.0.5 - 10/30/2002 - G.Juyn * */
+/* * - modified TERM/MEND processing for max(1, TERM_delay, * */
+/* * interframe_delay) * */
+/* * 1.0.5 - 11/04/2002 - G.Juyn * */
+/* * - fixed layer- & frame-counting during read() * */
+/* * - fixed goframe/golayer/gotime processing * */
+/* * 1.0.5 - 01/19/2003 - G.Juyn * */
+/* * - B654627 - fixed SEGV when no gettickcount callback * */
+/* * - B664383 - fixed typo * */
+/* * - finalized changes in TERM/final_delay to elected proposal* */
+/* * * */
+/* * 1.0.6 - 05/11/2003 - G. Juyn * */
+/* * - added conditionals around canvas update routines * */
+/* * 1.0.6 - 05/25/2003 - G.R-P * */
+/* * - added MNG_SKIPCHUNK_cHNK footprint optimizations * */
+/* * 1.0.6 - 07/07/2003 - G.R-P * */
+/* * - added conditionals around some JNG-supporting code * */
+/* * - added conditionals around 16-bit supporting code * */
+/* * - reversed some loops to use decrementing counter * */
+/* * - combined init functions into one function * */
+/* * 1.0.6 - 07/10/2003 - G.R-P * */
+/* * - replaced nested switches with simple init setup function * */
+/* * 1.0.6 - 07/29/2003 - G.R-P * */
+/* * - added conditionals around PAST chunk support * */
+/* * 1.0.6 - 08/17/2003 - G.R-P * */
+/* * - added conditionals around non-VLC chunk support * */
+/* * * */
+/* * 1.0.7 - 11/27/2003 - R.A * */
+/* * - added CANVAS_RGB565 and CANVAS_BGR565 * */
+/* * 1.0.7 - 12/06/2003 - R.A * */
+/* * - added CANVAS_RGBA565 and CANVAS_BGRA565 * */
+/* * 1.0.7 - 01/25/2004 - J.S * */
+/* * - added premultiplied alpha canvas' for RGBA, ARGB, ABGR * */
+/* * * */
+/* * 1.0.8 - 03/31/2004 - G.Juyn * */
+/* * - fixed problem with PAST usage where source > dest * */
+/* * 1.0.8 - 05/04/2004 - G.R-P. * */
+/* * - fixed misplaced 16-bit conditionals * */
+/* * * */
+/* * 1.0.9 - 09/18/2004 - G.R-P. * */
+/* * - revised some SKIPCHUNK conditionals * */
+/* * 1.0.9 - 10/10/2004 - G.R-P. * */
+/* * - added MNG_NO_1_2_4BIT_SUPPORT * */
+/* * 1.0.9 - 10/14/2004 - G.Juyn * */
+/* * - added bgr565_a8 canvas-style (thanks to J. Elvander) * */
+/* * 1.0.9 - 12/11/2004 - G.Juyn * */
+/* * - added conditional MNG_OPTIMIZE_DISPLAYCALLS * */
+/* * 1.0.9 - 12/20/2004 - G.Juyn * */
+/* * - cleaned up macro-invocations (thanks to D. Airlie) * */
+/* * * */
+/* * 1.0.10 - 07/06/2005 - G.R-P. * */
+/* * - added more SKIPCHUNK conditionals * */
+/* * 1.0.10 - 12/28/2005 - G.R-P. * */
+/* * - added missing SKIPCHUNK_MAGN conditional * */
+/* * 1.0.10 - 03/07/2006 - (thanks to W. Manthey) * */
+/* * - added CANVAS_RGB555 and CANVAS_BGR555 * */
+/* * 1.0.10 - 04/08/2007 - G.Juyn * */
+/* * - fixed several compiler warnings * */
+/* * 1.0.10 - 04/08/2007 - G.Juyn * */
+/* * - added support for mPNG proposal * */
+/* * 1.0.10 - 04/12/2007 - G.Juyn * */
+/* * - added support for ANG proposal * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_chunks.h"
+#include "libmng_objects.h"
+#include "libmng_object_prc.h"
+#include "libmng_memory.h"
+#include "libmng_zlib.h"
+#include "libmng_jpeg.h"
+#include "libmng_cms.h"
+#include "libmng_pixels.h"
+#include "libmng_display.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode set_delay (mng_datap pData,
+ mng_uint32 iInterval)
+{
+ if (!iInterval) /* at least 1 msec please! */
+ iInterval = 1;
+
+ if (pData->bRunning) /* only when really displaying */
+ if (!pData->fSettimer ((mng_handle)pData, iInterval))
+ MNG_ERROR (pData, MNG_APPTIMERERROR);
+
+#ifdef MNG_SUPPORT_DYNAMICMNG
+ if ((!pData->bDynamic) || (pData->bRunning))
+#else
+ if (pData->bRunning)
+#endif
+ pData->bTimerset = MNG_TRUE; /* and indicate so */
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_uint32 calculate_delay (mng_datap pData,
+ mng_uint32 iDelay)
+{
+ mng_uint32 iTicks = pData->iTicks;
+ mng_uint32 iWaitfor = 1; /* default non-MNG delay */
+
+ if (!iTicks) /* tick_count not specified ? */
+ if (pData->eImagetype == mng_it_mng)
+ iTicks = 1000;
+
+ if (iTicks)
+ {
+ switch (pData->iSpeed) /* honor speed modifier */
+ {
+ case mng_st_fast :
+ {
+ iWaitfor = (mng_uint32)(( 500 * iDelay) / iTicks);
+ break;
+ }
+ case mng_st_slow :
+ {
+ iWaitfor = (mng_uint32)((3000 * iDelay) / iTicks);
+ break;
+ }
+ case mng_st_slowest :
+ {
+ iWaitfor = (mng_uint32)((8000 * iDelay) / iTicks);
+ break;
+ }
+ default :
+ {
+ iWaitfor = (mng_uint32)((1000 * iDelay) / iTicks);
+ }
+ }
+ }
+
+ return iWaitfor;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Progressive display refresh - does the call to the refresh callback * */
+/* * and sets the timer to allow the app to perform the actual refresh to * */
+/* * the screen (eg. process its main message-loop) * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode mng_display_progressive_refresh (mng_datap pData,
+ mng_uint32 iInterval)
+{
+ { /* let the app refresh first ? */
+ if ((pData->bRunning) && (!pData->bSkipping) &&
+ (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
+ {
+ if (!pData->fRefresh (((mng_handle)pData),
+ pData->iUpdateleft, pData->iUpdatetop,
+ pData->iUpdateright - pData->iUpdateleft,
+ pData->iUpdatebottom - pData->iUpdatetop))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ pData->iUpdateleft = 0; /* reset update-region */
+ pData->iUpdateright = 0;
+ pData->iUpdatetop = 0;
+ pData->iUpdatebottom = 0; /* reset refreshneeded indicator */
+ pData->bNeedrefresh = MNG_FALSE;
+ /* interval requested ? */
+ if ((!pData->bFreezing) && (iInterval))
+ { /* setup the timer */
+ mng_retcode iRetcode = set_delay (pData, iInterval);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Generic display routines * */
+/* * * */
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode interframe_delay (mng_datap pData)
+{
+ mng_uint32 iWaitfor = 0;
+ mng_uint32 iInterval;
+ mng_uint32 iRuninterval;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_START);
+#endif
+
+ {
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pData->iFramedelay > 0 || pData->bForcedelay) /* real delay ? */
+ { /* let the app refresh first ? */
+ pData->bForcedelay = MNG_FALSE;
+ if ((pData->bRunning) && (!pData->bSkipping) &&
+ (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
+ if (!pData->fRefresh (((mng_handle)pData),
+ pData->iUpdateleft, pData->iUpdatetop,
+ pData->iUpdateright - pData->iUpdateleft,
+ pData->iUpdatebottom - pData->iUpdatetop))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ pData->iUpdateleft = 0; /* reset update-region */
+ pData->iUpdateright = 0;
+ pData->iUpdatetop = 0;
+ pData->iUpdatebottom = 0; /* reset refreshneeded indicator */
+ pData->bNeedrefresh = MNG_FALSE;
+
+#ifndef MNG_SKIPCHUNK_TERM
+ if (pData->bOnlyfirstframe) /* only processing first frame after TERM ? */
+ {
+ pData->iFramesafterTERM++;
+ /* did we do a frame yet ? */
+ if (pData->iFramesafterTERM > 1)
+ { /* then that's it; just stop right here ! */
+ pData->pCurraniobj = MNG_NULL;
+ pData->bRunning = MNG_FALSE;
+
+ return MNG_NOERROR;
+ }
+ }
+#endif
+
+ if (pData->fGettickcount)
+ { /* get current tickcount */
+ pData->iRuntime = pData->fGettickcount ((mng_handle)pData);
+ /* calculate interval since last sync-point */
+ if (pData->iRuntime < pData->iSynctime)
+ iRuninterval = pData->iRuntime + ~pData->iSynctime + 1;
+ else
+ iRuninterval = pData->iRuntime - pData->iSynctime;
+ /* calculate actual run-time */
+ if (pData->iRuntime < pData->iStarttime)
+ pData->iRuntime = pData->iRuntime + ~pData->iStarttime + 1;
+ else
+ pData->iRuntime = pData->iRuntime - pData->iStarttime;
+ }
+ else
+ {
+ iRuninterval = 0;
+ }
+
+ iWaitfor = calculate_delay (pData, pData->iFramedelay);
+
+ if (iWaitfor > iRuninterval) /* delay necessary ? */
+ iInterval = iWaitfor - iRuninterval;
+ else
+ iInterval = 1; /* force app to process messageloop */
+ /* set the timer ? */
+ if (((pData->bRunning) || (pData->bSearching) || (pData->bReading)) &&
+ (!pData->bSkipping))
+ {
+ iRetcode = set_delay (pData, iInterval);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+
+ if (!pData->bSkipping) /* increase frametime in advance */
+ pData->iFrametime = pData->iFrametime + iWaitfor;
+ /* setup for next delay */
+ pData->iFramedelay = pData->iNextdelay;
+ pData->iAccumdelay += pData->iFramedelay;
+#endif
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL void set_display_routine (mng_datap pData)
+{ /* actively running ? */
+ if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
+ {
+ switch (pData->iCanvasstyle) /* determine display routine */
+ {
+#ifndef MNG_SKIPCANVAS_RGB8
+ case MNG_CANVAS_RGB8 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGBA8
+ case MNG_CANVAS_RGBA8 : { pData->fDisplayrow = (mng_fptr)mng_display_rgba8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGBA8_PM
+ case MNG_CANVAS_RGBA8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_rgba8_pm; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_ARGB8
+ case MNG_CANVAS_ARGB8 : { pData->fDisplayrow = (mng_fptr)mng_display_argb8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_ARGB8_PM
+ case MNG_CANVAS_ARGB8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_argb8_pm; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGB8_A8
+ case MNG_CANVAS_RGB8_A8 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb8_a8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGR8
+ case MNG_CANVAS_BGR8 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGRX8
+ case MNG_CANVAS_BGRX8 : { pData->fDisplayrow = (mng_fptr)mng_display_bgrx8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGRA8
+ case MNG_CANVAS_BGRA8 : { pData->fDisplayrow = (mng_fptr)mng_display_bgra8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGRA8_PM
+ case MNG_CANVAS_BGRA8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_bgra8_pm; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_ABGR8
+ case MNG_CANVAS_ABGR8 : { pData->fDisplayrow = (mng_fptr)mng_display_abgr8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_ABGR8_PM
+ case MNG_CANVAS_ABGR8_PM: { pData->fDisplayrow = (mng_fptr)mng_display_abgr8_pm; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGB565
+ case MNG_CANVAS_RGB565 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb565; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGBA565
+ case MNG_CANVAS_RGBA565 : { pData->fDisplayrow = (mng_fptr)mng_display_rgba565; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGR565
+ case MNG_CANVAS_BGR565 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr565; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGRA565
+ case MNG_CANVAS_BGRA565 : { pData->fDisplayrow = (mng_fptr)mng_display_bgra565; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGR565_A8
+ case MNG_CANVAS_BGR565_A8 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr565_a8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGB555
+ case MNG_CANVAS_RGB555 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb555; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGR555
+ case MNG_CANVAS_BGR555 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr555; break; }
+#endif
+
+#ifndef MNG_NO_16BIT_SUPPORT
+/* case MNG_CANVAS_RGB16 : { pData->fDisplayrow = (mng_fptr)mng_display_rgb16; break; } */
+/* case MNG_CANVAS_RGBA16 : { pData->fDisplayrow = (mng_fptr)mng_display_rgba16; break; } */
+/* case MNG_CANVAS_ARGB16 : { pData->fDisplayrow = (mng_fptr)mng_display_argb16; break; } */
+/* case MNG_CANVAS_BGR16 : { pData->fDisplayrow = (mng_fptr)mng_display_bgr16; break; } */
+/* case MNG_CANVAS_BGRA16 : { pData->fDisplayrow = (mng_fptr)mng_display_bgra16; break; } */
+/* case MNG_CANVAS_ABGR16 : { pData->fDisplayrow = (mng_fptr)mng_display_abgr16; break; } */
+#endif
+/* case MNG_CANVAS_INDEX8 : { pData->fDisplayrow = (mng_fptr)mng_display_index8; break; } */
+/* case MNG_CANVAS_INDEXA8 : { pData->fDisplayrow = (mng_fptr)mng_display_indexa8; break; } */
+/* case MNG_CANVAS_AINDEX8 : { pData->fDisplayrow = (mng_fptr)mng_display_aindex8; break; } */
+/* case MNG_CANVAS_GRAY8 : { pData->fDisplayrow = (mng_fptr)mng_display_gray8; break; } */
+/* case MNG_CANVAS_AGRAY8 : { pData->fDisplayrow = (mng_fptr)mng_display_agray8; break; } */
+/* case MNG_CANVAS_GRAYA8 : { pData->fDisplayrow = (mng_fptr)mng_display_graya8; break; } */
+#ifndef MNG_NO_16BIT_SUPPORT
+/* case MNG_CANVAS_GRAY16 : { pData->fDisplayrow = (mng_fptr)mng_display_gray16; break; } */
+/* case MNG_CANVAS_GRAYA16 : { pData->fDisplayrow = (mng_fptr)mng_display_graya16; break; } */
+/* case MNG_CANVAS_AGRAY16 : { pData->fDisplayrow = (mng_fptr)mng_display_agray16; break; } */
+#endif
+/* case MNG_CANVAS_DX15 : { pData->fDisplayrow = (mng_fptr)mng_display_dx15; break; } */
+/* case MNG_CANVAS_DX16 : { pData->fDisplayrow = (mng_fptr)mng_display_dx16; break; } */
+ }
+ }
+
+ return;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode load_bkgdlayer (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_START);
+#endif
+ /* actively running ? */
+ if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
+ {
+ mng_int32 iY;
+ mng_retcode iRetcode;
+ mng_bool bColorcorr = MNG_FALSE;
+ /* save values */
+ mng_int32 iDestl = pData->iDestl;
+ mng_int32 iDestr = pData->iDestr;
+ mng_int32 iDestt = pData->iDestt;
+ mng_int32 iDestb = pData->iDestb;
+ mng_int32 iSourcel = pData->iSourcel;
+ mng_int32 iSourcer = pData->iSourcer;
+ mng_int32 iSourcet = pData->iSourcet;
+ mng_int32 iSourceb = pData->iSourceb;
+ mng_int8 iPass = pData->iPass;
+ mng_int32 iRow = pData->iRow;
+ mng_int32 iRowinc = pData->iRowinc;
+ mng_int32 iCol = pData->iCol;
+ mng_int32 iColinc = pData->iColinc;
+ mng_int32 iRowsamples = pData->iRowsamples;
+ mng_int32 iRowsize = pData->iRowsize;
+ mng_uint8p pPrevrow = pData->pPrevrow;
+ mng_uint8p pRGBArow = pData->pRGBArow;
+ mng_bool bIsRGBA16 = pData->bIsRGBA16;
+ mng_bool bIsOpaque = pData->bIsOpaque;
+ mng_fptr fCorrectrow = pData->fCorrectrow;
+ mng_fptr fDisplayrow = pData->fDisplayrow;
+ mng_fptr fRetrieverow = pData->fRetrieverow;
+ mng_objectp pCurrentobj = pData->pCurrentobj;
+ mng_objectp pRetrieveobj = pData->pRetrieveobj;
+
+ pData->iDestl = 0; /* determine clipping region */
+ pData->iDestt = 0;
+ pData->iDestr = pData->iWidth;
+ pData->iDestb = pData->iHeight;
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pData->bFrameclipping) /* frame clipping specified ? */
+ {
+ pData->iDestl = MAX_COORD (pData->iDestl, pData->iFrameclipl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pData->iFrameclipt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pData->iFrameclipr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pData->iFrameclipb);
+ }
+#endif
+ /* anything to clear ? */
+ if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
+ {
+ pData->iPass = -1; /* these are the object's dimensions now */
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iWidth;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->bIsRGBA16 = MNG_FALSE; /* let's keep it simple ! */
+ pData->bIsOpaque = MNG_TRUE;
+
+ pData->iSourcel = 0; /* source relative to destination */
+ pData->iSourcer = pData->iDestr - pData->iDestl;
+ pData->iSourcet = 0;
+ pData->iSourceb = pData->iDestb - pData->iDestt;
+
+ set_display_routine (pData); /* determine display routine */
+ /* default restore using preset BG color */
+ pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgcolor;
+
+#ifndef MNG_SKIPCHUNK_bKGD
+ if (((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng)) &&
+ (pData->bUseBKGD))
+ { /* prefer bKGD in PNG/JNG */
+ if (!pData->pCurrentobj)
+ pData->pCurrentobj = pData->pObjzero;
+
+ if (((mng_imagep)pData->pCurrentobj)->pImgbuf->bHasBKGD)
+ {
+ pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bkgd;
+ bColorcorr = MNG_TRUE;
+ }
+ }
+#endif
+
+ if (pData->fGetbkgdline) /* background-canvas-access callback set ? */
+ {
+ switch (pData->iBkgdstyle)
+ {
+#ifndef MNG_SKIPCANVAS_RGB8
+ case MNG_CANVAS_RGB8 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGR8
+ case MNG_CANVAS_BGR8 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGRX8
+ case MNG_CANVAS_BGRX8 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgrx8; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_BGR565
+ case MNG_CANVAS_BGR565 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr565; break; }
+#endif
+#ifndef MNG_SKIPCANVAS_RGB565
+ case MNG_CANVAS_RGB565 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb565; break; }
+#endif
+#ifndef MNG_NO_16BIT_SUPPORT
+ /* case MNG_CANVAS_RGB16 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_rgb16; break; } */
+ /* case MNG_CANVAS_BGR16 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_bgr16; break; } */
+#endif
+ /* case MNG_CANVAS_INDEX8 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_index8; break; } */
+ /* case MNG_CANVAS_GRAY8 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_gray8; break; } */
+#ifndef MNG_NO_16BIT_SUPPORT
+ /* case MNG_CANVAS_GRAY16 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_gray16; break; } */
+#endif
+ /* case MNG_CANVAS_DX15 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_dx15; break; } */
+ /* case MNG_CANVAS_DX16 : { pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_dx16; break; } */
+ }
+ }
+
+#ifndef MNG_SKIPCHUNK_BACK
+ if (pData->bHasBACK)
+ { /* background image ? */
+ if ((pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
+ {
+ pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_backcolor;
+ bColorcorr = MNG_TRUE;
+ }
+ else /* background color ? */
+ if (pData->iBACKmandatory & 0x01)
+ {
+ pData->fRestbkgdrow = (mng_fptr)mng_restore_bkgd_backcolor;
+ bColorcorr = MNG_TRUE;
+ }
+ }
+#endif
+
+ pData->fCorrectrow = MNG_NULL; /* default no color-correction */
+
+ if (bColorcorr) /* do we have to do color-correction ? */
+ {
+#ifdef MNG_NO_CMS
+ iRetcode = MNG_NOERROR;
+#else
+#if defined(MNG_FULL_CMS) /* determine color-management routine */
+ iRetcode = mng_init_full_cms (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
+#elif defined(MNG_GAMMA_ONLY)
+ iRetcode = mng_init_gamma_only (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
+#elif defined(MNG_APP_CMS)
+ iRetcode = mng_init_app_cms (pData, MNG_TRUE, MNG_FALSE, MNG_FALSE);
+#endif
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif /* MNG_NO_CMS */
+ }
+ /* get a temporary row-buffer */
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
+
+ iY = pData->iDestt; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* so far, so good */
+
+ while ((!iRetcode) && (iY < pData->iDestb))
+ { /* restore a background row */
+ iRetcode = ((mng_restbkgdrow)pData->fRestbkgdrow) (pData);
+ /* color correction ? */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* so... display it */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode)
+ iRetcode = mng_next_row (pData);
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#if defined(MNG_FULL_CMS) /* cleanup cms stuff */
+ if (bColorcorr) /* did we do color-correction ? */
+ {
+ iRetcode = mng_clear_cms (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif
+#ifndef MNG_SKIPCHUNK_BACK
+ /* background image ? */
+ if ((pData->bHasBACK) && (pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
+ {
+ mng_imagep pImage;
+ /* let's find that object then */
+ pData->pRetrieveobj = mng_find_imageobject (pData, pData->iBACKimageid);
+ pImage = (mng_imagep)pData->pRetrieveobj;
+ /* exists, viewable and visible ? */
+ if ((pImage) && (pImage->bViewable) && (pImage->bVisible))
+ { /* will it fall within the target region ? */
+ if ((pImage->iPosx < pData->iDestr) && (pImage->iPosy < pData->iDestb) &&
+ ((pData->iBACKtile) ||
+ ((pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth >= pData->iDestl) &&
+ (pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight >= pData->iDestt) )) &&
+ ((!pImage->bClipped) ||
+ ((pImage->iClipl <= pImage->iClipr) && (pImage->iClipt <= pImage->iClipb) &&
+ (pImage->iClipl < pData->iDestr) && (pImage->iClipr >= pData->iDestl) &&
+ (pImage->iClipt < pData->iDestb) && (pImage->iClipb >= pData->iDestt) )))
+ { /* right; we've got ourselves something to do */
+ if (pImage->bClipped) /* clip output region with image's clipping region ? */
+ {
+ if (pImage->iClipl > pData->iDestl)
+ pData->iDestl = pImage->iClipl;
+ if (pImage->iClipr < pData->iDestr)
+ pData->iDestr = pImage->iClipr;
+ if (pImage->iClipt > pData->iDestt)
+ pData->iDestt = pImage->iClipt;
+ if (pImage->iClipb < pData->iDestb)
+ pData->iDestb = pImage->iClipb;
+ }
+ /* image offset does some extra clipping too ! */
+ if (pImage->iPosx > pData->iDestl)
+ pData->iDestl = pImage->iPosx;
+ if (pImage->iPosy > pData->iDestt)
+ pData->iDestt = pImage->iPosy;
+
+ if (!pData->iBACKtile) /* without tiling further clipping is needed */
+ {
+ if (pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth < pData->iDestr)
+ pData->iDestr = pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth;
+ if (pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight < pData->iDestb)
+ pData->iDestb = pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight;
+ }
+
+ pData->iSourcel = 0; /* source relative to destination */
+ pData->iSourcer = pData->iDestr - pData->iDestl;
+ pData->iSourcet = 0;
+ pData->iSourceb = pData->iDestb - pData->iDestt;
+ /* 16-bit background ? */
+
+#ifdef MNG_NO_16BIT_SUPPORT
+ pData->bIsRGBA16 = MNG_FALSE;
+#else
+ pData->bIsRGBA16 = (mng_bool)(pImage->pImgbuf->iBitdepth > 8);
+#endif
+ /* let restore routine know the offsets !!! */
+ pData->iBackimgoffsx = pImage->iPosx;
+ pData->iBackimgoffsy = pImage->iPosy;
+ pData->iBackimgwidth = pImage->pImgbuf->iWidth;
+ pData->iBackimgheight = pImage->pImgbuf->iHeight;
+ pData->iRow = 0; /* start at the top again !! */
+ /* determine background object retrieval routine */
+ switch (pImage->pImgbuf->iColortype)
+ {
+ case 0 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+ case 2 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+ case 3 : { pData->fRetrieverow = (mng_fptr)mng_retrieve_idx8;
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+ case 4 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ case 6 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ case 8 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+ case 10 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+ case 12 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ case 14 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+ }
+
+#ifdef MNG_NO_CMS
+ iRetcode = MNG_NOERROR;
+#else
+#if defined(MNG_FULL_CMS) /* determine color-management routine */
+ iRetcode = mng_init_full_cms (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#elif defined(MNG_GAMMA_ONLY)
+ iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#elif defined(MNG_APP_CMS)
+ iRetcode = mng_init_app_cms (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#endif
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif /* MNG_NO_CMS */
+ /* get temporary row-buffers */
+ MNG_ALLOC (pData, pData->pPrevrow, pData->iRowsize);
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
+
+ iY = pData->iDestt; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* so far, so good */
+
+ while ((!iRetcode) && (iY < pData->iDestb))
+ { /* restore a background row */
+ iRetcode = mng_restore_bkgd_backimage (pData);
+ /* color correction ? */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* so... display it */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode)
+ iRetcode = mng_next_row (pData);
+
+ iY++; /* and next line */
+ }
+ /* drop temporary row-buffers */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
+ MNG_FREE (pData, pData->pPrevrow, pData->iRowsize);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#if defined(MNG_FULL_CMS) /* cleanup cms stuff */
+ iRetcode = mng_clear_cms (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif
+ }
+ }
+ }
+#endif
+ }
+
+ pData->iDestl = iDestl; /* restore values */
+ pData->iDestr = iDestr;
+ pData->iDestt = iDestt;
+ pData->iDestb = iDestb;
+ pData->iSourcel = iSourcel;
+ pData->iSourcer = iSourcer;
+ pData->iSourcet = iSourcet;
+ pData->iSourceb = iSourceb;
+ pData->iPass = iPass;
+ pData->iRow = iRow;
+ pData->iRowinc = iRowinc;
+ pData->iCol = iCol;
+ pData->iColinc = iColinc;
+ pData->iRowsamples = iRowsamples;
+ pData->iRowsize = iRowsize;
+ pData->pPrevrow = pPrevrow;
+ pData->pRGBArow = pRGBArow;
+ pData->bIsRGBA16 = bIsRGBA16;
+ pData->bIsOpaque = bIsOpaque;
+ pData->fCorrectrow = fCorrectrow;
+ pData->fDisplayrow = fDisplayrow;
+ pData->fRetrieverow = fRetrieverow;
+ pData->pCurrentobj = pCurrentobj;
+ pData->pRetrieveobj = pRetrieveobj;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode clear_canvas (mng_datap pData)
+{
+ mng_int32 iY;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_START);
+#endif
+
+ pData->iDestl = 0; /* clipping region is full canvas! */
+ pData->iDestt = 0;
+ pData->iDestr = pData->iWidth;
+ pData->iDestb = pData->iHeight;
+
+ pData->iSourcel = 0; /* source is same as destination */
+ pData->iSourcer = pData->iWidth;
+ pData->iSourcet = 0;
+ pData->iSourceb = pData->iHeight;
+
+ pData->iPass = -1; /* these are the object's dimensions now */
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iWidth;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->bIsRGBA16 = MNG_FALSE; /* let's keep it simple ! */
+ pData->bIsOpaque = MNG_TRUE;
+
+ set_display_routine (pData); /* determine display routine */
+ /* get a temporary row-buffer */
+ /* it's transparent black by default!! */
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
+
+ iY = pData->iDestt; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* so far, so good */
+
+ while ((!iRetcode) && (iY < pData->iDestb))
+ { /* clear a row then */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode)
+ iRetcode = mng_next_row (pData); /* adjust variables for next row */
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode next_frame (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_START);
+#endif
+
+ if (!pData->iBreakpoint) /* no previous break here ? */
+ {
+#ifndef MNG_SKIPCHUNK_FRAM
+ mng_uint8 iOldmode = pData->iFramemode;
+ /* interframe delay required ? */
+ if ((iOldmode == 2) || (iOldmode == 4))
+ {
+ if ((pData->iFrameseq) && (iFramemode != 1) && (iFramemode != 3))
+ iRetcode = interframe_delay (pData);
+ else
+ pData->iFramedelay = pData->iNextdelay;
+ }
+ else
+ { /* delay before inserting background layer? */
+ if ((pData->bFramedone) && (iFramemode == 4))
+ iRetcode = interframe_delay (pData);
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* now we'll assume we're in the next frame! */
+ if (iFramemode) /* save the new framing mode ? */
+ {
+ pData->iFRAMmode = iFramemode;
+ pData->iFramemode = iFramemode;
+ }
+ else /* reload default */
+ pData->iFramemode = pData->iFRAMmode;
+
+ if (iChangedelay) /* delay changed ? */
+ {
+ pData->iNextdelay = iDelay; /* for *after* next subframe */
+
+ if ((iOldmode == 2) || (iOldmode == 4))
+ pData->iFramedelay = pData->iFRAMdelay;
+
+ if (iChangedelay == 2) /* also overall ? */
+ pData->iFRAMdelay = iDelay;
+ }
+ else
+ { /* reload default */
+ pData->iNextdelay = pData->iFRAMdelay;
+ }
+
+ if (iChangetimeout) /* timeout changed ? */
+ { /* for next subframe */
+ pData->iFrametimeout = iTimeout;
+
+ if ((iChangetimeout == 2) || /* also overall ? */
+ (iChangetimeout == 4) ||
+ (iChangetimeout == 6) ||
+ (iChangetimeout == 8))
+ pData->iFRAMtimeout = iTimeout;
+ }
+ else /* reload default */
+ pData->iFrametimeout = pData->iFRAMtimeout;
+
+ if (iChangeclipping) /* clipping changed ? */
+ {
+ pData->bFrameclipping = MNG_TRUE;
+
+ if (!iCliptype) /* absolute ? */
+ {
+ pData->iFrameclipl = iClipl;
+ pData->iFrameclipr = iClipr;
+ pData->iFrameclipt = iClipt;
+ pData->iFrameclipb = iClipb;
+ }
+ else /* relative */
+ {
+ pData->iFrameclipl = pData->iFrameclipl + iClipl;
+ pData->iFrameclipr = pData->iFrameclipr + iClipr;
+ pData->iFrameclipt = pData->iFrameclipt + iClipt;
+ pData->iFrameclipb = pData->iFrameclipb + iClipb;
+ }
+
+ if (iChangeclipping == 2) /* also overall ? */
+ {
+ pData->bFRAMclipping = MNG_TRUE;
+
+ if (!iCliptype) /* absolute ? */
+ {
+ pData->iFRAMclipl = iClipl;
+ pData->iFRAMclipr = iClipr;
+ pData->iFRAMclipt = iClipt;
+ pData->iFRAMclipb = iClipb;
+ }
+ else /* relative */
+ {
+ pData->iFRAMclipl = pData->iFRAMclipl + iClipl;
+ pData->iFRAMclipr = pData->iFRAMclipr + iClipr;
+ pData->iFRAMclipt = pData->iFRAMclipt + iClipt;
+ pData->iFRAMclipb = pData->iFRAMclipb + iClipb;
+ }
+ }
+ }
+ else
+ { /* reload defaults */
+ pData->bFrameclipping = pData->bFRAMclipping;
+ pData->iFrameclipl = pData->iFRAMclipl;
+ pData->iFrameclipr = pData->iFRAMclipr;
+ pData->iFrameclipt = pData->iFRAMclipt;
+ pData->iFrameclipb = pData->iFRAMclipb;
+ }
+#endif
+ }
+
+ if (!pData->bTimerset) /* timer still off ? */
+ {
+ if (
+#ifndef MNG_SKIPCHUNK_FRAM
+ (pData->iFramemode == 4) || /* insert background layer after a new frame */
+#endif
+ (!pData->iLayerseq)) /* and certainly before the very first layer */
+ iRetcode = load_bkgdlayer (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pData->iFrameseq++; /* count the frame ! */
+ pData->bFramedone = MNG_TRUE; /* and indicate we've done one */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode next_layer (mng_datap pData)
+{
+ mng_imagep pImage;
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_START);
+#endif
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (!pData->iBreakpoint) /* no previous break here ? */
+ { /* interframe delay required ? */
+ if ((pData->eImagetype == mng_it_mng) && (pData->iLayerseq) &&
+ ((pData->iFramemode == 1) || (pData->iFramemode == 3)))
+ iRetcode = interframe_delay (pData);
+ else
+ pData->iFramedelay = pData->iNextdelay;
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif
+
+ if (!pData->bTimerset) /* timer still off ? */
+ {
+ if (!pData->iLayerseq) /* restore background for the very first layer ? */
+ { /* wait till IDAT/JDAT for PNGs & JNGs !!! */
+ if ((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng))
+ pData->bRestorebkgd = MNG_TRUE;
+ else
+ { /* for MNG we do it right away */
+ iRetcode = load_bkgdlayer (pData);
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+ }
+ }
+#ifndef MNG_SKIPCHUNK_FRAM
+ else
+ if (pData->iFramemode == 3) /* restore background for each layer ? */
+ iRetcode = load_bkgdlayer (pData);
+#endif
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifndef MNG_NO_DELTA_PNG
+ if (pData->bHasDHDR) /* processing a delta-image ? */
+ pImage = (mng_imagep)pData->pDeltaImage;
+ else
+#endif
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* not an active object ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* determine display rectangle */
+ pData->iDestl = MAX_COORD ((mng_int32)0, pImage->iPosx);
+ pData->iDestt = MAX_COORD ((mng_int32)0, pImage->iPosy);
+ /* is it a valid buffer ? */
+ if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
+ {
+ pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
+ pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth );
+ pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
+ pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight);
+ }
+ else /* it's a single image ! */
+ {
+ pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
+ (mng_int32)pData->iDatawidth );
+ pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
+ (mng_int32)pData->iDataheight);
+ }
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pData->bFrameclipping) /* frame clipping specified ? */
+ {
+ pData->iDestl = MAX_COORD (pData->iDestl, pData->iFrameclipl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pData->iFrameclipt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pData->iFrameclipr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pData->iFrameclipb);
+ }
+#endif
+
+ if (pImage->bClipped) /* is the image clipped itself ? */
+ {
+ pData->iDestl = MAX_COORD (pData->iDestl, pImage->iClipl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pImage->iClipt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pImage->iClipr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pImage->iClipb);
+ }
+ /* determine source starting point */
+ pData->iSourcel = MAX_COORD ((mng_int32)0, pData->iDestl - pImage->iPosx);
+ pData->iSourcet = MAX_COORD ((mng_int32)0, pData->iDestt - pImage->iPosy);
+
+ if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
+ { /* and maximum size */
+ pData->iSourcer = MIN_COORD ((mng_int32)pImage->pImgbuf->iWidth,
+ pData->iSourcel + pData->iDestr - pData->iDestl);
+ pData->iSourceb = MIN_COORD ((mng_int32)pImage->pImgbuf->iHeight,
+ pData->iSourcet + pData->iDestb - pData->iDestt);
+ }
+ else /* it's a single image ! */
+ {
+ pData->iSourcer = pData->iSourcel + pData->iDestr - pData->iDestl;
+ pData->iSourceb = pData->iSourcet + pData->iDestb - pData->iDestt;
+ }
+
+ pData->iLayerseq++; /* count the layer ! */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_display_image (mng_datap pData,
+ mng_imagep pImage,
+ mng_bool bLayeradvanced)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_START);
+#endif
+ /* actively running ? */
+#ifndef MNG_SKIPCHUNK_MAGN
+ if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
+ {
+ if ( (!pData->iBreakpoint) && /* needs magnification ? */
+ ( (pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY) ) )
+ {
+ iRetcode = mng_magnify_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+#endif
+
+ pData->pRetrieveobj = pImage; /* so retrieve-row and color-correction can find it */
+
+ if (!bLayeradvanced) /* need to advance the layer ? */
+ {
+ mng_imagep pSave = pData->pCurrentobj;
+ pData->pCurrentobj = pImage;
+ next_layer (pData); /* advance to next layer */
+ pData->pCurrentobj = pSave;
+ }
+ /* need to restore the background ? */
+ if ((!pData->bTimerset) && (pData->bRestorebkgd))
+ {
+ mng_imagep pSave = pData->pCurrentobj;
+ pData->pCurrentobj = pImage;
+ pData->bRestorebkgd = MNG_FALSE;
+ iRetcode = load_bkgdlayer (pData);
+ pData->pCurrentobj = pSave;
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+ }
+ /* actively running ? */
+ if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
+ {
+ if (!pData->bTimerset) /* all systems still go ? */
+ {
+ pData->iBreakpoint = 0; /* let's make absolutely sure... */
+ /* anything to display ? */
+ if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
+ {
+ mng_int32 iY;
+
+ set_display_routine (pData); /* determine display routine */
+ /* and image-buffer retrieval routine */
+ switch (pImage->pImgbuf->iColortype)
+ {
+ case 0 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+ case 2 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+
+ case 3 : { pData->fRetrieverow = (mng_fptr)mng_retrieve_idx8;
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+
+ case 4 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+
+ case 6 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ case 8 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+ case 10 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+
+ case 12 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+
+ case 14 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ }
+
+ pData->iPass = -1; /* these are the object's dimensions now */
+ pData->iRow = pData->iSourcet;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pImage->pImgbuf->iWidth;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->bIsRGBA16 = MNG_FALSE;
+ /* adjust for 16-bit object ? */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pImage->pImgbuf->iBitdepth > 8)
+ {
+ pData->bIsRGBA16 = MNG_TRUE;
+ pData->iRowsize = pData->iRowsamples << 3;
+ }
+#endif
+
+ pData->fCorrectrow = MNG_NULL; /* default no color-correction */
+
+#ifdef MNG_NO_CMS
+ iRetcode = MNG_NOERROR;
+#else
+#if defined(MNG_FULL_CMS) /* determine color-management routine */
+ iRetcode = mng_init_full_cms (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#elif defined(MNG_GAMMA_ONLY)
+ iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#elif defined(MNG_APP_CMS)
+ iRetcode = mng_init_app_cms (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#endif
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif /* MNG_NO_CMS */
+ /* get a temporary row-buffer */
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize);
+
+ iY = pData->iSourcet; /* this is where we start */
+
+ while ((!iRetcode) && (iY < pData->iSourceb))
+ { /* get a row */
+ iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
+ /* color correction ? */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* so... display it */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode) /* adjust variables for next row */
+ iRetcode = mng_next_row (pData);
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#if defined(MNG_FULL_CMS) /* cleanup cms stuff */
+ iRetcode = mng_clear_cms (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR; /* whehehe, this is good ! */
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+mng_retcode mng_execute_delta_image (mng_datap pData,
+ mng_imagep pTarget,
+ mng_imagep pDelta)
+{
+ mng_imagedatap pBuftarget = pTarget->pImgbuf;
+ mng_imagedatap pBufdelta = pDelta->pImgbuf;
+ mng_uint32 iY;
+ mng_retcode iRetcode;
+ mng_ptr pSaveRGBA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_START);
+#endif
+ /* actively running ? */
+ if (((pData->bRunning) || (pData->bSearching)) && (!pData->bSkipping))
+ {
+ if (pBufdelta->bHasPLTE) /* palette in delta ? */
+ {
+ mng_uint32 iX;
+ /* new palette larger than old one ? */
+ if ((!pBuftarget->bHasPLTE) || (pBuftarget->iPLTEcount < pBufdelta->iPLTEcount))
+ pBuftarget->iPLTEcount = pBufdelta->iPLTEcount;
+ /* it's definitely got a PLTE now */
+ pBuftarget->bHasPLTE = MNG_TRUE;
+
+ for (iX = 0; iX < pBufdelta->iPLTEcount; iX++)
+ {
+ pBuftarget->aPLTEentries[iX].iRed = pBufdelta->aPLTEentries[iX].iRed;
+ pBuftarget->aPLTEentries[iX].iGreen = pBufdelta->aPLTEentries[iX].iGreen;
+ pBuftarget->aPLTEentries[iX].iBlue = pBufdelta->aPLTEentries[iX].iBlue;
+ }
+ }
+
+ if (pBufdelta->bHasTRNS) /* cheap transparency in delta ? */
+ {
+ switch (pData->iColortype) /* drop it into the target */
+ {
+ case 0: { /* gray */
+ pBuftarget->iTRNSgray = pBufdelta->iTRNSgray;
+ pBuftarget->iTRNSred = 0;
+ pBuftarget->iTRNSgreen = 0;
+ pBuftarget->iTRNSblue = 0;
+ pBuftarget->iTRNScount = 0;
+ break;
+ }
+ case 2: { /* rgb */
+ pBuftarget->iTRNSgray = 0;
+ pBuftarget->iTRNSred = pBufdelta->iTRNSred;
+ pBuftarget->iTRNSgreen = pBufdelta->iTRNSgreen;
+ pBuftarget->iTRNSblue = pBufdelta->iTRNSblue;
+ pBuftarget->iTRNScount = 0;
+ break;
+ }
+ case 3: { /* indexed */
+ pBuftarget->iTRNSgray = 0;
+ pBuftarget->iTRNSred = 0;
+ pBuftarget->iTRNSgreen = 0;
+ pBuftarget->iTRNSblue = 0;
+ /* existing range smaller than new one ? */
+ if ((!pBuftarget->bHasTRNS) || (pBuftarget->iTRNScount < pBufdelta->iTRNScount))
+ pBuftarget->iTRNScount = pBufdelta->iTRNScount;
+
+ MNG_COPY (pBuftarget->aTRNSentries, pBufdelta->aTRNSentries, pBufdelta->iTRNScount);
+ break;
+ }
+ }
+
+ pBuftarget->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
+ }
+
+#ifndef MNG_SKIPCHUNK_bKGD
+ if (pBufdelta->bHasBKGD) /* bkgd in source ? */
+ { /* drop it onto the target */
+ pBuftarget->bHasBKGD = MNG_TRUE;
+ pBuftarget->iBKGDindex = pBufdelta->iBKGDindex;
+ pBuftarget->iBKGDgray = pBufdelta->iBKGDgray;
+ pBuftarget->iBKGDred = pBufdelta->iBKGDred;
+ pBuftarget->iBKGDgreen = pBufdelta->iBKGDgreen;
+ pBuftarget->iBKGDblue = pBufdelta->iBKGDblue;
+ }
+#endif
+
+ if (pBufdelta->bHasGAMA) /* gamma in source ? */
+ {
+ pBuftarget->bHasGAMA = MNG_TRUE; /* drop it onto the target */
+ pBuftarget->iGamma = pBufdelta->iGamma;
+ }
+
+#ifndef MNG_SKIPCHUNK_cHRM
+ if (pBufdelta->bHasCHRM) /* chroma in delta ? */
+ { /* drop it onto the target */
+ pBuftarget->bHasCHRM = MNG_TRUE;
+ pBuftarget->iWhitepointx = pBufdelta->iWhitepointx;
+ pBuftarget->iWhitepointy = pBufdelta->iWhitepointy;
+ pBuftarget->iPrimaryredx = pBufdelta->iPrimaryredx;
+ pBuftarget->iPrimaryredy = pBufdelta->iPrimaryredy;
+ pBuftarget->iPrimarygreenx = pBufdelta->iPrimarygreenx;
+ pBuftarget->iPrimarygreeny = pBufdelta->iPrimarygreeny;
+ pBuftarget->iPrimarybluex = pBufdelta->iPrimarybluex;
+ pBuftarget->iPrimarybluey = pBufdelta->iPrimarybluey;
+ }
+#endif
+
+#ifndef MNG_SKIPCHUNK_sRGB
+ if (pBufdelta->bHasSRGB) /* sRGB in delta ? */
+ { /* drop it onto the target */
+ pBuftarget->bHasSRGB = MNG_TRUE;
+ pBuftarget->iRenderingintent = pBufdelta->iRenderingintent;
+ }
+#endif
+
+#ifndef MNG_SKIPCHUNK_iCCP
+ if (pBufdelta->bHasICCP) /* ICC profile in delta ? */
+ {
+ pBuftarget->bHasICCP = MNG_TRUE; /* drop it onto the target */
+
+ if (pBuftarget->pProfile) /* profile existed ? */
+ MNG_FREEX (pData, pBuftarget->pProfile, pBuftarget->iProfilesize);
+ /* allocate a buffer & copy it */
+ MNG_ALLOC (pData, pBuftarget->pProfile, pBufdelta->iProfilesize);
+ MNG_COPY (pBuftarget->pProfile, pBufdelta->pProfile, pBufdelta->iProfilesize);
+ /* store its length as well */
+ pBuftarget->iProfilesize = pBufdelta->iProfilesize;
+ }
+#endif
+ /* need to execute delta pixels ? */
+ if ((!pData->bDeltaimmediate) && (pData->iDeltatype != MNG_DELTATYPE_NOCHANGE))
+ {
+ pData->fScalerow = MNG_NULL; /* not needed by default */
+
+ switch (pBufdelta->iBitdepth) /* determine scaling routine */
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 2 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g2; break; }
+ case 4 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g4; break; }
+
+ case 8 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g1_g16; break; }
+#endif
+ }
+ break;
+ }
+
+ case 2 : {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 1 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g1; break; }
+ case 4 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g4; break; }
+ case 8 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g2_g16; break; }
+#endif
+ }
+ break;
+ }
+
+ case 4 : {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 1 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g1; break; }
+ case 2 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g2; break; }
+ case 8 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g4_g16; break; }
+#endif
+ }
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+
+ case 8 : {
+ switch (pBufdelta->iColortype)
+ {
+ case 0 : ;
+ case 3 : ;
+ case 8 : {
+ switch (pBuftarget->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g1; break; }
+ case 2 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g2; break; }
+ case 4 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g4; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fScalerow = (mng_fptr)mng_scale_g8_g16; break; }
+#endif
+ }
+ break;
+ }
+ case 2 : ;
+ case 10 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pBuftarget->iBitdepth == 16)
+ pData->fScalerow = (mng_fptr)mng_scale_rgb8_rgb16;
+#endif
+ break;
+ }
+ case 4 : ;
+ case 12 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pBuftarget->iBitdepth == 16)
+ pData->fScalerow = (mng_fptr)mng_scale_ga8_ga16;
+#endif
+ break;
+ }
+ case 6 : ;
+ case 14 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pBuftarget->iBitdepth == 16)
+ pData->fScalerow = (mng_fptr)mng_scale_rgba8_rgba16;
+#endif
+ break;
+ }
+ }
+ break;
+ }
+
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ switch (pBufdelta->iColortype)
+ {
+ case 0 : ;
+ case 3 : ;
+ case 8 : {
+ switch (pBuftarget->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g1; break; }
+ case 2 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g2; break; }
+ case 4 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g4; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->fScalerow = (mng_fptr)mng_scale_g16_g8; break; }
+ }
+ break;
+ }
+ case 2 : ;
+ case 10 : {
+ if (pBuftarget->iBitdepth == 8)
+ pData->fScalerow = (mng_fptr)mng_scale_rgb16_rgb8;
+ break;
+ }
+ case 4 : ;
+ case 12 : {
+ if (pBuftarget->iBitdepth == 8)
+ pData->fScalerow = (mng_fptr)mng_scale_ga16_ga8;
+ break;
+ }
+ case 6 : ;
+ case 14 : {
+ if (pBuftarget->iBitdepth == 8)
+ pData->fScalerow = (mng_fptr)mng_scale_rgba16_rgba8;
+ break;
+ }
+ }
+ break;
+ }
+#endif
+
+ }
+
+ pData->fDeltarow = MNG_NULL; /* let's assume there's nothing to do */
+
+ switch (pBuftarget->iColortype) /* determine delta processing routine */
+ {
+ case 0 : ;
+ case 8 : { /* gray */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
+ (pBufdelta->iColortype == 8))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->fDeltarow = (mng_fptr)mng_delta_g1_g1; break; }
+ case 2 : { pData->fDeltarow = (mng_fptr)mng_delta_g2_g2; break; }
+ case 4 : { pData->fDeltarow = (mng_fptr)mng_delta_g4_g4; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_g8_g8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_g16_g16; break; }
+#endif
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 2 : ;
+ case 10 : { /* rgb */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgb8_rgb8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgb16_rgb16; break; }
+#endif
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 3 : { /* indexed; abuse gray routines */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->fDeltarow = (mng_fptr)mng_delta_g1_g1; break; }
+ case 2 : { pData->fDeltarow = (mng_fptr)mng_delta_g2_g2; break; }
+ case 4 : { pData->fDeltarow = (mng_fptr)mng_delta_g4_g4; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_g8_g8; break; }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 4 : ;
+ case 12 : { /* gray + alpha */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 4) || (pBufdelta->iColortype == 12))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_ga8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_ga16; break; }
+#endif
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
+ (pBufdelta->iColortype == 8))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_g8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_g16; break; }
+#endif
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_ga8_a8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_ga16_a16; break; }
+#endif
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 6 : ;
+ case 14 : { /* rgb + alpha */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 6) || (pBufdelta->iColortype == 14))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgba8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgba16; break; }
+#endif
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgb8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgb16; break; }
+#endif
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba8_a8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fDeltarow = (mng_fptr)mng_delta_rgba16_a16; break; }
+#endif
+ }
+ }
+ }
+
+ break;
+ }
+
+ }
+
+ if (pData->fDeltarow) /* do we need to take action ? */
+ {
+ pData->iPass = -1; /* setup row dimensions and stuff */
+ pData->iRow = pData->iDeltaBlocky;
+ pData->iRowinc = 1;
+ pData->iCol = pData->iDeltaBlockx;
+ pData->iColinc = 1;
+ pData->iRowsamples = pBufdelta->iWidth;
+ pData->iRowsize = pBuftarget->iRowsize;
+ /* indicate where to retrieve & where to store */
+ pData->pRetrieveobj = (mng_objectp)pDelta;
+ pData->pStoreobj = (mng_objectp)pTarget;
+
+ pSaveRGBA = pData->pRGBArow; /* save current temp-buffer! */
+ /* get a temporary row-buffer */
+ MNG_ALLOC (pData, pData->pRGBArow, (pBufdelta->iRowsize << 1));
+
+ iY = 0; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* still oke for now */
+
+ while ((!iRetcode) && (iY < pBufdelta->iHeight))
+ { /* get a row */
+ mng_uint8p pWork = pBufdelta->pImgdata + (iY * pBufdelta->iRowsize);
+
+ MNG_COPY (pData->pRGBArow, pWork, pBufdelta->iRowsize);
+
+ if (pData->fScalerow) /* scale it (if necessary) */
+ iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
+
+ if (!iRetcode) /* and... execute it */
+ iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
+
+ if (!iRetcode) /* adjust variables for next row */
+ iRetcode = mng_next_row (pData);
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, (pBufdelta->iRowsize << 1));
+ pData->pRGBArow = pSaveRGBA; /* restore saved temp-buffer! */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+ else
+ MNG_ERROR (pData, MNG_INVALIDDELTA);
+
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_NO_DELTA_PNG */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_SAVE
+MNG_LOCAL mng_retcode save_state (mng_datap pData)
+{
+ mng_savedatap pSave;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_START);
+#endif
+
+ if (pData->pSavedata) /* sanity check */
+ MNG_ERROR (pData, MNG_INTERNALERROR);
+ /* get a buffer for saving */
+ MNG_ALLOC (pData, pData->pSavedata, sizeof (mng_savedata));
+
+ pSave = pData->pSavedata; /* address it more directly */
+ /* and copy global data from the main struct */
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ pSave->bHasglobalPLTE = pData->bHasglobalPLTE;
+ pSave->bHasglobalTRNS = pData->bHasglobalTRNS;
+ pSave->bHasglobalGAMA = pData->bHasglobalGAMA;
+ pSave->bHasglobalCHRM = pData->bHasglobalCHRM;
+ pSave->bHasglobalSRGB = pData->bHasglobalSRGB;
+ pSave->bHasglobalICCP = pData->bHasglobalICCP;
+ pSave->bHasglobalBKGD = pData->bHasglobalBKGD;
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+#ifndef MNG_SKIPCHUNK_BACK
+ pSave->iBACKred = pData->iBACKred;
+ pSave->iBACKgreen = pData->iBACKgreen;
+ pSave->iBACKblue = pData->iBACKblue;
+ pSave->iBACKmandatory = pData->iBACKmandatory;
+ pSave->iBACKimageid = pData->iBACKimageid;
+ pSave->iBACKtile = pData->iBACKtile;
+#endif
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ pSave->iFRAMmode = pData->iFRAMmode;
+ pSave->iFRAMdelay = pData->iFRAMdelay;
+ pSave->iFRAMtimeout = pData->iFRAMtimeout;
+ pSave->bFRAMclipping = pData->bFRAMclipping;
+ pSave->iFRAMclipl = pData->iFRAMclipl;
+ pSave->iFRAMclipr = pData->iFRAMclipr;
+ pSave->iFRAMclipt = pData->iFRAMclipt;
+ pSave->iFRAMclipb = pData->iFRAMclipb;
+#endif
+
+ pSave->iGlobalPLTEcount = pData->iGlobalPLTEcount;
+
+ MNG_COPY (pSave->aGlobalPLTEentries, pData->aGlobalPLTEentries, sizeof (mng_rgbpaltab));
+
+ pSave->iGlobalTRNSrawlen = pData->iGlobalTRNSrawlen;
+ MNG_COPY (pSave->aGlobalTRNSrawdata, pData->aGlobalTRNSrawdata, 256);
+
+ pSave->iGlobalGamma = pData->iGlobalGamma;
+
+#ifndef MNG_SKIPCHUNK_cHRM
+ pSave->iGlobalWhitepointx = pData->iGlobalWhitepointx;
+ pSave->iGlobalWhitepointy = pData->iGlobalWhitepointy;
+ pSave->iGlobalPrimaryredx = pData->iGlobalPrimaryredx;
+ pSave->iGlobalPrimaryredy = pData->iGlobalPrimaryredy;
+ pSave->iGlobalPrimarygreenx = pData->iGlobalPrimarygreenx;
+ pSave->iGlobalPrimarygreeny = pData->iGlobalPrimarygreeny;
+ pSave->iGlobalPrimarybluex = pData->iGlobalPrimarybluex;
+ pSave->iGlobalPrimarybluey = pData->iGlobalPrimarybluey;
+#endif
+
+#ifndef MNG_SKIPCHUNK_sRGB
+ pSave->iGlobalRendintent = pData->iGlobalRendintent;
+#endif
+
+#ifndef MNG_SKIPCHUNK_iCCP
+ pSave->iGlobalProfilesize = pData->iGlobalProfilesize;
+
+ if (pSave->iGlobalProfilesize) /* has a profile ? */
+ { /* then copy that ! */
+ MNG_ALLOC (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize);
+ MNG_COPY (pSave->pGlobalProfile, pData->pGlobalProfile, pSave->iGlobalProfilesize);
+ }
+#endif
+
+#ifndef MNG_SKIPCHUNK_bKGD
+ pSave->iGlobalBKGDred = pData->iGlobalBKGDred;
+ pSave->iGlobalBKGDgreen = pData->iGlobalBKGDgreen;
+ pSave->iGlobalBKGDblue = pData->iGlobalBKGDblue;
+#endif
+
+ /* freeze current image objects */
+ pImage = (mng_imagep)pData->pFirstimgobj;
+
+ while (pImage)
+ { /* freeze the object AND its buffer */
+ pImage->bFrozen = MNG_TRUE;
+ pImage->pImgbuf->bFrozen = MNG_TRUE;
+ /* neeeext */
+ pImage = (mng_imagep)pImage->sHeader.pNext;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode mng_reset_objzero (mng_datap pData)
+{
+ mng_imagep pImage = (mng_imagep)pData->pObjzero;
+ mng_retcode iRetcode = mng_reset_object_details (pData, pImage, 0, 0, 0,
+ 0, 0, 0, 0, MNG_TRUE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pImage->bVisible = MNG_TRUE;
+ pImage->bViewable = MNG_TRUE;
+ pImage->iPosx = 0;
+ pImage->iPosy = 0;
+ pImage->bClipped = MNG_FALSE;
+ pImage->iClipl = 0;
+ pImage->iClipr = 0;
+ pImage->iClipt = 0;
+ pImage->iClipb = 0;
+#ifndef MNG_SKIPCHUNK_MAGN
+ pImage->iMAGN_MethodX = 0;
+ pImage->iMAGN_MethodY = 0;
+ pImage->iMAGN_MX = 0;
+ pImage->iMAGN_MY = 0;
+ pImage->iMAGN_ML = 0;
+ pImage->iMAGN_MR = 0;
+ pImage->iMAGN_MT = 0;
+ pImage->iMAGN_MB = 0;
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+MNG_LOCAL mng_retcode restore_state (mng_datap pData)
+{
+#ifndef MNG_SKIPCHUNK_SAVE
+ mng_savedatap pSave;
+#endif
+ mng_imagep pImage;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_START);
+#endif
+ /* restore object 0 status !!! */
+ iRetcode = mng_reset_objzero (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fresh cycle; fake no frames done yet */
+ pData->bFramedone = MNG_FALSE;
+
+#ifndef MNG_SKIPCHUNK_SAVE
+ if (pData->pSavedata) /* do we have a saved state ? */
+ {
+ pSave = pData->pSavedata; /* address it more directly */
+ /* and copy it back to the main struct */
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ pData->bHasglobalPLTE = pSave->bHasglobalPLTE;
+ pData->bHasglobalTRNS = pSave->bHasglobalTRNS;
+ pData->bHasglobalGAMA = pSave->bHasglobalGAMA;
+ pData->bHasglobalCHRM = pSave->bHasglobalCHRM;
+ pData->bHasglobalSRGB = pSave->bHasglobalSRGB;
+ pData->bHasglobalICCP = pSave->bHasglobalICCP;
+ pData->bHasglobalBKGD = pSave->bHasglobalBKGD;
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+#ifndef MNG_SKIPCHUNK_BACK
+ pData->iBACKred = pSave->iBACKred;
+ pData->iBACKgreen = pSave->iBACKgreen;
+ pData->iBACKblue = pSave->iBACKblue;
+ pData->iBACKmandatory = pSave->iBACKmandatory;
+ pData->iBACKimageid = pSave->iBACKimageid;
+ pData->iBACKtile = pSave->iBACKtile;
+#endif
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ pData->iFRAMmode = pSave->iFRAMmode;
+/* pData->iFRAMdelay = pSave->iFRAMdelay; */
+ pData->iFRAMtimeout = pSave->iFRAMtimeout;
+ pData->bFRAMclipping = pSave->bFRAMclipping;
+ pData->iFRAMclipl = pSave->iFRAMclipl;
+ pData->iFRAMclipr = pSave->iFRAMclipr;
+ pData->iFRAMclipt = pSave->iFRAMclipt;
+ pData->iFRAMclipb = pSave->iFRAMclipb;
+ /* NOOOOOOOOOOOO */
+/* pData->iFramemode = pSave->iFRAMmode;
+ pData->iFramedelay = pSave->iFRAMdelay;
+ pData->iFrametimeout = pSave->iFRAMtimeout;
+ pData->bFrameclipping = pSave->bFRAMclipping;
+ pData->iFrameclipl = pSave->iFRAMclipl;
+ pData->iFrameclipr = pSave->iFRAMclipr;
+ pData->iFrameclipt = pSave->iFRAMclipt;
+ pData->iFrameclipb = pSave->iFRAMclipb; */
+
+/* pData->iNextdelay = pSave->iFRAMdelay; */
+ pData->iNextdelay = pData->iFramedelay;
+#endif
+
+ pData->iGlobalPLTEcount = pSave->iGlobalPLTEcount;
+ MNG_COPY (pData->aGlobalPLTEentries, pSave->aGlobalPLTEentries, sizeof (mng_rgbpaltab));
+
+ pData->iGlobalTRNSrawlen = pSave->iGlobalTRNSrawlen;
+ MNG_COPY (pData->aGlobalTRNSrawdata, pSave->aGlobalTRNSrawdata, 256);
+
+ pData->iGlobalGamma = pSave->iGlobalGamma;
+
+#ifndef MNG_SKIPCHUNK_cHRM
+ pData->iGlobalWhitepointx = pSave->iGlobalWhitepointx;
+ pData->iGlobalWhitepointy = pSave->iGlobalWhitepointy;
+ pData->iGlobalPrimaryredx = pSave->iGlobalPrimaryredx;
+ pData->iGlobalPrimaryredy = pSave->iGlobalPrimaryredy;
+ pData->iGlobalPrimarygreenx = pSave->iGlobalPrimarygreenx;
+ pData->iGlobalPrimarygreeny = pSave->iGlobalPrimarygreeny;
+ pData->iGlobalPrimarybluex = pSave->iGlobalPrimarybluex;
+ pData->iGlobalPrimarybluey = pSave->iGlobalPrimarybluey;
+#endif
+
+ pData->iGlobalRendintent = pSave->iGlobalRendintent;
+
+#ifndef MNG_SKIPCHUNK_iCCP
+ pData->iGlobalProfilesize = pSave->iGlobalProfilesize;
+
+ if (pData->iGlobalProfilesize) /* has a profile ? */
+ { /* then copy that ! */
+ MNG_ALLOC (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
+ MNG_COPY (pData->pGlobalProfile, pSave->pGlobalProfile, pData->iGlobalProfilesize);
+ }
+#endif
+
+#ifndef MNG_SKIPCHUNK_bKGD
+ pData->iGlobalBKGDred = pSave->iGlobalBKGDred;
+ pData->iGlobalBKGDgreen = pSave->iGlobalBKGDgreen;
+ pData->iGlobalBKGDblue = pSave->iGlobalBKGDblue;
+#endif
+ }
+ else /* no saved-data; so reset the lot */
+#endif /* SKIPCHUNK_SAVE */
+ {
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ pData->bHasglobalPLTE = MNG_FALSE;
+ pData->bHasglobalTRNS = MNG_FALSE;
+ pData->bHasglobalGAMA = MNG_FALSE;
+ pData->bHasglobalCHRM = MNG_FALSE;
+ pData->bHasglobalSRGB = MNG_FALSE;
+ pData->bHasglobalICCP = MNG_FALSE;
+ pData->bHasglobalBKGD = MNG_FALSE;
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+#ifndef MNG_SKIPCHUNK_TERM
+ if (!pData->bMisplacedTERM) /* backward compatible ugliness !!! */
+ {
+ pData->iBACKred = 0;
+ pData->iBACKgreen = 0;
+ pData->iBACKblue = 0;
+ pData->iBACKmandatory = 0;
+ pData->iBACKimageid = 0;
+ pData->iBACKtile = 0;
+ }
+#endif
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ pData->iFRAMmode = 1;
+/* pData->iFRAMdelay = 1; */
+ pData->iFRAMtimeout = 0x7fffffffl;
+ pData->bFRAMclipping = MNG_FALSE;
+ pData->iFRAMclipl = 0;
+ pData->iFRAMclipr = 0;
+ pData->iFRAMclipt = 0;
+ pData->iFRAMclipb = 0;
+ /* NOOOOOOOOOOOO */
+/* pData->iFramemode = 1;
+ pData->iFramedelay = 1;
+ pData->iFrametimeout = 0x7fffffffl;
+ pData->bFrameclipping = MNG_FALSE;
+ pData->iFrameclipl = 0;
+ pData->iFrameclipr = 0;
+ pData->iFrameclipt = 0;
+ pData->iFrameclipb = 0; */
+
+/* pData->iNextdelay = 1; */
+ pData->iNextdelay = pData->iFramedelay;
+#endif
+
+ pData->iGlobalPLTEcount = 0;
+
+ pData->iGlobalTRNSrawlen = 0;
+
+ pData->iGlobalGamma = 0;
+
+#ifndef MNG_SKIPCHUNK_cHRM
+ pData->iGlobalWhitepointx = 0;
+ pData->iGlobalWhitepointy = 0;
+ pData->iGlobalPrimaryredx = 0;
+ pData->iGlobalPrimaryredy = 0;
+ pData->iGlobalPrimarygreenx = 0;
+ pData->iGlobalPrimarygreeny = 0;
+ pData->iGlobalPrimarybluex = 0;
+ pData->iGlobalPrimarybluey = 0;
+#endif
+
+ pData->iGlobalRendintent = 0;
+
+#ifndef MNG_SKIPCHUNK_iCCP
+ if (pData->iGlobalProfilesize) /* free a previous profile ? */
+ MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
+
+ pData->iGlobalProfilesize = 0;
+#endif
+
+#ifndef MNG_SKIPCHUNK_bKGD
+ pData->iGlobalBKGDred = 0;
+ pData->iGlobalBKGDgreen = 0;
+ pData->iGlobalBKGDblue = 0;
+#endif
+ }
+
+#ifndef MNG_SKIPCHUNK_TERM
+ if (!pData->bMisplacedTERM) /* backward compatible ugliness !!! */
+ {
+ pImage = (mng_imagep)pData->pFirstimgobj;
+ /* drop un-frozen image objects */
+ while (pImage)
+ {
+ mng_imagep pNext = (mng_imagep)pImage->sHeader.pNext;
+
+ if (!pImage->bFrozen) /* is it un-frozen ? */
+ {
+ mng_imagep pPrev = (mng_imagep)pImage->sHeader.pPrev;
+
+ if (pPrev) /* unlink it */
+ pPrev->sHeader.pNext = pNext;
+ else
+ pData->pFirstimgobj = pNext;
+
+ if (pNext)
+ pNext->sHeader.pPrev = pPrev;
+ else
+ pData->pLastimgobj = pPrev;
+
+ if (pImage->pImgbuf->bFrozen) /* buffer frozen ? */
+ {
+ if (pImage->pImgbuf->iRefcount < 2)
+ MNG_ERROR (pData, MNG_INTERNALERROR);
+ /* decrease ref counter */
+ pImage->pImgbuf->iRefcount--;
+ /* just cleanup the object then */
+ MNG_FREEX (pData, pImage, sizeof (mng_image));
+ }
+ else
+ { /* free the image buffer */
+ iRetcode = mng_free_imagedataobject (pData, pImage->pImgbuf);
+ /* and cleanup the object */
+ MNG_FREEX (pData, pImage, sizeof (mng_image));
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+
+ pImage = pNext; /* neeeext */
+ }
+ }
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * General display processing routine * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode mng_process_display (mng_datap pData)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_START);
+#endif
+
+ if (!pData->iBreakpoint) /* not broken previously ? */
+ {
+ if ((pData->iRequestframe) || (pData->iRequestlayer) || (pData->iRequesttime))
+ {
+ pData->bSearching = MNG_TRUE; /* indicate we're searching */
+
+ iRetcode = clear_canvas (pData); /* make the canvas virgin black ?!? */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* let's start from the top, shall we */
+ pData->pCurraniobj = pData->pFirstaniobj;
+ }
+ }
+
+ do /* process the objects */
+ {
+ if (pData->bSearching) /* clear timer-flag when searching !!! */
+ pData->bTimerset = MNG_FALSE;
+ /* do we need to finish something first ? */
+ if ((pData->iBreakpoint) && (pData->iBreakpoint < 99))
+ {
+ switch (pData->iBreakpoint) /* return to broken display routine */
+ {
+#ifndef MNG_SKIPCHUNK_FRAM
+ case 1 : { iRetcode = mng_process_display_fram2 (pData); break; }
+#endif
+#ifndef MNG_SKIPCHUNK_SHOW
+ case 3 : ; /* same as 4 !!! */
+ case 4 : { iRetcode = mng_process_display_show (pData); break; }
+#endif
+#ifndef MNG_SKIPCHUNK_CLON
+ case 5 : { iRetcode = mng_process_display_clon2 (pData); break; }
+#endif
+#ifndef MNG_SKIPCHUNK_MAGN
+ case 9 : { iRetcode = mng_process_display_magn2 (pData); break; }
+ case 10 : { iRetcode = mng_process_display_mend2 (pData); break; }
+#endif
+#ifndef MNG_SKIPCHUNK_PAST
+ case 11 : { iRetcode = mng_process_display_past2 (pData); break; }
+#endif
+ default : MNG_ERROR (pData, MNG_INTERNALERROR);
+ }
+ }
+ else
+ {
+ if (pData->pCurraniobj)
+ iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
+ }
+
+ if (!pData->bTimerset) /* reset breakpoint flag ? */
+ pData->iBreakpoint = 0;
+ /* can we advance to next object ? */
+ if ((!iRetcode) && (pData->pCurraniobj) &&
+ (!pData->bTimerset) && (!pData->bSectionwait))
+ {
+ pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
+ /* MEND processing to be done ? */
+ if ((pData->eImagetype == mng_it_mng) && (!pData->pCurraniobj))
+ iRetcode = mng_process_display_mend (pData);
+
+ if (!pData->pCurraniobj) /* refresh after last image ? */
+ pData->bNeedrefresh = MNG_TRUE;
+ }
+
+ if (pData->bSearching) /* are we looking for something ? */
+ {
+ if ((pData->iRequestframe) && (pData->iRequestframe <= pData->iFrameseq))
+ {
+ pData->iRequestframe = 0; /* found the frame ! */
+ pData->bSearching = MNG_FALSE;
+ }
+ else
+ if ((pData->iRequestlayer) && (pData->iRequestlayer <= pData->iLayerseq))
+ {
+ pData->iRequestlayer = 0; /* found the layer ! */
+ pData->bSearching = MNG_FALSE;
+ }
+ else
+ if ((pData->iRequesttime) && (pData->iRequesttime <= pData->iFrametime))
+ {
+ pData->iRequesttime = 0; /* found the playtime ! */
+ pData->bSearching = MNG_FALSE;
+ }
+ }
+ } /* until error or a break or no more objects */
+ while ((!iRetcode) && (pData->pCurraniobj) &&
+ (((pData->bRunning) && (!pData->bTimerset)) || (pData->bSearching)) &&
+ (!pData->bSectionwait) && (!pData->bFreezing));
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* refresh needed ? */
+ if ((!pData->bTimerset) && (pData->bNeedrefresh))
+ {
+ iRetcode = mng_display_progressive_refresh (pData, 1);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* timer break ? */
+ if ((pData->bTimerset) && (!pData->iBreakpoint))
+ pData->iBreakpoint = 99;
+ else
+ if (!pData->bTimerset)
+ pData->iBreakpoint = 0; /* reset if no timer break */
+
+ if ((!pData->bTimerset) && (!pData->pCurraniobj))
+ pData->bRunning = MNG_FALSE; /* all done now ! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk display processing routines * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+png_imgtype mng_png_imgtype(mng_uint8 colortype, mng_uint8 bitdepth)
+{
+ png_imgtype ret;
+ switch (bitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1:
+ {
+ png_imgtype imgtype[]={png_g1,png_none,png_none,png_idx1};
+ ret=imgtype[colortype];
+ break;
+ }
+ case 2:
+ {
+ png_imgtype imgtype[]={png_g2,png_none,png_none,png_idx2};
+ ret=imgtype[colortype];
+ break;
+ }
+ case 4:
+ {
+ png_imgtype imgtype[]={png_g4,png_none,png_none,png_idx4};
+ ret=imgtype[colortype];
+ break;
+ }
+#endif
+ case 8:
+ {
+ png_imgtype imgtype[]={png_g8,png_none,png_rgb8,png_idx8,png_ga8,
+ png_none,png_rgba8};
+ ret=imgtype[colortype];
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16:
+ {
+ png_imgtype imgtype[]={png_g16,png_none,png_rgb16,png_none,png_ga16,
+ png_none,png_rgba16};
+ ret=imgtype[colortype];
+ break;
+ }
+#endif
+ default:
+ ret=png_none;
+ break;
+ }
+ return (ret);
+}
+#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_display_ihdr (mng_datap pData)
+{ /* address the current "object" if any */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_START);
+#endif
+
+ if (!pData->bHasDHDR)
+ {
+ pData->fInitrowproc = MNG_NULL; /* do nothing by default */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->fDifferrow = MNG_NULL;
+ pData->pStoreobj = MNG_NULL;
+ }
+
+ if (!pData->iBreakpoint) /* not previously broken ? */
+ {
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifndef MNG_NO_DELTA_PNG
+ if (pData->bHasDHDR) /* is a delta-image ? */
+ {
+ if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
+ iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
+
+ if (!iRetcode)
+ { /* process immediately if bitdepth & colortype are equal */
+ pData->bDeltaimmediate =
+ (mng_bool)((pData->iBitdepth == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
+ (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype) );
+ /* be sure to reset object 0 */
+ iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ }
+ }
+ else
+#endif
+ {
+ if (pImage) /* update object buffer ? */
+ iRetcode = mng_reset_object_details (pData, pImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ else
+ iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+#ifndef MNG_NO_DELTA_PNG
+ if (!pData->bHasDHDR)
+#endif
+ {
+ if (pImage) /* real object ? */
+ pData->pStoreobj = pImage; /* tell the row routines */
+ else /* otherwise use object 0 */
+ pData->pStoreobj = pData->pObjzero;
+
+#if !defined(MNG_INCLUDE_MPNG_PROPOSAL) && !defined(MNG_INCLUDE_ANG_PROPOSAL)
+ if ( /* display "on-the-fly" ? */
+#ifndef MNG_SKIPCHUNK_MAGN
+ (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
+ (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
+#endif
+ ( (pData->eImagetype == mng_it_png ) ||
+ (((mng_imagep)pData->pStoreobj)->bVisible) ) )
+ {
+ next_layer (pData); /* that's a new layer then ! */
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 2;
+ else
+ {
+ pData->iBreakpoint = 0;
+ /* anything to display ? */
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ set_display_routine (pData); /* then determine display routine */
+ }
+ }
+#endif
+ }
+
+ if (!pData->bTimerset) /* no timer break ? */
+ {
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+ pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
+ pData->ePng_imgtype=mng_png_imgtype(pData->iColortype,pData->iBitdepth);
+#else
+ switch (pData->iColortype) /* determine row initialization routine */
+ {
+ case 0 : { /* gray */
+ switch (pData->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 2 : { /* rgb */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ switch (pData->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
+
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ }
+#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
+
+ pData->iFilterofs = 0; /* determine filter characteristics */
+ pData->iLevel0 = 0; /* default levels */
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iFilter == MNG_FILTER_DIFFERING)
+ {
+ switch (pData->iColortype)
+ {
+ case 0 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 1;
+ else
+ pData->iFilterofs = 2;
+
+ break;
+ }
+ case 2 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 3;
+ else
+ pData->iFilterofs = 6;
+
+ break;
+ }
+ case 3 : {
+ pData->iFilterofs = 1;
+ break;
+ }
+ case 4 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 2;
+ else
+ pData->iFilterofs = 4;
+
+ break;
+ }
+ case 6 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 4;
+ else
+ pData->iFilterofs = 8;
+
+ break;
+ }
+ }
+ }
+#endif
+
+#ifdef FILTER193 /* no adaptive filtering ? */
+ if (pData->iFilter == MNG_FILTER_NOFILTER)
+ pData->iPixelofs = pData->iFilterofs;
+ else
+#endif
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_MPNG_PROPOSAL
+mng_retcode mng_process_display_mpng (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MPNG, MNG_LC_START);
+#endif
+
+ pData->iAlphadepth = 8; /* assume transparency !! */
+
+ if (pData->fProcessheader) /* inform the app (creating the output canvas) ? */
+ {
+ pData->iWidth = ((mng_mpng_objp)pData->pMPNG)->iFramewidth;
+ pData->iHeight = ((mng_mpng_objp)pData->pMPNG)->iFrameheight;
+
+ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+ }
+
+ next_layer (pData); /* first mPNG layer then ! */
+ pData->bTimerset = MNG_FALSE;
+ pData->iBreakpoint = 0;
+
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ set_display_routine (pData); /* then determine display routine */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MPNG, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ANG_PROPOSAL
+mng_retcode mng_process_display_ang (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_ANG, MNG_LC_START);
+#endif
+
+ if (pData->fProcessheader) /* inform the app (creating the output canvas) ? */
+ {
+ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+ }
+
+ next_layer (pData); /* first mPNG layer then ! */
+ pData->bTimerset = MNG_FALSE;
+ pData->iBreakpoint = 0;
+
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ set_display_routine (pData); /* then determine display routine */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_ANG, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_idat (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+#else
+mng_retcode mng_process_display_idat (mng_datap pData)
+#endif
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_START);
+#endif
+
+#if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
+ if ((pData->eImagetype == mng_it_png) && (pData->iLayerseq <= 0))
+ {
+ if (pData->fProcessheader) /* inform the app (creating the output canvas) ? */
+ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ next_layer (pData); /* first regular PNG layer then ! */
+ pData->bTimerset = MNG_FALSE;
+ pData->iBreakpoint = 0;
+
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ set_display_routine (pData); /* then determine display routine */
+ }
+#endif
+
+ if (pData->bRestorebkgd) /* need to restore the background ? */
+ {
+ pData->bRestorebkgd = MNG_FALSE;
+ iRetcode = load_bkgdlayer (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+ }
+
+ if (pData->fInitrowproc) /* need to initialize row processing? */
+ {
+ iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
+ pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
+ }
+
+ if ((!iRetcode) && (!pData->bInflating))
+ /* initialize inflate */
+ iRetcode = mngzlib_inflateinit (pData);
+
+ if (!iRetcode) /* all ok? then inflate, my man */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ iRetcode = mngzlib_inflaterows (pData, iRawlen, pRawdata);
+#else
+ iRetcode = mngzlib_inflaterows (pData, pData->iRawlen, pData->pRawdata);
+#endif
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_display_iend (mng_datap pData)
+{
+ mng_retcode iRetcode, iRetcode2;
+ mng_bool bDodisplay = MNG_FALSE;
+ mng_bool bMagnify = MNG_FALSE;
+ mng_bool bCleanup = (mng_bool)(pData->iBreakpoint != 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_START);
+#endif
+
+#ifdef MNG_INCLUDE_JNG /* progressive+alpha JNG can be displayed now */
+ if ( (pData->bHasJHDR ) &&
+ ( (pData->bJPEGprogressive) || (pData->bJPEGprogressive2)) &&
+ ( (pData->eImagetype == mng_it_jng ) ||
+ (((mng_imagep)pData->pStoreobj)->bVisible) ) &&
+ ( (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) )
+ bDodisplay = MNG_TRUE;
+#endif
+
+#ifndef MNG_SKIPCHUNK_MAGN
+ if ( (pData->pStoreobj) && /* on-the-fly magnification ? */
+ ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX) ||
+ (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY) ) )
+ bMagnify = MNG_TRUE;
+#endif
+
+ if ((pData->bHasBASI) || /* was it a BASI stream */
+ (bDodisplay) || /* or should we display the JNG */
+#ifndef MNG_SKIPCHUNK_MAGN
+ (bMagnify) || /* or should we magnify it */
+#endif
+ /* or did we get broken here last time ? */
+ ((pData->iBreakpoint) && (pData->iBreakpoint != 8)))
+ {
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* or was it object 0 ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* display it now then ? */
+ if ((pImage->bVisible) && (pImage->bViewable))
+ { /* ok, so do it */
+ iRetcode = mng_display_image (pData, pImage, bDodisplay);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 6;
+ }
+ }
+#ifndef MNG_NO_DELTA_PNG
+ else
+ if ((pData->bHasDHDR) || /* was it a DHDR stream */
+ (pData->iBreakpoint == 8)) /* or did we get broken here last time ? */
+ {
+ mng_imagep pImage = (mng_imagep)pData->pDeltaImage;
+
+ if (!pData->iBreakpoint)
+ { /* perform the delta operations needed */
+ iRetcode = mng_execute_delta_image (pData, pImage, (mng_imagep)pData->pObjzero);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* display it now then ? */
+ if ((pImage->bVisible) && (pImage->bViewable))
+ { /* ok, so do it */
+ iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 8;
+ }
+ }
+#endif
+
+ if (!pData->bTimerset) /* can we continue ? */
+ {
+ pData->iBreakpoint = 0; /* clear this flag now ! */
+
+
+#ifdef MNG_INCLUDE_MPNG_PROPOSAL
+ if (pData->eImagetype == mng_it_mpng)
+ {
+ pData->pCurraniobj = pData->pFirstaniobj;
+ } else
+#endif
+#ifdef MNG_INCLUDE_ANG_PROPOSAL
+ if (pData->eImagetype == mng_it_ang)
+ {
+ pData->pCurraniobj = pData->pFirstaniobj;
+ } else
+#endif
+ { /* cleanup object 0 */
+ mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ 0, 0, 0, 0, 0, 0, 0, MNG_TRUE);
+ }
+
+ if (pData->bInflating) /* if we've been inflating */
+ { /* cleanup row-processing, */
+ iRetcode = mng_cleanup_rowproc (pData);
+ /* also cleanup inflate! */
+ iRetcode2 = mngzlib_inflatefree (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ if (iRetcode2)
+ return iRetcode2;
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if (pData->bJPEGdecompress) /* if we've been decompressing JDAT */
+ { /* cleanup row-processing, */
+ iRetcode = mng_cleanup_rowproc (pData);
+ /* also cleanup decompress! */
+ iRetcode2 = mngjpeg_decompressfree (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ if (iRetcode2)
+ return iRetcode2;
+ }
+
+ if (pData->bJPEGdecompress2) /* if we've been decompressing JDAA */
+ { /* cleanup row-processing, */
+ iRetcode = mng_cleanup_rowproc (pData);
+ /* also cleanup decompress! */
+ iRetcode2 = mngjpeg_decompressfree2 (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ if (iRetcode2)
+ return iRetcode2;
+ }
+#endif
+
+ if (bCleanup) /* if we got broken last time we need to cleanup */
+ {
+ pData->bHasIHDR = MNG_FALSE; /* IEND signals the end for most ... */
+ pData->bHasBASI = MNG_FALSE;
+ pData->bHasDHDR = MNG_FALSE;
+#ifdef MNG_INCLUDE_JNG
+ pData->bHasJHDR = MNG_FALSE;
+ pData->bHasJSEP = MNG_FALSE;
+ pData->bHasJDAA = MNG_FALSE;
+ pData->bHasJDAT = MNG_FALSE;
+#endif
+ pData->bHasPLTE = MNG_FALSE;
+ pData->bHasTRNS = MNG_FALSE;
+ pData->bHasGAMA = MNG_FALSE;
+ pData->bHasCHRM = MNG_FALSE;
+ pData->bHasSRGB = MNG_FALSE;
+ pData->bHasICCP = MNG_FALSE;
+ pData->bHasBKGD = MNG_FALSE;
+ pData->bHasIDAT = MNG_FALSE;
+ }
+ /* if the image was displayed on the fly, */
+ /* we'll have to make the app refresh */
+ if ((pData->eImagetype != mng_it_mng) && (pData->fDisplayrow))
+ pData->bNeedrefresh = MNG_TRUE;
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+/* change in the MNG spec with regards to TERM delay & interframe_delay
+ as proposed by Adam M. Costello (option 4) and finalized by official vote
+ during december 2002 / check the 'mng-list' archives for more details */
+
+mng_retcode mng_process_display_mend (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START);
+#endif
+
+ pData->bForcedelay = pData->iAccumdelay ? MNG_FALSE : MNG_TRUE;
+ pData->iAccumdelay = 0;
+
+#ifdef MNG_SUPPORT_DYNAMICMNG
+ if (pData->bStopafterseek) /* need to stop after this ? */
+ {
+ pData->bFreezing = MNG_TRUE; /* stop processing on this one */
+ pData->bRunningevent = MNG_FALSE;
+ pData->bStopafterseek = MNG_FALSE;
+ pData->bNeedrefresh = MNG_TRUE; /* make sure the last bit is displayed ! */
+ }
+#endif
+
+#ifndef MNG_SKIPCHUNK_TERM
+ /* TERM processed ? */
+ if ((pData->bDisplaying) && (pData->bRunning) &&
+ (pData->bHasTERM) && (pData->pTermaniobj))
+ {
+ mng_retcode iRetcode;
+ mng_ani_termp pTERM;
+ /* get the right animation object ! */
+ pTERM = (mng_ani_termp)pData->pTermaniobj;
+
+ pData->iIterations++; /* increase iteration count */
+
+ switch (pTERM->iTermaction) /* determine what to do! */
+ {
+ case 0 : { /* show last frame indefinitly */
+ break; /* piece of cake, that is... */
+ }
+
+ case 1 : { /* cease displaying anything */
+ /* max(1, TERM delay, interframe_delay) */
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pTERM->iDelay > pData->iFramedelay)
+ pData->iFramedelay = pTERM->iDelay;
+ if (!pData->iFramedelay)
+ pData->iFramedelay = 1;
+#endif
+
+ iRetcode = interframe_delay (pData);
+ /* no interframe_delay? then fake it */
+ if ((!iRetcode) && (!pData->bTimerset))
+ iRetcode = set_delay (pData, 1);
+
+ if (iRetcode)
+ return iRetcode;
+
+ pData->iBreakpoint = 10;
+ break;
+ }
+
+ case 2 : { /* show first image after TERM */
+ iRetcode = restore_state (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* notify the app ? */
+ if (pData->fProcessmend)
+ if (!pData->fProcessmend ((mng_handle)pData, pData->iIterations, 0))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ /* show first frame after TERM chunk */
+ pData->pCurraniobj = pTERM;
+ pData->bOnlyfirstframe = MNG_TRUE;
+ pData->iFramesafterTERM = 0;
+
+ /* max(1, TERM delay, interframe_delay) */
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pTERM->iDelay > pData->iFramedelay)
+ pData->iFramedelay = pTERM->iDelay;
+ if (!pData->iFramedelay)
+ pData->iFramedelay = 1;
+#endif
+
+ break;
+ }
+
+ case 3 : { /* repeat */
+ if ((pTERM->iItermax) && (pTERM->iItermax < 0x7FFFFFFF))
+ pTERM->iItermax--;
+
+ if (pTERM->iItermax) /* go back to TERM ? */
+ { /* restore to initial or SAVE state */
+ iRetcode = restore_state (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* notify the app ? */
+ if (pData->fProcessmend)
+ if (!pData->fProcessmend ((mng_handle)pData,
+ pData->iIterations, pTERM->iItermax))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ /* restart from TERM chunk */
+ pData->pCurraniobj = pTERM;
+
+ if (pTERM->iDelay) /* set the delay (?) */
+ {
+ /* max(1, TERM delay, interframe_delay) */
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pTERM->iDelay > pData->iFramedelay)
+ pData->iFramedelay = pTERM->iDelay;
+ if (!pData->iFramedelay)
+ pData->iFramedelay = 1;
+#endif
+
+ pData->bNeedrefresh = MNG_TRUE;
+ }
+ }
+ else
+ {
+ switch (pTERM->iIteraction)
+ {
+ case 0 : { /* show last frame indefinitly */
+ break; /* piece of cake, that is... */
+ }
+
+ case 1 : { /* cease displaying anything */
+ /* max(1, TERM delay, interframe_delay) */
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pTERM->iDelay > pData->iFramedelay)
+ pData->iFramedelay = pTERM->iDelay;
+ if (!pData->iFramedelay)
+ pData->iFramedelay = 1;
+#endif
+
+ iRetcode = interframe_delay (pData);
+ /* no interframe_delay? then fake it */
+ if ((!iRetcode) && (!pData->bTimerset))
+ iRetcode = set_delay (pData, 1);
+
+ if (iRetcode)
+ return iRetcode;
+
+ pData->iBreakpoint = 10;
+ break;
+ }
+
+ case 2 : { /* show first image after TERM */
+ iRetcode = restore_state (pData);
+ /* on error bail out */
+ if (iRetcode)
+ return iRetcode;
+ /* notify the app ? */
+ if (pData->fProcessmend)
+ if (!pData->fProcessmend ((mng_handle)pData,
+ pData->iIterations, 0))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ /* show first frame after TERM chunk */
+ pData->pCurraniobj = pTERM;
+ pData->bOnlyfirstframe = MNG_TRUE;
+ pData->iFramesafterTERM = 0;
+ /* max(1, TERM delay, interframe_delay) */
+#ifndef MNG_SKIPCHUNK_FRAM
+ if (pTERM->iDelay > pData->iFramedelay)
+ pData->iFramedelay = pTERM->iDelay;
+ if (!pData->iFramedelay)
+ pData->iFramedelay = 1;
+#endif
+
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+ }
+#endif /* MNG_SKIPCHUNK_TERM */
+ /* just reading ? */
+ if ((!pData->bDisplaying) && (pData->bReading))
+ if (pData->fProcessmend) /* inform the app ? */
+ if (!pData->fProcessmend ((mng_handle)pData, 0, 0))
+ MNG_ERROR (pData, MNG_APPMISCERROR);
+
+ if (!pData->pCurraniobj) /* always let the app refresh at the end ! */
+ pData->bNeedrefresh = MNG_TRUE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_display_mend2 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START);
+#endif
+
+#ifndef MNG_SKIPCHUNK_FRAM
+ pData->bFrameclipping = MNG_FALSE; /* nothing to do but restore the app background */
+#endif
+ load_bkgdlayer (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_DEFI
+mng_retcode mng_process_display_defi (mng_datap pData)
+{
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_START);
+#endif
+
+ if (!pData->iDEFIobjectid) /* object id=0 ? */
+ {
+ pImage = (mng_imagep)pData->pObjzero;
+
+ if (pData->bDEFIhasdonotshow)
+ pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
+
+ if (pData->bDEFIhasloca)
+ {
+ pImage->iPosx = pData->iDEFIlocax;
+ pImage->iPosy = pData->iDEFIlocay;
+ }
+
+ if (pData->bDEFIhasclip)
+ {
+ pImage->bClipped = pData->bDEFIhasclip;
+ pImage->iClipl = pData->iDEFIclipl;
+ pImage->iClipr = pData->iDEFIclipr;
+ pImage->iClipt = pData->iDEFIclipt;
+ pImage->iClipb = pData->iDEFIclipb;
+ }
+
+ pData->pCurrentobj = 0; /* not a real object ! */
+ }
+ else
+ { /* already exists ? */
+ pImage = (mng_imagep)mng_find_imageobject (pData, pData->iDEFIobjectid);
+
+ if (!pImage) /* if not; create new */
+ {
+ mng_retcode iRetcode = mng_create_imageobject (pData, pData->iDEFIobjectid,
+ (mng_bool)(pData->iDEFIconcrete == 1),
+ (mng_bool)(pData->iDEFIdonotshow == 0),
+ MNG_FALSE, 0, 0, 0, 0, 0, 0, 0,
+ pData->iDEFIlocax, pData->iDEFIlocay,
+ pData->bDEFIhasclip,
+ pData->iDEFIclipl, pData->iDEFIclipr,
+ pData->iDEFIclipt, pData->iDEFIclipb,
+ &pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ { /* exists; then set new info */
+ if (pData->bDEFIhasdonotshow)
+ pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
+
+ pImage->bViewable = MNG_FALSE;
+
+ if (pData->bDEFIhasloca)
+ {
+ pImage->iPosx = pData->iDEFIlocax;
+ pImage->iPosy = pData->iDEFIlocay;
+ }
+
+ if (pData->bDEFIhasclip)
+ {
+ pImage->bClipped = pData->bDEFIhasclip;
+ pImage->iClipl = pData->iDEFIclipl;
+ pImage->iClipr = pData->iDEFIclipr;
+ pImage->iClipt = pData->iDEFIclipt;
+ pImage->iClipb = pData->iDEFIclipb;
+ }
+
+ if (pData->bDEFIhasconcrete)
+ pImage->pImgbuf->bConcrete = (mng_bool)(pData->iDEFIconcrete == 1);
+ }
+
+ pData->pCurrentobj = pImage; /* others may want to know this */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_BASI
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_basi (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_bool bHasalpha,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable)
+#else
+mng_retcode mng_process_display_basi (mng_datap pData)
+#endif
+{ /* address the current "object" if any */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_uint8p pWork;
+ mng_uint32 iX;
+ mng_imagedatap pBuf;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_START);
+#endif
+
+ if (!pImage) /* or is it an "on-the-fly" image ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* address the object-buffer */
+ pBuf = pImage->pImgbuf;
+
+ pData->fDisplayrow = MNG_NULL; /* do nothing by default */
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ /* set parms now that they're known */
+ iRetcode = mng_reset_object_details (pData, pImage, pData->iDatawidth,
+ pData->iDataheight, pData->iBitdepth,
+ pData->iColortype, pData->iCompression,
+ pData->iFilter, pData->iInterlace, MNG_FALSE);
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* save the viewable flag */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->bViewable = (mng_bool)(iViewable == 1);
+#else
+ pImage->bViewable = (mng_bool)(pData->iBASIviewable == 1);
+#endif
+ pBuf->bViewable = pImage->bViewable;
+ pData->pStoreobj = pImage; /* let row-routines know which object */
+
+ pWork = pBuf->pImgdata; /* fill the object-buffer with the specified
+ "color" sample */
+ switch (pData->iColortype) /* depending on color_type & bit_depth */
+ {
+ case 0 : { /* gray */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth == 16)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ mng_put_uint16 (pWork, iRed);
+#else
+ mng_put_uint16 (pWork, pData->iBASIred);
+#endif
+ pWork += 2;
+ }
+ }
+ else
+#endif
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ *pWork = (mng_uint8)iRed;
+#else
+ *pWork = (mng_uint8)pData->iBASIred;
+#endif
+ pWork++;
+ }
+ }
+ /* force tRNS ? */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if ((bHasalpha) && (!iAlpha))
+#else
+ if ((pData->bBASIhasalpha) && (!pData->iBASIalpha))
+#endif
+ {
+ pBuf->bHasTRNS = MNG_TRUE;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pBuf->iTRNSgray = iRed;
+#else
+ pBuf->iTRNSgray = pData->iBASIred;
+#endif
+ }
+
+ break;
+ }
+
+ case 2 : { /* rgb */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth == 16)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ mng_put_uint16 (pWork, iRed );
+ mng_put_uint16 (pWork+2, iGreen);
+ mng_put_uint16 (pWork+4, iBlue );
+#else
+ mng_put_uint16 (pWork, pData->iBASIred );
+ mng_put_uint16 (pWork+2, pData->iBASIgreen);
+ mng_put_uint16 (pWork+4, pData->iBASIblue );
+#endif
+ pWork += 6;
+ }
+ }
+ else
+#endif
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ *pWork = (mng_uint8)iRed;
+ *(pWork+1) = (mng_uint8)iGreen;
+ *(pWork+2) = (mng_uint8)iBlue;
+#else
+ *pWork = (mng_uint8)pData->iBASIred;
+ *(pWork+1) = (mng_uint8)pData->iBASIgreen;
+ *(pWork+2) = (mng_uint8)pData->iBASIblue;
+#endif
+ pWork += 3;
+ }
+ }
+ /* force tRNS ? */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if ((bHasalpha) && (!iAlpha))
+#else
+ if ((pData->bBASIhasalpha) && (!pData->iBASIalpha))
+#endif
+ {
+ pBuf->bHasTRNS = MNG_TRUE;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pBuf->iTRNSred = iRed;
+ pBuf->iTRNSgreen = iGreen;
+ pBuf->iTRNSblue = iBlue;
+#else
+ pBuf->iTRNSred = pData->iBASIred;
+ pBuf->iTRNSgreen = pData->iBASIgreen;
+ pBuf->iTRNSblue = pData->iBASIblue;
+#endif
+ }
+
+ break;
+ }
+
+ case 3 : { /* indexed */
+ pBuf->bHasPLTE = MNG_TRUE;
+
+ switch (pData->iBitdepth)
+ {
+ case 1 : { pBuf->iPLTEcount = 2; break; }
+ case 2 : { pBuf->iPLTEcount = 4; break; }
+ case 4 : { pBuf->iPLTEcount = 16; break; }
+ case 8 : { pBuf->iPLTEcount = 256; break; }
+ default : { pBuf->iPLTEcount = 1; break; }
+ }
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pBuf->aPLTEentries [0].iRed = (mng_uint8)iRed;
+ pBuf->aPLTEentries [0].iGreen = (mng_uint8)iGreen;
+ pBuf->aPLTEentries [0].iBlue = (mng_uint8)iBlue;
+#else
+ pBuf->aPLTEentries [0].iRed = (mng_uint8)pData->iBASIred;
+ pBuf->aPLTEentries [0].iGreen = (mng_uint8)pData->iBASIgreen;
+ pBuf->aPLTEentries [0].iBlue = (mng_uint8)pData->iBASIblue;
+#endif
+
+ for (iX = 1; iX < pBuf->iPLTEcount; iX++)
+ {
+ pBuf->aPLTEentries [iX].iRed = 0;
+ pBuf->aPLTEentries [iX].iGreen = 0;
+ pBuf->aPLTEentries [iX].iBlue = 0;
+ }
+ /* force tRNS ? */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if ((bHasalpha) && (iAlpha < 255))
+#else
+ if ((pData->bBASIhasalpha) && (pData->iBASIalpha < 255))
+#endif
+ {
+ pBuf->bHasTRNS = MNG_TRUE;
+ pBuf->iTRNScount = 1;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pBuf->aTRNSentries [0] = (mng_uint8)iAlpha;
+#else
+ pBuf->aTRNSentries [0] = (mng_uint8)pData->iBASIalpha;
+#endif
+ }
+
+ break;
+ }
+
+ case 4 : { /* gray+alpha */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth == 16)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ mng_put_uint16 (pWork, iRed);
+ mng_put_uint16 (pWork+2, iAlpha);
+#else
+ mng_put_uint16 (pWork, pData->iBASIred);
+ mng_put_uint16 (pWork+2, pData->iBASIalpha);
+#endif
+ pWork += 4;
+ }
+ }
+ else
+#endif
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ *pWork = (mng_uint8)iRed;
+ *(pWork+1) = (mng_uint8)iAlpha;
+#else
+ *pWork = (mng_uint8)pData->iBASIred;
+ *(pWork+1) = (mng_uint8)pData->iBASIalpha;
+#endif
+ pWork += 2;
+ }
+ }
+
+ break;
+ }
+
+ case 6 : { /* rgb+alpha */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth == 16)
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ mng_put_uint16 (pWork, iRed);
+ mng_put_uint16 (pWork+2, iGreen);
+ mng_put_uint16 (pWork+4, iBlue);
+ mng_put_uint16 (pWork+6, iAlpha);
+#else
+ mng_put_uint16 (pWork, pData->iBASIred);
+ mng_put_uint16 (pWork+2, pData->iBASIgreen);
+ mng_put_uint16 (pWork+4, pData->iBASIblue);
+ mng_put_uint16 (pWork+6, pData->iBASIalpha);
+#endif
+ pWork += 8;
+ }
+ }
+ else
+#endif
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (iX = pData->iDatawidth * pData->iDataheight;
+ iX > 0;iX--)
+#else
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ *pWork = (mng_uint8)iRed;
+ *(pWork+1) = (mng_uint8)iGreen;
+ *(pWork+2) = (mng_uint8)iBlue;
+ *(pWork+3) = (mng_uint8)iAlpha;
+#else
+ *pWork = (mng_uint8)pData->iBASIred;
+ *(pWork+1) = (mng_uint8)pData->iBASIgreen;
+ *(pWork+2) = (mng_uint8)pData->iBASIblue;
+ *(pWork+3) = (mng_uint8)pData->iBASIalpha;
+#endif
+ pWork += 4;
+ }
+ }
+
+ break;
+ }
+
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+ pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
+ pData->ePng_imgtype=mng_png_imgtype(pData->iColortype,pData->iBitdepth);
+#else
+ switch (pData->iColortype) /* determine row initialization routine */
+ { /* just to accomodate IDAT if it arrives */
+ case 0 : { /* gray */
+ switch (pData->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
+
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 2 : { /* rgb */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ switch (pData->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
+
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ }
+#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
+
+ pData->iFilterofs = 0; /* determine filter characteristics */
+ pData->iLevel0 = 0; /* default levels */
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+
+#ifdef FILTER192
+ if (pData->iFilter == 0xC0) /* leveling & differing ? */
+ {
+ switch (pData->iColortype)
+ {
+ case 0 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth <= 8)
+#endif
+ pData->iFilterofs = 1;
+#ifndef MNG_NO_16BIT_SUPPORT
+ else
+ pData->iFilterofs = 2;
+#endif
+
+ break;
+ }
+ case 2 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth <= 8)
+#endif
+ pData->iFilterofs = 3;
+#ifndef MNG_NO_16BIT_SUPPORT
+ else
+ pData->iFilterofs = 6;
+#endif
+
+ break;
+ }
+ case 3 : {
+ pData->iFilterofs = 1;
+ break;
+ }
+ case 4 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth <= 8)
+#endif
+ pData->iFilterofs = 2;
+#ifndef MNG_NO_16BIT_SUPPORT
+ else
+ pData->iFilterofs = 4;
+#endif
+
+ break;
+ }
+ case 6 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (pData->iBitdepth <= 8)
+#endif
+ pData->iFilterofs = 4;
+#ifndef MNG_NO_16BIT_SUPPORT
+ else
+ pData->iFilterofs = 8;
+#endif
+
+ break;
+ }
+ }
+ }
+#endif
+
+#ifdef FILTER193
+ if (pData->iFilter == 0xC1) /* no adaptive filtering ? */
+ pData->iPixelofs = pData->iFilterofs;
+ else
+#endif
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_CLON
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_clon (mng_datap pData,
+ mng_uint16 iSourceid,
+ mng_uint16 iCloneid,
+ mng_uint8 iClonetype,
+ mng_bool bHasdonotshow,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy)
+#else
+mng_retcode mng_process_display_clon (mng_datap pData)
+#endif
+{
+ mng_imagep pSource, pClone;
+ mng_bool bVisible, bAbstract;
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START);
+#endif
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ /* locate the source object first */
+ pSource = mng_find_imageobject (pData, iSourceid);
+ /* check if the clone exists */
+ pClone = mng_find_imageobject (pData, iCloneid);
+#else
+ /* locate the source object first */
+ pSource = mng_find_imageobject (pData, pData->iCLONsourceid);
+ /* check if the clone exists */
+ pClone = mng_find_imageobject (pData, pData->iCLONcloneid);
+#endif
+
+ if (!pSource) /* source must exist ! */
+ MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
+
+ if (pClone) /* clone must not exist ! */
+ MNG_ERROR (pData, MNG_OBJECTEXISTS);
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (bHasdonotshow) /* DoNotShow flag filled ? */
+ bVisible = (mng_bool)(iDonotshow == 0);
+ else
+ bVisible = pSource->bVisible;
+#else
+ if (pData->bCLONhasdonotshow) /* DoNotShow flag filled ? */
+ bVisible = (mng_bool)(pData->iCLONdonotshow == 0);
+ else
+ bVisible = pSource->bVisible;
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ bAbstract = (mng_bool)(iConcrete == 1);
+#else
+ bAbstract = (mng_bool)(pData->iCLONconcrete == 1);
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ switch (iClonetype) /* determine action to take */
+ {
+ case 0 : { /* full clone */
+ iRetcode = mng_clone_imageobject (pData, iCloneid, MNG_FALSE,
+ bVisible, bAbstract, bHasloca,
+ iLocationtype, iLocationx, iLocationy,
+ pSource, &pClone);
+ break;
+ }
+
+ case 1 : { /* partial clone */
+ iRetcode = mng_clone_imageobject (pData, iCloneid, MNG_TRUE,
+ bVisible, bAbstract, bHasloca,
+ iLocationtype, iLocationx, iLocationy,
+ pSource, &pClone);
+ break;
+ }
+
+ case 2 : { /* renumber object */
+ iRetcode = mng_renum_imageobject (pData, pSource, iCloneid,
+ bVisible, bAbstract, bHasloca,
+ iLocationtype, iLocationx, iLocationy);
+ pClone = pSource;
+ break;
+ }
+
+ }
+#else
+ switch (pData->iCLONclonetype) /* determine action to take */
+ {
+ case 0 : { /* full clone */
+ iRetcode = mng_clone_imageobject (pData, pData->iCLONcloneid, MNG_FALSE,
+ bVisible, bAbstract,
+ pData->bCLONhasloca, pData->iCLONlocationtype,
+ pData->iCLONlocationx, pData->iCLONlocationy,
+ pSource, &pClone);
+ break;
+ }
+
+ case 1 : { /* partial clone */
+ iRetcode = mng_clone_imageobject (pData, pData->iCLONcloneid, MNG_TRUE,
+ bVisible, bAbstract,
+ pData->bCLONhasloca, pData->iCLONlocationtype,
+ pData->iCLONlocationx, pData->iCLONlocationy,
+ pSource, &pClone);
+ break;
+ }
+
+ case 2 : { /* renumber object */
+ iRetcode = mng_renum_imageobject (pData, pSource, pData->iCLONcloneid,
+ bVisible, bAbstract,
+ pData->bCLONhasloca, pData->iCLONlocationtype,
+ pData->iCLONlocationx, pData->iCLONlocationy);
+ pClone = pSource;
+ break;
+ }
+
+ }
+#endif
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ /* display on the fly ? */
+ if ((pClone->bViewable) && (pClone->bVisible))
+ {
+ pData->pLastclone = pClone; /* remember in case of timer break ! */
+ /* display it */
+ mng_display_image (pData, pClone, MNG_FALSE);
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 5;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_display_clon2 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START);
+#endif
+ /* only called after timer break ! */
+ mng_display_image (pData, (mng_imagep)pData->pLastclone, MNG_FALSE);
+ pData->iBreakpoint = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_DISC
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_disc (mng_datap pData,
+ mng_uint32 iCount,
+ mng_uint16p pIds)
+#else
+mng_retcode mng_process_display_disc (mng_datap pData)
+#endif
+{
+ mng_uint32 iX;
+ mng_imagep pImage;
+ mng_uint32 iRetcode;
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_START);
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (iCount) /* specific list ? */
+#else
+ if (pData->iDISCcount) /* specific list ? */
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ mng_uint16p pWork = pIds;
+#else
+ mng_uint16p pWork = pData->pDISCids;
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+#ifdef MNG_DECREMENT_LOOPS /* iterate the list */
+ for (iX = iCount; iX > 0; iX--)
+#else
+ for (iX = 0; iX < iCount; iX++)
+#endif
+#else
+#ifdef MNG_DECREMENT_LOOPS /* iterate the list */
+ for (iX = pData->iDISCcount; iX > 0; iX--)
+#else
+ for (iX = 0; iX < pData->iDISCcount; iX++)
+#endif
+#endif
+ {
+ pImage = mng_find_imageobject (pData, *pWork++);
+
+ if (pImage) /* found the object ? */
+ { /* then drop it */
+ iRetcode = mng_free_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+ else /* empty: drop all un-frozen objects */
+ {
+ mng_imagep pNext = (mng_imagep)pData->pFirstimgobj;
+
+ while (pNext) /* any left ? */
+ {
+ pImage = pNext;
+ pNext = pImage->sHeader.pNext;
+
+ if (!pImage->bFrozen) /* not frozen ? */
+ { /* then drop it */
+ iRetcode = mng_free_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_FRAM
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_fram (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+#else
+mng_retcode mng_process_display_fram (mng_datap pData)
+#endif
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START);
+#endif
+ /* advance a frame then */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ iRetcode = next_frame (pData, iFramemode, iChangedelay, iDelay,
+ iChangetimeout, iTimeout, iChangeclipping,
+ iCliptype, iClipl, iClipr, iClipt, iClipb);
+#else
+ iRetcode = next_frame (pData, pData->iTempFramemode, pData->iTempChangedelay,
+ pData->iTempDelay, pData->iTempChangetimeout,
+ pData->iTempTimeout, pData->iTempChangeclipping,
+ pData->iTempCliptype, pData->iTempClipl, pData->iTempClipr,
+ pData->iTempClipt, pData->iTempClipb);
+#endif
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END);
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_display_fram2 (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START);
+#endif
+ /* again; after the break */
+ iRetcode = next_frame (pData, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ pData->iBreakpoint = 0; /* not again! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END);
+#endif
+
+ return iRetcode;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_MOVE
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_move (mng_datap pData,
+ mng_uint16 iFromid,
+ mng_uint16 iToid,
+ mng_uint8 iMovetype,
+ mng_int32 iMovex,
+ mng_int32 iMovey)
+#else
+mng_retcode mng_process_display_move (mng_datap pData)
+#endif
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_START);
+#endif
+ /* iterate the list */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = iFromid; iX <= iToid; iX++)
+#else
+ for (iX = pData->iMOVEfromid; iX <= pData->iMOVEtoid; iX++)
+#endif
+ {
+ if (!iX) /* object id=0 ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ else
+ pImage = mng_find_imageobject (pData, iX);
+
+ if (pImage) /* object exists ? */
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ switch (iMovetype)
+#else
+ switch (pData->iMOVEmovetype)
+#endif
+ {
+ case 0 : { /* absolute */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->iPosx = iMovex;
+ pImage->iPosy = iMovey;
+#else
+ pImage->iPosx = pData->iMOVEmovex;
+ pImage->iPosy = pData->iMOVEmovey;
+#endif
+ break;
+ }
+ case 1 : { /* relative */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->iPosx = pImage->iPosx + iMovex;
+ pImage->iPosy = pImage->iPosy + iMovey;
+#else
+ pImage->iPosx = pImage->iPosx + pData->iMOVEmovex;
+ pImage->iPosy = pImage->iPosy + pData->iMOVEmovey;
+#endif
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_CLIP
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_clip (mng_datap pData,
+ mng_uint16 iFromid,
+ mng_uint16 iToid,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+#else
+mng_retcode mng_process_display_clip (mng_datap pData)
+#endif
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_START);
+#endif
+ /* iterate the list */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = iFromid; iX <= iToid; iX++)
+#else
+ for (iX = pData->iCLIPfromid; iX <= pData->iCLIPtoid; iX++)
+#endif
+ {
+ if (!iX) /* object id=0 ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ else
+ pImage = mng_find_imageobject (pData, iX);
+
+ if (pImage) /* object exists ? */
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ switch (iCliptype)
+#else
+ switch (pData->iCLIPcliptype)
+#endif
+ {
+ case 0 : { /* absolute */
+ pImage->bClipped = MNG_TRUE;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->iClipl = iClipl;
+ pImage->iClipr = iClipr;
+ pImage->iClipt = iClipt;
+ pImage->iClipb = iClipb;
+#else
+ pImage->iClipl = pData->iCLIPclipl;
+ pImage->iClipr = pData->iCLIPclipr;
+ pImage->iClipt = pData->iCLIPclipt;
+ pImage->iClipb = pData->iCLIPclipb;
+#endif
+ break;
+ }
+ case 1 : { /* relative */
+ pImage->bClipped = MNG_TRUE;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->iClipl = pImage->iClipl + iClipl;
+ pImage->iClipr = pImage->iClipr + iClipr;
+ pImage->iClipt = pImage->iClipt + iClipt;
+ pImage->iClipb = pImage->iClipb + iClipb;
+#else
+ pImage->iClipl = pImage->iClipl + pData->iCLIPclipl;
+ pImage->iClipr = pImage->iClipr + pData->iCLIPclipr;
+ pImage->iClipt = pImage->iClipt + pData->iCLIPclipt;
+ pImage->iClipb = pImage->iClipb + pData->iCLIPclipb;
+#endif
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_SHOW
+mng_retcode mng_process_display_show (mng_datap pData)
+{
+ mng_int16 iX, iS, iFrom, iTo;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_START);
+#endif
+
+ /* TODO: optimization for the cases where "abs (iTo - iFrom)" is rather high;
+ especially where ((iFrom==1) && (iTo==65535)); eg. an empty SHOW !!! */
+
+ if (pData->iBreakpoint == 3) /* previously broken during cycle-mode ? */
+ {
+ pImage = mng_find_imageobject (pData, pData->iSHOWnextid);
+
+ if (pImage) /* still there ? */
+ mng_display_image (pData, pImage, MNG_FALSE);
+
+ pData->iBreakpoint = 0; /* let's not go through this again! */
+ }
+ else
+ {
+ if (pData->iBreakpoint) /* previously broken at other point ? */
+ { /* restore last parms */
+ iFrom = (mng_int16)pData->iSHOWfromid;
+ iTo = (mng_int16)pData->iSHOWtoid;
+ iX = (mng_int16)pData->iSHOWnextid;
+ iS = (mng_int16)pData->iSHOWskip;
+ }
+ else
+ { /* regular sequence ? */
+ if (pData->iSHOWtoid >= pData->iSHOWfromid)
+ iS = 1;
+ else /* reverse sequence ! */
+ iS = -1;
+
+ iFrom = (mng_int16)pData->iSHOWfromid;
+ iTo = (mng_int16)pData->iSHOWtoid;
+ iX = iFrom;
+
+ pData->iSHOWfromid = (mng_uint16)iFrom;
+ pData->iSHOWtoid = (mng_uint16)iTo;
+ pData->iSHOWskip = iS;
+ }
+ /* cycle mode ? */
+ if ((pData->iSHOWmode == 6) || (pData->iSHOWmode == 7))
+ {
+ mng_uint16 iTrigger = 0;
+ mng_uint16 iFound = 0;
+ mng_uint16 iPass = 0;
+ mng_imagep pFound = 0;
+
+ do
+ {
+ iPass++; /* lets prevent endless loops when there
+ are no potential candidates in the list! */
+
+ if (iS > 0) /* forward ? */
+ {
+ for (iX = iFrom; iX <= iTo; iX += iS)
+ {
+ pImage = mng_find_imageobject (pData, (mng_uint16)iX);
+
+ if (pImage) /* object exists ? */
+ {
+ if (iFound) /* already found a candidate ? */
+ pImage->bVisible = MNG_FALSE;
+ else
+ if (iTrigger) /* found the trigger ? */
+ {
+ pImage->bVisible = MNG_TRUE;
+ iFound = iX;
+ pFound = pImage;
+ }
+ else
+ if (pImage->bVisible) /* ok, this is the trigger */
+ {
+ pImage->bVisible = MNG_FALSE;
+ iTrigger = iX;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (iX = iFrom; iX >= iTo; iX += iS)
+ {
+ pImage = mng_find_imageobject (pData, (mng_uint16)iX);
+
+ if (pImage) /* object exists ? */
+ {
+ if (iFound) /* already found a candidate ? */
+ pImage->bVisible = MNG_FALSE;
+ else
+ if (iTrigger) /* found the trigger ? */
+ {
+ pImage->bVisible = MNG_TRUE;
+ iFound = iX;
+ pFound = pImage;
+ }
+ else
+ if (pImage->bVisible) /* ok, this is the trigger */
+ {
+ pImage->bVisible = MNG_FALSE;
+ iTrigger = iX;
+ }
+ }
+ }
+ }
+
+ if (!iTrigger) /* did not find a trigger ? */
+ iTrigger = 1; /* then fake it so the first image
+ gets nominated */
+ } /* cycle back to beginning ? */
+ while ((iPass < 2) && (iTrigger) && (!iFound));
+
+ pData->iBreakpoint = 0; /* just a sanity precaution */
+ /* display it ? */
+ if ((pData->iSHOWmode == 6) && (pFound))
+ {
+ mng_display_image (pData, pFound, MNG_FALSE);
+
+ if (pData->bTimerset) /* timer set ? */
+ {
+ pData->iBreakpoint = 3;
+ pData->iSHOWnextid = iFound; /* save it for after the break */
+ }
+ }
+ }
+ else
+ {
+ do
+ {
+ pImage = mng_find_imageobject (pData, iX);
+
+ if (pImage) /* object exists ? */
+ {
+ if (pData->iBreakpoint) /* did we get broken last time ? */
+ { /* could only happen in the display routine */
+ mng_display_image (pData, pImage, MNG_FALSE);
+ pData->iBreakpoint = 0; /* only once inside this loop please ! */
+ }
+ else
+ {
+ switch (pData->iSHOWmode) /* do what ? */
+ {
+ case 0 : {
+ pImage->bVisible = MNG_TRUE;
+ mng_display_image (pData, pImage, MNG_FALSE);
+ break;
+ }
+ case 1 : {
+ pImage->bVisible = MNG_FALSE;
+ break;
+ }
+ case 2 : {
+ if (pImage->bVisible)
+ mng_display_image (pData, pImage, MNG_FALSE);
+ break;
+ }
+ case 3 : {
+ pImage->bVisible = MNG_TRUE;
+ break;
+ }
+ case 4 : {
+ pImage->bVisible = (mng_bool)(!pImage->bVisible);
+ if (pImage->bVisible)
+ mng_display_image (pData, pImage, MNG_FALSE);
+ break;
+ }
+ case 5 : {
+ pImage->bVisible = (mng_bool)(!pImage->bVisible);
+ }
+ }
+ }
+ }
+
+ if (!pData->bTimerset) /* next ? */
+ iX += iS;
+
+ } /* continue ? */
+ while ((!pData->bTimerset) && (((iS > 0) && (iX <= iTo)) ||
+ ((iS < 0) && (iX >= iTo)) ));
+
+ if (pData->bTimerset) /* timer set ? */
+ {
+ pData->iBreakpoint = 4;
+ pData->iSHOWnextid = iX; /* save for next time */
+ }
+ else
+ pData->iBreakpoint = 0;
+
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_SAVE
+mng_retcode mng_process_display_save (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_START);
+#endif
+
+ iRetcode = save_state (pData); /* save the current state */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_SEEK
+mng_retcode mng_process_display_seek (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_START);
+#endif
+
+#ifdef MNG_SUPPORT_DYNAMICMNG
+ if (pData->bStopafterseek) /* need to stop after this SEEK ? */
+ {
+ pData->bFreezing = MNG_TRUE; /* stop processing on this one */
+ pData->bRunningevent = MNG_FALSE;
+ pData->bStopafterseek = MNG_FALSE;
+ pData->bNeedrefresh = MNG_TRUE; /* make sure the last bit is displayed ! */
+ }
+ else
+#endif
+ { /* restore the initial or SAVE state */
+ mng_retcode iRetcode = restore_state (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_DYNAMICMNG
+ /* stop after next SEEK ? */
+ if ((pData->bDynamic) || (pData->bRunningevent))
+ pData->bStopafterseek = MNG_TRUE;
+#endif
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode mng_process_display_jhdr (mng_datap pData)
+{ /* address the current "object" if any */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_START);
+#endif
+
+ if (!pData->bHasDHDR)
+ {
+ pData->fInitrowproc = MNG_NULL; /* do nothing by default */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->fDifferrow = MNG_NULL;
+ pData->fStorerow2 = MNG_NULL;
+ pData->fStorerow3 = MNG_NULL;
+
+ pData->pStoreobj = MNG_NULL; /* initialize important work-parms */
+
+ pData->iJPEGrow = 0;
+ pData->iJPEGalpharow = 0;
+ pData->iJPEGrgbrow = 0;
+ pData->iRowmax = 0; /* so init_rowproc does the right thing ! */
+ }
+
+ if (!pData->iBreakpoint) /* not previously broken ? */
+ {
+#ifndef MNG_NO_DELTA_PNG
+ if (pData->bHasDHDR) /* delta-image ? */
+ {
+ if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
+ {
+ iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
+ pData->iJHDRalphacompression, pData->iJHDRalphafilter,
+ pData->iJHDRalphainterlace, MNG_TRUE);
+
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
+
+ }
+ else
+#endif /* MNG_NO_DELTA_PNG */
+ {
+ if (pImage) /* update object buffer ? */
+ {
+ iRetcode = mng_reset_object_details (pData, pImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
+ pData->iJHDRalphacompression, pData->iJHDRalphafilter,
+ pData->iJHDRalphainterlace, MNG_TRUE);
+
+ pImage->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
+ pImage->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
+ pImage->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
+ pImage->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ else /* update object 0 */
+ {
+ iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
+ pData->iJHDRalphacompression, pData->iJHDRalphafilter,
+ pData->iJHDRalphainterlace, MNG_TRUE);
+
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (!pData->bHasDHDR)
+ { /* we're always storing a JPEG */
+ if (pImage) /* real object ? */
+ pData->pStoreobj = pImage; /* tell the row routines */
+ else /* otherwise use object 0 */
+ pData->pStoreobj = pData->pObjzero;
+ /* display "on-the-fly" ? */
+ if (
+#ifndef MNG_SKIPCHUNK_MAGN
+ ( ((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
+ ( ((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
+#endif
+ ( (pData->eImagetype == mng_it_jng ) ||
+ (((mng_imagep)pData->pStoreobj)->bVisible) ) )
+ {
+ next_layer (pData); /* that's a new layer then ! */
+
+ pData->iBreakpoint = 0;
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 7;
+ else
+ if (pData->bRunning) /* still running ? */
+ { /* anything to display ? */
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ {
+ set_display_routine (pData); /* then determine display routine */
+ /* display from the object we store in */
+ pData->pRetrieveobj = pData->pStoreobj;
+ }
+ }
+ }
+ }
+
+ if (!pData->bTimerset) /* no timer break ? */
+ { /* default row initialization ! */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+ pData->ePng_imgtype=png_none;
+#endif
+ pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
+
+ if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_REPLACE))
+ { /* 8-bit JPEG ? */
+ if (pData->iJHDRimgbitdepth == 8)
+ { /* intermediate row is 8-bit deep */
+ pData->bIsRGBA16 = MNG_FALSE;
+ pData->iRowsamples = pData->iDatawidth;
+
+ switch (pData->iJHDRcolortype) /* determine pixel processing routines */
+ {
+ case MNG_COLORTYPE_JPEGGRAY :
+ {
+ pData->fStorerow2 = (mng_fptr)mng_store_jpeg_g8;
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+ case MNG_COLORTYPE_JPEGCOLOR :
+ {
+ pData->fStorerow2 = (mng_fptr)mng_store_jpeg_rgb8;
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+ case MNG_COLORTYPE_JPEGGRAYA :
+ {
+ pData->fStorerow2 = (mng_fptr)mng_store_jpeg_ga8;
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+ case MNG_COLORTYPE_JPEGCOLORA :
+ {
+ pData->fStorerow2 = (mng_fptr)mng_store_jpeg_rgba8;
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+ }
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ else
+ {
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+ /* TODO: 12-bit JPEG */
+ /* TODO: 8- + 12-bit JPEG (eg. type=20) */
+
+ }
+#endif
+ /* possible IDAT alpha-channel ? */
+ if (pData->iJHDRalphacompression == MNG_COMPRESSION_DEFLATE)
+ {
+ /* determine alpha processing routine */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+ pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
+#endif
+ switch (pData->iJHDRalphabitdepth)
+ {
+#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a1_ni; break; }
+ case 2 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a2_ni; break; }
+ case 4 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a4_ni; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a8_ni; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fInitrowproc = (mng_fptr)mng_init_jpeg_a16_ni; break; }
+#endif
+#else
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->ePng_imgtype = png_jpeg_a1; break; }
+ case 2 : { pData->ePng_imgtype = png_jpeg_a2; break; }
+ case 4 : { pData->ePng_imgtype = png_jpeg_a4; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->ePng_imgtype = png_jpeg_a8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->ePng_imgtype = png_jpeg_a16; break; }
+#endif
+#endif
+ }
+ }
+ else /* possible JDAA alpha-channel ? */
+ if (pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG)
+ { /* 8-bit JPEG ? */
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)
+ pData->fStorerow3 = (mng_fptr)mng_store_jpeg_g8_alpha;
+ else
+ if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)
+ pData->fStorerow3 = (mng_fptr)mng_store_jpeg_rgb8_alpha;
+ }
+ else
+ {
+ /* TODO: 12-bit JPEG with 8-bit JDAA */
+ }
+ }
+ /* initialize JPEG library */
+ iRetcode = mngjpeg_initialize (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ { /* must be alpha add/replace !! */
+ if ((pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAADD ) &&
+ (pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ MNG_ERROR (pData, MNG_INVDELTATYPE);
+ /* determine alpha processing routine */
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+ pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
+#endif
+ switch (pData->iJHDRalphabitdepth)
+ {
+#ifndef MNG_OPTIMIZE_FOOTPRINT_INIT
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->fInitrowproc = (mng_fptr)mng_init_g1_ni; break; }
+ case 2 : { pData->fInitrowproc = (mng_fptr)mng_init_g2_ni; break; }
+ case 4 : { pData->fInitrowproc = (mng_fptr)mng_init_g4_ni; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->fInitrowproc = (mng_fptr)mng_init_g8_ni; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->fInitrowproc = (mng_fptr)mng_init_g16_ni; break; }
+#endif
+#else
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : { pData->ePng_imgtype = png_jpeg_a1; break; }
+ case 2 : { pData->ePng_imgtype = png_jpeg_a2; break; }
+ case 4 : { pData->ePng_imgtype = png_jpeg_a4; break; }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : { pData->ePng_imgtype = png_jpeg_a8; break; }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : { pData->ePng_imgtype = png_jpeg_a16; break; }
+#endif
+#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
+ }
+ }
+
+ pData->iFilterofs = 0; /* determine filter characteristics */
+ pData->iLevel0 = 0; /* default levels */
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+
+#ifdef FILTER192 /* leveling & differing ? */
+ if (pData->iJHDRalphafilter == 0xC0)
+ {
+ if (pData->iJHDRalphabitdepth <= 8)
+ pData->iFilterofs = 1;
+ else
+ pData->iFilterofs = 2;
+
+ }
+#endif
+#ifdef FILTER193 /* no adaptive filtering ? */
+ if (pData->iJHDRalphafilter == 0xC1)
+ pData->iPixelofs = pData->iFilterofs;
+ else
+#endif
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_jdaa (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+#else
+mng_retcode mng_process_display_jdaa (mng_datap pData)
+#endif
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_START);
+#endif
+
+ if (!pData->bJPEGdecompress2) /* if we're not decompressing already */
+ {
+ if (pData->fInitrowproc) /* initialize row-processing? */
+ {
+ iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
+ pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
+ }
+
+ if (!iRetcode) /* initialize decompress */
+ iRetcode = mngjpeg_decompressinit2 (pData);
+ }
+
+ if (!iRetcode) /* all ok? then decompress, my man */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ iRetcode = mngjpeg_decompressdata2 (pData, iRawlen, pRawdata);
+#else
+ iRetcode = mngjpeg_decompressdata2 (pData, pData->iRawlen, pData->pRawdata);
+#endif
+
+ if (iRetcode)
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_jdat (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+#else
+mng_retcode mng_process_display_jdat (mng_datap pData)
+#endif
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_START);
+#endif
+
+ if (pData->bRestorebkgd) /* need to restore the background ? */
+ {
+ pData->bRestorebkgd = MNG_FALSE;
+ iRetcode = load_bkgdlayer (pData);
+
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (!pData->bJPEGdecompress) /* if we're not decompressing already */
+ {
+ if (pData->fInitrowproc) /* initialize row-processing? */
+ {
+ iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
+ pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
+ }
+
+ if (!iRetcode) /* initialize decompress */
+ iRetcode = mngjpeg_decompressinit (pData);
+ }
+
+ if (!iRetcode) /* all ok? then decompress, my man */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ iRetcode = mngjpeg_decompressdata (pData, iRawlen, pRawdata);
+#else
+ iRetcode = mngjpeg_decompressdata (pData, pData->iRawlen, pData->pRawdata);
+#endif
+
+ if (iRetcode)
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_dhdr (mng_datap pData,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky)
+#else
+mng_retcode mng_process_display_dhdr (mng_datap pData)
+#endif
+{
+ mng_imagep pImage;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_START);
+#endif
+
+ pData->fInitrowproc = MNG_NULL; /* do nothing by default */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->pStoreobj = MNG_NULL;
+
+ pData->fDeltagetrow = MNG_NULL;
+ pData->fDeltaaddrow = MNG_NULL;
+ pData->fDeltareplacerow = MNG_NULL;
+ pData->fDeltaputrow = MNG_NULL;
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage = mng_find_imageobject (pData, iObjectid);
+#else
+ pImage = mng_find_imageobject (pData, pData->iDHDRobjectid);
+#endif
+
+ if (pImage) /* object exists ? */
+ {
+ if (pImage->pImgbuf->bConcrete) /* is it concrete ? */
+ { /* previous magnification to be done ? */
+#ifndef MNG_SKIPCHUNK_MAGN
+ if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
+ {
+ iRetcode = mng_magnify_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif
+ /* save delta fields */
+ pData->pDeltaImage = (mng_ptr)pImage;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pData->iDeltaImagetype = iImagetype;
+ pData->iDeltatype = iDeltatype;
+ pData->iDeltaBlockwidth = iBlockwidth;
+ pData->iDeltaBlockheight = iBlockheight;
+ pData->iDeltaBlockx = iBlockx;
+ pData->iDeltaBlocky = iBlocky;
+#else
+ pData->iDeltaImagetype = pData->iDHDRimagetype;
+ pData->iDeltatype = pData->iDHDRdeltatype;
+ pData->iDeltaBlockwidth = pData->iDHDRblockwidth;
+ pData->iDeltaBlockheight = pData->iDHDRblockheight;
+ pData->iDeltaBlockx = pData->iDHDRblockx;
+ pData->iDeltaBlocky = pData->iDHDRblocky;
+#endif
+ /* restore target-object fields */
+ pData->iDatawidth = pImage->pImgbuf->iWidth;
+ pData->iDataheight = pImage->pImgbuf->iHeight;
+ pData->iBitdepth = pImage->pImgbuf->iBitdepth;
+ pData->iColortype = pImage->pImgbuf->iColortype;
+ pData->iCompression = pImage->pImgbuf->iCompression;
+ pData->iFilter = pImage->pImgbuf->iFilter;
+ pData->iInterlace = pImage->pImgbuf->iInterlace;
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if ((iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ pData->iBitdepth = pImage->pImgbuf->iPixelsampledepth;
+ else
+ if ((iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ pData->iBitdepth = pImage->pImgbuf->iAlphasampledepth;
+ else
+ if ((iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ pData->iBitdepth = pImage->pImgbuf->iPixelsampledepth;
+#else
+ if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ pData->iBitdepth = pImage->pImgbuf->iPixelsampledepth;
+ else
+ if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ pData->iBitdepth = pImage->pImgbuf->iAlphasampledepth;
+ else
+ if ((pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDHDRdeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ pData->iBitdepth = pImage->pImgbuf->iPixelsampledepth;
+#endif
+
+#ifdef MNG_INCLUDE_JNG
+ pData->iJHDRimgbitdepth = pImage->pImgbuf->iBitdepth;
+ pData->iJHDRcolortype = pImage->pImgbuf->iColortype;
+ pData->iJHDRimgcompression = pImage->pImgbuf->iJHDRcompression;
+ pData->iJHDRimginterlace = pImage->pImgbuf->iJHDRinterlace;
+ pData->iJHDRalphacompression = pImage->pImgbuf->iCompression;
+ pData->iJHDRalphafilter = pImage->pImgbuf->iFilter;
+ pData->iJHDRalphainterlace = pImage->pImgbuf->iInterlace;
+ pData->iJHDRalphabitdepth = pImage->pImgbuf->iAlphabitdepth;
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ /* block size specified ? */
+ if (iDeltatype != MNG_DELTATYPE_NOCHANGE)
+ { /* block entirely within target ? */
+ if (iDeltatype != MNG_DELTATYPE_REPLACE)
+ {
+ if (((iBlockx + iBlockwidth ) > pData->iDatawidth ) ||
+ ((iBlocky + iBlockheight) > pData->iDataheight) )
+ MNG_ERROR (pData, MNG_INVALIDBLOCK);
+ }
+
+ pData->iDatawidth = iBlockwidth;
+ pData->iDataheight = iBlockheight;
+ }
+#else
+ /* block size specified ? */
+ if (pData->iDHDRdeltatype != MNG_DELTATYPE_NOCHANGE)
+ { /* block entirely within target ? */
+ if (pData->iDHDRdeltatype != MNG_DELTATYPE_REPLACE)
+ {
+ if (((pData->iDHDRblockx + pData->iDHDRblockwidth ) > pData->iDatawidth ) ||
+ ((pData->iDHDRblocky + pData->iDHDRblockheight) > pData->iDataheight) )
+ MNG_ERROR (pData, MNG_INVALIDBLOCK);
+ }
+
+ pData->iDatawidth = pData->iDHDRblockwidth;
+ pData->iDataheight = pData->iDHDRblockheight;
+ }
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ switch (iDeltatype) /* determine nr of delta-channels */
+#else
+ switch (pData->iDHDRdeltatype) /* determine nr of delta-channels */
+#endif
+ {
+ case MNG_DELTATYPE_BLOCKALPHAADD : ;
+ case MNG_DELTATYPE_BLOCKALPHAREPLACE :
+ {
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
+ }
+ else
+ if ((pData->iColortype == MNG_COLORTYPE_RGBA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
+ }
+#else
+ if (pData->iColortype == MNG_COLORTYPE_GRAYA)
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ else
+ if (pData->iColortype == MNG_COLORTYPE_RGBA)
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+#endif
+ else /* target has no alpha; that sucks! */
+ MNG_ERROR (pData, MNG_TARGETNOALPHA);
+
+ break;
+ }
+
+ case MNG_DELTATYPE_BLOCKCOLORADD : ;
+ case MNG_DELTATYPE_BLOCKCOLORREPLACE :
+ {
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
+ }
+ else
+ if ((pData->iColortype == MNG_COLORTYPE_RGBA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_RGB;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGCOLOR;
+ }
+#else
+ if (pData->iColortype == MNG_COLORTYPE_GRAYA)
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ else
+ if (pData->iColortype == MNG_COLORTYPE_RGBA)
+ pData->iColortype = MNG_COLORTYPE_RGB;
+#endif
+ else /* target has no alpha; that sucks! */
+ MNG_ERROR (pData, MNG_TARGETNOALPHA);
+
+ break;
+ }
+
+ }
+ /* full image replace ? */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (iDeltatype == MNG_DELTATYPE_REPLACE)
+#else
+ if (pData->iDHDRdeltatype == MNG_DELTATYPE_REPLACE)
+#endif
+ {
+ iRetcode = mng_reset_object_details (pData, pImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_FALSE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pData->pStoreobj = pImage; /* and store straight into this object */
+ }
+ else
+ {
+ mng_imagedatap pBufzero, pBuf;
+ /* we store in object 0 and process it later */
+ pData->pStoreobj = pData->pObjzero;
+ /* make sure to initialize object 0 then */
+ iRetcode = mng_reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pBuf = pImage->pImgbuf; /* copy possible palette & cheap transparency */
+ pBufzero = ((mng_imagep)pData->pObjzero)->pImgbuf;
+
+ pBufzero->bHasPLTE = pBuf->bHasPLTE;
+ pBufzero->bHasTRNS = pBuf->bHasTRNS;
+
+ if (pBufzero->bHasPLTE) /* copy palette ? */
+ {
+ mng_uint32 iX;
+
+ pBufzero->iPLTEcount = pBuf->iPLTEcount;
+
+ for (iX = 0; iX < pBuf->iPLTEcount; iX++)
+ {
+ pBufzero->aPLTEentries [iX].iRed = pBuf->aPLTEentries [iX].iRed;
+ pBufzero->aPLTEentries [iX].iGreen = pBuf->aPLTEentries [iX].iGreen;
+ pBufzero->aPLTEentries [iX].iBlue = pBuf->aPLTEentries [iX].iBlue;
+ }
+ }
+
+ if (pBufzero->bHasTRNS) /* copy cheap transparency ? */
+ {
+ pBufzero->iTRNSgray = pBuf->iTRNSgray;
+ pBufzero->iTRNSred = pBuf->iTRNSred;
+ pBufzero->iTRNSgreen = pBuf->iTRNSgreen;
+ pBufzero->iTRNSblue = pBuf->iTRNSblue;
+ pBufzero->iTRNScount = pBuf->iTRNScount;
+
+ MNG_COPY (pBufzero->aTRNSentries, pBuf->aTRNSentries,
+ sizeof (pBufzero->aTRNSentries));
+ }
+ /* process immediately if bitdepth & colortype are equal */
+ pData->bDeltaimmediate =
+ (mng_bool)((pData->bDisplaying) && (!pData->bSkipping) &&
+ ((pData->bRunning) || (pData->bSearching)) &&
+ (pData->iBitdepth == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
+ (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype) );
+ }
+
+#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
+ pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
+ pData->ePng_imgtype = mng_png_imgtype (pData->iColortype, pData->iBitdepth);
+#else
+ switch (pData->iColortype) /* determine row initialization routine */
+ {
+ case 0 : { /* gray */
+ switch (pData->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
+
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 2 : { /* rgb */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ switch (pData->iBitdepth)
+ {
+#ifndef MNG_NO_1_2_4BIT_SUPPORT
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
+
+ break;
+ }
+#endif /* MNG_NO_1_2_4BIT_SUPPORT */
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
+
+ break;
+ }
+#ifndef MNG_NO_16BIT_SUPPORT
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
+
+ break;
+ }
+#endif
+ }
+
+ break;
+ }
+ }
+#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
+ }
+ else
+ MNG_ERROR (pData, MNG_OBJNOTCONCRETE);
+
+ }
+ else
+ MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_prom (mng_datap pData,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype)
+#else
+mng_retcode mng_process_display_prom (mng_datap pData)
+#endif
+{
+ mng_imagep pImage;
+ mng_imagedatap pBuf;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_START);
+#endif
+
+ if (!pData->pDeltaImage) /* gotta have this now! */
+ MNG_ERROR (pData, MNG_INVALIDDELTA);
+
+ pImage = (mng_imagep)pData->pDeltaImage;
+ pBuf = pImage->pImgbuf;
+ /* can't demote bitdepth! */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (iBitdepth < pBuf->iBitdepth)
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
+
+ if ( ((pBuf->iColortype == MNG_COLORTYPE_GRAY ) &&
+ (iColortype != MNG_COLORTYPE_GRAY ) &&
+ (iColortype != MNG_COLORTYPE_GRAYA ) &&
+ (iColortype != MNG_COLORTYPE_RGB ) &&
+ (iColortype != MNG_COLORTYPE_RGBA ) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_GRAYA ) &&
+ (iColortype != MNG_COLORTYPE_GRAYA ) &&
+ (iColortype != MNG_COLORTYPE_RGBA ) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_RGB ) &&
+ (iColortype != MNG_COLORTYPE_RGB ) &&
+ (iColortype != MNG_COLORTYPE_RGBA ) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_RGBA ) &&
+ (iColortype != MNG_COLORTYPE_RGBA ) ) ||
+#ifdef MNG_INCLUDE_JNG
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY ) &&
+ (iColortype != MNG_COLORTYPE_JPEGGRAY ) &&
+ (iColortype != MNG_COLORTYPE_JPEGCOLOR ) &&
+ (iColortype != MNG_COLORTYPE_JPEGGRAYA ) &&
+ (iColortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR ) &&
+ (iColortype != MNG_COLORTYPE_JPEGCOLOR ) &&
+ (iColortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA ) &&
+ (iColortype != MNG_COLORTYPE_JPEGGRAYA ) &&
+ (iColortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) &&
+ (iColortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+#endif
+ ((pBuf->iColortype == MNG_COLORTYPE_INDEXED ) &&
+ (iColortype != MNG_COLORTYPE_INDEXED ) &&
+ (iColortype != MNG_COLORTYPE_RGB ) &&
+ (iColortype != MNG_COLORTYPE_RGBA ) ) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
+
+ iRetcode = mng_promote_imageobject (pData, pImage, iBitdepth, iColortype, iFilltype);
+#else
+ if (pData->iPROMbitdepth < pBuf->iBitdepth)
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
+
+ if ( ((pBuf->iColortype == MNG_COLORTYPE_GRAY ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_GRAY ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_GRAYA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGB ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGBA ) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_GRAYA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_GRAYA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGBA ) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_RGB ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGB ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGBA ) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_RGBA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGBA ) ) ||
+#ifdef MNG_INCLUDE_JNG
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAY ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+ ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_JPEGCOLORA) ) ||
+#endif
+ ((pBuf->iColortype == MNG_COLORTYPE_INDEXED ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_INDEXED ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGB ) &&
+ (pData->iPROMcolortype != MNG_COLORTYPE_RGBA ) ) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
+
+ iRetcode = mng_promote_imageobject (pData, pImage, pData->iPROMbitdepth,
+ pData->iPROMcolortype, pData->iPROMfilltype);
+#endif
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+mng_retcode mng_process_display_ipng (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_START);
+#endif
+ /* indicate it for what it is now */
+ pData->iDeltaImagetype = MNG_IMAGETYPE_PNG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+#ifdef MNG_INCLUDE_JNG
+mng_retcode mng_process_display_ijng (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_START);
+#endif
+ /* indicate it for what it is now */
+ pData->iDeltaImagetype = MNG_IMAGETYPE_JNG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_NO_DELTA_PNG
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_pplt (mng_datap pData,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_palette8ep paIndexentries,
+ mng_uint8p paAlphaentries,
+ mng_uint8p paUsedentries)
+#else
+mng_retcode mng_process_display_pplt (mng_datap pData)
+#endif
+{
+ mng_uint32 iX;
+ mng_imagep pImage = (mng_imagep)pData->pObjzero;
+ mng_imagedatap pBuf = pImage->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_START);
+#endif
+
+#ifdef MNG_DECREMENT_LOOPS
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ iX = iCount;
+#else
+ iX = pData->iPPLTcount;
+#endif
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ switch (iType)
+#else
+ switch (pData->iPPLTtype)
+#endif
+ {
+ case MNG_DELTATYPE_REPLACERGB :
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (; iX > 0;iX--)
+#else
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = 0; iX < iCount; iX++)
+#else
+ for (iX = 0; iX < pData->iPPLTcount; iX++)
+#endif
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed = paIndexentries [iX].iRed;
+ pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
+ pBuf->aPLTEentries [iX].iBlue = paIndexentries [iX].iBlue;
+ }
+#else
+ if (pData->paPPLTusedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed = pData->paPPLTindexentries [iX].iRed;
+ pBuf->aPLTEentries [iX].iGreen = pData->paPPLTindexentries [iX].iGreen;
+ pBuf->aPLTEentries [iX].iBlue = pData->paPPLTindexentries [iX].iBlue;
+ }
+#endif
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_DELTARGB :
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (; iX > 0;iX--)
+#else
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = 0; iX < iCount; iX++)
+#else
+ for (iX = 0; iX < pData->iPPLTcount; iX++)
+#endif
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
+ paIndexentries [iX].iRed );
+ pBuf->aPLTEentries [iX].iGreen =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
+ paIndexentries [iX].iGreen);
+ pBuf->aPLTEentries [iX].iBlue =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
+ paIndexentries [iX].iBlue );
+ }
+#else
+ if (pData->paPPLTusedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
+ pData->paPPLTindexentries [iX].iRed );
+ pBuf->aPLTEentries [iX].iGreen =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
+ pData->paPPLTindexentries [iX].iGreen);
+ pBuf->aPLTEentries [iX].iBlue =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
+ pData->paPPLTindexentries [iX].iBlue );
+ }
+#endif
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_REPLACEALPHA :
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (; iX > 0;iX--)
+#else
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = 0; iX < iCount; iX++)
+#else
+ for (iX = 0; iX < pData->iPPLTcount; iX++)
+#endif
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (paUsedentries [iX])
+ pBuf->aTRNSentries [iX] = paAlphaentries [iX];
+ }
+#else
+ if (pData->paPPLTusedentries [iX])
+ pBuf->aTRNSentries [iX] = pData->paPPLTalphaentries [iX];
+ }
+#endif
+
+ break;
+ }
+ case MNG_DELTATYPE_DELTAALPHA :
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (; iX > 0;iX--)
+#else
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = 0; iX < iCount; iX++)
+#else
+ for (iX = 0; iX < pData->iPPLTcount; iX++)
+#endif
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (paUsedentries [iX])
+ pBuf->aTRNSentries [iX] =
+ (mng_uint8)(pBuf->aTRNSentries [iX] +
+ paAlphaentries [iX]);
+#else
+ if (pData->paPPLTusedentries [iX])
+ pBuf->aTRNSentries [iX] =
+ (mng_uint8)(pBuf->aTRNSentries [iX] +
+ pData->paPPLTalphaentries [iX]);
+#endif
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_REPLACERGBA :
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (; iX > 0;iX--)
+#else
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = 0; iX < iCount; iX++)
+#else
+ for (iX = 0; iX < pData->iPPLTcount; iX++)
+#endif
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed = paIndexentries [iX].iRed;
+ pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
+ pBuf->aPLTEentries [iX].iBlue = paIndexentries [iX].iBlue;
+ pBuf->aTRNSentries [iX] = paAlphaentries [iX];
+ }
+#else
+ if (pData->paPPLTusedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed = pData->paPPLTindexentries [iX].iRed;
+ pBuf->aPLTEentries [iX].iGreen = pData->paPPLTindexentries [iX].iGreen;
+ pBuf->aPLTEentries [iX].iBlue = pData->paPPLTindexentries [iX].iBlue;
+ pBuf->aTRNSentries [iX] = pData->paPPLTalphaentries [iX];
+ }
+#endif
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_DELTARGBA :
+ {
+#ifdef MNG_DECREMENT_LOOPS
+ for (; iX > 0;iX--)
+#else
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = 0; iX < iCount; iX++)
+#else
+ for (iX = 0; iX < pData->iPPLTcount; iX++)
+#endif
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
+ paIndexentries [iX].iRed );
+ pBuf->aPLTEentries [iX].iGreen =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
+ paIndexentries [iX].iGreen);
+ pBuf->aPLTEentries [iX].iBlue =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
+ paIndexentries [iX].iBlue );
+ pBuf->aTRNSentries [iX] =
+ (mng_uint8)(pBuf->aTRNSentries [iX] +
+ paAlphaentries [iX]);
+ }
+#else
+ if (pData->paPPLTusedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
+ pData->paPPLTindexentries [iX].iRed );
+ pBuf->aPLTEentries [iX].iGreen =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
+ pData->paPPLTindexentries [iX].iGreen);
+ pBuf->aPLTEentries [iX].iBlue =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
+ pData->paPPLTindexentries [iX].iBlue );
+ pBuf->aTRNSentries [iX] =
+ (mng_uint8)(pBuf->aTRNSentries [iX] +
+ pData->paPPLTalphaentries [iX]);
+ }
+#endif
+ }
+
+ break;
+ }
+ }
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if ((iType != MNG_DELTATYPE_REPLACERGB) && (iType != MNG_DELTATYPE_DELTARGB))
+#else
+ if ((pData->iPPLTtype != MNG_DELTATYPE_REPLACERGB) &&
+ (pData->iPPLTtype != MNG_DELTATYPE_DELTARGB ) )
+#endif
+ {
+ if (pBuf->bHasTRNS)
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (iCount > pBuf->iTRNScount)
+ pBuf->iTRNScount = iCount;
+#else
+ if (pData->iPPLTcount > pBuf->iTRNScount)
+ pBuf->iTRNScount = pData->iPPLTcount;
+#endif
+ }
+ else
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pBuf->iTRNScount = iCount;
+ pBuf->bHasTRNS = MNG_TRUE;
+#else
+ pBuf->iTRNScount = pData->iPPLTcount;
+ pBuf->bHasTRNS = MNG_TRUE;
+#endif
+ }
+ }
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if ((iType != MNG_DELTATYPE_REPLACEALPHA) && (iType != MNG_DELTATYPE_DELTAALPHA))
+#else
+ if ((pData->iPPLTtype != MNG_DELTATYPE_REPLACEALPHA) &&
+ (pData->iPPLTtype != MNG_DELTATYPE_DELTAALPHA ) )
+#endif
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (iCount > pBuf->iPLTEcount)
+ pBuf->iPLTEcount = iCount;
+#else
+ if (pData->iPPLTcount > pBuf->iPLTEcount)
+ pBuf->iPLTEcount = pData->iPPLTcount;
+#endif
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_MAGN
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_magn (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint8 iMethodY)
+#else
+mng_retcode mng_process_display_magn (mng_datap pData)
+#endif
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START);
+#endif
+ /* iterate the object-ids */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ for (iX = iFirstid; iX <= iLastid; iX++)
+#else
+ for (iX = pData->iMAGNfirstid; iX <= pData->iMAGNlastid; iX++)
+#endif
+ {
+ if (iX == 0) /* process object 0 ? */
+ {
+ pImage = (mng_imagep)pData->pObjzero;
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->iMAGN_MethodX = iMethodX;
+ pImage->iMAGN_MethodY = iMethodY;
+ pImage->iMAGN_MX = iMX;
+ pImage->iMAGN_MY = iMY;
+ pImage->iMAGN_ML = iML;
+ pImage->iMAGN_MR = iMR;
+ pImage->iMAGN_MT = iMT;
+ pImage->iMAGN_MB = iMB;
+#else
+ pImage->iMAGN_MethodX = pData->iMAGNmethodX;
+ pImage->iMAGN_MethodY = pData->iMAGNmethodY;
+ pImage->iMAGN_MX = pData->iMAGNmX;
+ pImage->iMAGN_MY = pData->iMAGNmY;
+ pImage->iMAGN_ML = pData->iMAGNmL;
+ pImage->iMAGN_MR = pData->iMAGNmR;
+ pImage->iMAGN_MT = pData->iMAGNmT;
+ pImage->iMAGN_MB = pData->iMAGNmB;
+#endif
+ }
+ else
+ {
+ pImage = mng_find_imageobject (pData, iX);
+ /* object exists & is not frozen ? */
+ if ((pImage) && (!pImage->bFrozen))
+ { /* previous magnification to be done ? */
+ if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
+ {
+ mng_retcode iRetcode = mng_magnify_imageobject (pData, pImage);
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pImage->iMAGN_MethodX = iMethodX;
+ pImage->iMAGN_MethodY = iMethodY;
+ pImage->iMAGN_MX = iMX;
+ pImage->iMAGN_MY = iMY;
+ pImage->iMAGN_ML = iML;
+ pImage->iMAGN_MR = iMR;
+ pImage->iMAGN_MT = iMT;
+ pImage->iMAGN_MB = iMB;
+#else
+ pImage->iMAGN_MethodX = pData->iMAGNmethodX;
+ pImage->iMAGN_MethodY = pData->iMAGNmethodY;
+ pImage->iMAGN_MX = pData->iMAGNmX;
+ pImage->iMAGN_MY = pData->iMAGNmY;
+ pImage->iMAGN_ML = pData->iMAGNmL;
+ pImage->iMAGN_MR = pData->iMAGNmR;
+ pImage->iMAGN_MT = pData->iMAGNmT;
+ pImage->iMAGN_MB = pData->iMAGNmB;
+#endif
+ }
+ }
+ }
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pData->iMAGNfromid = iFirstid;
+ pData->iMAGNtoid = iLastid;
+ iX = iFirstid;
+#else
+ pData->iMAGNfromid = pData->iMAGNfirstid;
+ pData->iMAGNtoid = pData->iMAGNlastid;
+ iX = pData->iMAGNfirstid;
+#endif
+ /* iterate again for showing */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ while ((iX <= iLastid) && (!pData->bTimerset))
+#else
+ while ((iX <= pData->iMAGNlastid) && (!pData->bTimerset))
+#endif
+ {
+ pData->iMAGNcurrentid = iX;
+
+ if (iX) /* only real objects ! */
+ {
+ pImage = mng_find_imageobject (pData, iX);
+ /* object exists & is not frozen &
+ is visible & is viewable ? */
+ if ((pImage) && (!pImage->bFrozen) &&
+ (pImage->bVisible) && (pImage->bViewable))
+ {
+ mng_retcode iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
+ if (iRetcode)
+ return iRetcode;
+ }
+ }
+
+ iX++;
+ }
+
+ if (pData->bTimerset) /* broken ? */
+ pData->iBreakpoint = 9;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_process_display_magn2 (mng_datap pData)
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START);
+#endif
+
+ iX = pData->iMAGNcurrentid;
+ /* iterate again for showing */
+ while ((iX <= pData->iMAGNtoid) && (!pData->bTimerset))
+ {
+ pData->iMAGNcurrentid = iX;
+
+ if (iX) /* only real objects ! */
+ {
+ pImage = mng_find_imageobject (pData, iX);
+ /* object exists & is not frozen &
+ is visible & is viewable ? */
+ if ((pImage) && (!pImage->bFrozen) &&
+ (pImage->bVisible) && (pImage->bViewable))
+ {
+ mng_retcode iRetcode = mng_display_image (pData, pImage, MNG_FALSE);
+ if (iRetcode)
+ return iRetcode;
+ }
+ }
+
+ iX++;
+ }
+
+ if (pData->bTimerset) /* broken ? */
+ pData->iBreakpoint = 9;
+ else
+ pData->iBreakpoint = 0; /* not again ! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_PAST
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+mng_retcode mng_process_display_past (mng_datap pData,
+ mng_uint16 iTargetid,
+ mng_uint8 iTargettype,
+ mng_int32 iTargetx,
+ mng_int32 iTargety,
+ mng_uint32 iCount,
+ mng_ptr pSources)
+#else
+mng_retcode mng_process_display_past (mng_datap pData)
+#endif
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+ mng_imagep pTargetimg;
+ mng_imagep pSourceimg;
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ mng_past_sourcep pSource = (mng_past_sourcep)pSources;
+#else
+ mng_past_sourcep pSource = (mng_past_sourcep)pData->pPASTsources;
+#endif
+ mng_uint32 iX = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_START);
+#endif
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (iTargetid) /* a real destination object ? */
+#else
+ if (pData->iPASTtargetid) /* a real destination object ? */
+#endif
+ { /* let's find it then */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pTargetimg = (mng_imagep)mng_find_imageobject (pData, iTargetid);
+#else
+ pTargetimg = (mng_imagep)mng_find_imageobject (pData, pData->iPASTtargetid);
+#endif
+
+ if (!pTargetimg) /* if it doesn't exists; do a barf */
+ MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
+ /* it's gotta be abstract !!! */
+ if (pTargetimg->pImgbuf->bConcrete)
+ MNG_ERROR (pData, MNG_OBJNOTABSTRACT);
+ /* we want 32-/64-bit RGBA to play with ! */
+ if ((pTargetimg->pImgbuf->iBitdepth <= MNG_BITDEPTH_8) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_GRAY) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_RGB) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_INDEXED) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_GRAYA) )
+ iRetcode = mng_promote_imageobject (pData, pTargetimg, MNG_BITDEPTH_8,
+ MNG_COLORTYPE_RGBA,
+ MNG_FILLMETHOD_LEFTBITREPLICATE);
+ else
+ if ((pTargetimg->pImgbuf->iBitdepth > MNG_BITDEPTH_8) &&
+ ((pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_GRAY) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_RGB) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_GRAYA) ) )
+ iRetcode = mng_promote_imageobject (pData, pTargetimg, MNG_BITDEPTH_16,
+ MNG_COLORTYPE_RGBA,
+ MNG_FILLMETHOD_LEFTBITREPLICATE);
+#ifdef MNG_INCLUDE_JNG
+ else
+ if ((pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_JPEGGRAY) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) ||
+ (pTargetimg->pImgbuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) )
+ iRetcode = mng_promote_imageobject (pData, pTargetimg,
+ pTargetimg->pImgbuf->iBitdepth,
+ MNG_COLORTYPE_JPEGCOLORA,
+ MNG_FILLMETHOD_LEFTBITREPLICATE);
+#endif
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* make it really abstract ? */
+ if (!pTargetimg->pImgbuf->bCorrected)
+ {
+ iRetcode = mng_colorcorrect_object (pData, pTargetimg);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ else
+ { /* pasting into object 0 !!! */
+ pTargetimg = (mng_imagep)pData->pObjzero;
+ /* is it usable ??? */
+ if ((pTargetimg->bClipped) &&
+ (pTargetimg->iClipr > pTargetimg->iPosx) &&
+ (pTargetimg->iClipb > pTargetimg->iPosy))
+ {
+ /* make it 32-bit RGBA please !!! */
+ iRetcode = mng_reset_object_details (pData, pTargetimg,
+ pTargetimg->iClipr - pTargetimg->iPosx,
+ pTargetimg->iClipb - pTargetimg->iPosy,
+ MNG_BITDEPTH_8, MNG_COLORTYPE_RGBA,
+ 0, 0, 0, MNG_FALSE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ pTargetimg = MNG_NULL; /* clipped beyond visibility ! */
+ }
+
+ if (pTargetimg) /* usable destination ? */
+ {
+ mng_int32 iSourceY;
+ mng_int32 iSourceYinc;
+ mng_int32 iSourcerowsize;
+ mng_int32 iSourcesamples;
+ mng_bool bSourceRGBA16;
+ mng_int32 iTargetY;
+ mng_int32 iTargetrowsize;
+ mng_int32 iTargetsamples;
+ mng_bool bTargetRGBA16 = MNG_FALSE;
+ mng_int32 iTemprowsize;
+ mng_imagedatap pBuf;
+#ifndef MNG_SKIPCHUNK_MAGN
+ /* needs magnification ? */
+ if ((pTargetimg->iMAGN_MethodX) || (pTargetimg->iMAGN_MethodY))
+ iRetcode = mng_magnify_imageobject (pData, pTargetimg);
+#endif
+
+ if (!iRetcode) /* still ok ? */
+ {
+ bTargetRGBA16 = (mng_bool)(pTargetimg->pImgbuf->iBitdepth > 8);
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ switch (iTargettype) /* determine target x/y */
+#else
+ switch (pData->iPASTtargettype) /* determine target x/y */
+#endif
+ {
+ case 0 : {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pData->iPastx = iTargetx;
+ pData->iPasty = iTargety;
+#else
+ pData->iPastx = pData->iPASTtargetx;
+ pData->iPasty = pData->iPASTtargety;
+#endif
+ break;
+ }
+
+ case 1 : {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pData->iPastx = pTargetimg->iPastx + iTargetx;
+ pData->iPasty = pTargetimg->iPasty + iTargety;
+#else
+ pData->iPastx = pTargetimg->iPastx + pData->iPASTtargetx;
+ pData->iPasty = pTargetimg->iPasty + pData->iPASTtargety;
+#endif
+ break;
+ }
+
+ case 2 : {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pData->iPastx += iTargetx;
+ pData->iPasty += iTargety;
+#else
+ pData->iPastx += pData->iPASTtargetx;
+ pData->iPasty += pData->iPASTtargety;
+#endif
+ break;
+ }
+ }
+ /* save for next time ... */
+ pTargetimg->iPastx = pData->iPastx;
+ pTargetimg->iPasty = pData->iPasty;
+ /* address destination for row-routines */
+ pData->pStoreobj = (mng_objectp)pTargetimg;
+ pData->pStorebuf = (mng_objectp)pTargetimg->pImgbuf;
+ }
+ /* process the sources one by one */
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ while ((!iRetcode) && (iX < iCount))
+#else
+ while ((!iRetcode) && (iX < pData->iPASTcount))
+#endif
+ { /* find the little bastards first */
+ pSourceimg = (mng_imagep)mng_find_imageobject (pData, pSource->iSourceid);
+ /* exists and viewable? */
+ if ((pSourceimg) && (pSourceimg->bViewable))
+ { /* needs magnification ? */
+#ifndef MNG_SKIPCHUNK_MAGN
+ if ((pSourceimg->iMAGN_MethodX) || (pSourceimg->iMAGN_MethodY))
+ iRetcode = mng_magnify_imageobject (pData, pSourceimg);
+#endif
+
+ if (!iRetcode) /* still ok ? */
+ {
+ pBuf = (mng_imagedatap)pSourceimg->pImgbuf;
+ /* address source for row-routines */
+ pData->pRetrieveobj = (mng_objectp)pSourceimg;
+
+ pData->iPass = -1; /* init row-processing variables */
+ pData->iRowinc = 1;
+ pData->iColinc = 1;
+ pData->iPixelofs = 0;
+ iSourcesamples = (mng_int32)pBuf->iWidth;
+ iSourcerowsize = pBuf->iRowsize;
+ bSourceRGBA16 = (mng_bool)(pBuf->iBitdepth > 8);
+ /* make sure the delta-routines do the right thing */
+ pData->iDeltatype = MNG_DELTATYPE_BLOCKPIXELREPLACE;
+
+ switch (pBuf->iColortype)
+ {
+ case 0 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+
+ pData->bIsOpaque = (mng_bool)(!pBuf->bHasTRNS);
+ break;
+ }
+
+ case 2 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+
+ pData->bIsOpaque = (mng_bool)(!pBuf->bHasTRNS);
+ break;
+ }
+
+
+ case 3 : { pData->fRetrieverow = (mng_fptr)mng_retrieve_idx8;
+ pData->bIsOpaque = (mng_bool)(!pBuf->bHasTRNS);
+ break;
+ }
+
+
+ case 4 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+
+ case 6 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ case 8 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_g8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+ case 10 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgb8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+
+ case 12 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+
+ case 14 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bSourceRGBA16)
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16;
+ else
+#endif
+ pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+ }
+ /* determine scaling */
+#ifndef MNG_NO_16BIT_SUPPORT
+#ifndef MNG_NO_DELTA_PNG
+ if ((!bSourceRGBA16) && (bTargetRGBA16))
+ pData->fScalerow = (mng_fptr)mng_scale_rgba8_rgba16;
+ else
+ if ((bSourceRGBA16) && (!bTargetRGBA16))
+ pData->fScalerow = (mng_fptr)mng_scale_rgba16_rgba8;
+ else
+#endif
+#endif
+ pData->fScalerow = MNG_NULL;
+
+ /* default no color-correction */
+ pData->fCorrectrow = MNG_NULL;
+
+#if defined(MNG_FULL_CMS) /* determine color-management routine */
+ iRetcode = mng_init_full_cms (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#elif defined(MNG_GAMMA_ONLY)
+ iRetcode = mng_init_gamma_only (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#elif defined(MNG_APP_CMS)
+ iRetcode = mng_init_app_cms (pData, MNG_FALSE, MNG_FALSE, MNG_TRUE);
+#endif
+ }
+
+ if (!iRetcode) /* still ok ? */
+ {
+ pData->fFliprow = MNG_NULL; /* no flipping or tiling by default */
+ pData->fTilerow = MNG_NULL;
+ /* but perhaps we do have to ... */
+ switch (pSource->iOrientation)
+ {
+ case 2 : ;
+ case 4 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16)
+ pData->fFliprow = (mng_fptr)mng_flip_rgba16;
+ else
+#endif
+ pData->fFliprow = (mng_fptr)mng_flip_rgba8;
+ break;
+ }
+
+ case 8 : {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16)
+ pData->fTilerow = (mng_fptr)mng_tile_rgba16;
+ else
+#endif
+ pData->fTilerow = (mng_fptr)mng_tile_rgba8;
+ break;
+ }
+ }
+ /* determine composition routine */
+ /* note that we're abusing the delta-routine setup !!! */
+ switch (pSource->iComposition)
+ {
+ case 0 : { /* composite over */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16)
+ pData->fDeltarow = (mng_fptr)mng_composeover_rgba16;
+ else
+#endif
+ pData->fDeltarow = (mng_fptr)mng_composeover_rgba8;
+ break;
+ }
+
+ case 1 : { /* replace */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16)
+ pData->fDeltarow = (mng_fptr)mng_delta_rgba16_rgba16;
+ else
+#endif
+ pData->fDeltarow = (mng_fptr)mng_delta_rgba8_rgba8;
+ break;
+ }
+
+ case 2 : { /* composite under */
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16)
+ pData->fDeltarow = (mng_fptr)mng_composeunder_rgba16;
+ else
+#endif
+ pData->fDeltarow = (mng_fptr)mng_composeunder_rgba8;
+ break;
+ }
+ }
+ /* determine offsets & clipping */
+ if (pSource->iOffsettype == 1)
+ {
+ pData->iDestl = pData->iPastx + pSource->iOffsetx;
+ pData->iDestt = pData->iPasty + pSource->iOffsety;
+ }
+ else
+ {
+ pData->iDestl = pSource->iOffsetx;
+ pData->iDestt = pSource->iOffsety;
+ }
+
+ pData->iDestr = (mng_int32)pTargetimg->pImgbuf->iWidth;
+ pData->iDestb = (mng_int32)pTargetimg->pImgbuf->iHeight;
+ /* take the source dimension into account ? */
+ if (pSource->iOrientation != 8)
+ {
+ pData->iDestr = MIN_COORD (pData->iDestr, pData->iDestl + (mng_int32)pBuf->iWidth);
+ pData->iDestb = MIN_COORD (pData->iDestb, pData->iDestt + (mng_int32)pBuf->iHeight);
+ }
+ /* source clipping */
+ if (pSource->iBoundarytype == 1)
+ {
+ if (pData->iDestl < pData->iPastx + pSource->iBoundaryl)
+ pData->iSourcel = pData->iPastx + pSource->iBoundaryl - pData->iDestl;
+ else
+ pData->iSourcel = 0;
+
+ if (pData->iDestt < pData->iPasty + pSource->iBoundaryt)
+ pData->iSourcet = pData->iPasty + pSource->iBoundaryt - pData->iDestt;
+ else
+ pData->iSourcet = 0;
+
+ pData->iDestl = MAX_COORD (pData->iDestl, pData->iPastx + pSource->iBoundaryl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pData->iPasty + pSource->iBoundaryt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pData->iPastx + pSource->iBoundaryr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pData->iPasty + pSource->iBoundaryb);
+ }
+ else
+ {
+ if (pData->iDestl < pSource->iBoundaryl)
+ pData->iSourcel = pSource->iBoundaryl - pData->iDestl;
+ else
+ pData->iSourcel = 0;
+
+ if (pData->iDestt < pSource->iBoundaryt)
+ pData->iSourcet = pSource->iBoundaryt - pData->iDestt;
+ else
+ pData->iSourcet = 0;
+
+ pData->iDestl = MAX_COORD (pData->iDestl, pSource->iBoundaryl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pSource->iBoundaryt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pSource->iBoundaryr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pSource->iBoundaryb);
+ }
+
+ if (pData->iSourcel) /* indent source ? */
+ {
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16) /* abuse tiling routine to shift source-pixels */
+ pData->fTilerow = (mng_fptr)mng_tile_rgba16;
+ else
+#endif
+ pData->fTilerow = (mng_fptr)mng_tile_rgba8;
+ }
+ /* anything to display ? */
+ if ((pData->iDestl <= pData->iDestr) && (pData->iDestt <= pData->iDestb))
+ { /* init variables for the loop */
+ if ((pSource->iOrientation == 2) || (pSource->iOrientation == 6))
+ {
+ iSourceY = (mng_int32)pBuf->iHeight - 1 - pData->iSourcet;
+ iSourceYinc = -1;
+ }
+ else
+ {
+ iSourceY = pData->iSourcet;
+ iSourceYinc = 1;
+ }
+
+ iTargetY = pData->iDestt;
+ pData->iCol = pData->iDestl;
+
+ iTargetsamples = pData->iDestr - pData->iDestl;
+
+#ifndef MNG_NO_16BIT_SUPPORT
+ if (bTargetRGBA16)
+ iTargetrowsize = (iTargetsamples << 3);
+ else
+#endif
+ iTargetrowsize = (iTargetsamples << 2);
+
+ /* get temporary work-buffers */
+ if (iSourcerowsize > iTargetrowsize)
+ iTemprowsize = iSourcerowsize << 1;
+ else
+ iTemprowsize = iTargetrowsize << 1;
+ MNG_ALLOC (pData, pData->pRGBArow, iTemprowsize);
+ MNG_ALLOC (pData, pData->pWorkrow, iTemprowsize);
+
+ while ((!iRetcode) && (iTargetY < pData->iDestb))
+ { /* get a row */
+ pData->iRow = iSourceY;
+ pData->iRowsamples = iSourcesamples;
+ pData->iRowsize = iSourcerowsize;
+ pData->bIsRGBA16 = bSourceRGBA16;
+ iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
+ /* scale it (if necessary) */
+ if ((!iRetcode) && (pData->fScalerow))
+ iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
+
+ pData->bIsRGBA16 = bTargetRGBA16;
+ /* color correction (if necessary) */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+ /* flipping (if necessary) */
+ if ((!iRetcode) && (pData->fFliprow))
+ iRetcode = ((mng_fliprow)pData->fFliprow) (pData);
+ /* tiling (if necessary) */
+ if ((!iRetcode) && (pData->fTilerow))
+ iRetcode = ((mng_tilerow)pData->fTilerow) (pData);
+
+ if (!iRetcode) /* and paste..... */
+ {
+ pData->iRow = iTargetY;
+ pData->iRowsamples = iTargetsamples;
+ pData->iRowsize = iTargetrowsize;
+ iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
+ }
+
+ iSourceY += iSourceYinc; /* and next line */
+
+ if (iSourceY < 0)
+ iSourceY = (mng_int32)pBuf->iHeight - 1;
+ else
+ if (iSourceY >= (mng_int32)pBuf->iHeight)
+ iSourceY = 0;
+
+ iTargetY++;
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREEX (pData, pData->pWorkrow, iTemprowsize);
+ MNG_FREEX (pData, pData->pRGBArow, iTemprowsize);
+ }
+
+#if defined(MNG_FULL_CMS) /* cleanup cms stuff */
+ if (!iRetcode)
+ iRetcode = mng_clear_cms (pData);
+#endif
+ }
+
+ pSource++; /* neeeeext */
+ iX++;
+ }
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ if (!iTargetid) /* did we paste into object 0 ? */
+#else
+ if (!pData->iPASTtargetid) /* did we paste into object 0 ? */
+#endif
+ { /* display it then ! */
+ iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ { /* target is visible & viewable ? */
+ if ((pTargetimg->bVisible) && (pTargetimg->bViewable))
+ {
+ iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
+ if (iRetcode)
+ return iRetcode;
+ }
+ }
+ }
+
+ if (pData->bTimerset) /* broken ? */
+ {
+#ifndef MNG_OPTIMIZE_DISPLAYCALLS
+ pData->iPASTid = iTargetid;
+#else
+ pData->iPASTid = pData->iPASTtargetid;
+#endif
+ pData->iBreakpoint = 11;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCHUNK_PAST */
+
+/* ************************************************************************** */
+
+#ifndef MNG_SKIPCHUNK_PAST
+mng_retcode mng_process_display_past2 (mng_datap pData)
+{
+ mng_retcode iRetcode;
+ mng_imagep pTargetimg;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_START);
+#endif
+
+ if (pData->iPASTid) /* a real destination object ? */
+ pTargetimg = (mng_imagep)mng_find_imageobject (pData, pData->iPASTid);
+ else /* otherwise object 0 */
+ pTargetimg = (mng_imagep)pData->pObjzero;
+
+ iRetcode = mng_display_image (pData, pTargetimg, MNG_FALSE);
+ if (iRetcode)
+ return iRetcode;
+
+ pData->iBreakpoint = 0; /* only once */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PAST, MNG_LC_END);
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SKIPCHUNK_PAST */
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_DISPLAY_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
+