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

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

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