| /* ************************************************************************** */ |
| /* * For conditions of distribution and use, * */ |
| /* * see copyright notice in libmng.h * */ |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * project : libmng * */ |
| /* * file : libmng_object_prc.c copyright (c) 2000-2007 G.Juyn * */ |
| /* * version : 1.0.10 * */ |
| /* * * */ |
| /* * purpose : Object processing routines (implementation) * */ |
| /* * * */ |
| /* * author : G.Juyn * */ |
| /* * * */ |
| /* * comment : implementation of the internal object processing routines * */ |
| /* * * */ |
| /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */ |
| /* * - changed strict-ANSI stuff * */ |
| /* * 0.5.1 - 05/12/2000 - G.Juyn * */ |
| /* * - changed trace to macro for callback error-reporting * */ |
| /* * * */ |
| /* * 0.5.2 - 05/20/2000 - G.Juyn * */ |
| /* * - fixed to support JNG objects * */ |
| /* * 0.5.2 - 05/24/2000 - G.Juyn * */ |
| /* * - added support for global color-chunks in animation * */ |
| /* * - added support for global PLTE,tRNS,bKGD in animation * */ |
| /* * - added SAVE & SEEK animation objects * */ |
| /* * 0.5.2 - 05/29/2000 - G.Juyn * */ |
| /* * - added initialization of framenr/layernr/playtime * */ |
| /* * - changed ani_object create routines not to return the * */ |
| /* * created object (wasn't necessary) * */ |
| /* * 0.5.2 - 05/30/2000 - G.Juyn * */ |
| /* * - added object promotion routine (PROM handling) * */ |
| /* * - added ani-object routines for delta-image processing * */ |
| /* * - added compression/filter/interlace fields to * */ |
| /* * object-buffer for delta-image processing * */ |
| /* * * */ |
| /* * 0.5.3 - 06/17/2000 - G.Juyn * */ |
| /* * - changed support for delta-image processing * */ |
| /* * 0.5.3 - 06/20/2000 - G.Juyn * */ |
| /* * - fixed some small things (as precaution) * */ |
| /* * 0.5.3 - 06/21/2000 - G.Juyn * */ |
| /* * - added processing of PLTE/tRNS & color-info for * */ |
| /* * delta-images in the ani_objects chain * */ |
| /* * 0.5.3 - 06/22/2000 - G.Juyn * */ |
| /* * - added support for PPLT chunk * */ |
| /* * * */ |
| /* * 0.9.1 - 07/07/2000 - G.Juyn * */ |
| /* * - added support for freeze/restart/resume & go_xxxx * */ |
| /* * 0.9.1 - 07/16/2000 - G.Juyn * */ |
| /* * - fixed support for mng_display() after mng_read() * */ |
| /* * * */ |
| /* * 0.9.2 - 07/29/2000 - G.Juyn * */ |
| /* * - fixed small bugs in display processing * */ |
| /* * 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/26/2000 - G.Juyn * */ |
| /* * - added MAGN chunk * */ |
| /* * 0.9.3 - 09/10/2000 - G.Juyn * */ |
| /* * - fixed DEFI behavior * */ |
| /* * 0.9.3 - 10/17/2000 - G.Juyn * */ |
| /* * - added valid-flag to stored objects for read() / display()* */ |
| /* * - added routine to discard "invalid" objects * */ |
| /* * 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.4 - 1/18/2001 - G.Juyn * */ |
| /* * - removed "old" MAGN methods 3 & 4 * */ |
| /* * - added "new" MAGN methods 3, 4 & 5 * */ |
| /* * * */ |
| /* * 0.9.5 - 1/22/2001 - G.Juyn * */ |
| /* * - B129681 - fixed compiler warnings SGI/Irix * */ |
| /* * * */ |
| /* * 1.0.2 - 06/23/2001 - G.Juyn * */ |
| /* * - added optimization option for MNG-video playback * */ |
| /* * * */ |
| /* * 1.0.5 - 08/15/2002 - G.Juyn * */ |
| /* * - completed PROM support * */ |
| /* * 1.0.5 - 08/16/2002 - G.Juyn * */ |
| /* * - completed MAGN support (16-bit functions) * */ |
| /* * 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 * */ |
| /* * - added event handling for dynamic MNG * */ |
| /* * 1.0.5 - 09/20/2002 - G.Juyn * */ |
| /* * - added support for PAST * */ |
| /* * 1.0.5 - 09/23/2002 - G.Juyn * */ |
| /* * - fixed reset_object_detail to clear old buffer * */ |
| /* * - added in-memory color-correction of abstract images * */ |
| /* * 1.0.5 - 10/05/2002 - G.Juyn * */ |
| /* * - fixed problem with cloned objects marked as invalid * */ |
| /* * - fixed problem cloning frozen object_buffers * */ |
| /* * 1.0.5 - 10/07/2002 - G.Juyn * */ |
| /* * - fixed DISC support * */ |
| /* * 1.0.5 - 11/04/2002 - G.Juyn * */ |
| /* * - fixed goframe/golayer/gotime processing * */ |
| /* * 1.0.5 - 11/07/2002 - G.Juyn * */ |
| /* * - fixed magnification bug with object 0 * */ |
| /* * 1.0.5 - 01/19/2003 - G.Juyn * */ |
| /* * - B664911 - fixed buffer overflow during init * */ |
| /* * * */ |
| /* * 1.0.6 - 04/19/2003 - G.Juyn * */ |
| /* * - fixed problem with infinite loops during readdisplay() * */ |
| /* * 1.0.6 - 05/25/2003 - G.R-P * */ |
| /* * - added MNG_SKIPCHUNK_cHNK footprint optimizations * */ |
| /* * 1.0.6 - 06/09/2003 - G. R-P * */ |
| /* * - added conditionals around 8-bit magn routines * */ |
| /* * 1.0.6 - 07/07/2003 - G.R-P * */ |
| /* * - added conditionals around some JNG-supporting code * */ |
| /* * - removed conditionals around 8-bit magn routines * */ |
| /* * - added conditionals around delta-png and 16-bit code * */ |
| /* * 1.0.6 - 07/14/2003 - G.R-P * */ |
| /* * - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional * */ |
| /* * 1.0.6 - 07/29/2003 - G.Juyn * */ |
| /* * - fixed invalid test in promote_imageobject * */ |
| /* * 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 MAGN chunk support * */ |
| /* * * */ |
| /* * 1.0.7 - 03/21/2004 - G.Juyn * */ |
| /* * - fixed some 64-bit platform compiler warnings * */ |
| /* * * */ |
| /* * 1.0.9 - 10/10/2004 - G.R-P. * */ |
| /* * - added MNG_NO_1_2_4BIT_SUPPORT support * */ |
| /* * 1.0.9 - 12/05/2004 - G.Juyn * */ |
| /* * - added conditional MNG_OPTIMIZE_OBJCLEANUP * */ |
| /* * 1.0.9 - 12/11/2004 - G.Juyn * */ |
| /* * - added conditional MNG_OPTIMIZE_DISPLAYCALLS * */ |
| /* * 1.0.9 - 12/31/2004 - G.R-P. * */ |
| /* * - fixed warnings about possible uninitialized pointers * */ |
| /* * 1.0.9 - 01/02/2005 - G.Juyn * */ |
| /* * - fixing some compiler-warnings * */ |
| /* * * */ |
| /* * 1.0.10 - 02/07/2005 - G.Juyn * */ |
| /* * - fixed some compiler-warnings * */ |
| /* * 1.0.10 - 07/30/2005 - G.Juyn * */ |
| /* * - fixed problem with CLON object during readdisplay() * */ |
| /* * 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_memory.h" |
| #include "libmng_chunks.h" |
| #include "libmng_objects.h" |
| #include "libmng_display.h" |
| #include "libmng_pixels.h" |
| #include "libmng_object_prc.h" |
| #include "libmng_cms.h" |
| |
| #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI) |
| #pragma option -A /* force ANSI-C */ |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_INCLUDE_DISPLAY_PROCS |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Generic object routines * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_drop_invalid_objects (mng_datap pData) |
| { |
| mng_objectp pObject; |
| mng_objectp pNext; |
| mng_cleanupobject fCleanup; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_START); |
| #endif |
| |
| pObject = pData->pFirstimgobj; /* get first stored image-object (if any) */ |
| |
| while (pObject) /* more objects to check ? */ |
| { |
| pNext = ((mng_object_headerp)pObject)->pNext; |
| /* invalid ? */ |
| if (!((mng_imagep)pObject)->bValid) |
| { /* call appropriate cleanup */ |
| fCleanup = ((mng_object_headerp)pObject)->fCleanup; |
| fCleanup (pData, pObject); |
| } |
| |
| pObject = pNext; /* neeeext */ |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| MNG_LOCAL mng_retcode create_obj_general (mng_datap pData, |
| mng_size_t iObjsize, |
| mng_cleanupobject fCleanup, |
| mng_processobject fProcess, |
| mng_ptr *ppObject) |
| { |
| mng_object_headerp pWork; |
| |
| MNG_ALLOC (pData, pWork, iObjsize); |
| |
| pWork->fCleanup = fCleanup; |
| pWork->fProcess = fProcess; |
| pWork->iObjsize = iObjsize; |
| *ppObject = (mng_ptr)pWork; |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| MNG_LOCAL mng_retcode mng_free_obj_general (mng_datap pData, |
| mng_objectp pObject) |
| { |
| MNG_FREEX (pData, pObject, ((mng_object_headerp)pObject)->iObjsize); |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Image-data-object routines * */ |
| /* * * */ |
| /* * these handle the "object buffer" as defined by the MNG specification * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_create_imagedataobject (mng_datap pData, |
| mng_bool bConcrete, |
| mng_bool bViewable, |
| mng_uint32 iWidth, |
| mng_uint32 iHeight, |
| mng_uint8 iBitdepth, |
| mng_uint8 iColortype, |
| mng_uint8 iCompression, |
| mng_uint8 iFilter, |
| mng_uint8 iInterlace, |
| mng_imagedatap *ppObject) |
| { |
| mng_imagedatap pImagedata; |
| mng_uint32 iSamplesize = 0; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_START); |
| #endif |
| /* get a buffer */ |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| { |
| mng_ptr pTemp; |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_imagedata), |
| (mng_cleanupobject)mng_free_imagedataobject, |
| MNG_NULL, &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pImagedata = (mng_imagedatap)pTemp; |
| } |
| #else |
| MNG_ALLOC (pData, pImagedata, sizeof (mng_imagedata)); |
| /* fill the appropriate fields */ |
| pImagedata->sHeader.fCleanup = (mng_cleanupobject)mng_free_imagedataobject; |
| pImagedata->sHeader.fProcess = MNG_NULL; |
| #endif |
| pImagedata->iRefcount = 1; |
| pImagedata->bFrozen = MNG_FALSE; |
| pImagedata->bConcrete = bConcrete; |
| pImagedata->bViewable = bViewable; |
| pImagedata->iWidth = iWidth; |
| pImagedata->iHeight = iHeight; |
| pImagedata->iBitdepth = iBitdepth; |
| pImagedata->iColortype = iColortype; |
| pImagedata->iCompression = iCompression; |
| pImagedata->iFilter = iFilter; |
| pImagedata->iInterlace = iInterlace; |
| pImagedata->bCorrected = MNG_FALSE; |
| pImagedata->iAlphabitdepth = 0; |
| pImagedata->iJHDRcompression = 0; |
| pImagedata->iJHDRinterlace = 0; |
| pImagedata->iPixelsampledepth = iBitdepth; |
| pImagedata->iAlphasampledepth = iBitdepth; |
| /* determine samplesize from color_type/bit_depth */ |
| switch (iColortype) /* for < 8-bit samples we just reserve 8 bits */ |
| { |
| case 0 : ; /* gray */ |
| case 8 : { /* JPEG gray */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 2; |
| else |
| #endif |
| iSamplesize = 1; |
| |
| break; |
| } |
| case 2 : ; /* rgb */ |
| case 10 : { /* JPEG rgb */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 6; |
| else |
| #endif |
| iSamplesize = 3; |
| |
| break; |
| } |
| case 3 : { /* indexed */ |
| iSamplesize = 1; |
| break; |
| } |
| case 4 : ; /* gray+alpha */ |
| case 12 : { /* JPEG gray+alpha */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 4; |
| else |
| #endif |
| iSamplesize = 2; |
| |
| break; |
| } |
| case 6 : ; /* rgb+alpha */ |
| case 14 : { /* JPEG rgb+alpha */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 8; |
| else |
| #endif |
| iSamplesize = 4; |
| |
| break; |
| } |
| } |
| /* make sure we remember all this */ |
| pImagedata->iSamplesize = iSamplesize; |
| pImagedata->iRowsize = iSamplesize * iWidth; |
| pImagedata->iImgdatasize = pImagedata->iRowsize * iHeight; |
| |
| if (pImagedata->iImgdatasize) /* need a buffer ? */ |
| { /* so allocate it */ |
| MNG_ALLOCX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize); |
| |
| if (!pImagedata->pImgdata) /* enough memory ? */ |
| { |
| MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata)); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| } |
| /* check global stuff */ |
| pImagedata->bHasGAMA = pData->bHasglobalGAMA; |
| #ifndef MNG_SKIPCHUNK_cHRM |
| pImagedata->bHasCHRM = pData->bHasglobalCHRM; |
| #endif |
| pImagedata->bHasSRGB = pData->bHasglobalSRGB; |
| #ifndef MNG_SKIPCHUNK_iCCP |
| pImagedata->bHasICCP = pData->bHasglobalICCP; |
| #endif |
| #ifndef MNG_SKIPCHUNK_bKGD |
| pImagedata->bHasBKGD = pData->bHasglobalBKGD; |
| #endif |
| |
| if (pData->bHasglobalGAMA) /* global gAMA present ? */ |
| pImagedata->iGamma = pData->iGlobalGamma; |
| |
| #ifndef MNG_SKIPCHUNK_cHRM |
| if (pData->bHasglobalCHRM) /* global cHRM present ? */ |
| { |
| pImagedata->iWhitepointx = pData->iGlobalWhitepointx; |
| pImagedata->iWhitepointy = pData->iGlobalWhitepointy; |
| pImagedata->iPrimaryredx = pData->iGlobalPrimaryredx; |
| pImagedata->iPrimaryredy = pData->iGlobalPrimaryredy; |
| pImagedata->iPrimarygreenx = pData->iGlobalPrimarygreenx; |
| pImagedata->iPrimarygreeny = pData->iGlobalPrimarygreeny; |
| pImagedata->iPrimarybluex = pData->iGlobalPrimarybluex; |
| pImagedata->iPrimarybluey = pData->iGlobalPrimarybluey; |
| } |
| #endif |
| |
| if (pData->bHasglobalSRGB) /* glbal sRGB present ? */ |
| pImagedata->iRenderingintent = pData->iGlobalRendintent; |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pData->bHasglobalICCP) /* glbal iCCP present ? */ |
| { |
| pImagedata->iProfilesize = pData->iGlobalProfilesize; |
| |
| if (pImagedata->iProfilesize) |
| { |
| MNG_ALLOCX (pData, pImagedata->pProfile, pImagedata->iProfilesize); |
| |
| if (!pImagedata->pProfile) /* enough memory ? */ |
| { |
| MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize); |
| MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata)); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| |
| MNG_COPY (pImagedata->pProfile, pData->pGlobalProfile, pImagedata->iProfilesize); |
| } |
| } |
| #endif |
| |
| #ifndef MNG_SKIPCHUNK_bKGD |
| if (pData->bHasglobalBKGD) /* global bKGD present ? */ |
| { |
| pImagedata->iBKGDred = pData->iGlobalBKGDred; |
| pImagedata->iBKGDgreen = pData->iGlobalBKGDgreen; |
| pImagedata->iBKGDblue = pData->iGlobalBKGDblue; |
| } |
| #endif |
| |
| *ppObject = pImagedata; /* return it */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_free_imagedataobject (mng_datap pData, |
| mng_imagedatap pImagedata) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_START); |
| #endif |
| |
| if (pImagedata->iRefcount) /* decrease reference count */ |
| pImagedata->iRefcount--; |
| |
| if (!pImagedata->iRefcount) /* reached zero ? */ |
| { |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pImagedata->iProfilesize) /* stored an iCCP profile ? */ |
| MNG_FREEX (pData, pImagedata->pProfile, pImagedata->iProfilesize); |
| #endif |
| if (pImagedata->iImgdatasize) /* sample-buffer present ? */ |
| MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize); |
| /* drop the buffer */ |
| MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata)); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_clone_imagedataobject (mng_datap pData, |
| mng_bool bConcrete, |
| mng_imagedatap pSource, |
| mng_imagedatap *ppClone) |
| { |
| mng_imagedatap pNewdata; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_START); |
| #endif |
| /* get a buffer */ |
| MNG_ALLOC (pData, pNewdata, sizeof (mng_imagedata)); |
| /* blatently copy the original buffer */ |
| MNG_COPY (pNewdata, pSource, sizeof (mng_imagedata)); |
| |
| pNewdata->iRefcount = 1; /* only the reference count */ |
| pNewdata->bConcrete = bConcrete; /* and concrete-flag are different */ |
| pNewdata->bFrozen = MNG_FALSE; |
| |
| if (pNewdata->iImgdatasize) /* sample buffer present ? */ |
| { |
| MNG_ALLOCX (pData, pNewdata->pImgdata, pNewdata->iImgdatasize); |
| |
| if (!pNewdata->pImgdata) /* not enough memory ? */ |
| { |
| MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata)); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| /* make a copy */ |
| MNG_COPY (pNewdata->pImgdata, pSource->pImgdata, pNewdata->iImgdatasize); |
| } |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pNewdata->iProfilesize) /* iCCP profile present ? */ |
| { |
| MNG_ALLOCX (pData, pNewdata->pProfile, pNewdata->iProfilesize); |
| |
| if (!pNewdata->pProfile) /* enough memory ? */ |
| { |
| MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata)); |
| MNG_ERROR (pData, MNG_OUTOFMEMORY); |
| } |
| /* make a copy */ |
| MNG_COPY (pNewdata->pProfile, pSource->pProfile, pNewdata->iProfilesize); |
| } |
| #endif |
| |
| *ppClone = pNewdata; /* return the clone */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Image-object routines * */ |
| /* * * */ |
| /* * these handle the "object" as defined by the MNG specification * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_create_imageobject (mng_datap pData, |
| mng_uint16 iId, |
| mng_bool bConcrete, |
| mng_bool bVisible, |
| mng_bool bViewable, |
| mng_uint32 iWidth, |
| mng_uint32 iHeight, |
| mng_uint8 iBitdepth, |
| mng_uint8 iColortype, |
| mng_uint8 iCompression, |
| mng_uint8 iFilter, |
| mng_uint8 iInterlace, |
| mng_int32 iPosx, |
| mng_int32 iPosy, |
| mng_bool bClipped, |
| mng_int32 iClipl, |
| mng_int32 iClipr, |
| mng_int32 iClipt, |
| mng_int32 iClipb, |
| mng_imagep *ppObject) |
| { |
| mng_imagep pImage; |
| mng_imagep pPrev, pNext; |
| mng_retcode iRetcode; |
| mng_imagedatap pImgbuf; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_START); |
| #endif |
| /* get a buffer */ |
| MNG_ALLOC (pData, pImage, sizeof (mng_image)); |
| /* now get a new "object buffer" */ |
| iRetcode = mng_create_imagedataobject (pData, bConcrete, bViewable, |
| iWidth, iHeight, iBitdepth, iColortype, |
| iCompression, iFilter, iInterlace, |
| &pImgbuf); |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pImage, sizeof (mng_image)); |
| return iRetcode; |
| } |
| /* fill the appropriate fields */ |
| pImage->sHeader.fCleanup = (mng_cleanupobject)mng_free_imageobject; |
| pImage->sHeader.fProcess = MNG_NULL; |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| pImage->sHeader.iObjsize = sizeof (mng_image); |
| #endif |
| pImage->iId = iId; |
| pImage->bFrozen = MNG_FALSE; |
| pImage->bVisible = bVisible; |
| pImage->bViewable = bViewable; |
| pImage->bValid = (mng_bool)((pData->bDisplaying) && |
| ((pData->bRunning) || (pData->bSearching)) && |
| (!pData->bFreezing)); |
| pImage->iPosx = iPosx; |
| pImage->iPosy = iPosy; |
| pImage->bClipped = bClipped; |
| pImage->iClipl = iClipl; |
| pImage->iClipr = iClipr; |
| pImage->iClipt = iClipt; |
| pImage->iClipb = iClipb; |
| #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 |
| #ifndef MNG_SKIPCHUNK_PAST |
| pImage->iPastx = 0; |
| pImage->iPasty = 0; |
| #endif |
| pImage->pImgbuf = pImgbuf; |
| |
| if (iId) /* only if not object 0 ! */ |
| { /* find previous lower object-id */ |
| pPrev = (mng_imagep)pData->pLastimgobj; |
| |
| while ((pPrev) && (pPrev->iId > iId)) |
| pPrev = (mng_imagep)pPrev->sHeader.pPrev; |
| |
| if (pPrev) /* found it ? */ |
| { |
| pImage->sHeader.pPrev = pPrev; /* than link it in place */ |
| pImage->sHeader.pNext = pPrev->sHeader.pNext; |
| pPrev->sHeader.pNext = pImage; |
| } |
| else /* if not found, it becomes the first ! */ |
| { |
| pImage->sHeader.pNext = pData->pFirstimgobj; |
| pData->pFirstimgobj = pImage; |
| } |
| |
| pNext = (mng_imagep)pImage->sHeader.pNext; |
| |
| if (pNext) |
| pNext->sHeader.pPrev = pImage; |
| else |
| pData->pLastimgobj = pImage; |
| |
| } |
| |
| *ppObject = pImage; /* and return the new buffer */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* okido */ |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_free_imageobject (mng_datap pData, |
| mng_imagep pImage) |
| { |
| mng_retcode iRetcode; |
| mng_imagep pPrev = pImage->sHeader.pPrev; |
| mng_imagep pNext = pImage->sHeader.pNext; |
| mng_imagedatap pImgbuf = pImage->pImgbuf; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_START); |
| #endif |
| |
| if (pImage->iId) /* not for object 0 */ |
| { |
| if (pPrev) /* unlink from the list first ! */ |
| pPrev->sHeader.pNext = pImage->sHeader.pNext; |
| else |
| pData->pFirstimgobj = pImage->sHeader.pNext; |
| |
| if (pNext) |
| pNext->sHeader.pPrev = pImage->sHeader.pPrev; |
| else |
| pData->pLastimgobj = pImage->sHeader.pPrev; |
| |
| } |
| /* unlink the image-data buffer */ |
| iRetcode = mng_free_imagedataobject (pData, pImgbuf); |
| /* drop its own buffer */ |
| MNG_FREEX (pData, pImage, sizeof (mng_image)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_imagep mng_find_imageobject (mng_datap pData, |
| mng_uint16 iId) |
| { |
| mng_imagep pImage = (mng_imagep)pData->pFirstimgobj; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_START); |
| #endif |
| /* look up the right id */ |
| while ((pImage) && (pImage->iId != iId)) |
| pImage = (mng_imagep)pImage->sHeader.pNext; |
| |
| #ifdef MNG_INCLUDE_MPNG_PROPOSAL |
| if ((!pImage) && (pData->eImagetype == mng_it_mpng)) |
| pImage = pData->pObjzero; |
| #endif |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return pImage; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_clone_imageobject (mng_datap pData, |
| mng_uint16 iId, |
| mng_bool bPartial, |
| mng_bool bVisible, |
| mng_bool bAbstract, |
| mng_bool bHasloca, |
| mng_uint8 iLocationtype, |
| mng_int32 iLocationx, |
| mng_int32 iLocationy, |
| mng_imagep pSource, |
| mng_imagep *ppClone) |
| { |
| mng_imagep pNew; |
| mng_imagep pPrev, pNext; |
| mng_retcode iRetcode; |
| mng_imagedatap pImgbuf; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_START); |
| #endif |
| |
| #ifndef MNG_SKIPCHUNK_MAGN |
| if ((pSource->iId) && /* needs magnification ? */ |
| ((pSource->iMAGN_MethodX) || (pSource->iMAGN_MethodY))) |
| { |
| iRetcode = mng_magnify_imageobject (pData, pSource); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| #endif |
| /* get a buffer */ |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| { |
| mng_ptr pTemp; |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_image), |
| (mng_cleanupobject)mng_free_imageobject, |
| MNG_NULL, &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pNew = (mng_imagep)pTemp; |
| } |
| #else |
| MNG_ALLOC (pData, pNew, sizeof (mng_image)); |
| /* fill or copy the appropriate fields */ |
| pNew->sHeader.fCleanup = (mng_cleanupobject)mng_free_imageobject; |
| pNew->sHeader.fProcess = MNG_NULL; |
| #endif |
| pNew->iId = iId; |
| pNew->bFrozen = MNG_FALSE; |
| pNew->bVisible = bVisible; |
| pNew->bViewable = pSource->bViewable; |
| pNew->bValid = MNG_TRUE; |
| |
| if (bHasloca) /* location info available ? */ |
| { |
| if (iLocationtype == 0) /* absolute position ? */ |
| { |
| pNew->iPosx = iLocationx; |
| pNew->iPosy = iLocationy; |
| } |
| else /* relative */ |
| { |
| pNew->iPosx = pSource->iPosx + iLocationx; |
| pNew->iPosy = pSource->iPosy + iLocationy; |
| } |
| } |
| else /* copy from source */ |
| { |
| pNew->iPosx = pSource->iPosx; |
| pNew->iPosy = pSource->iPosy; |
| } |
| /* copy clipping info */ |
| pNew->bClipped = pSource->bClipped; |
| pNew->iClipl = pSource->iClipl; |
| pNew->iClipr = pSource->iClipr; |
| pNew->iClipt = pSource->iClipt; |
| pNew->iClipb = pSource->iClipb; |
| #ifndef MNG_SKIPCHUNK_MAGN |
| /* copy magnification info */ |
| /* pNew->iMAGN_MethodX = pSource->iMAGN_MethodX; LET'S NOT !!!!!! |
| pNew->iMAGN_MethodY = pSource->iMAGN_MethodY; |
| pNew->iMAGN_MX = pSource->iMAGN_MX; |
| pNew->iMAGN_MY = pSource->iMAGN_MY; |
| pNew->iMAGN_ML = pSource->iMAGN_ML; |
| pNew->iMAGN_MR = pSource->iMAGN_MR; |
| pNew->iMAGN_MT = pSource->iMAGN_MT; |
| pNew->iMAGN_MB = pSource->iMAGN_MB; */ |
| #endif |
| |
| #ifndef MNG_SKIPCHUNK_PAST |
| pNew->iPastx = 0; /* initialize PAST info */ |
| pNew->iPasty = 0; |
| #endif |
| |
| if (iId) /* not for object 0 */ |
| { /* find previous lower object-id */ |
| pPrev = (mng_imagep)pData->pLastimgobj; |
| while ((pPrev) && (pPrev->iId > iId)) |
| pPrev = (mng_imagep)pPrev->sHeader.pPrev; |
| |
| if (pPrev) /* found it ? */ |
| { |
| pNew->sHeader.pPrev = pPrev; /* than link it in place */ |
| pNew->sHeader.pNext = pPrev->sHeader.pNext; |
| pPrev->sHeader.pNext = pNew; |
| } |
| else /* if not found, it becomes the first ! */ |
| { |
| pNew->sHeader.pNext = pData->pFirstimgobj; |
| pData->pFirstimgobj = pNew; |
| } |
| |
| pNext = (mng_imagep)pNew->sHeader.pNext; |
| |
| if (pNext) |
| pNext->sHeader.pPrev = pNew; |
| else |
| pData->pLastimgobj = pNew; |
| |
| } |
| |
| if (bPartial) /* partial clone ? */ |
| { |
| pNew->pImgbuf = pSource->pImgbuf; /* use the same object buffer */ |
| pNew->pImgbuf->iRefcount++; /* and increase the reference count */ |
| } |
| else /* create a full clone ! */ |
| { |
| mng_bool bConcrete = MNG_FALSE; /* it's abstract by default (?) */ |
| |
| if (!bAbstract) /* determine concreteness from source ? */ |
| bConcrete = pSource->pImgbuf->bConcrete; |
| /* create a full clone ! */ |
| iRetcode = mng_clone_imagedataobject (pData, bConcrete, pSource->pImgbuf, &pImgbuf); |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pNew, sizeof (mng_image)); |
| return iRetcode; |
| } |
| |
| pNew->pImgbuf = pImgbuf; /* and remember it */ |
| } |
| |
| *ppClone = pNew; /* return it */ |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_renum_imageobject (mng_datap pData, |
| mng_imagep pSource, |
| mng_uint16 iId, |
| mng_bool bVisible, |
| mng_bool bAbstract, |
| mng_bool bHasloca, |
| mng_uint8 iLocationtype, |
| mng_int32 iLocationx, |
| mng_int32 iLocationy) |
| { |
| mng_imagep pPrev, pNext; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_START); |
| #endif |
| |
| pSource->bVisible = bVisible; /* store the new visibility */ |
| |
| if (bHasloca) /* location info available ? */ |
| { |
| if (iLocationtype == 0) /* absolute position ? */ |
| { |
| pSource->iPosx = iLocationx; |
| pSource->iPosy = iLocationy; |
| } |
| else /* relative */ |
| { |
| pSource->iPosx = pSource->iPosx + iLocationx; |
| pSource->iPosy = pSource->iPosy + iLocationy; |
| } |
| } |
| |
| if (iId) /* not for object 0 */ |
| { /* find previous lower object-id */ |
| pPrev = (mng_imagep)pData->pLastimgobj; |
| while ((pPrev) && (pPrev->iId > iId)) |
| pPrev = (mng_imagep)pPrev->sHeader.pPrev; |
| /* different from current ? */ |
| if (pPrev != (mng_imagep)pSource->sHeader.pPrev) |
| { |
| if (pSource->sHeader.pPrev) /* unlink from current position !! */ |
| ((mng_imagep)pSource->sHeader.pPrev)->sHeader.pNext = pSource->sHeader.pNext; |
| else |
| pData->pFirstimgobj = pSource->sHeader.pNext; |
| |
| if (pSource->sHeader.pNext) |
| ((mng_imagep)pSource->sHeader.pNext)->sHeader.pPrev = pSource->sHeader.pPrev; |
| else |
| pData->pLastimgobj = pSource->sHeader.pPrev; |
| |
| if (pPrev) /* found the previous ? */ |
| { /* than link it in place */ |
| pSource->sHeader.pPrev = pPrev; |
| pSource->sHeader.pNext = pPrev->sHeader.pNext; |
| pPrev->sHeader.pNext = pSource; |
| } |
| else /* if not found, it becomes the first ! */ |
| { |
| pSource->sHeader.pNext = pData->pFirstimgobj; |
| pData->pFirstimgobj = pSource; |
| } |
| |
| pNext = (mng_imagep)pSource->sHeader.pNext; |
| |
| if (pNext) |
| pNext->sHeader.pPrev = pSource; |
| else |
| pData->pLastimgobj = pSource; |
| |
| } |
| } |
| |
| pSource->iId = iId; /* now set the new id! */ |
| |
| if (bAbstract) /* force it to abstract ? */ |
| pSource->pImgbuf->bConcrete = MNG_FALSE; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_reset_object_details (mng_datap pData, |
| mng_imagep pImage, |
| mng_uint32 iWidth, |
| mng_uint32 iHeight, |
| mng_uint8 iBitdepth, |
| mng_uint8 iColortype, |
| mng_uint8 iCompression, |
| mng_uint8 iFilter, |
| mng_uint8 iInterlace, |
| mng_bool bResetall) |
| { |
| mng_imagedatap pBuf = pImage->pImgbuf; |
| mng_uint32 iSamplesize = 0; |
| mng_uint32 iRowsize; |
| mng_uint32 iImgdatasize; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_START); |
| #endif |
| |
| pBuf->iWidth = iWidth; /* set buffer characteristics */ |
| pBuf->iHeight = iHeight; |
| pBuf->iBitdepth = iBitdepth; |
| pBuf->iColortype = iColortype; |
| pBuf->iCompression = iCompression; |
| pBuf->iFilter = iFilter; |
| pBuf->iInterlace = iInterlace; |
| pBuf->bCorrected = MNG_FALSE; |
| pBuf->iAlphabitdepth = 0; |
| /* determine samplesize from color_type/bit_depth */ |
| switch (iColortype) /* for < 8-bit samples we just reserve 8 bits */ |
| { |
| case 0 : ; /* gray */ |
| case 8 : { /* JPEG gray */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 2; |
| else |
| #endif |
| iSamplesize = 1; |
| |
| break; |
| } |
| case 2 : ; /* rgb */ |
| case 10 : { /* JPEG rgb */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 6; |
| else |
| #endif |
| iSamplesize = 3; |
| |
| break; |
| } |
| case 3 : { /* indexed */ |
| iSamplesize = 1; |
| break; |
| } |
| case 4 : ; /* gray+alpha */ |
| case 12 : { /* JPEG gray+alpha */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 4; |
| else |
| #endif |
| iSamplesize = 2; |
| |
| break; |
| } |
| case 6 : ; /* rgb+alpha */ |
| case 14 : { /* JPEG rgb+alpha */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iSamplesize = 8; |
| else |
| #endif |
| iSamplesize = 4; |
| |
| break; |
| } |
| } |
| |
| iRowsize = iSamplesize * iWidth; |
| iImgdatasize = iRowsize * iHeight; |
| /* buffer size changed ? */ |
| if (iImgdatasize != pBuf->iImgdatasize) |
| { /* drop the old one */ |
| MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| |
| if (iImgdatasize) /* allocate new sample-buffer ? */ |
| MNG_ALLOC (pData, pBuf->pImgdata, iImgdatasize); |
| } |
| else |
| { |
| if (iImgdatasize) /* clear old buffer */ |
| { |
| mng_uint8p pTemp = pBuf->pImgdata; |
| mng_uint32 iX; |
| |
| for (iX = 0; iX < (iImgdatasize & (mng_uint32)(~3L)); iX += 4) |
| { |
| *((mng_uint32p)pTemp) = 0x00000000l; |
| pTemp += 4; |
| } |
| |
| while (pTemp < (pBuf->pImgdata + iImgdatasize)) |
| { |
| *pTemp = 0; |
| pTemp++; |
| } |
| } |
| } |
| |
| pBuf->iSamplesize = iSamplesize; /* remember new sizes */ |
| pBuf->iRowsize = iRowsize; |
| pBuf->iImgdatasize = iImgdatasize; |
| |
| if (!pBuf->iPixelsampledepth) /* set delta sampledepths if empty */ |
| pBuf->iPixelsampledepth = iBitdepth; |
| if (!pBuf->iAlphasampledepth) |
| pBuf->iAlphasampledepth = iBitdepth; |
| /* dimension set and clipping not ? */ |
| if ((iWidth) && (iHeight) && (!pImage->bClipped)) |
| { |
| pImage->iClipl = 0; /* set clipping to dimension by default */ |
| pImage->iClipr = iWidth; |
| pImage->iClipt = 0; |
| pImage->iClipb = iHeight; |
| } |
| |
| #ifndef MNG_SKIPCHUNK_MAGN |
| if (pImage->iId) /* reset magnification info ? */ |
| { |
| 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 |
| |
| if (bResetall) /* reset the other characteristics ? */ |
| { |
| #ifndef MNG_SKIPCHUNK_PAST |
| pImage->iPastx = 0; |
| pImage->iPasty = 0; |
| #endif |
| |
| pBuf->bHasPLTE = MNG_FALSE; |
| pBuf->bHasTRNS = MNG_FALSE; |
| pBuf->bHasGAMA = pData->bHasglobalGAMA; |
| #ifndef MNG_SKIPCHUNK_cHRM |
| pBuf->bHasCHRM = pData->bHasglobalCHRM; |
| #endif |
| pBuf->bHasSRGB = pData->bHasglobalSRGB; |
| #ifndef MNG_SKIPCHUNK_iCCP |
| pBuf->bHasICCP = pData->bHasglobalICCP; |
| #endif |
| #ifndef MNG_SKIPCHUNK_bKGD |
| pBuf->bHasBKGD = pData->bHasglobalBKGD; |
| #endif |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pBuf->iProfilesize) /* drop possibly old ICC profile */ |
| { |
| MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize); |
| pBuf->iProfilesize = 0; |
| } |
| #endif |
| |
| if (pData->bHasglobalGAMA) /* global gAMA present ? */ |
| pBuf->iGamma = pData->iGlobalGamma; |
| |
| #ifndef MNG_SKIPCHUNK_cHRM |
| if (pData->bHasglobalCHRM) /* global cHRM present ? */ |
| { |
| pBuf->iWhitepointx = pData->iGlobalWhitepointx; |
| pBuf->iWhitepointy = pData->iGlobalWhitepointy; |
| pBuf->iPrimaryredx = pData->iGlobalPrimaryredx; |
| pBuf->iPrimaryredy = pData->iGlobalPrimaryredy; |
| pBuf->iPrimarygreenx = pData->iGlobalPrimarygreenx; |
| pBuf->iPrimarygreeny = pData->iGlobalPrimarygreeny; |
| pBuf->iPrimarybluex = pData->iGlobalPrimarybluex; |
| pBuf->iPrimarybluey = pData->iGlobalPrimarybluey; |
| } |
| #endif |
| |
| if (pData->bHasglobalSRGB) /* global sRGB present ? */ |
| pBuf->iRenderingintent = pData->iGlobalRendintent; |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pData->bHasglobalICCP) /* global iCCP present ? */ |
| { |
| if (pData->iGlobalProfilesize) |
| { |
| MNG_ALLOC (pData, pBuf->pProfile, pData->iGlobalProfilesize); |
| MNG_COPY (pBuf->pProfile, pData->pGlobalProfile, pData->iGlobalProfilesize); |
| } |
| |
| pBuf->iProfilesize = pData->iGlobalProfilesize; |
| } |
| #endif |
| |
| #ifndef MNG_SKIPCHUNK_bKGD |
| if (pData->bHasglobalBKGD) /* global bKGD present ? */ |
| { |
| pBuf->iBKGDred = pData->iGlobalBKGDred; |
| pBuf->iBKGDgreen = pData->iGlobalBKGDgreen; |
| pBuf->iBKGDblue = pData->iGlobalBKGDblue; |
| } |
| #endif |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #if !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN) |
| mng_retcode mng_promote_imageobject (mng_datap pData, |
| mng_imagep pImage, |
| mng_uint8 iBitdepth, |
| mng_uint8 iColortype, |
| mng_uint8 iFilltype) |
| { |
| mng_retcode iRetcode = MNG_NOERROR; |
| mng_imagedatap pBuf = pImage->pImgbuf; |
| mng_uint32 iW = pBuf->iWidth; |
| mng_uint32 iH = pBuf->iHeight; |
| mng_uint8p pNewbuf; |
| mng_uint32 iNewbufsize; |
| mng_uint32 iNewrowsize; |
| mng_uint32 iNewsamplesize = pBuf->iSamplesize; |
| mng_uint32 iY; |
| mng_uint8 iTempdepth; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_START); |
| #endif |
| |
| #ifdef MNG_NO_1_2_4BIT_SUPPORT |
| if (iBitdepth < 8) |
| iBitdepth=8; |
| if (pBuf->iBitdepth < 8) |
| pBuf->iBitdepth=8; |
| #endif |
| #ifdef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth > 8) |
| iBitdepth=8; |
| if (pBuf->iBitdepth > 8) |
| pBuf->iBitdepth=8; |
| #endif |
| |
| pData->fPromoterow = MNG_NULL; /* init promotion fields */ |
| pData->fPromBitdepth = MNG_NULL; |
| pData->iPromColortype = iColortype; |
| pData->iPromBitdepth = iBitdepth; |
| pData->iPromFilltype = iFilltype; |
| |
| if (iBitdepth != pBuf->iBitdepth) /* determine bitdepth promotion */ |
| { |
| if (pBuf->iColortype == MNG_COLORTYPE_INDEXED) |
| iTempdepth = 8; |
| else |
| iTempdepth = pBuf->iBitdepth; |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (iFilltype == MNG_FILLMETHOD_ZEROFILL) |
| { |
| switch (iTempdepth) |
| { |
| #ifndef MNG_NO_1_2_4BIT_SUPPORT |
| case 1 : { |
| switch (iBitdepth) |
| { |
| case 2 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_2; break; } |
| case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_4; break; } |
| case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_8; break; } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_16; break; } |
| #endif |
| } |
| break; |
| } |
| case 2 : { |
| switch (iBitdepth) |
| { |
| case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_4; break; } |
| case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_8; break; } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_16; break; } |
| #endif |
| } |
| break; |
| } |
| case 4 : { |
| switch (iBitdepth) |
| { |
| case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_4_8; break; } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_4_16; break; } |
| #endif |
| } |
| break; |
| } |
| #endif /* MNG_NO_1_2_4BIT_SUPPORT */ |
| case 8 : { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_8_16; |
| #endif |
| break; |
| } |
| } |
| } |
| else |
| #endif |
| { |
| switch (iTempdepth) |
| { |
| #ifndef MNG_NO_1_2_4BIT_SUPPORT |
| case 1 : { |
| switch (iBitdepth) |
| { |
| case 2 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_2; break; } |
| case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_4; break; } |
| case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_8; break; } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_16; break; } |
| #endif |
| } |
| break; |
| } |
| case 2 : { |
| switch (iBitdepth) |
| { |
| case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_4; break; } |
| case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_8; break; } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_16; break; } |
| #endif |
| } |
| break; |
| } |
| case 4 : { |
| switch (iBitdepth) |
| { |
| case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_4_8; break; } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_4_16; break; } |
| #endif |
| } |
| break; |
| } |
| #endif /* MNG_NO_1_2_4BIT_SUPPORT */ |
| case 8 : { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_8_16; |
| #endif |
| break; |
| } |
| } |
| } |
| } |
| /* g -> g */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) && |
| (iColortype == MNG_COLORTYPE_GRAY)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_g16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_g8; |
| } |
| |
| iNewsamplesize = 1; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 2; |
| #endif |
| } |
| else /* g -> ga */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) && |
| (iColortype == MNG_COLORTYPE_GRAYA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_ga16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_ga8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_g16_ga16; |
| #endif |
| |
| iNewsamplesize = 2; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 4; |
| #endif |
| } |
| else /* g -> rgb */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) && |
| (iColortype == MNG_COLORTYPE_RGB)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_g16_rgb16; |
| #endif |
| |
| iNewsamplesize = 3; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 6; |
| #endif |
| } |
| else /* g -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) && |
| (iColortype == MNG_COLORTYPE_RGBA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_g16_rgba16; |
| #endif |
| |
| iNewsamplesize = 4; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* ga -> ga */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_GRAYA) && |
| (iColortype == MNG_COLORTYPE_GRAYA)) |
| { |
| iNewsamplesize = 2; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_ga8_ga16; |
| if (iBitdepth == 16) |
| iNewsamplesize = 4; |
| #endif |
| } |
| else /* ga -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_GRAYA) && |
| (iColortype == MNG_COLORTYPE_RGBA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_ga16_rgba16; |
| #endif |
| |
| iNewsamplesize = 4; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* rgb -> rgb */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_RGB) && |
| (iColortype == MNG_COLORTYPE_RGB)) |
| { |
| iNewsamplesize = 3; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgb16; |
| if (iBitdepth == 16) |
| iNewsamplesize = 6; |
| #endif |
| } |
| else /* rgb -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_RGB) && |
| (iColortype == MNG_COLORTYPE_RGBA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb16_rgba16; |
| #endif |
| |
| iNewsamplesize = 4; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* indexed -> rgb */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_INDEXED) && |
| (iColortype == MNG_COLORTYPE_RGB)) |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgb16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgb8; |
| |
| iNewsamplesize = 3; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 6; |
| #endif |
| } |
| else /* indexed -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_INDEXED) && |
| (iColortype == MNG_COLORTYPE_RGBA)) |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgba8; |
| |
| iNewsamplesize = 4; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* rgba -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_RGBA) && |
| (iColortype == MNG_COLORTYPE_RGBA)) |
| { |
| iNewsamplesize = 4; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_rgba8_rgba16; |
| } |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| #ifdef MNG_INCLUDE_JNG |
| else /* JPEG g -> g */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) && |
| (iColortype == MNG_COLORTYPE_JPEGGRAY)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_g16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_g8; |
| } |
| |
| iNewsamplesize = 1; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 2; |
| #endif |
| } |
| else /* JPEG g -> ga */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) && |
| (iColortype == MNG_COLORTYPE_JPEGGRAYA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_ga16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_ga8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_g16_ga16; |
| #endif |
| |
| iNewsamplesize = 2; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 4; |
| #endif |
| } |
| else /* JPEG g -> rgb */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) && |
| (iColortype == MNG_COLORTYPE_JPEGCOLOR)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_g16_rgb16; |
| #endif |
| |
| iNewsamplesize = 3; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 6; |
| #endif |
| } |
| else /* JPEG g -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) && |
| (iColortype == MNG_COLORTYPE_JPEGCOLORA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_g16_rgba16; |
| #endif |
| |
| iNewsamplesize = 4; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* JPEG ga -> ga */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) && |
| (iColortype == MNG_COLORTYPE_JPEGGRAYA)) |
| { |
| iNewsamplesize = 2; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_ga8_ga16; |
| if (iBitdepth == 16) |
| iNewsamplesize = 4; |
| #endif |
| |
| } |
| else /* JPEG ga -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) && |
| (iColortype == MNG_COLORTYPE_JPEGCOLORA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_ga16_rgba16; |
| #endif |
| |
| iNewsamplesize = 4; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* JPEG rgb -> rgb */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) && |
| (iColortype == MNG_COLORTYPE_JPEGCOLOR)) |
| { |
| iNewsamplesize = 3; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgb16; |
| if (iBitdepth == 16) |
| iNewsamplesize = 6; |
| #endif |
| |
| } |
| else /* JPEG rgb -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) && |
| (iColortype == MNG_COLORTYPE_JPEGCOLORA)) |
| { |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| { |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba16; |
| else |
| #endif |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba8; |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else /* source = 16 bits */ |
| pData->fPromoterow = (mng_fptr)mng_promote_rgb16_rgba16; |
| #endif |
| |
| iNewsamplesize = 4; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (iBitdepth == 16) /* 16-bit wide ? */ |
| iNewsamplesize = 8; |
| #endif |
| } |
| else /* JPEG rgba -> rgba */ |
| if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) && |
| (iColortype == MNG_COLORTYPE_JPEGCOLORA)) |
| { |
| iNewsamplesize = 4; |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth <= 8) /* source <= 8 bits */ |
| if (iBitdepth == 16) |
| pData->fPromoterow = (mng_fptr)mng_promote_rgba8_rgba16; |
| if (iBitdepth == 16) |
| iNewsamplesize = 8; |
| #endif |
| } |
| #endif /* JNG */ |
| |
| /* found a proper promotion ? */ |
| if (pData->fPromoterow) |
| { |
| pData->pPromBuf = (mng_ptr)pBuf; |
| pData->iPromWidth = pBuf->iWidth; |
| iNewrowsize = iW * iNewsamplesize; |
| iNewbufsize = iH * iNewrowsize; |
| |
| MNG_ALLOC (pData, pNewbuf, iNewbufsize); |
| |
| pData->pPromSrc = (mng_ptr)pBuf->pImgdata; |
| pData->pPromDst = (mng_ptr)pNewbuf; |
| iY = 0; |
| |
| while ((!iRetcode) && (iY < iH)) |
| { |
| iRetcode = ((mng_promoterow)pData->fPromoterow) (pData); |
| pData->pPromSrc = (mng_uint8p)pData->pPromSrc + pBuf->iRowsize; |
| pData->pPromDst = (mng_uint8p)pData->pPromDst + iNewrowsize; |
| /* pData->pPromSrc = (mng_ptr)((mng_uint32)pData->pPromSrc + pBuf->iRowsize); */ |
| /* pData->pPromDst = (mng_ptr)((mng_uint32)pData->pPromDst + iNewrowsize); */ |
| iY++; |
| } |
| |
| MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| |
| pBuf->iBitdepth = iBitdepth; |
| pBuf->iColortype = iColortype; |
| pBuf->iSamplesize = iNewsamplesize; |
| pBuf->iRowsize = iNewrowsize; |
| pBuf->iImgdatasize = iNewbufsize; |
| pBuf->pImgdata = pNewbuf; |
| pBuf->bHasPLTE = MNG_FALSE; |
| pBuf->iPLTEcount = 0; |
| pBuf->bHasTRNS = MNG_FALSE; |
| pBuf->iTRNScount = 0; |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_MAGN |
| mng_retcode mng_magnify_imageobject (mng_datap pData, |
| mng_imagep pImage) |
| { |
| mng_uint8p pNewdata; |
| mng_uint8p pSrcline1; |
| mng_uint8p pSrcline2; |
| mng_uint8p pTempline; |
| mng_uint8p pDstline; |
| mng_uint32 iNewrowsize; |
| mng_uint32 iNewsize; |
| mng_uint32 iY; |
| mng_int32 iS, iM; |
| mng_retcode iRetcode; |
| |
| mng_imagedatap pBuf = pImage->pImgbuf; |
| mng_uint32 iNewW = pBuf->iWidth; |
| mng_uint32 iNewH = pBuf->iHeight; |
| mng_magnify_x fMagnifyX = MNG_NULL; |
| mng_magnify_y fMagnifyY = MNG_NULL; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_MAGNIFY_IMGOBJECT, MNG_LC_START); |
| #endif |
| |
| if (pBuf->iColortype == MNG_COLORTYPE_INDEXED) /* indexed color ? */ |
| { /* concrete buffer ? */ |
| if ((pBuf->bConcrete) && (pImage->iId)) |
| MNG_ERROR (pData, MNG_INVALIDCOLORTYPE); |
| |
| #ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN |
| if (pBuf->iTRNScount) /* with transparency ? */ |
| iRetcode = mng_promote_imageobject (pData, pImage, 8, 6, 0); |
| else |
| iRetcode = mng_promote_imageobject (pData, pImage, 8, 2, 0); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| #endif |
| } |
| |
| #ifdef MNG_OPTIMIZE_FOOTPRINT_MAGN |
| /* Promote everything to RGBA, using fill method 0 (LBR) */ |
| iRetcode = mng_promote_imageobject (pData, pImage, 8, 6, 0); |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| #endif |
| |
| if (pImage->iMAGN_MethodX) /* determine new width */ |
| { |
| if (pImage->iMAGN_MethodX == 1) |
| { |
| iNewW = pImage->iMAGN_ML; |
| if (pBuf->iWidth > 1) |
| iNewW = iNewW + pImage->iMAGN_MR; |
| if (pBuf->iWidth > 2) |
| iNewW = iNewW + (pBuf->iWidth - 2) * (pImage->iMAGN_MX); |
| } |
| else |
| { |
| iNewW = pBuf->iWidth + pImage->iMAGN_ML - 1; |
| if (pBuf->iWidth > 2) |
| iNewW = iNewW + pImage->iMAGN_MR - 1; |
| if (pBuf->iWidth > 3) |
| iNewW = iNewW + (pBuf->iWidth - 3) * (pImage->iMAGN_MX - 1); |
| } |
| } |
| |
| if (pImage->iMAGN_MethodY) /* determine new height */ |
| { |
| if (pImage->iMAGN_MethodY == 1) |
| { |
| iNewH = pImage->iMAGN_MT; |
| if (pBuf->iHeight > 1) |
| iNewH = iNewH + pImage->iMAGN_ML; |
| if (pBuf->iHeight > 2) |
| iNewH = iNewH + (pBuf->iHeight - 2) * (pImage->iMAGN_MY); |
| } |
| else |
| { |
| iNewH = pBuf->iHeight + pImage->iMAGN_MT - 1; |
| if (pBuf->iHeight > 2) |
| iNewH = iNewH + pImage->iMAGN_MB - 1; |
| if (pBuf->iHeight > 3) |
| iNewH = iNewH + (pBuf->iHeight - 3) * (pImage->iMAGN_MY - 1); |
| } |
| } |
| /* get new buffer */ |
| iNewrowsize = iNewW * pBuf->iSamplesize; |
| iNewsize = iNewH * iNewrowsize; |
| |
| MNG_ALLOC (pData, pNewdata, iNewsize); |
| |
| switch (pBuf->iColortype) /* determine magnification routines */ |
| { |
| #ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN |
| case 0 : ; |
| case 8 : { |
| if (pBuf->iBitdepth <= 8) |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_g8_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_g8_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_g8_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_g8_x2; break; } |
| case 5 : { fMagnifyX = mng_magnify_g8_x3; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_g8_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_g8_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_g8_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_g8_y2; break; } |
| case 5 : { fMagnifyY = mng_magnify_g8_y3; break; } |
| } |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_g16_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_g16_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_g16_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_g16_x2; break; } |
| case 5 : { fMagnifyX = mng_magnify_g16_x3; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_g16_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_g16_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_g16_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_g16_y2; break; } |
| case 5 : { fMagnifyY = mng_magnify_g16_y3; break; } |
| } |
| } |
| #endif |
| |
| break; |
| } |
| |
| case 2 : ; |
| case 10 : { |
| if (pBuf->iBitdepth <= 8) |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_rgb8_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_rgb8_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_rgb8_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_rgb8_x2; break; } |
| case 5 : { fMagnifyX = mng_magnify_rgb8_x3; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_rgb8_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_rgb8_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_rgb8_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_rgb8_y2; break; } |
| case 5 : { fMagnifyY = mng_magnify_rgb8_y3; break; } |
| } |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_rgb16_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_rgb16_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_rgb16_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_rgb16_x2; break; } |
| case 5 : { fMagnifyX = mng_magnify_rgb16_x3; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_rgb16_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_rgb16_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_rgb16_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_rgb16_y2; break; } |
| case 5 : { fMagnifyY = mng_magnify_rgb16_y3; break; } |
| } |
| } |
| #endif |
| |
| break; |
| } |
| |
| case 4 : ; |
| case 12 : { |
| if (pBuf->iBitdepth <= 8) |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_ga8_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_ga8_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_ga8_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_ga8_x4; break; } |
| case 5 : { fMagnifyX = mng_magnify_ga8_x5; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_ga8_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_ga8_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_ga8_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_ga8_y4; break; } |
| case 5 : { fMagnifyY = mng_magnify_ga8_y5; break; } |
| } |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| else |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_ga16_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_ga16_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_ga16_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_ga16_x4; break; } |
| case 5 : { fMagnifyX = mng_magnify_ga16_x5; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_ga16_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_ga16_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_ga16_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_ga16_y4; break; } |
| case 5 : { fMagnifyY = mng_magnify_ga16_y5; break; } |
| } |
| } |
| #endif |
| |
| break; |
| } |
| #endif |
| |
| case 6 : ; |
| case 14 : { |
| if (pBuf->iBitdepth <= 8) |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_rgba8_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_rgba8_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_rgba8_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_rgba8_x4; break; } |
| case 5 : { fMagnifyX = mng_magnify_rgba8_x5; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_rgba8_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_rgba8_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_rgba8_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_rgba8_y4; break; } |
| case 5 : { fMagnifyY = mng_magnify_rgba8_y5; break; } |
| } |
| } |
| #ifndef MNG_NO_16BIT_SUPPORT |
| #ifndef MNG_OPTIMIZE_FOOTPRINT_MAGN |
| else |
| { |
| switch (pImage->iMAGN_MethodX) |
| { |
| case 1 : { fMagnifyX = mng_magnify_rgba16_x1; break; } |
| case 2 : { fMagnifyX = mng_magnify_rgba16_x2; break; } |
| case 3 : { fMagnifyX = mng_magnify_rgba16_x3; break; } |
| case 4 : { fMagnifyX = mng_magnify_rgba16_x4; break; } |
| case 5 : { fMagnifyX = mng_magnify_rgba16_x5; break; } |
| } |
| |
| switch (pImage->iMAGN_MethodY) |
| { |
| case 1 : { fMagnifyY = mng_magnify_rgba16_y1; break; } |
| case 2 : { fMagnifyY = mng_magnify_rgba16_y2; break; } |
| case 3 : { fMagnifyY = mng_magnify_rgba16_y3; break; } |
| case 4 : { fMagnifyY = mng_magnify_rgba16_y4; break; } |
| case 5 : { fMagnifyY = mng_magnify_rgba16_y5; break; } |
| } |
| } |
| #endif |
| #endif |
| break; |
| } |
| } |
| |
| pSrcline1 = pBuf->pImgdata; /* initialize row-loop variables */ |
| pDstline = pNewdata; |
| /* allocate temporary row */ |
| MNG_ALLOC (pData, pTempline, iNewrowsize); |
| |
| for (iY = 0; iY < pBuf->iHeight; iY++) |
| { |
| pSrcline2 = pSrcline1 + pBuf->iRowsize; |
| |
| if (fMagnifyX) /* magnifying in X-direction ? */ |
| { |
| iRetcode = fMagnifyX (pData, pImage->iMAGN_MX, |
| pImage->iMAGN_ML, pImage->iMAGN_MR, |
| pBuf->iWidth, pSrcline1, pDstline); |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pTempline, iNewrowsize); |
| MNG_FREEX (pData, pNewdata, iNewsize); |
| return iRetcode; |
| } |
| } |
| else |
| { |
| MNG_COPY (pDstline, pSrcline1, iNewrowsize); |
| } |
| |
| pDstline += iNewrowsize; |
| /* magnifying in Y-direction ? */ |
| if ((fMagnifyY) && |
| ((iY < pBuf->iHeight - 1) || (pBuf->iHeight == 1) || (pImage->iMAGN_MethodY == 1))) |
| { |
| if (iY == 0) /* first interval ? */ |
| { |
| if (pBuf->iHeight == 1) /* single row ? */ |
| pSrcline2 = MNG_NULL; |
| |
| iM = (mng_int32)pImage->iMAGN_MT; |
| } |
| else /* last interval ? */ |
| if (((pImage->iMAGN_MethodY == 1) && (iY == (pBuf->iHeight - 1))) || |
| ((pImage->iMAGN_MethodY != 1) && (iY == (pBuf->iHeight - 2))) ) |
| iM = (mng_int32)pImage->iMAGN_MB; |
| else /* middle interval */ |
| iM = (mng_int32)pImage->iMAGN_MY; |
| |
| for (iS = 1; iS < iM; iS++) |
| { |
| iRetcode = fMagnifyY (pData, iS, iM, pBuf->iWidth, |
| pSrcline1, pSrcline2, pTempline); |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pTempline, iNewrowsize); |
| MNG_FREEX (pData, pNewdata, iNewsize); |
| return iRetcode; |
| } |
| |
| if (fMagnifyX) /* magnifying in X-direction ? */ |
| { |
| iRetcode = fMagnifyX (pData, pImage->iMAGN_MX, |
| pImage->iMAGN_ML, pImage->iMAGN_MR, |
| pBuf->iWidth, pTempline, pDstline); |
| |
| if (iRetcode) /* on error bail out */ |
| { |
| MNG_FREEX (pData, pTempline, iNewrowsize); |
| MNG_FREEX (pData, pNewdata, iNewsize); |
| return iRetcode; |
| } |
| } |
| else |
| { |
| MNG_COPY (pDstline, pTempline, iNewrowsize); |
| } |
| |
| pDstline += iNewrowsize; |
| } |
| } |
| |
| pSrcline1 += pBuf->iRowsize; |
| } |
| /* drop temporary row */ |
| MNG_FREEX (pData, pTempline, iNewrowsize); |
| /* drop old pixel-data */ |
| MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| |
| pBuf->pImgdata = pNewdata; /* save new buffer dimensions */ |
| pBuf->iRowsize = iNewrowsize; |
| pBuf->iImgdatasize = iNewsize; |
| pBuf->iWidth = iNewW; |
| pBuf->iHeight = iNewH; |
| |
| if (pImage->iId) /* real object ? */ |
| { |
| pImage->iMAGN_MethodX = 0; /* it's done; don't do it again !!! */ |
| 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; |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_MAGNIFY_IMGOBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_colorcorrect_object (mng_datap pData, |
| mng_imagep pImage) |
| { |
| mng_imagedatap pBuf = pImage->pImgbuf; |
| mng_retcode iRetcode; |
| mng_uint32 iY; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_COLORCORRECT_OBJECT, MNG_LC_START); |
| #endif |
| |
| #ifdef MNG_INCLUDE_JNG |
| if ((pBuf->iBitdepth < 8) || /* we need 8- or 16-bit RGBA !!! */ |
| ((pBuf->iColortype != MNG_COLORTYPE_RGBA ) && |
| (pBuf->iColortype != MNG_COLORTYPE_JPEGCOLORA) )) |
| #else |
| if (pBuf->iBitdepth < 8) /* we need 8- or 16-bit RGBA !!! */ |
| #endif |
| MNG_ERROR (pData, MNG_OBJNOTABSTRACT); |
| |
| if (!pBuf->bCorrected) /* only if not already done ! */ |
| { /* so the row routines now to find it */ |
| pData->pRetrieveobj = (mng_objectp)pImage; |
| pData->pStoreobj = (mng_objectp)pImage; |
| pData->pStorebuf = (mng_objectp)pImage->pImgbuf; |
| |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->iBitdepth > 8) |
| { |
| pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba16; |
| pData->fStorerow = (mng_fptr)mng_store_rgba16; |
| } |
| else |
| #endif |
| { |
| pData->fRetrieverow = (mng_fptr)mng_retrieve_rgba8; |
| pData->fStorerow = (mng_fptr)mng_store_rgba8; |
| } |
| |
| pData->bIsOpaque = MNG_FALSE; |
| |
| pData->iPass = -1; /* these are the object's dimensions now */ |
| pData->iRow = 0; |
| pData->iRowinc = 1; |
| pData->iCol = 0; |
| pData->iColinc = 1; |
| pData->iRowsamples = pBuf->iWidth; |
| pData->iRowsize = pData->iRowsamples << 2; |
| pData->iPixelofs = 0; |
| pData->bIsRGBA16 = MNG_FALSE; |
| /* adjust for 16-bit object ? */ |
| #ifndef MNG_NO_16BIT_SUPPORT |
| if (pBuf->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 */ |
| |
| if (pData->fCorrectrow) /* really correct something ? */ |
| { /* get a temporary row-buffer */ |
| MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize); |
| |
| pData->pWorkrow = pData->pRGBArow; |
| iY = 0; /* start from the top */ |
| |
| while ((!iRetcode) && (iY < pBuf->iHeight)) |
| { /* get a row */ |
| iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData); |
| |
| if (!iRetcode) /* color correct it */ |
| iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData); |
| |
| if (!iRetcode) /* store it back ! */ |
| iRetcode = ((mng_storerow)pData->fStorerow) (pData); |
| |
| if (!iRetcode) /* adjust variables for next row */ |
| iRetcode = mng_next_row (pData); |
| |
| iY++; /* and next line */ |
| } |
| /* drop the temporary row-buffer */ |
| MNG_FREEX (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 |
| } |
| |
| pBuf->bCorrected = MNG_TRUE; /* let's not go through that again ! */ |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_COLORCORRECT_OBJECT, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| /* * * */ |
| /* * Animation-object routines * */ |
| /* * * */ |
| /* * these handle the animation objects used to re-run parts of a MNG. * */ |
| /* * eg. during LOOP or TERM processing * */ |
| /* * * */ |
| /* ************************************************************************** */ |
| |
| void mng_add_ani_object (mng_datap pData, |
| mng_object_headerp pObject) |
| { |
| mng_object_headerp pLast = (mng_object_headerp)pData->pLastaniobj; |
| |
| if (pLast) /* link it as last in the chain */ |
| { |
| pObject->pPrev = pLast; |
| pLast->pNext = pObject; |
| } |
| else |
| { |
| pObject->pPrev = MNG_NULL; /* be on the safe side */ |
| pData->pFirstaniobj = pObject; |
| } |
| |
| pObject->pNext = MNG_NULL; /* be on the safe side */ |
| pData->pLastaniobj = pObject; |
| /* keep track for jumping */ |
| pObject->iFramenr = pData->iFrameseq; |
| pObject->iLayernr = pData->iLayerseq; |
| pObject->iPlaytime = pData->iFrametime; |
| /* save restart object ? */ |
| if ((pData->bDisplaying) && (!pData->bRunning) && (!pData->pCurraniobj)) |
| pData->pCurraniobj = pObject; |
| |
| return; |
| } |
| |
| /* ************************************************************************** */ |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_create_ani_image (mng_datap pData) |
| { |
| mng_ani_imagep pImage; |
| mng_imagep pCurrent; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_IMAGE, MNG_LC_START); |
| #endif |
| |
| if (pData->bCacheplayback) /* caching playback info ? */ |
| { |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* processing delta-image ? */ |
| pCurrent = (mng_imagep)pData->pObjzero; |
| else /* get the current object */ |
| #endif |
| pCurrent = (mng_imagep)pData->pCurrentobj; |
| |
| if (!pCurrent) /* otherwise object 0 */ |
| pCurrent = (mng_imagep)pData->pObjzero; |
| /* now just clone the object !!! */ |
| iRetcode = mng_clone_imageobject (pData, 0, MNG_FALSE, pCurrent->bVisible, |
| MNG_FALSE, MNG_FALSE, 0, 0, 0, pCurrent, |
| &pImage); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| |
| pImage->sHeader.fCleanup = mng_free_ani_image; |
| pImage->sHeader.fProcess = mng_process_ani_image; |
| |
| mng_add_ani_object (pData, (mng_object_headerp)pImage); |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_IMAGE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; /* okido */ |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_free_ani_image (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_ani_imagep pImage = (mng_ani_imagep)pObject; |
| mng_imagedatap pImgbuf = pImage->pImgbuf; |
| mng_retcode iRetcode; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_IMAGE, MNG_LC_START); |
| #endif |
| /* unlink the image-data buffer */ |
| iRetcode = mng_free_imagedataobject (pData, pImgbuf); |
| /* drop its own buffer */ |
| MNG_FREEX (pData, pImage, sizeof (mng_ani_image)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_IMAGE, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_process_ani_image (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_retcode iRetcode = MNG_NOERROR; |
| mng_ani_imagep pImage = (mng_imagep)pObject; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IMAGE, MNG_LC_START); |
| #endif |
| |
| #ifndef MNG_NO_DELTA_PNG |
| if (pData->bHasDHDR) /* processing delta-image ? */ |
| { |
| mng_imagep pDelta = (mng_imagep)pData->pDeltaImage; |
| |
| if (!pData->iBreakpoint) /* only execute if not broken before */ |
| { /* make sure to process pixels as well */ |
| pData->bDeltaimmediate = MNG_FALSE; |
| /* execute the delta process */ |
| iRetcode = mng_execute_delta_image (pData, pDelta, (mng_imagep)pObject); |
| |
| if (iRetcode) /* on error bail out */ |
| return iRetcode; |
| } |
| /* now go and shoot it off (if required) */ |
| if ((pDelta->bVisible) && (pDelta->bViewable)) |
| iRetcode = mng_display_image (pData, pDelta, MNG_FALSE); |
| |
| if (!pData->bTimerset) |
| pData->bHasDHDR = MNG_FALSE; /* this image signifies IEND !! */ |
| |
| } |
| else |
| #endif |
| if (pData->pCurrentobj) /* active object ? */ |
| { |
| mng_imagep pCurrent = (mng_imagep)pData->pCurrentobj; |
| mng_imagedatap pBuf = pCurrent->pImgbuf; |
| |
| if (!pData->iBreakpoint) /* don't copy it again ! */ |
| { |
| if (pBuf->iImgdatasize) /* buffer present in active object ? */ |
| /* then drop it */ |
| MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pBuf->iProfilesize) /* iCCP profile present ? */ |
| /* then drop it */ |
| MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize); |
| #endif |
| /* now blatently copy the animation buffer */ |
| MNG_COPY (pBuf, pImage->pImgbuf, sizeof (mng_imagedata)); |
| /* copy viewability */ |
| pCurrent->bViewable = pImage->bViewable; |
| |
| if (pBuf->iImgdatasize) /* sample buffer present ? */ |
| { /* then make a copy */ |
| MNG_ALLOC (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| MNG_COPY (pBuf->pImgdata, pImage->pImgbuf->pImgdata, pBuf->iImgdatasize); |
| } |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pBuf->iProfilesize) /* iCCP profile present ? */ |
| { /* then make a copy */ |
| MNG_ALLOC (pData, pBuf->pProfile, pBuf->iProfilesize); |
| MNG_COPY (pBuf->pProfile, pImage->pImgbuf->pProfile, pBuf->iProfilesize); |
| } |
| #endif |
| } |
| /* now go and shoot it off (if required) */ |
| if ((pCurrent->bVisible) && (pCurrent->bViewable)) |
| iRetcode = mng_display_image (pData, pCurrent, MNG_FALSE); |
| } |
| else |
| { |
| mng_imagep pObjzero = (mng_imagep)pData->pObjzero; |
| mng_imagedatap pBuf = pObjzero->pImgbuf; |
| |
| if (!pData->iBreakpoint) /* don't copy it again ! */ |
| { |
| if (pBuf->iImgdatasize) /* buffer present in active object ? */ |
| /* then drop it */ |
| MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pBuf->iProfilesize) /* iCCP profile present ? */ |
| /* then drop it */ |
| MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize); |
| #endif |
| /* now blatently copy the animation buffer */ |
| MNG_COPY (pBuf, pImage->pImgbuf, sizeof (mng_imagedata)); |
| /* copy viewability */ |
| pObjzero->bViewable = pImage->bViewable; |
| |
| if (pBuf->iImgdatasize) /* sample buffer present ? */ |
| { /* then make a copy */ |
| MNG_ALLOC (pData, pBuf->pImgdata, pBuf->iImgdatasize); |
| MNG_COPY (pBuf->pImgdata, pImage->pImgbuf->pImgdata, pBuf->iImgdatasize); |
| } |
| |
| #ifndef MNG_SKIPCHUNK_iCCP |
| if (pBuf->iProfilesize) /* iCCP profile present ? */ |
| { /* then make a copy */ |
| MNG_ALLOC (pData, pBuf->pProfile, pBuf->iProfilesize); |
| MNG_COPY (pBuf->pProfile, pImage->pImgbuf->pProfile, pBuf->iProfilesize); |
| } |
| #endif |
| } |
| /* now go and show it */ |
| iRetcode = mng_display_image (pData, pObjzero, MNG_FALSE); |
| } |
| |
| if (!iRetcode) /* all's well ? */ |
| { |
| if (pData->bTimerset) /* timer break ? */ |
| pData->iBreakpoint = 99; /* fictive number; no more processing needed! */ |
| else |
| pData->iBreakpoint = 0; /* else clear it */ |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IMAGE, MNG_LC_END); |
| #endif |
| |
| return iRetcode; |
| } |
| |
| /* ************************************************************************** */ |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| mng_retcode mng_create_ani_plte (mng_datap pData, |
| mng_uint32 iEntrycount, |
| mng_palette8ep paEntries) |
| #else |
| mng_retcode mng_create_ani_plte (mng_datap pData) |
| #endif |
| { |
| mng_ani_pltep pPLTE; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_PLTE, MNG_LC_START); |
| #endif |
| |
| if (pData->bCacheplayback) /* caching playback info ? */ |
| { |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| mng_ptr pTemp; |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_plte), |
| mng_free_obj_general, |
| mng_process_ani_plte, |
| &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pPLTE = (mng_ani_pltep)pTemp; |
| #else |
| MNG_ALLOC (pData, pPLTE, sizeof (mng_ani_plte)); |
| |
| pPLTE->sHeader.fCleanup = mng_free_ani_plte; |
| pPLTE->sHeader.fProcess = mng_process_ani_plte; |
| #endif |
| |
| mng_add_ani_object (pData, (mng_object_headerp)pPLTE); |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| pPLTE->iEntrycount = iEntrycount; |
| MNG_COPY (pPLTE->aEntries, paEntries, sizeof (pPLTE->aEntries)); |
| #else |
| pPLTE->iEntrycount = pData->iGlobalPLTEcount; |
| MNG_COPY (pPLTE->aEntries, pData->aGlobalPLTEentries, sizeof (pPLTE->aEntries)); |
| #endif |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_PLTE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_OBJCLEANUP |
| mng_retcode mng_free_ani_plte (mng_datap pData, |
| mng_objectp pObject) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_PLTE, MNG_LC_START); |
| #endif |
| |
| MNG_FREEX (pData, pObject, sizeof (mng_ani_plte)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_PLTE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_process_ani_plte (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_ani_pltep pPLTE = (mng_ani_pltep)pObject; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PLTE, MNG_LC_START); |
| #endif |
| |
| pData->bHasglobalPLTE = MNG_TRUE; |
| pData->iGlobalPLTEcount = pPLTE->iEntrycount; |
| |
| MNG_COPY (pData->aGlobalPLTEentries, pPLTE->aEntries, sizeof (pPLTE->aEntries)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PLTE, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| mng_retcode mng_create_ani_trns (mng_datap pData, |
| mng_uint32 iRawlen, |
| mng_uint8p pRawdata) |
| #else |
| mng_retcode mng_create_ani_trns (mng_datap pData) |
| #endif |
| { |
| mng_ani_trnsp pTRNS; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_TRNS, MNG_LC_START); |
| #endif |
| |
| if (pData->bCacheplayback) /* caching playback info ? */ |
| { |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| mng_ptr pTemp; |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_trns), |
| mng_free_obj_general, |
| mng_process_ani_trns, |
| &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pTRNS = (mng_ani_trnsp)pTemp; |
| #else |
| MNG_ALLOC (pData, pTRNS, sizeof (mng_ani_trns)); |
| |
| pTRNS->sHeader.fCleanup = mng_free_ani_trns; |
| pTRNS->sHeader.fProcess = mng_process_ani_trns; |
| #endif |
| |
| mng_add_ani_object (pData, (mng_object_headerp)pTRNS); |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| pTRNS->iRawlen = iRawlen; |
| MNG_COPY (pTRNS->aRawdata, pRawdata, sizeof (pTRNS->aRawdata)); |
| #else |
| pTRNS->iRawlen = pData->iGlobalTRNSrawlen; |
| MNG_COPY (pTRNS->aRawdata, pData->aGlobalTRNSrawdata, sizeof (pTRNS->aRawdata)); |
| #endif |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_TRNS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_OBJCLEANUP |
| mng_retcode mng_free_ani_trns (mng_datap pData, |
| mng_objectp pObject) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_TRNS, MNG_LC_START); |
| #endif |
| |
| MNG_FREEX (pData, pObject, sizeof (mng_ani_trns)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_TRNS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_process_ani_trns (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_ani_trnsp pTRNS = (mng_ani_trnsp)pObject; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TRNS, MNG_LC_START); |
| #endif |
| |
| pData->bHasglobalTRNS = MNG_TRUE; |
| pData->iGlobalTRNSrawlen = pTRNS->iRawlen; |
| |
| MNG_COPY (pData->aGlobalTRNSrawdata, pTRNS->aRawdata, sizeof (pTRNS->aRawdata)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TRNS, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_gAMA |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| mng_retcode mng_create_ani_gama (mng_datap pData, |
| mng_bool bEmpty, |
| mng_uint32 iGamma) |
| #else |
| mng_retcode mng_create_ani_gama (mng_datap pData, |
| mng_chunkp pChunk) |
| #endif |
| { |
| mng_ani_gamap pGAMA; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_GAMA, MNG_LC_START); |
| #endif |
| |
| if (pData->bCacheplayback) /* caching playback info ? */ |
| { |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| mng_ptr pTemp; |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_gama), |
| mng_free_obj_general, |
| mng_process_ani_gama, |
| &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pGAMA = (mng_ani_gamap)pTemp; |
| #else |
| MNG_ALLOC (pData, pGAMA, sizeof (mng_ani_gama)); |
| |
| pGAMA->sHeader.fCleanup = mng_free_ani_gama; |
| pGAMA->sHeader.fProcess = mng_process_ani_gama; |
| #endif |
| |
| mng_add_ani_object (pData, (mng_object_headerp)pGAMA); |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| pGAMA->bEmpty = bEmpty; |
| pGAMA->iGamma = iGamma; |
| #else |
| pGAMA->bEmpty = ((mng_gamap)pChunk)->bEmpty; |
| pGAMA->iGamma = ((mng_gamap)pChunk)->iGamma; |
| #endif |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_GAMA, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_OBJCLEANUP |
| mng_retcode mng_free_ani_gama (mng_datap pData, |
| mng_objectp pObject) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_GAMA, MNG_LC_START); |
| #endif |
| |
| MNG_FREEX (pData, pObject, sizeof (mng_ani_gama)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_GAMA, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_process_ani_gama (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_ani_gamap pGAMA = (mng_ani_gamap)pObject; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_GAMA, MNG_LC_START); |
| #endif |
| |
| if (pGAMA->bEmpty) /* empty chunk ? */ |
| { /* clear global gAMA */ |
| pData->bHasglobalGAMA = MNG_FALSE; |
| pData->iGlobalGamma = 0; |
| } |
| else |
| { /* set global gAMA */ |
| pData->bHasglobalGAMA = MNG_TRUE; |
| pData->iGlobalGamma = pGAMA->iGamma; |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_GAMA, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_cHRM |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| mng_retcode mng_create_ani_chrm (mng_datap pData, |
| mng_bool bEmpty, |
| mng_uint32 iWhitepointx, |
| mng_uint32 iWhitepointy, |
| mng_uint32 iRedx, |
| mng_uint32 iRedy, |
| mng_uint32 iGreenx, |
| mng_uint32 iGreeny, |
| mng_uint32 iBluex, |
| mng_uint32 iBluey) |
| #else |
| mng_retcode mng_create_ani_chrm (mng_datap pData, |
| mng_chunkp pChunk) |
| #endif |
| { |
| mng_ptr pTemp; |
| mng_ani_chrmp pCHRM; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_CHRM, MNG_LC_START); |
| #endif |
| |
| if (pData->bCacheplayback) /* caching playback info ? */ |
| { |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_chrm), |
| mng_free_obj_general, |
| mng_process_ani_chrm, |
| &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pCHRM = (mng_ani_chrmp)pTemp; |
| #else |
| MNG_ALLOC (pData, pCHRM, sizeof (mng_ani_chrm)); |
| |
| pCHRM->sHeader.fCleanup = mng_free_ani_chrm; |
| pCHRM->sHeader.fProcess = mng_process_ani_chrm; |
| #endif |
| |
| mng_add_ani_object (pData, (mng_object_headerp)pCHRM); |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| pCHRM->bEmpty = bEmpty; |
| pCHRM->iWhitepointx = iWhitepointx; |
| pCHRM->iWhitepointy = iWhitepointy; |
| pCHRM->iRedx = iRedx; |
| pCHRM->iRedy = iRedy; |
| pCHRM->iGreenx = iGreenx; |
| pCHRM->iGreeny = iGreeny; |
| pCHRM->iBluex = iBluex; |
| pCHRM->iBluey = iBluey; |
| #else |
| pCHRM->bEmpty = ((mng_chrmp)pChunk)->bEmpty; |
| pCHRM->iWhitepointx = ((mng_chrmp)pChunk)->iWhitepointx; |
| pCHRM->iWhitepointy = ((mng_chrmp)pChunk)->iWhitepointy; |
| pCHRM->iRedx = ((mng_chrmp)pChunk)->iRedx; |
| pCHRM->iRedy = ((mng_chrmp)pChunk)->iRedy; |
| pCHRM->iGreenx = ((mng_chrmp)pChunk)->iGreenx; |
| pCHRM->iGreeny = ((mng_chrmp)pChunk)->iGreeny; |
| pCHRM->iBluex = ((mng_chrmp)pChunk)->iBluex; |
| pCHRM->iBluey = ((mng_chrmp)pChunk)->iBluey; |
| #endif |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_CHRM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_OBJCLEANUP |
| mng_retcode mng_free_ani_chrm (mng_datap pData, |
| mng_objectp pObject) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_CHRM, MNG_LC_START); |
| #endif |
| |
| MNG_FREEX (pData, pObject, sizeof (mng_ani_chrm)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_CHRM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_process_ani_chrm (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_ani_chrmp pCHRM = (mng_ani_chrmp)pObject; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CHRM, MNG_LC_START); |
| #endif |
| |
| if (pCHRM->bEmpty) /* empty chunk ? */ |
| { /* clear global cHRM */ |
| pData->bHasglobalCHRM = MNG_FALSE; |
| pData->iGlobalWhitepointx = 0; |
| pData->iGlobalWhitepointy = 0; |
| pData->iGlobalPrimaryredx = 0; |
| pData->iGlobalPrimaryredy = 0; |
| pData->iGlobalPrimarygreenx = 0; |
| pData->iGlobalPrimarygreeny = 0; |
| pData->iGlobalPrimarybluex = 0; |
| pData->iGlobalPrimarybluey = 0; |
| } |
| else |
| { /* set global cHRM */ |
| pData->bHasglobalCHRM = MNG_TRUE; |
| pData->iGlobalWhitepointx = pCHRM->iWhitepointx; |
| pData->iGlobalWhitepointy = pCHRM->iWhitepointy; |
| pData->iGlobalPrimaryredx = pCHRM->iRedx; |
| pData->iGlobalPrimaryredy = pCHRM->iRedy; |
| pData->iGlobalPrimarygreenx = pCHRM->iGreenx; |
| pData->iGlobalPrimarygreeny = pCHRM->iGreeny; |
| pData->iGlobalPrimarybluex = pCHRM->iBluex; |
| pData->iGlobalPrimarybluey = pCHRM->iBluey; |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CHRM, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_SKIPCHUNK_sRGB |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| mng_retcode mng_create_ani_srgb (mng_datap pData, |
| mng_bool bEmpty, |
| mng_uint8 iRenderingintent) |
| #else |
| mng_retcode mng_create_ani_srgb (mng_datap pData, |
| mng_chunkp pChunk) |
| #endif |
| { |
| mng_ani_srgbp pSRGB; |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_SRGB, MNG_LC_START); |
| #endif |
| |
| if (pData->bCacheplayback) /* caching playback info ? */ |
| { |
| #ifdef MNG_OPTIMIZE_OBJCLEANUP |
| mng_ptr pTemp; |
| mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_ani_srgb), |
| mng_free_obj_general, |
| mng_process_ani_srgb, |
| &pTemp); |
| if (iRetcode) |
| return iRetcode; |
| pSRGB = (mng_ani_srgbp)pTemp; |
| #else |
| MNG_ALLOC (pData, pSRGB, sizeof (mng_ani_srgb)); |
| |
| pSRGB->sHeader.fCleanup = mng_free_ani_srgb; |
| pSRGB->sHeader.fProcess = mng_process_ani_srgb; |
| #endif |
| |
| mng_add_ani_object (pData, (mng_object_headerp)pSRGB); |
| |
| #ifndef MNG_OPTIMIZE_CHUNKREADER |
| pSRGB->bEmpty = bEmpty; |
| pSRGB->iRenderingintent = iRenderingintent; |
| #else |
| pSRGB->bEmpty = ((mng_srgbp)pChunk)->bEmpty; |
| pSRGB->iRenderingintent = ((mng_srgbp)pChunk)->iRenderingintent; |
| #endif |
| } |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_CREATE_ANI_SRGB, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| |
| /* ************************************************************************** */ |
| |
| #ifndef MNG_OPTIMIZE_OBJCLEANUP |
| mng_retcode mng_free_ani_srgb (mng_datap pData, |
| mng_objectp pObject) |
| { |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_SRGB, MNG_LC_START); |
| #endif |
| |
| MNG_FREEX (pData, pObject, sizeof (mng_ani_srgb)); |
| |
| #ifdef MNG_SUPPORT_TRACE |
| MNG_TRACE (pData, MNG_FN_FREE_ANI_SRGB, MNG_LC_END); |
| #endif |
| |
| return MNG_NOERROR; |
| } |
| #endif |
| |
| /* ************************************************************************** */ |
| |
| mng_retcode mng_process_ani_srgb (mng_datap pData, |
| mng_objectp pObject) |
| { |
| mng_ani_srgbp pSRGB = (mng_ani_srgbp)pObject; |
| |
| #ifdef MNG_SUPPORT_TRACE |
|