source: trunk/src/3rdparty/libmng/libmng_cms.c@ 122

Last change on this file since 122 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 29.5 KB
Line 
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
Note: See TracBrowser for help on using the repository browser.