summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libmng/libmng_cms.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libmng/libmng_cms.c')
-rw-r--r--src/3rdparty/libmng/libmng_cms.c928
1 files changed, 928 insertions, 0 deletions
diff --git a/src/3rdparty/libmng/libmng_cms.c b/src/3rdparty/libmng/libmng_cms.c
new file mode 100644
index 000000000..081283fe5
--- /dev/null
+++ b/src/3rdparty/libmng/libmng_cms.c
@@ -0,0 +1,928 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_cms.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.1 * */
+/* * * */
+/* * purpose : color management routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:[email protected] * */
+/* * * */
+/* * 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!) * */
+/* * * */
+/* ************************************************************************** */
+
+#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 init_full_cms (mng_datap pData)
+{
+ mng_cmsprof hProf;
+ mng_cmstrans hTrans;
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_START)
+#endif
+
+ if (!pImage) /* no current object? then use object 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address the buffer */
+
+ if ((pBuf->bHasICCP) || (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->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)
+
+ 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)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if ((pBuf->bHasSRGB) || (pData->bHasglobalSRGB))
+ {
+ mng_uint8 iIntent;
+
+ if (pData->bIssRGB) /* sRGB system ? */
+ return MNG_NOERROR; /* no conversion retquired */
+
+ 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->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)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if ( ((pBuf->bHasCHRM) || (pData->bHasglobalCHRM)) &&
+ ( ((pBuf->bHasGAMA) && (pBuf->iGamma > 0)) ||
+ ((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)
+ }
+
+ if (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;
+ }
+
+ sWhitepoint.Y = /* Y component is always 1.0 */
+ sPrimaries.Red.Y =
+ sPrimaries.Green.Y =
+ sPrimaries.Blue.Y = 1.0;
+
+ if (pBuf->bHasGAMA) /* get the gamma value */
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+ else
+ dGamma = (mng_float)pData->iGlobalGamma / 100000;
+
+/* dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma); ??? */
+ dGamma = pData->dViewgamma / dGamma;
+
+ pGammatable [0] = /* and build the lookup tables */
+ pGammatable [1] =
+ pGammatable [2] = cmsBuildGamma (256, dGamma);
+
+/* B001 start */
+ if (!pGammatable [0]) /* enough memory ? */
+/* B001 end */
+ MNG_ERRORL (pData, MNG_LCMS_NOMEM)
+ /* create the profile */
+ hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
+
+/* B001 start */
+ cmsFreeGamma (pGammatable [0]); /* free the temporary gamma tables ? */
+ /* yes! but just the one! */
+/* B001 end */
+
+ 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)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_END)
+#endif
+
+ return init_gamma_only (pData); /* if we get here, we'll only do gamma */
+}
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+
+mng_retcode init_full_cms_object (mng_datap pData)
+{
+ mng_cmsprof hProf;
+ mng_cmstrans hTrans;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS_OBJ, MNG_LC_START)
+#endif
+ /* address the object-buffer */
+ pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+
+ if (pBuf->bHasICCP)
+ {
+ 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)
+ }
+ /* generate a profile handle */
+ hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
+
+ 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)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if (pBuf->bHasSRGB)
+ {
+ if (pData->bIssRGB) /* sRGB system ? */
+ return MNG_NOERROR; /* no conversion retquired */
+
+ 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 (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ pBuf->iRenderingintent, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ pBuf->iRenderingintent, 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)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if ((pBuf->bHasCHRM) && (pBuf->bHasGAMA) && (pBuf->iGamma > 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)
+ }
+
+ 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;
+
+ sWhitepoint.Y = /* Y component is always 1.0 */
+ sPrimaries.Red.Y =
+ sPrimaries.Green.Y =
+ sPrimaries.Blue.Y = 1.0;
+
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+
+/* dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma); ??? */
+ dGamma = pData->dViewgamma / dGamma;
+
+ pGammatable [0] = /* and build the lookup tables */
+ pGammatable [1] =
+ pGammatable [2] = cmsBuildGamma (256, dGamma);
+
+/* B001 start */
+ if (!pGammatable [0]) /* enough memory ? */
+/* B001 end */
+ MNG_ERRORL (pData, MNG_LCMS_NOMEM)
+
+ /* create the profile */
+ hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
+
+/* B001 start */
+ cmsFreeGamma (pGammatable [0]); /* free the temporary gamma tables ? */
+ /* yes! but just the one! */
+/* B001 end */
+
+ 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)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS_OBJ, MNG_LC_END)
+#endif
+ /* if we get here, we'll only do gamma */
+ return init_gamma_only_object (pData);
+}
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+mng_retcode 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)
+mng_retcode init_gamma_only (mng_datap pData)
+{
+ mng_float dGamma;
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_START)
+#endif
+
+ if (!pImage) /* no current object? then use object 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address the buffer */
+
+ if (pBuf->bHasSRGB) /* get the gamma value */
+ dGamma = 0.45455;
+ else
+ if (pBuf->bHasGAMA)
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+ else
+ if (pData->bHasglobalSRGB)
+ dGamma = 0.45455;
+ else
+ if (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)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 */
+
+/* ************************************************************************** */
+
+#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
+mng_retcode init_gamma_only_object (mng_datap pData)
+{
+ mng_float dGamma;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY_OBJ, MNG_LC_START)
+#endif
+ /* address the object-buffer */
+ pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+
+ if (pBuf->bHasSRGB) /* get the gamma value */
+ dGamma = 0.45455;
+ else
+ if (pBuf->bHasGAMA)
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+ else
+ dGamma = pData->dDfltimggamma;
+
+ if (dGamma) /* lets not divide by zero, shall we... */
+ 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)correct_gamma_only;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY_OBJ, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
+mng_retcode 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 */
+
+/* ************************************************************************** */
+
+#ifdef MNG_APP_CMS
+mng_retcode init_app_cms (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_START)
+#endif
+
+ if ( (pData->fProcessiccp) &&
+ ((pBuf->bHasICCP) || (pData->bHasglobalICCP)) )
+ {
+ mng_uint32 iProfilesize;
+ mng_ptr pProfile;
+
+ if (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)correct_app_cms;
+ }
+
+ if ( (pData->fProcesssrgb) &&
+ ((pBuf->bHasSRGB) || (pData->bHasglobalSRGB)) )
+ {
+ mng_uint8 iIntent;
+
+ if (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)correct_app_cms;
+ }
+
+ if ( (pData->fProcesschroma) &&
+ ( ((pBuf->bHasCHRM) || (pData->bHasglobalCHRM)) ) )
+ {
+ mng_uint32 iWhitepointx, iWhitepointy;
+ mng_uint32 iPrimaryredx, iPrimaryredy;
+ mng_uint32 iPrimarygreenx, iPrimarygreeny;
+ mng_uint32 iPrimarybluex, iPrimarybluey;
+
+ if (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)correct_app_cms;
+ }
+
+ if ( (pData->fProcessgamma) &&
+ ((pBuf->bHasGAMA) || (pData->bHasglobalGAMA)) )
+ {
+ mng_uint32 iGamma;
+
+ if (pBuf->bHasGAMA) /* get the gamma value */
+ iGamma = pBuf->iGamma;
+ else
+ iGamma = pData->iGlobalGamma;
+ /* inform the app */
+ if (!pData->fProcessgamma ((mng_handle)pData, iGamma))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)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 init_app_cms_object (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pCurrentobj)->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS_OBJ, MNG_LC_START)
+#endif
+
+ if ((pData->fProcessiccp) && (pBuf->bHasICCP))
+ { /* inform the app */
+ if (!pData->fProcessiccp ((mng_handle)pData, pBuf->iProfilesize, pBuf->pProfile))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ((pData->fProcesssrgb) && (pBuf->bHasSRGB))
+ { /* inform the app */
+ if (!pData->fProcesssrgb ((mng_handle)pData, pBuf->iRenderingintent))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ((pData->fProcesschroma) && (pBuf->bHasCHRM))
+ { /* inform the app */
+ if (!pData->fProcesschroma ((mng_handle)pData, pBuf->iWhitepointx, pBuf->iWhitepointy,
+ pBuf->iPrimaryredx, pBuf->iPrimaryredy,
+ pBuf->iPrimarygreenx, pBuf->iPrimarygreeny,
+ pBuf->iPrimarybluex, pBuf->iPrimarybluey))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ((pData->fProcessgamma) && (pBuf->bHasGAMA))
+ { /* inform the app */
+ if (!pData->fProcessgamma ((mng_handle)pData, pBuf->iGamma))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS_OBJ, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_APP_CMS
+mng_retcode 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 * */
+/* ************************************************************************** */
+
+
+