PageRenderTime 38ms CodeModel.GetById 2ms app.highlight 30ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/LibMNG/libmng_cms.c

https://bitbucket.org/cabalistic/ogredeps/
C | 758 lines | 504 code | 133 blank | 121 comment | 117 complexity | 70f9d9de9d45716aafb320f70b1813b5 MD5 | raw file
  1/* ************************************************************************** */
  2/* *             For conditions of distribution and use,                    * */
  3/* *                see copyright notice in libmng.h                        * */
  4/* ************************************************************************** */
  5/* *                                                                        * */
  6/* * project   : libmng                                                     * */
  7/* * file      : libmng_cms.c              copyright (c) 2000-2004 G.Juyn   * */
  8/* * version   : 1.0.9                                                      * */
  9/* *                                                                        * */
 10/* * purpose   : color management routines (implementation)                 * */
 11/* *                                                                        * */
 12/* * author    : G.Juyn                                                     * */
 13/* *                                                                        * */
 14/* * comment   : implementation of the color management routines            * */
 15/* *                                                                        * */
 16/* * changes   : 0.5.1 - 05/01/2000 - G.Juyn                                * */
 17/* *             - B001(105795) - fixed a typo and misconception about      * */
 18/* *               freeing allocated gamma-table. (reported by Marti Maria) * */
 19/* *             0.5.1 - 05/08/2000 - G.Juyn                                * */
 20/* *             - changed strict-ANSI stuff                                * */
 21/* *             0.5.1 - 05/09/2000 - G.Juyn                                * */
 22/* *             - filled application-based color-management routines       * */
 23/* *             0.5.1 - 05/11/2000 - G.Juyn                                * */
 24/* *             - added creatememprofile                                   * */
 25/* *             - added callback error-reporting support                   * */
 26/* *             0.5.1 - 05/12/2000 - G.Juyn                                * */
 27/* *             - changed trace to macro for callback error-reporting      * */
 28/* *                                                                        * */
 29/* *             0.5.2 - 06/10/2000 - G.Juyn                                * */
 30/* *             - fixed some compilation-warnings (contrib Jason Morris)   * */
 31/* *                                                                        * */
 32/* *             0.5.3 - 06/21/2000 - G.Juyn                                * */
 33/* *             - fixed problem with color-correction for stored images    * */
 34/* *             0.5.3 - 06/23/2000 - G.Juyn                                * */
 35/* *             - fixed problem with incorrect gamma-correction            * */
 36/* *                                                                        * */
 37/* *             0.9.2 - 08/05/2000 - G.Juyn                                * */
 38/* *             - changed file-prefixes                                    * */
 39/* *                                                                        * */
 40/* *             0.9.3 - 08/31/2000 - G.Juyn                                * */
 41/* *             - fixed sRGB precedence for gamma_only corection           * */
 42/* *                                                                        * */
 43/* *             0.9.4 - 12/16/2000 - G.Juyn                                * */
 44/* *             - fixed mixup of data- & function-pointers (thanks Dimitri)* */
 45/* *                                                                        * */
 46/* *             1.0.1 - 03/31/2001 - G.Juyn                                * */
 47/* *             - ignore gamma=0 (see png-list for more info)              * */
 48/* *             1.0.1 - 04/25/2001 - G.Juyn (reported by Gregg Kelly)      * */
 49/* *             - fixed problem with cms profile being created multiple    * */
 50/* *               times when both iCCP & cHRM/gAMA are present             * */
 51/* *             1.0.1 - 04/25/2001 - G.Juyn                                * */
 52/* *             - moved mng_clear_cms to libmng_cms                        * */
 53/* *             1.0.1 - 05/02/2001 - G.Juyn                                * */
 54/* *             - added "default" sRGB generation (Thanks Marti!)          * */
 55/* *                                                                        * */
 56/* *             1.0.5 - 08/19/2002 - G.Juyn                                * */
 57/* *             - B597134 - libmng pollutes the linker namespace           * */
 58/* *             1.0.5 - 09/19/2002 - G.Juyn                                * */
 59/* *             - optimized color-correction routines                      * */
 60/* *             1.0.5 - 09/23/2002 - G.Juyn                                * */
 61/* *             - added in-memory color-correction of abstract images      * */
 62/* *             1.0.5 - 11/08/2002 - G.Juyn                                * */
 63/* *             - fixed issues in init_app_cms()                           * */
 64/* *                                                                        * */
 65/* *             1.0.6 - 04/11/2003 - G.Juyn                                * */
 66/* *             - B719420 - fixed several MNG_APP_CMS problems             * */
 67/* *             1.0.6 - 07/11/2003 - G. R-P                                * */
 68/* *             - added conditional MNG_SKIPCHUNK_cHRM/iCCP                * */
 69/* *                                                                        * */
 70/* *             1.0.9 - 12/20/2004 - G.Juyn                                * */
 71/* *             - cleaned up macro-invocations (thanks to D. Airlie)       * */
 72/* *                                                                        * */
 73/* ************************************************************************** */
 74
 75#include "libmng.h"
 76#include "libmng_data.h"
 77#include "libmng_error.h"
 78#include "libmng_trace.h"
 79#ifdef __BORLANDC__
 80#pragma hdrstop
 81#endif
 82#include "libmng_objects.h"
 83#include "libmng_cms.h"
 84
 85#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
 86#pragma option -A                      /* force ANSI-C */
 87#endif
 88
 89/* ************************************************************************** */
 90
 91#ifdef MNG_INCLUDE_DISPLAY_PROCS
 92
 93/* ************************************************************************** */
 94/* *                                                                        * */
 95/* * Little CMS helper routines                                             * */
 96/* *                                                                        * */
 97/* ************************************************************************** */
 98
 99#ifdef MNG_INCLUDE_LCMS
100
101#define MNG_CMS_FLAGS 0
102
103/* ************************************************************************** */
104
105void mnglcms_initlibrary ()
106{
107  cmsErrorAction (LCMS_ERROR_IGNORE);  /* LCMS should ignore errors! */
108}
109
110/* ************************************************************************** */
111
112mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename)
113{
114  return cmsOpenProfileFromFile (zFilename, "r");
115}
116
117/* ************************************************************************** */
118
119mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
120                                      mng_ptr    pProfile)
121{
122  return cmsOpenProfileFromMem (pProfile, iProfilesize);
123}
124
125/* ************************************************************************** */
126
127mng_cmsprof mnglcms_createsrgbprofile (void)
128{
129  cmsCIExyY       D65;
130  cmsCIExyYTRIPLE Rec709Primaries = {
131                                      {0.6400, 0.3300, 1.0},
132                                      {0.3000, 0.6000, 1.0},
133                                      {0.1500, 0.0600, 1.0}
134                                    };
135  LPGAMMATABLE    Gamma24[3];
136  mng_cmsprof     hsRGB;
137
138  cmsWhitePointFromTemp(6504, &D65);
139  Gamma24[0] = Gamma24[1] = Gamma24[2] = cmsBuildGamma(256, 2.4);
140  hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma24);
141  cmsFreeGamma(Gamma24[0]);
142
143  return hsRGB;
144}
145
146/* ************************************************************************** */
147
148void mnglcms_freeprofile (mng_cmsprof hProf)
149{
150  cmsCloseProfile (hProf);
151  return;
152}
153
154/* ************************************************************************** */
155
156void mnglcms_freetransform (mng_cmstrans hTrans)
157{
158/* B001 start */
159  cmsDeleteTransform (hTrans);
160/* B001 end */
161  return;
162}
163
164/* ************************************************************************** */
165
166mng_retcode mng_clear_cms (mng_datap pData)
167{
168#ifdef MNG_SUPPORT_TRACE
169  MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_START);
170#endif
171
172  if (pData->hTrans)                   /* transformation still active ? */
173    mnglcms_freetransform (pData->hTrans);
174
175  pData->hTrans = 0;
176
177  if (pData->hProf1)                   /* file profile still active ? */
178    mnglcms_freeprofile (pData->hProf1);
179
180  pData->hProf1 = 0;
181
182#ifdef MNG_SUPPORT_TRACE
183  MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_END);
184#endif
185
186  return MNG_NOERROR;
187}
188
189/* ************************************************************************** */
190
191#endif /* MNG_INCLUDE_LCMS */
192
193/* ************************************************************************** */
194/* *                                                                        * */
195/* * Color-management initialization & correction routines                  * */
196/* *                                                                        * */
197/* ************************************************************************** */
198
199#ifdef MNG_INCLUDE_LCMS
200
201mng_retcode mng_init_full_cms (mng_datap pData,
202                               mng_bool  bGlobal,
203                               mng_bool  bObject,
204                               mng_bool  bRetrobj)
205{
206  mng_cmsprof    hProf;
207  mng_cmstrans   hTrans;
208  mng_imagep     pImage = MNG_NULL;
209  mng_imagedatap pBuf   = MNG_NULL;
210
211#ifdef MNG_SUPPORT_TRACE
212  MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_START);
213#endif
214
215  if (bObject)                         /* use object if present ? */
216  {                                    /* current object ? */
217    if ((mng_imagep)pData->pCurrentobj)
218      pImage = (mng_imagep)pData->pCurrentobj;
219    else                               /* if not; use object 0 */
220      pImage = (mng_imagep)pData->pObjzero;
221  }
222
223  if (bRetrobj)                        /* retrieving from an object ? */
224    pImage = (mng_imagep)pData->pRetrieveobj;
225
226  if (pImage)                          /* are we using an object ? */
227    pBuf = pImage->pImgbuf;            /* then address the buffer */
228
229  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
230  {
231#ifndef MNG_SKIPCHUNK_iCCP
232    if (((pBuf) && (pBuf->bHasICCP)) || ((bGlobal) && (pData->bHasglobalICCP)))
233    {
234      if (!pData->hProf2)              /* output profile not defined ? */
235      {                                /* then assume sRGB !! */
236        pData->hProf2 = mnglcms_createsrgbprofile ();
237
238        if (!pData->hProf2)            /* handle error ? */
239          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
240      }
241
242      if ((pBuf) && (pBuf->bHasICCP))  /* generate a profile handle */
243        hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
244      else
245        hProf = cmsOpenProfileFromMem (pData->pGlobalProfile, pData->iGlobalProfilesize);
246
247      pData->hProf1 = hProf;           /* save for future use */
248
249      if (!hProf)                      /* handle error ? */
250        MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
251
252#ifndef MNG_NO_16BIT_SUPPORT
253      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
254        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
255                                     pData->hProf2, TYPE_RGBA_16_SE,
256                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
257      else
258#endif
259        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
260                                     pData->hProf2, TYPE_RGBA_8,
261                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
262
263      pData->hTrans = hTrans;          /* save for future use */
264
265      if (!hTrans)                     /* handle error ? */
266        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
267                                       /* load color-correction routine */
268      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
269
270      return MNG_NOERROR;              /* and done */
271    }
272    else
273#endif
274    if (((pBuf) && (pBuf->bHasSRGB)) || ((bGlobal) && (pData->bHasglobalSRGB)))
275    {
276      mng_uint8 iIntent;
277
278      if (pData->bIssRGB)              /* sRGB system ? */
279        return MNG_NOERROR;            /* no conversion required */
280
281      if (!pData->hProf3)              /* sRGB profile not defined ? */
282      {                                /* then create it implicitly !! */
283        pData->hProf3 = mnglcms_createsrgbprofile ();
284
285        if (!pData->hProf3)            /* handle error ? */
286          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
287      }
288
289      hProf = pData->hProf3;           /* convert from sRGB profile */
290
291      if ((pBuf) && (pBuf->bHasSRGB))  /* determine rendering intent */
292        iIntent = pBuf->iRenderingintent;
293      else
294        iIntent = pData->iGlobalRendintent;
295
296      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
297        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
298                                     pData->hProf2, TYPE_RGBA_16_SE,
299                                     iIntent, MNG_CMS_FLAGS);
300      else
301        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
302                                     pData->hProf2, TYPE_RGBA_8,
303                                     iIntent, MNG_CMS_FLAGS);
304
305      pData->hTrans = hTrans;          /* save for future use */
306
307      if (!hTrans)                     /* handle error ? */
308        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
309                                       /* load color-correction routine */
310      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
311
312      return MNG_NOERROR;              /* and done */
313    }
314    else
315    if ( (((pBuf) && (pBuf->bHasCHRM)) || ((bGlobal) && (pData->bHasglobalCHRM))) &&
316         ( ((pBuf) && (pBuf->bHasGAMA) && (pBuf->iGamma > 0)) ||
317           ((bGlobal) && (pData->bHasglobalGAMA) && (pData->iGlobalGamma > 0))  )    )
318    {
319      mng_CIExyY       sWhitepoint;
320      mng_CIExyYTRIPLE sPrimaries;
321      mng_gammatabp    pGammatable[3];
322      mng_float        dGamma;
323
324      if (!pData->hProf2)              /* output profile not defined ? */
325      {                                /* then assume sRGB !! */
326        pData->hProf2 = mnglcms_createsrgbprofile ();
327
328        if (!pData->hProf2)            /* handle error ? */
329          MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
330      }
331
332#ifndef MNG_SKIPCHUNK_cHRM
333      if ((pBuf) && (pBuf->bHasCHRM))  /* local cHRM ? */
334      {
335        sWhitepoint.x      = (mng_float)pBuf->iWhitepointx   / 100000;
336        sWhitepoint.y      = (mng_float)pBuf->iWhitepointy   / 100000;
337        sPrimaries.Red.x   = (mng_float)pBuf->iPrimaryredx   / 100000;
338        sPrimaries.Red.y   = (mng_float)pBuf->iPrimaryredy   / 100000;
339        sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
340        sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
341        sPrimaries.Blue.x  = (mng_float)pBuf->iPrimarybluex  / 100000;
342        sPrimaries.Blue.y  = (mng_float)pBuf->iPrimarybluey  / 100000;
343      }
344      else
345      {
346        sWhitepoint.x      = (mng_float)pData->iGlobalWhitepointx   / 100000;
347        sWhitepoint.y      = (mng_float)pData->iGlobalWhitepointy   / 100000;
348        sPrimaries.Red.x   = (mng_float)pData->iGlobalPrimaryredx   / 100000;
349        sPrimaries.Red.y   = (mng_float)pData->iGlobalPrimaryredy   / 100000;
350        sPrimaries.Green.x = (mng_float)pData->iGlobalPrimarygreenx / 100000;
351        sPrimaries.Green.y = (mng_float)pData->iGlobalPrimarygreeny / 100000;
352        sPrimaries.Blue.x  = (mng_float)pData->iGlobalPrimarybluex  / 100000;
353        sPrimaries.Blue.y  = (mng_float)pData->iGlobalPrimarybluey  / 100000;
354      }
355#endif
356
357      sWhitepoint.Y      =             /* Y component is always 1.0 */
358      sPrimaries.Red.Y   =
359      sPrimaries.Green.Y =
360      sPrimaries.Blue.Y  = 1.0;
361
362      if ((pBuf) && (pBuf->bHasGAMA))  /* get the gamma value */
363        dGamma = (mng_float)pBuf->iGamma / 100000;
364      else
365        dGamma = (mng_float)pData->iGlobalGamma / 100000;
366
367      dGamma = pData->dViewgamma / dGamma;
368
369      pGammatable [0] =                /* and build the lookup tables */
370      pGammatable [1] =
371      pGammatable [2] = cmsBuildGamma (256, dGamma);
372
373      if (!pGammatable [0])            /* enough memory ? */
374        MNG_ERRORL (pData, MNG_LCMS_NOMEM);
375                                       /* create the profile */
376      hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
377
378      cmsFreeGamma (pGammatable [0]);  /* free the temporary gamma tables ? */
379                                       /* yes! but just the one! */
380
381      pData->hProf1 = hProf;           /* save for future use */
382
383      if (!hProf)                      /* handle error ? */
384        MNG_ERRORL (pData, MNG_LCMS_NOHANDLE);
385
386      if (pData->bIsRGBA16)            /* 16-bit intermediates ? */
387        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_16_SE,
388                                     pData->hProf2, TYPE_RGBA_16_SE,
389                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
390      else
391        hTrans = cmsCreateTransform (hProf,         TYPE_RGBA_8,
392                                     pData->hProf2, TYPE_RGBA_8,
393                                     INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
394
395      pData->hTrans = hTrans;          /* save for future use */
396
397      if (!hTrans)                     /* handle error ? */
398        MNG_ERRORL (pData, MNG_LCMS_NOTRANS);
399                                       /* load color-correction routine */
400      pData->fCorrectrow = (mng_fptr)mng_correct_full_cms;
401
402      return MNG_NOERROR;              /* and done */
403    }
404  }
405
406#ifdef MNG_SUPPORT_TRACE
407  MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_END);
408#endif
409                                       /* if we get here, we'll only do gamma */
410  return mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
411}
412#endif /* MNG_INCLUDE_LCMS */
413
414/* ************************************************************************** */
415
416#ifdef MNG_INCLUDE_LCMS
417mng_retcode mng_correct_full_cms (mng_datap pData)
418{
419#ifdef MNG_SUPPORT_TRACE
420  MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_START);
421#endif
422
423  cmsDoTransform (pData->hTrans, pData->pRGBArow, pData->pRGBArow, pData->iRowsamples);
424
425#ifdef MNG_SUPPORT_TRACE
426  MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_END);
427#endif
428
429  return MNG_NOERROR;
430}
431#endif /* MNG_INCLUDE_LCMS */
432
433/* ************************************************************************** */
434
435#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
436mng_retcode mng_init_gamma_only (mng_datap pData,
437                                 mng_bool  bGlobal,
438                                 mng_bool  bObject,
439                                 mng_bool  bRetrobj)
440{
441  mng_float      dGamma;
442  mng_imagep     pImage = MNG_NULL;
443  mng_imagedatap pBuf   = MNG_NULL;
444
445#ifdef MNG_SUPPORT_TRACE
446  MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_START);
447#endif
448
449  if (bObject)                         /* use object if present ? */
450  {                                    /* current object ? */
451    if ((mng_imagep)pData->pCurrentobj)
452      pImage = (mng_imagep)pData->pCurrentobj;
453    else                               /* if not; use object 0 */
454      pImage = (mng_imagep)pData->pObjzero;
455  }
456
457  if (bRetrobj)                        /* retrieving from an object ? */
458    pImage = (mng_imagep)pData->pRetrieveobj;
459
460  if (pImage)                          /* are we using an object ? */
461    pBuf = pImage->pImgbuf;            /* then address the buffer */
462
463  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
464  {
465    if ((pBuf) && (pBuf->bHasSRGB))    /* get the gamma value */
466      dGamma = 0.45455;
467    else
468    if ((pBuf) && (pBuf->bHasGAMA))
469      dGamma = (mng_float)pBuf->iGamma / 100000;
470    else
471    if ((bGlobal) && (pData->bHasglobalSRGB))
472      dGamma = 0.45455;
473    else
474    if ((bGlobal) && (pData->bHasglobalGAMA))
475      dGamma = (mng_float)pData->iGlobalGamma / 100000;
476    else
477      dGamma = pData->dDfltimggamma;
478
479    if (dGamma > 0)                    /* ignore gamma=0 */
480    {
481      dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
482
483      if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
484      {
485        mng_int32 iX;
486
487        pData->aGammatab [0] = 0;
488
489        for (iX = 1; iX <= 255; iX++)
490          pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
491
492        pData->dLastgamma = dGamma;    /* keep for next time */
493      }
494                                       /* load color-correction routine */
495      pData->fCorrectrow = (mng_fptr)mng_correct_gamma_only;
496    }
497  }
498
499#ifdef MNG_SUPPORT_TRACE
500  MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_END);
501#endif
502
503  return MNG_NOERROR;
504}
505#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS || MNG_APP_CMS */
506
507/* ************************************************************************** */
508
509#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS) || defined(MNG_APP_CMS)
510mng_retcode mng_correct_gamma_only (mng_datap pData)
511{
512  mng_uint8p pWork;
513  mng_int32  iX;
514
515#ifdef MNG_SUPPORT_TRACE
516  MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_START);
517#endif
518
519  pWork = pData->pRGBArow;             /* address intermediate row */
520
521  if (pData->bIsRGBA16)                /* 16-bit intermediate row ? */
522  {
523
524  
525     /* TODO: 16-bit precision gamma processing */
526     /* we'll just do the high-order byte for now */
527
528     
529                                       /* convert all samples in the row */
530     for (iX = 0; iX < pData->iRowsamples; iX++)
531     {                                 /* using the precalculated gamma lookup table */
532       *pWork     = pData->aGammatab [*pWork];
533       *(pWork+2) = pData->aGammatab [*(pWork+2)];
534       *(pWork+4) = pData->aGammatab [*(pWork+4)];
535
536       pWork += 8;
537     }
538  }
539  else
540  {                                    /* convert all samples in the row */
541     for (iX = 0; iX < pData->iRowsamples; iX++)
542     {                                 /* using the precalculated gamma lookup table */
543       *pWork     = pData->aGammatab [*pWork];
544       *(pWork+1) = pData->aGammatab [*(pWork+1)];
545       *(pWork+2) = pData->aGammatab [*(pWork+2)];
546
547       pWork += 4;
548     }
549  }
550
551#ifdef MNG_SUPPORT_TRACE
552  MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_END);
553#endif
554
555  return MNG_NOERROR;
556}
557#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS || MNG_APP_CMS */
558
559/* ************************************************************************** */
560
561#ifdef MNG_APP_CMS
562mng_retcode mng_init_app_cms (mng_datap pData,
563                              mng_bool  bGlobal,
564                              mng_bool  bObject,
565                              mng_bool  bRetrobj)
566{
567  mng_imagep     pImage = MNG_NULL;
568  mng_imagedatap pBuf   = MNG_NULL;
569  mng_bool       bDone  = MNG_FALSE;
570  mng_retcode    iRetcode;
571  
572#ifdef MNG_SUPPORT_TRACE
573  MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_START);
574#endif
575
576  if (bObject)                         /* use object if present ? */
577  {                                    /* current object ? */
578    if ((mng_imagep)pData->pCurrentobj)
579      pImage = (mng_imagep)pData->pCurrentobj;
580    else                               /* if not; use object 0 */
581      pImage = (mng_imagep)pData->pObjzero;
582  }
583
584  if (bRetrobj)                        /* retrieving from an object ? */
585    pImage = (mng_imagep)pData->pRetrieveobj;
586
587  if (pImage)                          /* are we using an object ? */
588    pBuf = pImage->pImgbuf;            /* then address the buffer */
589
590  if ((!pBuf) || (!pBuf->bCorrected))  /* is the buffer already corrected ? */
591  {
592#ifndef MNG_SKIPCHUNK_iCCP
593    if ( (pData->fProcessiccp) &&
594         (((pBuf) && (pBuf->bHasICCP)) || ((bGlobal) && (pData->bHasglobalICCP))) )
595    {
596      mng_uint32 iProfilesize;
597      mng_ptr    pProfile;
598
599      if ((pBuf) && (pBuf->bHasICCP))  /* get the right profile */
600      {
601        iProfilesize = pBuf->iProfilesize;
602        pProfile     = pBuf->pProfile;
603      }
604      else
605      {
606        iProfilesize = pData->iGlobalProfilesize;
607        pProfile     = pData->pGlobalProfile;
608      }
609                                       /* inform the app */
610      if (!pData->fProcessiccp ((mng_handle)pData, iProfilesize, pProfile))
611        MNG_ERROR (pData, MNG_APPCMSERROR);
612                                       /* load color-correction routine */
613      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
614      bDone              = MNG_TRUE;
615    }
616#endif
617
618    if ( (pData->fProcesssrgb) &&
619         (((pBuf) && (pBuf->bHasSRGB)) || ((bGlobal) && (pData->bHasglobalSRGB))) )
620    {
621      mng_uint8 iIntent;
622
623      if ((pBuf) && (pBuf->bHasSRGB))  /* determine rendering intent */
624        iIntent = pBuf->iRenderingintent;
625      else
626        iIntent = pData->iGlobalRendintent;
627                                       /* inform the app */
628      if (!pData->fProcesssrgb ((mng_handle)pData, iIntent))
629        MNG_ERROR (pData, MNG_APPCMSERROR);
630                                       /* load color-correction routine */
631      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
632      bDone              = MNG_TRUE;
633    }
634
635#ifndef MNG_SKIPCHUNK_cHRM
636    if ( (pData->fProcesschroma) &&
637         (((pBuf) && (pBuf->bHasCHRM)) || ((bGlobal) && (pData->bHasglobalCHRM))) )
638    {
639      mng_uint32 iWhitepointx,   iWhitepointy;
640      mng_uint32 iPrimaryredx,   iPrimaryredy;
641      mng_uint32 iPrimarygreenx, iPrimarygreeny;
642      mng_uint32 iPrimarybluex,  iPrimarybluey;
643
644      if ((pBuf) && (pBuf->bHasCHRM))  /* local cHRM ? */
645      {
646        iWhitepointx   = pBuf->iWhitepointx;
647        iWhitepointy   = pBuf->iWhitepointy;
648        iPrimaryredx   = pBuf->iPrimaryredx;
649        iPrimaryredy   = pBuf->iPrimaryredy;
650        iPrimarygreenx = pBuf->iPrimarygreenx;
651        iPrimarygreeny = pBuf->iPrimarygreeny;
652        iPrimarybluex  = pBuf->iPrimarybluex;
653        iPrimarybluey  = pBuf->iPrimarybluey;
654      }
655      else
656      {
657        iWhitepointx   = pData->iGlobalWhitepointx;
658        iWhitepointy   = pData->iGlobalWhitepointy;
659        iPrimaryredx   = pData->iGlobalPrimaryredx;
660        iPrimaryredy   = pData->iGlobalPrimaryredy;
661        iPrimarygreenx = pData->iGlobalPrimarygreenx;
662        iPrimarygreeny = pData->iGlobalPrimarygreeny;
663        iPrimarybluex  = pData->iGlobalPrimarybluex;
664        iPrimarybluey  = pData->iGlobalPrimarybluey;
665      }
666                                       /* inform the app */
667      if (!pData->fProcesschroma ((mng_handle)pData, iWhitepointx,   iWhitepointy,
668                                                     iPrimaryredx,   iPrimaryredy,
669                                                     iPrimarygreenx, iPrimarygreeny,
670                                                     iPrimarybluex,  iPrimarybluey))
671        MNG_ERROR (pData, MNG_APPCMSERROR);
672                                       /* load color-correction routine */
673      pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
674      bDone              = MNG_TRUE;
675    }
676#endif
677
678    if ( (pData->fProcessgamma) &&
679         (((pBuf) && (pBuf->bHasGAMA)) || ((bGlobal) && (pData->bHasglobalGAMA))) )
680    {
681      mng_uint32 iGamma;
682
683      if ((pBuf) && (pBuf->bHasGAMA))  /* get the gamma value */
684        iGamma = pBuf->iGamma;
685      else
686        iGamma = pData->iGlobalGamma;
687                                       /* inform the app */
688      if (!pData->fProcessgamma ((mng_handle)pData, iGamma))
689      {                                /* app wants us to use internal routines ! */
690        iRetcode = mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
691        if (iRetcode)                  /* on error bail out */
692          return iRetcode;
693      }
694      else
695      {                                /* load color-correction routine */
696        pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
697      }
698
699      bDone = MNG_TRUE;
700    }
701
702    if (!bDone)                        /* no color-info at all ? */
703    {
704                                       /* then use default image gamma ! */
705      if (!pData->fProcessgamma ((mng_handle)pData,
706                                 (mng_uint32)((pData->dDfltimggamma * 100000) + 0.5)))
707      {                                /* app wants us to use internal routines ! */
708        iRetcode = mng_init_gamma_only (pData, bGlobal, bObject, bRetrobj);
709        if (iRetcode)                  /* on error bail out */
710          return iRetcode;
711      }
712      else
713      {                                /* load color-correction routine */
714        pData->fCorrectrow = (mng_fptr)mng_correct_app_cms;
715      }  
716    }
717  }
718
719#ifdef MNG_SUPPORT_TRACE
720  MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_END);
721#endif
722
723  return MNG_NOERROR;
724}
725#endif /* MNG_APP_CMS */
726
727/* ************************************************************************** */
728
729#ifdef MNG_APP_CMS
730mng_retcode mng_correct_app_cms (mng_datap pData)
731{
732#ifdef MNG_SUPPORT_TRACE
733  MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_START);
734#endif
735
736  if (pData->fProcessarow)             /* let the app do something with our row */
737    if (!pData->fProcessarow ((mng_handle)pData, pData->iRowsamples,
738                              pData->bIsRGBA16, pData->pRGBArow))
739      MNG_ERROR (pData, MNG_APPCMSERROR);
740
741#ifdef MNG_SUPPORT_TRACE
742  MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_END);
743#endif
744
745  return MNG_NOERROR;
746}
747#endif /* MNG_APP_CMS */
748
749/* ************************************************************************** */
750
751#endif /* MNG_INCLUDE_DISPLAY_PROCS */
752
753/* ************************************************************************** */
754/* * end of file                                                            * */
755/* ************************************************************************** */
756
757
758