/src/FreeImage/Source/LibMNG/libmng_display.c
C | 1418 lines | 951 code | 148 blank | 319 comment | 202 complexity | 0db316acf17863ec734bc3a61aa9cc6c MD5 | raw file
Possible License(s): LGPL-3.0, BSD-3-Clause, CPL-1.0, Unlicense, GPL-2.0, GPL-3.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, BSD-2-Clause, LGPL-2.1
- /* ************************************************************************** */
- /* * 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) /* real delay ? */
- { /* 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;
- #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;
- #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)
-