blob: f6691ff422fad118bc3b7c421f7db8e120195dab [file] [log] [blame] [edit]
/* ************************************************************************** */
/* * 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