diff options
Diffstat (limited to 'plugins/FreeImage/src/LibMNG/libmng_cms.c')
| -rw-r--r-- | plugins/FreeImage/src/LibMNG/libmng_cms.c | 758 | 
1 files changed, 758 insertions, 0 deletions
diff --git a/plugins/FreeImage/src/LibMNG/libmng_cms.c b/plugins/FreeImage/src/LibMNG/libmng_cms.c new file mode 100644 index 0000000000..f215271f2a --- /dev/null +++ b/plugins/FreeImage/src/LibMNG/libmng_cms.c @@ -0,0 +1,758 @@ +/* ************************************************************************** */
 +/* *             For conditions of distribution and use,                    * */
 +/* *                see copyright notice in libmng.h                        * */
 +/* ************************************************************************** */
 +/* *                                                                        * */
 +/* * project   : libmng                                                     * */
 +/* * file      : libmng_cms.c              copyright (c) 2000-2004 G.Juyn   * */
 +/* * version   : 1.0.9                                                      * */
 +/* *                                                                        * */
 +/* * purpose   : color management routines (implementation)                 * */
 +/* *                                                                        * */
 +/* * author    : G.Juyn                                                     * */
 +/* *                                                                        * */
 +/* * comment   : implementation of the color management routines            * */
 +/* *                                                                        * */
 +/* * changes   : 0.5.1 - 05/01/2000 - G.Juyn                                * */
 +/* *             - B001(105795) - fixed a typo and misconception about      * */
 +/* *               freeing allocated gamma-table. (reported by Marti Maria) * */
 +/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
 +/* *             - changed strict-ANSI stuff                                * */
 +/* *             0.5.1 - 05/09/2000 - G.Juyn                                * */
 +/* *             - filled application-based color-management routines       * */
 +/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
 +/* *             - added creatememprofile                                   * */
 +/* *             - added callback error-reporting support                   * */
 +/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
 +/* *             - changed trace to macro for callback error-reporting      * */
 +/* *                                                                        * */
 +/* *             0.5.2 - 06/10/2000 - G.Juyn                                * */
 +/* *             - fixed some compilation-warnings (contrib Jason Morris)   * */
 +/* *                                                                        * */
 +/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
 +/* *             - fixed problem with color-correction for stored images    * */
 +/* *             0.5.3 - 06/23/2000 - G.Juyn                                * */
 +/* *             - fixed problem with incorrect gamma-correction            * */
 +/* *                                                                        * */
 +/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
 +/* *             - changed file-prefixes                                    * */
 +/* *                                                                        * */
 +/* *             0.9.3 - 08/31/2000 - G.Juyn                                * */
 +/* *             - fixed sRGB precedence for gamma_only corection           * */
 +/* *                                                                        * */
 +/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
 +/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
 +/* *                                                                        * */
 +/* *             1.0.1 - 03/31/2001 - G.Juyn                                * */
 +/* *             - ignore gamma=0 (see png-list for more info)              * */
 +/* *             1.0.1 - 04/25/2001 - G.Juyn (reported by Gregg Kelly)      * */
 +/* *             - fixed problem with cms profile being created multiple    * */
 +/* *               times when both iCCP & cHRM/gAMA are present             * */
 +/* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
 +/* *             - moved mng_clear_cms to libmng_cms                        * */
 +/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
 +/* *             - added "default" sRGB generation (Thanks Marti!)          * */
 +/* *                                                                        * */
 +/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
 +/* *             - B597134 - libmng pollutes the linker namespace           * */
 +/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
 +/* *             - optimized color-correction routines                      * */
 +/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
 +/* *             - added in-memory color-correction of abstract images      * */
 +/* *             1.0.5 - 11/08/2002 - G.Juyn                                * */
 +/* *             - fixed issues in init_app_cms()                           * */
 +/* *                                                                        * */
 +/* *             1.0.6 - 04/11/2003 - G.Juyn                                * */
 +/* *             - B719420 - fixed several MNG_APP_CMS problems             * */
 +/* *             1.0.6 - 07/11/2003 - G. R-P                                * */
 +/* *             - added conditional MNG_SKIPCHUNK_cHRM/iCCP                * */
 +/* *                                                                        * */
 +/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
 +/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
 +/* *                                                                        * */
 +/* ************************************************************************** */
 +
 +#include "libmng.h"
 +#include "libmng_data.h"
 +#include "libmng_error.h"
 +#include "libmng_trace.h"
 +#ifdef __BORLANDC__
 +#pragma hdrstop
 +#endif
 +#include "libmng_objects.h"
 +#include "libmng_cms.h"
 +
 +#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
 +#pragma option -A                      /* force ANSI-C */
 +#endif
 +
 +/* ************************************************************************** */
 +
 +#ifdef MNG_INCLUDE_DISPLAY_PROCS
 +
 +/* ************************************************************************** */
 +/* *                                                                        * */
 +/* * Little CMS helper routines                                             * */
 +/* *                                                                        * */
 +/* ************************************************************************** */
 +
 +#ifdef MNG_INCLUDE_LCMS
 +
 +#define MNG_CMS_FLAGS 0
 +
 +/* ************************************************************************** */
 +
 +void mnglcms_initlibrary ()
 +{
 +  cmsErrorAction (LCMS_ERROR_IGNORE);  /* LCMS should ignore errors! */
 +}
 +
 +/* ************************************************************************** */
 +
 +mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename)
 +{
 +  return cmsOpenProfileFromFile (zFilename, "r");
 +}
 +
 +/* ************************************************************************** */
 +
 +mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
 +                                      mng_ptr    pProfile)
 +{
 +  return cmsOpenProfileFromMem (pProfile, iProfilesize);
 +}
 +
 +/* ************************************************************************** */
 +
 +mng_cmsprof mnglcms_createsrgbprofile (void)
 +{
 +  cmsCIExyY       D65;
 +  cmsCIExyYTRIPLE Rec709Primaries = {
 +                                      {0.6400, 0.3300, 1.0},
 +                                      {0.3000, 0.6000, 1.0},
 +                                      {0.1500, 0.0600, 1.0}
 +                                    };
 +  LPGAMMATABLE    Gamma24[3];
 +  mng_cmsprof     hsRGB;
 +
 +  cmsWhitePointFromTemp(6504, &D65);
 +  Gamma24[0] = Gamma24[1] = Gamma24[2] = cmsBuildGamma(256, 2.4);
 +  hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma24);
 +  cmsFreeGamma(Gamma24[0]);
 +
 +  return hsRGB;
 +}
 +
 +/* ************************************************************************** */
 +
 +void mnglcms_freeprofile (mng_cmsprof hProf)
 +{
 +  cmsCloseProfile (hProf);
 +  return;
 +}
 +
 +/* ************************************************************************** */
 +
 +void mnglcms_freetransform (mng_cmstrans hTrans)
 +{
 +/* B001 start */
 +  cmsDeleteTransform (hTrans);
 +/* B001 end */
 +  return;
 +}
 +
 +/* ************************************************************************** */
 +
 +mng_retcode mng_clear_cms (mng_datap pData)
 +{
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_START);
 +#endif
 +
 +  if (pData->hTrans)                   /* transformation still active ? */
 +    mnglcms_freetransform (pData->hTrans);
 +
 +  pData->hTrans = 0;
 +
 +  if (pData->hProf1)                   /* file profile still active ? */
 +    mnglcms_freeprofile (pData->hProf1);
 +
 +  pData->hProf1 = 0;
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_END);
 +#endif
 +
 +  return MNG_NOERROR;
 +}
 +
 +/* ************************************************************************** */
 +
 +#endif /* MNG_INCLUDE_LCMS */
 +
 +/* ************************************************************************** */
 +/* *                                                                        * */
 +/* * Color-management initialization & correction routines                  * */
 +/* *                                                                        * */
 +/* ************************************************************************** */
 +
 +#ifdef MNG_INCLUDE_LCMS
 +
 +mng_retcode mng_init_full_cms (mng_datap pData,
 +                               mng_bool  bGlobal,
 +                               mng_bool  bObject,
 +                               mng_bool  bRetrobj)
 +{
 +  mng_cmsprof    hProf;
 +  mng_cmstrans   hTrans;
 +  mng_imagep     pImage = MNG_NULL;
 +  mng_imagedatap pBuf   = MNG_NULL;
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_START);
 +#endif
 +
 +  if (bObject)                         /* use object if present ? */
 +  {                                    /* current object ? */
 +    if ((mng_imagep)pData->pCurrentobj)
 +      pImage = (mng_imagep)pData->pCurrentobj;
 +    else                               /* if not; use object 0 */
 +      pImage = (mng_imagep)pData->pObjzero;
 +  }
 +
 +  if (bRetrobj)                        /* retrieving from an object ? */
 +    pImage = (mng_imagep)pData->pRetrieveobj;
 +
 +  if (pImage)                          /* are we using an object ? */
 +    pBuf = pImage->pImgbuf;            /* then address the buffer */
 +
 +  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
 +  {
 +#ifndef MNG_SKIPCHUNK_iCCP
 +    if (((pBuf) && (pBuf->bHasICCP)) || ((bGlobal) && (pData->bHasglobalICCP)))
 +    {
 +      if (!pData->hProf2)              /* output profile not defined ? */
 +      {                                /* then assume sRGB !! */
 +        pData->hProf2 = mnglcms_createsrgbprofile ();
 +
 +        if (!pData->hProf2)            /* handle error ? */
 +          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
 +      }
 +
 +      if ((pBuf) && (pBuf->bHasICCP))  /* generate a profile handle */
 +        hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
 +      else
 +        hProf = cmsOpenProfileFromMem (pData->pGlobalProfile, pData->iGlobalProfilesize);
 +
 +      pData->hProf1 = hProf;           /* save for future use */
 +
 +      if (!hProf)                      /* handle error ? */
 +        MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
 +
 +#ifndef MNG_NO_16BIT_SUPPORT
 +      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
 +        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
 +                                     pData->hProf2, TYPE_RGBA_16_SE,
 +                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
 +      else
 +#endif
 +        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
 +                                     pData->hProf2, TYPE_RGBA_8,
 +                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
 +
 +      pData->hTrans = hTrans;          /* save for future use */
 +
 +      if (!hTrans)                     /* handle error ? */
 +        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
 +
 +      return MNG_NOERROR;              /* and done */
 +    }
 +    else
 +#endif
 +    if (((pBuf) && (pBuf->bHasSRGB)) || ((bGlobal) && (pData->bHasglobalSRGB)))
 +    {
 +      mng_uint8 iIntent;
 +
 +      if (pData->bIssRGB)              /* sRGB system ? */
 +        return MNG_NOERROR;            /* no conversion required */
 +
 +      if (!pData->hProf3)              /* sRGB profile not defined ? */
 +      {                                /* then create it implicitly !! */
 +        pData->hProf3 = mnglcms_createsrgbprofile ();
 +
 +        if (!pData->hProf3)            /* handle error ? */
 +          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
 +      }
 +
 +      hProf = pData->hProf3;           /* convert from sRGB profile */
 +
 +      if ((pBuf) && (pBuf->bHasSRGB))  /* determine rendering intent */
 +        iIntent = pBuf->iRenderingintent;
 +      else
 +        iIntent = pData->iGlobalRendintent;
 +
 +      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
 +        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
 +                                     pData->hProf2, TYPE_RGBA_16_SE,
 +                                     iIntent, MNG_CMS_FLAGS);
 +      else
 +        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
 +                                     pData->hProf2, TYPE_RGBA_8,
 +                                     iIntent, MNG_CMS_FLAGS);
 +
 +      pData->hTrans = hTrans;          /* save for future use */
 +
 +      if (!hTrans)                     /* handle error ? */
 +        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
 +
 +      return MNG_NOERROR;              /* and done */
 +    }
 +    else
 +    if ( (((pBuf) && (pBuf->bHasCHRM)) || ((bGlobal) && (pData->bHasglobalCHRM))) &&
 +         ( ((pBuf) && (pBuf->bHasGAMA) && (pBuf->iGamma > 0)) ||
 +           ((bGlobal) && (pData->bHasglobalGAMA) && (pData->iGlobalGamma > 0))  )    )
 +    {
 +      mng_CIExyY       sWhitepoint;
 +      mng_CIExyYTRIPLE sPrimaries;
 +      mng_gammatabp    pGammatable[3];
 +      mng_float        dGamma;
 +
 +      if (!pData->hProf2)              /* output profile not defined ? */
 +      {                                /* then assume sRGB !! */
 +        pData->hProf2 = mnglcms_createsrgbprofile ();
 +
 +        if (!pData->hProf2)            /* handle error ? */
 +          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
 +      }
 +
 +#ifndef MNG_SKIPCHUNK_cHRM
 +      if ((pBuf) && (pBuf->bHasCHRM))  /* local cHRM ? */
 +      {
 +        sWhitepoint.x      = (mng_float)pBuf->iWhitepointx   / 100000;
 +        sWhitepoint.y      = (mng_float)pBuf->iWhitepointy   / 100000;
 +        sPrimaries.Red.x   = (mng_float)pBuf->iPrimaryredx   / 100000;
 +        sPrimaries.Red.y   = (mng_float)pBuf->iPrimaryredy   / 100000;
 +        sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
 +        sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
 +        sPrimaries.Blue.x  = (mng_float)pBuf->iPrimarybluex  / 100000;
 +        sPrimaries.Blue.y  = (mng_float)pBuf->iPrimarybluey  / 100000;
 +      }
 +      else
 +      {
 +        sWhitepoint.x      = (mng_float)pData->iGlobalWhitepointx   / 100000;
 +        sWhitepoint.y      = (mng_float)pData->iGlobalWhitepointy   / 100000;
 +        sPrimaries.Red.x   = (mng_float)pData->iGlobalPrimaryredx   / 100000;
 +        sPrimaries.Red.y   = (mng_float)pData->iGlobalPrimaryredy   / 100000;
 +        sPrimaries.Green.x = (mng_float)pData->iGlobalPrimarygreenx / 100000;
 +        sPrimaries.Green.y = (mng_float)pData->iGlobalPrimarygreeny / 100000;
 +        sPrimaries.Blue.x  = (mng_float)pData->iGlobalPrimarybluex  / 100000;
 +        sPrimaries.Blue.y  = (mng_float)pData->iGlobalPrimarybluey  / 100000;
 +      }
 +#endif
 +
 +      sWhitepoint.Y      =             /* Y component is always 1.0 */
 +      sPrimaries.Red.Y   =
 +      sPrimaries.Green.Y =
 +      sPrimaries.Blue.Y  = 1.0;
 +
 +      if ((pBuf) && (pBuf->bHasGAMA))  /* get the gamma value */
 +        dGamma = (mng_float)pBuf->iGamma / 100000;
 +      else
 +        dGamma = (mng_float)pData->iGlobalGamma / 100000;
 +
 +      dGamma = pData->dViewgamma / dGamma;
 +
 +      pGammatable [0] =                /* and build the lookup tables */
 +      pGammatable [1] =
 +      pGammatable [2] = cmsBuildGamma (256, dGamma);
 +
 +      if (!pGammatable [0])            /* enough memory ? */
 +        MNG_ERRORL (pData, MNG_LCMS_NOMEM);
 +                                       /* create the profile */
 +      hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
 +
 +      cmsFreeGamma (pGammatable [0]);  /* free the temporary gamma tables ? */
 +                                       /* yes! but just the one! */
 +
 +      pData->hProf1 = hProf;           /* save for future use */
 +
 +      if (!hProf)                      /* handle error ? */
 +        MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
 +
 +      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
 +        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
 +                                     pData->hProf2, TYPE_RGBA_16_SE,
 +                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
 +      else
 +        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
 +                                     pData->hProf2, TYPE_RGBA_8,
 +                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
 +
 +      pData->hTrans = hTrans;          /* save for future use */
 +
 +      if (!hTrans)                     /* handle error ? */
 +        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
 +
 +      return MNG_NOERROR;              /* and done */
 +    }
 +  }
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_END);
 +#endif
 +                                       /* if we get here, we'll only do gamma */
 +  return mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
 +}
 +#endif /* MNG_INCLUDE_LCMS */
 +
 +/* ************************************************************************** */
 +
 +#ifdef MNG_INCLUDE_LCMS
 +mng_retcode mng_correct_full_cms (mng_datap pData)
 +{
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_START);
 +#endif
 +
 +  cmsDoTransform (pData->hTrans, pData->pRGBArow, pData->pRGBArow, pData->iRowsamples);
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_END);
 +#endif
 +
 +  return MNG_NOERROR;
 +}
 +#endif /* MNG_INCLUDE_LCMS */
 +
 +/* ************************************************************************** */
 +
 +#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
 +mng_retcode mng_init_gamma_only (mng_datap pData,
 +                                 mng_bool  bGlobal,
 +                                 mng_bool  bObject,
 +                                 mng_bool  bRetrobj)
 +{
 +  mng_float      dGamma;
 +  mng_imagep     pImage = MNG_NULL;
 +  mng_imagedatap pBuf   = MNG_NULL;
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_START);
 +#endif
 +
 +  if (bObject)                         /* use object if present ? */
 +  {                                    /* current object ? */
 +    if ((mng_imagep)pData->pCurrentobj)
 +      pImage = (mng_imagep)pData->pCurrentobj;
 +    else                               /* if not; use object 0 */
 +      pImage = (mng_imagep)pData->pObjzero;
 +  }
 +
 +  if (bRetrobj)                        /* retrieving from an object ? */
 +    pImage = (mng_imagep)pData->pRetrieveobj;
 +
 +  if (pImage)                          /* are we using an object ? */
 +    pBuf = pImage->pImgbuf;            /* then address the buffer */
 +
 +  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
 +  {
 +    if ((pBuf) && (pBuf->bHasSRGB))    /* get the gamma value */
 +      dGamma = 0.45455;
 +    else
 +    if ((pBuf) && (pBuf->bHasGAMA))
 +      dGamma = (mng_float)pBuf->iGamma / 100000;
 +    else
 +    if ((bGlobal) && (pData->bHasglobalSRGB))
 +      dGamma = 0.45455;
 +    else
 +    if ((bGlobal) && (pData->bHasglobalGAMA))
 +      dGamma = (mng_float)pData->iGlobalGamma / 100000;
 +    else
 +      dGamma = pData->dDfltimggamma;
 +
 +    if (dGamma > 0)                    /* ignore gamma=0 */
 +    {
 +      dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
 +
 +      if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
 +      {
 +        mng_int32 iX;
 +
 +        pData->aGammatab [0] = 0;
 +
 +        for (iX = 1; iX <= 255; iX++)
 +          pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
 +
 +        pData->dLastgamma = dGamma;    /* keep for next time */
 +      }
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_gamma_only;
 +    }
 +  }
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_END);
 +#endif
 +
 +  return MNG_NOERROR;
 +}
 +#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS || MNG_APP_CMS */
 +
 +/* ************************************************************************** */
 +
 +#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
 +mng_retcode mng_correct_gamma_only (mng_datap pData)
 +{
 +  mng_uint8p pWork;
 +  mng_int32  iX;
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_START);
 +#endif
 +
 +  pWork = pData->pRGBArow;             /* address intermediate row */
 +
 +  if (pData->bIsRGBA16)                /* 16-bit intermediate row ? */
 +  {
 +
 +  
 +     /* TODO: 16-bit precision gamma processing */
 +     /* we'll just do the high-order byte for now */
 +
 +     
 +                                       /* convert all samples in the row */
 +     for (iX = 0; iX < pData->iRowsamples; iX++)
 +     {                                 /* using the precalculated gamma lookup table */
 +       *pWork     = pData->aGammatab [*pWork];
 +       *(pWork+2) = pData->aGammatab [*(pWork+2)];
 +       *(pWork+4) = pData->aGammatab [*(pWork+4)];
 +
 +       pWork += 8;
 +     }
 +  }
 +  else
 +  {                                    /* convert all samples in the row */
 +     for (iX = 0; iX < pData->iRowsamples; iX++)
 +     {                                 /* using the precalculated gamma lookup table */
 +       *pWork     = pData->aGammatab [*pWork];
 +       *(pWork+1) = pData->aGammatab [*(pWork+1)];
 +       *(pWork+2) = pData->aGammatab [*(pWork+2)];
 +
 +       pWork += 4;
 +     }
 +  }
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_END);
 +#endif
 +
 +  return MNG_NOERROR;
 +}
 +#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS || MNG_APP_CMS */
 +
 +/* ************************************************************************** */
 +
 +#ifdef MNG_APP_CMS
 +mng_retcode mng_init_app_cms (mng_datap pData,
 +                              mng_bool  bGlobal,
 +                              mng_bool  bObject,
 +                              mng_bool  bRetrobj)
 +{
 +  mng_imagep     pImage = MNG_NULL;
 +  mng_imagedatap pBuf   = MNG_NULL;
 +  mng_bool       bDone  = MNG_FALSE;
 +  mng_retcode    iRetcode;
 +  
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_START);
 +#endif
 +
 +  if (bObject)                         /* use object if present ? */
 +  {                                    /* current object ? */
 +    if ((mng_imagep)pData->pCurrentobj)
 +      pImage = (mng_imagep)pData->pCurrentobj;
 +    else                               /* if not; use object 0 */
 +      pImage = (mng_imagep)pData->pObjzero;
 +  }
 +
 +  if (bRetrobj)                        /* retrieving from an object ? */
 +    pImage = (mng_imagep)pData->pRetrieveobj;
 +
 +  if (pImage)                          /* are we using an object ? */
 +    pBuf = pImage->pImgbuf;            /* then address the buffer */
 +
 +  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
 +  {
 +#ifndef MNG_SKIPCHUNK_iCCP
 +    if ( (pData->fProcessiccp) &&
 +         (((pBuf) && (pBuf->bHasICCP)) || ((bGlobal) && (pData->bHasglobalICCP))) )
 +    {
 +      mng_uint32 iProfilesize;
 +      mng_ptr    pProfile;
 +
 +      if ((pBuf) && (pBuf->bHasICCP))  /* get the right profile */
 +      {
 +        iProfilesize = pBuf->iProfilesize;
 +        pProfile     = pBuf->pProfile;
 +      }
 +      else
 +      {
 +        iProfilesize = pData->iGlobalProfilesize;
 +        pProfile     = pData->pGlobalProfile;
 +      }
 +                                       /* inform the app */
 +      if (!pData->fProcessiccp ((mng_handle)pData, iProfilesize, pProfile))
 +        MNG_ERROR (pData, MNG_APPCMSERROR);
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
 +      bDone              = MNG_TRUE;
 +    }
 +#endif
 +
 +    if ( (pData->fProcesssrgb) &&
 +         (((pBuf) && (pBuf->bHasSRGB)) || ((bGlobal) && (pData->bHasglobalSRGB))) )
 +    {
 +      mng_uint8 iIntent;
 +
 +      if ((pBuf) && (pBuf->bHasSRGB))  /* determine rendering intent */
 +        iIntent = pBuf->iRenderingintent;
 +      else
 +        iIntent = pData->iGlobalRendintent;
 +                                       /* inform the app */
 +      if (!pData->fProcesssrgb ((mng_handle)pData, iIntent))
 +        MNG_ERROR (pData, MNG_APPCMSERROR);
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
 +      bDone              = MNG_TRUE;
 +    }
 +
 +#ifndef MNG_SKIPCHUNK_cHRM
 +    if ( (pData->fProcesschroma) &&
 +         (((pBuf) && (pBuf->bHasCHRM)) || ((bGlobal) && (pData->bHasglobalCHRM))) )
 +    {
 +      mng_uint32 iWhitepointx,   iWhitepointy;
 +      mng_uint32 iPrimaryredx,   iPrimaryredy;
 +      mng_uint32 iPrimarygreenx, iPrimarygreeny;
 +      mng_uint32 iPrimarybluex,  iPrimarybluey;
 +
 +      if ((pBuf) && (pBuf->bHasCHRM))  /* local cHRM ? */
 +      {
 +        iWhitepointx   = pBuf->iWhitepointx;
 +        iWhitepointy   = pBuf->iWhitepointy;
 +        iPrimaryredx   = pBuf->iPrimaryredx;
 +        iPrimaryredy   = pBuf->iPrimaryredy;
 +        iPrimarygreenx = pBuf->iPrimarygreenx;
 +        iPrimarygreeny = pBuf->iPrimarygreeny;
 +        iPrimarybluex  = pBuf->iPrimarybluex;
 +        iPrimarybluey  = pBuf->iPrimarybluey;
 +      }
 +      else
 +      {
 +        iWhitepointx   = pData->iGlobalWhitepointx;
 +        iWhitepointy   = pData->iGlobalWhitepointy;
 +        iPrimaryredx   = pData->iGlobalPrimaryredx;
 +        iPrimaryredy   = pData->iGlobalPrimaryredy;
 +        iPrimarygreenx = pData->iGlobalPrimarygreenx;
 +        iPrimarygreeny = pData->iGlobalPrimarygreeny;
 +        iPrimarybluex  = pData->iGlobalPrimarybluex;
 +        iPrimarybluey  = pData->iGlobalPrimarybluey;
 +      }
 +                                       /* inform the app */
 +      if (!pData->fProcesschroma ((mng_handle)pData, iWhitepointx,   iWhitepointy,
 +                                                     iPrimaryredx,   iPrimaryredy,
 +                                                     iPrimarygreenx, iPrimarygreeny,
 +                                                     iPrimarybluex,  iPrimarybluey))
 +        MNG_ERROR (pData, MNG_APPCMSERROR);
 +                                       /* load color-correction routine */
 +      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
 +      bDone              = MNG_TRUE;
 +    }
 +#endif
 +
 +    if ( (pData->fProcessgamma) &&
 +         (((pBuf) && (pBuf->bHasGAMA)) || ((bGlobal) && (pData->bHasglobalGAMA))) )
 +    {
 +      mng_uint32 iGamma;
 +
 +      if ((pBuf) && (pBuf->bHasGAMA))  /* get the gamma value */
 +        iGamma = pBuf->iGamma;
 +      else
 +        iGamma = pData->iGlobalGamma;
 +                                       /* inform the app */
 +      if (!pData->fProcessgamma ((mng_handle)pData, iGamma))
 +      {                                /* app wants us to use internal routines ! */
 +        iRetcode = mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
 +        if (iRetcode)                  /* on error bail out */
 +          return iRetcode;
 +      }
 +      else
 +      {                                /* load color-correction routine */
 +        pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
 +      }
 +
 +      bDone = MNG_TRUE;
 +    }
 +
 +    if (!bDone)                        /* no color-info at all ? */
 +    {
 +                                       /* then use default image gamma ! */
 +      if (!pData->fProcessgamma ((mng_handle)pData,
 +                                 (mng_uint32)((pData->dDfltimggamma * 100000) + 0.5)))
 +      {                                /* app wants us to use internal routines ! */
 +        iRetcode = mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
 +        if (iRetcode)                  /* on error bail out */
 +          return iRetcode;
 +      }
 +      else
 +      {                                /* load color-correction routine */
 +        pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
 +      }  
 +    }
 +  }
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_END);
 +#endif
 +
 +  return MNG_NOERROR;
 +}
 +#endif /* MNG_APP_CMS */
 +
 +/* ************************************************************************** */
 +
 +#ifdef MNG_APP_CMS
 +mng_retcode mng_correct_app_cms (mng_datap pData)
 +{
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_START);
 +#endif
 +
 +  if (pData->fProcessarow)             /* let the app do something with our row */
 +    if (!pData->fProcessarow ((mng_handle)pData, pData->iRowsamples,
 +                              pData->bIsRGBA16, pData->pRGBArow))
 +      MNG_ERROR (pData, MNG_APPCMSERROR);
 +
 +#ifdef MNG_SUPPORT_TRACE
 +  MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_END);
 +#endif
 +
 +  return MNG_NOERROR;
 +}
 +#endif /* MNG_APP_CMS */
 +
 +/* ************************************************************************** */
 +
 +#endif /* MNG_INCLUDE_DISPLAY_PROCS */
 +
 +/* ************************************************************************** */
 +/* * end of file                                                            * */
 +/* ************************************************************************** */
 +
 +
 +
  | 
