/* ************************************************************************** */ /* * 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 * */ /* ************************************************************************** */