2 * The copyright in this software is being made available under the 2-clauses
3 * BSD License, included below. This software may be subject to other third
4 * party and contributor rights, including patent rights, and no such rights
5 * are granted under this license.
7 * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
8 * Copyright (c) 2002-2014, Professor Benoit Macq
9 * Copyright (c) 2001-2003, David Janssens
10 * Copyright (c) 2002-2003, Yannick Verschueren
11 * Copyright (c) 2003-2007, Francois-Olivier Devaux
12 * Copyright (c) 2003-2014, Antonin Descampe
13 * Copyright (c) 2005, Herve Drolon, FreeImage Team
14 * All rights reserved.
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
44 #include "opj_apps_config.h"
48 #ifdef OPJ_HAVE_LIBLCMS2
51 #ifdef OPJ_HAVE_LIBLCMS1
56 #define OPJ_CLRSPC_GRAY CLRSPC_GRAY
57 #define OPJ_CLRSPC_SRGB CLRSPC_SRGB
60 /*--------------------------------------------------------
61 Matrix for sYCC, Amendment 1 to IEC 61966-2-1
63 Y : 0.299 0.587 0.114 :R
64 Cb: -0.1687 -0.3312 0.5 :G
65 Cr: 0.5 -0.4187 -0.0812 :B
69 R: 1 -3.68213e-05 1.40199 :Y
70 G: 1.00003 -0.344125 -0.714128 :Cb - 2^(prec - 1)
71 B: 0.999823 1.77204 -8.04142e-06 :Cr - 2^(prec - 1)
73 -----------------------------------------------------------*/
74 static void sycc_to_rgb(int offset, int upb, int y, int cb, int cr,
75 int *out_r, int *out_g, int *out_b)
79 cb -= offset; cr -= offset;
80 r = y + (int)(1.402 * (float)cr);
81 if(r < 0) r = 0; else if(r > upb) r = upb; *out_r = r;
83 g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
84 if(g < 0) g = 0; else if(g > upb) g = upb; *out_g = g;
86 b = y + (int)(1.772 * (float)cb);
87 if(b < 0) b = 0; else if(b > upb) b = upb; *out_b = b;
90 static void sycc444_to_rgb(opj_image_t *img)
92 int *d0, *d1, *d2, *r, *g, *b;
93 const int *y, *cb, *cr;
94 size_t maxw, maxh, max, i;
97 upb = (int)img->comps[0].prec;
98 offset = 1<<(upb - 1); upb = (1<<upb)-1;
100 maxw = (size_t)img->comps[0].w; maxh = (size_t)img->comps[0].h;
103 y = img->comps[0].data;
104 cb = img->comps[1].data;
105 cr = img->comps[2].data;
107 d0 = r = (int*)malloc(sizeof(int) * max);
108 d1 = g = (int*)malloc(sizeof(int) * max);
109 d2 = b = (int*)malloc(sizeof(int) * max);
111 if(r == NULL || g == NULL || b == NULL) goto fails;
113 for(i = 0U; i < max; ++i)
115 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
116 ++y; ++cb; ++cr; ++r; ++g; ++b;
118 free(img->comps[0].data); img->comps[0].data = d0;
119 free(img->comps[1].data); img->comps[1].data = d1;
120 free(img->comps[2].data); img->comps[2].data = d2;
121 img->color_space = OPJ_CLRSPC_SRGB;
128 }/* sycc444_to_rgb() */
130 static void sycc422_to_rgb(opj_image_t *img)
132 int *d0, *d1, *d2, *r, *g, *b;
133 const int *y, *cb, *cr;
134 size_t maxw, maxh, max, offx, loopmaxw;
138 upb = (int)img->comps[0].prec;
139 offset = 1<<(upb - 1); upb = (1<<upb)-1;
141 maxw = (size_t)img->comps[0].w; maxh = (size_t)img->comps[0].h;
144 y = img->comps[0].data;
145 cb = img->comps[1].data;
146 cr = img->comps[2].data;
148 d0 = r = (int*)malloc(sizeof(int) * max);
149 d1 = g = (int*)malloc(sizeof(int) * max);
150 d2 = b = (int*)malloc(sizeof(int) * max);
152 if(r == NULL || g == NULL || b == NULL) goto fails;
154 /* if img->x0 is odd, then first column shall use Cb/Cr = 0 */
156 loopmaxw = maxw - offx;
158 for(i=0U; i < maxh; ++i)
163 sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
167 for(j=0U; j < (loopmaxw & ~(size_t)1U); j += 2U)
169 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
171 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
172 ++y; ++r; ++g; ++b; ++cb; ++cr;
175 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
176 ++y; ++r; ++g; ++b; ++cb; ++cr;
180 free(img->comps[0].data); img->comps[0].data = d0;
181 free(img->comps[1].data); img->comps[1].data = d1;
182 free(img->comps[2].data); img->comps[2].data = d2;
184 img->comps[1].w = img->comps[2].w = img->comps[0].w;
185 img->comps[1].h = img->comps[2].h = img->comps[0].h;
186 img->comps[1].dx = img->comps[2].dx = img->comps[0].dx;
187 img->comps[1].dy = img->comps[2].dy = img->comps[0].dy;
188 img->color_space = OPJ_CLRSPC_SRGB;
195 }/* sycc422_to_rgb() */
197 static void sycc420_to_rgb(opj_image_t *img)
199 int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
200 const int *y, *cb, *cr, *ny;
201 size_t maxw, maxh, max, offx, loopmaxw, offy, loopmaxh;
205 upb = (int)img->comps[0].prec;
206 offset = 1<<(upb - 1); upb = (1<<upb)-1;
208 maxw = (size_t)img->comps[0].w; maxh = (size_t)img->comps[0].h;
211 y = img->comps[0].data;
212 cb = img->comps[1].data;
213 cr = img->comps[2].data;
215 d0 = r = (int*)malloc(sizeof(int) * max);
216 d1 = g = (int*)malloc(sizeof(int) * max);
217 d2 = b = (int*)malloc(sizeof(int) * max);
219 if (r == NULL || g == NULL || b == NULL) goto fails;
221 /* if img->x0 is odd, then first column shall use Cb/Cr = 0 */
223 loopmaxw = maxw - offx;
224 /* if img->y0 is odd, then first line shall use Cb/Cr = 0 */
226 loopmaxh = maxh - offy;
231 for(j=0; j < maxw; ++j)
233 sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
238 for(i=0U; i < (loopmaxh & ~(size_t)1U); i += 2U)
243 nr = r + maxw; ng = g + maxw; nb = b + maxw;
246 sycc_to_rgb(offset, upb, *y, 0, 0, r, g, b);
248 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
249 ++ny; ++nr; ++ng; ++nb;
252 for(j=0; j < (loopmaxw & ~(size_t)1U); j += 2U)
254 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
256 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
259 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
260 ++ny; ++nr; ++ng; ++nb;
261 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
262 ++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
266 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
269 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
270 ++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
272 y += maxw; r += maxw; g += maxw; b += maxw;
278 for(j=0U; j < (maxw & ~(size_t)1U); j += 2U)
280 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
284 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
286 ++y; ++r; ++g; ++b; ++cb; ++cr;
290 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
294 free(img->comps[0].data); img->comps[0].data = d0;
295 free(img->comps[1].data); img->comps[1].data = d1;
296 free(img->comps[2].data); img->comps[2].data = d2;
298 img->comps[1].w = img->comps[2].w = img->comps[0].w;
299 img->comps[1].h = img->comps[2].h = img->comps[0].h;
300 img->comps[1].dx = img->comps[2].dx = img->comps[0].dx;
301 img->comps[1].dy = img->comps[2].dy = img->comps[0].dy;
302 img->color_space = OPJ_CLRSPC_SRGB;
309 }/* sycc420_to_rgb() */
311 void color_sycc_to_rgb(opj_image_t *img)
313 if(img->numcomps < 3)
315 img->color_space = OPJ_CLRSPC_GRAY;
319 if((img->comps[0].dx == 1)
320 && (img->comps[1].dx == 2)
321 && (img->comps[2].dx == 2)
322 && (img->comps[0].dy == 1)
323 && (img->comps[1].dy == 2)
324 && (img->comps[2].dy == 2))/* horizontal and vertical sub-sample */
329 if((img->comps[0].dx == 1)
330 && (img->comps[1].dx == 2)
331 && (img->comps[2].dx == 2)
332 && (img->comps[0].dy == 1)
333 && (img->comps[1].dy == 1)
334 && (img->comps[2].dy == 1))/* horizontal sub-sample only */
339 if((img->comps[0].dx == 1)
340 && (img->comps[1].dx == 1)
341 && (img->comps[2].dx == 1)
342 && (img->comps[0].dy == 1)
343 && (img->comps[1].dy == 1)
344 && (img->comps[2].dy == 1))/* no sub-sample */
350 fprintf(stderr,"%s:%d:color_sycc_to_rgb\n\tCAN NOT CONVERT\n", __FILE__,__LINE__);
353 }/* color_sycc_to_rgb() */
355 #if defined(OPJ_HAVE_LIBLCMS2) || defined(OPJ_HAVE_LIBLCMS1)
357 #ifdef OPJ_HAVE_LIBLCMS1
358 /* Bob Friesenhahn proposed:*/
359 #define cmsSigXYZData icSigXYZData
360 #define cmsSigLabData icSigLabData
361 #define cmsSigCmykData icSigCmykData
362 #define cmsSigYCbCrData icSigYCbCrData
363 #define cmsSigLuvData icSigLuvData
364 #define cmsSigGrayData icSigGrayData
365 #define cmsSigRgbData icSigRgbData
366 #define cmsUInt32Number DWORD
368 #define cmsColorSpaceSignature icColorSpaceSignature
369 #define cmsGetHeaderRenderingIntent cmsTakeRenderingIntent
371 #endif /* OPJ_HAVE_LIBLCMS1 */
373 /*#define DEBUG_PROFILE*/
374 void color_apply_icc_profile(opj_image_t *image)
376 cmsHPROFILE in_prof, out_prof;
377 cmsHTRANSFORM transform;
378 cmsColorSpaceSignature in_space, out_space;
379 cmsUInt32Number intent, in_type, out_type;
381 size_t nr_samples, i, max, max_w, max_h;
383 OPJ_COLOR_SPACE new_space;
385 in_prof = cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
387 FILE *icm = fopen("debug.icm","wb");
388 fwrite( image->icc_profile_buf,1, image->icc_profile_len,icm);
392 if(in_prof == NULL) return;
394 in_space = cmsGetPCS(in_prof);
395 out_space = cmsGetColorSpace(in_prof);
396 intent = cmsGetHeaderRenderingIntent(in_prof);
399 max_w = image->comps[0].w;
400 max_h = image->comps[0].h;
401 prec = (int)image->comps[0].prec;
403 if(out_space == cmsSigRgbData) /* enumCS 16 */
407 in_type = TYPE_RGB_8;
408 out_type = TYPE_RGB_8;
412 in_type = TYPE_RGB_16;
413 out_type = TYPE_RGB_16;
415 out_prof = cmsCreate_sRGBProfile();
416 new_space = OPJ_CLRSPC_SRGB;
418 else if(out_space == cmsSigGrayData) /* enumCS 17 */
420 in_type = TYPE_GRAY_8;
421 out_type = TYPE_RGB_8;
422 out_prof = cmsCreate_sRGBProfile();
423 new_space = OPJ_CLRSPC_SRGB;
425 else if(out_space == cmsSigYCbCrData) /* enumCS 18 */
427 in_type = TYPE_YCbCr_16;
428 out_type = TYPE_RGB_16;
429 out_prof = cmsCreate_sRGBProfile();
430 new_space = OPJ_CLRSPC_SRGB;
435 fprintf(stderr,"%s:%d: color_apply_icc_profile\n\tICC Profile has unknown "
436 "output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
437 __FILE__,__LINE__,out_space,
438 (out_space>>24) & 0xff,(out_space>>16) & 0xff,
439 (out_space>>8) & 0xff, out_space & 0xff);
441 cmsCloseProfile(in_prof);
447 cmsCloseProfile(in_prof);
452 fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
453 "\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
454 max_w,max_h, (void*)in_prof,(void*)out_prof);
456 fprintf(stderr,"\trender_intent (%u)\n\t"
457 "color_space: in(%#x)(%c%c%c%c) out:(%#x)(%c%c%c%c)\n\t"
458 " type: in(%u) out:(%u)\n",
461 (in_space>>24) & 0xff,(in_space>>16) & 0xff,
462 (in_space>>8) & 0xff, in_space & 0xff,
465 (out_space>>24) & 0xff,(out_space>>16) & 0xff,
466 (out_space>>8) & 0xff, out_space & 0xff,
473 #endif /* DEBUG_PROFILE */
475 transform = cmsCreateTransform(in_prof, in_type, out_prof, out_type, intent, 0);
477 #ifdef OPJ_HAVE_LIBLCMS2
478 /* Possible for: LCMS_VERSION >= 2000 :*/
479 cmsCloseProfile(in_prof);
480 cmsCloseProfile(out_prof);
483 if(transform == NULL)
486 fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. "
487 "ICC Profile ignored.\n",__FILE__,__LINE__);
490 #ifdef OPJ_HAVE_LIBLCMS1
491 cmsCloseProfile(in_prof);
492 cmsCloseProfile(out_prof);
497 if(image->numcomps > 2)/* RGB, RGBA */
501 unsigned char *inbuf, *outbuf, *in, *out;
504 nr_samples = (size_t)(max * 3U * sizeof(unsigned char));
505 in = inbuf = (unsigned char*)malloc(nr_samples);
506 out = outbuf = (unsigned char*)malloc(nr_samples);
508 if(inbuf == NULL || outbuf == NULL) goto fails0;
510 r = image->comps[0].data;
511 g = image->comps[1].data;
512 b = image->comps[2].data;
514 for(i = 0U; i < max; ++i)
516 *in++ = (unsigned char)*r++;
517 *in++ = (unsigned char)*g++;
518 *in++ = (unsigned char)*b++;
521 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
523 r = image->comps[0].data;
524 g = image->comps[1].data;
525 b = image->comps[2].data;
527 for(i = 0U; i < max; ++i)
541 unsigned short *inbuf, *outbuf, *in, *out;
544 nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
545 in = inbuf = (unsigned short*)malloc(nr_samples);
546 out = outbuf = (unsigned short*)malloc(nr_samples);
548 if(inbuf == NULL || outbuf == NULL) goto fails1;
550 r = image->comps[0].data;
551 g = image->comps[1].data;
552 b = image->comps[2].data;
554 for(i = 0U ; i < max; ++i)
556 *in++ = (unsigned short)*r++;
557 *in++ = (unsigned short)*g++;
558 *in++ = (unsigned short)*b++;
561 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
563 r = image->comps[0].data;
564 g = image->comps[1].data;
565 b = image->comps[2].data;
567 for(i = 0; i < max; ++i)
580 else /* image->numcomps <= 2 : GRAY, GRAYA */
584 unsigned char *in, *inbuf, *out, *outbuf;
585 opj_image_comp_t *new_comps;
588 nr_samples = (size_t)(max * 3 * sizeof(unsigned char));
589 in = inbuf = (unsigned char*)malloc(nr_samples);
590 out = outbuf = (unsigned char*)malloc(nr_samples);
591 g = (int*)calloc((size_t)max, sizeof(int));
592 b = (int*)calloc((size_t)max, sizeof(int));
594 if(inbuf == NULL || outbuf == NULL || g == NULL || b == NULL) goto fails2;
596 new_comps = (opj_image_comp_t*)realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
598 if(new_comps == NULL) goto fails2;
600 image->comps = new_comps;
602 if(image->numcomps == 2)
603 image->comps[3] = image->comps[1];
605 image->comps[1] = image->comps[0];
606 image->comps[2] = image->comps[0];
608 image->comps[1].data = g;
609 image->comps[2].data = b;
611 image->numcomps += 2;
613 r = image->comps[0].data;
615 for(i = 0U; i < max; ++i)
617 *in++ = (unsigned char)*r++;
619 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
621 r = image->comps[0].data;
622 g = image->comps[1].data;
623 b = image->comps[2].data;
625 for(i = 0U; i < max; ++i)
627 *r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
640 unsigned short *in, *inbuf, *out, *outbuf;
641 opj_image_comp_t *new_comps;
644 nr_samples = (size_t)(max * 3U * sizeof(unsigned short));
645 in = inbuf = (unsigned short*)malloc(nr_samples);
646 out = outbuf = (unsigned short*)malloc(nr_samples);
647 g = (int*)calloc((size_t)max, sizeof(int));
648 b = (int*)calloc((size_t)max, sizeof(int));
650 if(inbuf == NULL || outbuf == NULL || g == NULL || b == NULL) goto fails3;
652 new_comps = (opj_image_comp_t*)realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
654 if(new_comps == NULL) goto fails3;
656 image->comps = new_comps;
658 if(image->numcomps == 2)
659 image->comps[3] = image->comps[1];
661 image->comps[1] = image->comps[0];
662 image->comps[2] = image->comps[0];
664 image->comps[1].data = g;
665 image->comps[2].data = b;
667 image->numcomps += 2;
669 r = image->comps[0].data;
671 for(i = 0U; i < max; ++i)
673 *in++ = (unsigned short)*r++;
675 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
677 r = image->comps[0].data;
678 g = image->comps[1].data;
679 b = image->comps[2].data;
681 for(i = 0; i < max; ++i)
683 *r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
694 }/* if(image->numcomps > 2) */
696 cmsDeleteTransform(transform);
698 #ifdef OPJ_HAVE_LIBLCMS1
699 cmsCloseProfile(in_prof);
700 cmsCloseProfile(out_prof);
704 image->color_space = new_space;
706 }/* color_apply_icc_profile() */
708 void color_cielab_to_rgb(opj_image_t *image)
711 int enumcs, numcomps;
712 OPJ_COLOR_SPACE new_space;
714 numcomps = (int)image->numcomps;
718 fprintf(stderr,"%s:%d:\n\tnumcomps %d not handled. Quitting.\n",
719 __FILE__,__LINE__,numcomps);
723 row = (int*)image->icc_profile_buf;
726 if(enumcs == 14) /* CIELab */
728 int *L, *a, *b, *red, *green, *blue;
729 int *src0, *src1, *src2, *dst0, *dst1, *dst2;
730 double rl, ol, ra, oa, rb, ob, prec0, prec1, prec2;
731 double minL, maxL, mina, maxa, minb, maxb;
732 unsigned int default_type;
735 cmsHTRANSFORM transform;
736 cmsUInt16Number RGB[3];
739 in = cmsCreateLab4Profile(NULL);
743 out = cmsCreate_sRGBProfile();
748 transform = cmsCreateTransform(in, TYPE_Lab_DBL, out, TYPE_RGB_16, INTENT_PERCEPTUAL, 0);
750 #ifdef OPJ_HAVE_LIBLCMS2
752 cmsCloseProfile(out);
754 if(transform == NULL)
756 #ifdef OPJ_HAVE_LIBLCMS1
758 cmsCloseProfile(out);
762 new_space = OPJ_CLRSPC_SRGB;
764 prec0 = (double)image->comps[0].prec;
765 prec1 = (double)image->comps[1].prec;
766 prec2 = (double)image->comps[2].prec;
768 default_type = (unsigned int)row[1];
770 if(default_type == 0x44454600)/* DEF : default */
772 rl = 100; ra = 170; rb = 200;
774 oa = pow(2, prec1 - 1);
775 ob = pow(2, prec2 - 2) + pow(2, prec2 - 3);
779 rl = row[2]; ra = row[4]; rb = row[6];
780 ol = row[3]; oa = row[5]; ob = row[7];
783 L = src0 = image->comps[0].data;
784 a = src1 = image->comps[1].data;
785 b = src2 = image->comps[2].data;
787 max = image->comps[0].w * image->comps[0].h;
789 red = dst0 = (int*)malloc(max * sizeof(int));
790 green = dst1 = (int*)malloc(max * sizeof(int));
791 blue = dst2 = (int*)malloc(max * sizeof(int));
793 if(red == NULL || green == NULL || blue == NULL) goto fails;
795 minL = -(rl * ol)/(pow(2, prec0)-1);
798 mina = -(ra * oa)/(pow(2, prec1)-1);
801 minb = -(rb * ob)/(pow(2, prec2)-1);
804 for(i = 0; i < max; ++i)
806 Lab.L = minL + (double)(*L) * (maxL - minL)/(pow(2, prec0)-1); ++L;
807 Lab.a = mina + (double)(*a) * (maxa - mina)/(pow(2, prec1)-1); ++a;
808 Lab.b = minb + (double)(*b) * (maxb - minb)/(pow(2, prec2)-1); ++b;
810 cmsDoTransform(transform, &Lab, RGB, 1);
816 cmsDeleteTransform(transform);
817 #ifdef OPJ_HAVE_LIBLCMS1
819 cmsCloseProfile(out);
821 free(src0); image->comps[0].data = dst0;
822 free(src1); image->comps[1].data = dst1;
823 free(src2); image->comps[2].data = dst2;
825 image->color_space = new_space;
826 image->comps[0].prec = 16;
827 image->comps[1].prec = 16;
828 image->comps[2].prec = 16;
833 cmsDeleteTransform(transform);
834 #ifdef OPJ_HAVE_LIBLCMS1
836 cmsCloseProfile(out);
839 if(green) free(green);
844 fprintf(stderr,"%s:%d:\n\tenumCS %d not handled. Ignoring.\n", __FILE__,__LINE__, enumcs);
845 }/* color_cielab_to_rgb() */
847 #endif /* OPJ_HAVE_LIBLCMS2 || OPJ_HAVE_LIBLCMS1 */
849 void color_cmyk_to_rgb(opj_image_t *image)
852 float sC, sM, sY, sK;
853 unsigned int w, h, max, i;
855 w = image->comps[0].w;
856 h = image->comps[0].h;
858 if(image->numcomps < 4) return;
862 sC = 1.0F / (float)((1 << image->comps[0].prec) - 1);
863 sM = 1.0F / (float)((1 << image->comps[1].prec) - 1);
864 sY = 1.0F / (float)((1 << image->comps[2].prec) - 1);
865 sK = 1.0F / (float)((1 << image->comps[3].prec) - 1);
867 for(i = 0; i < max; ++i)
869 /* CMYK values from 0 to 1 */
870 C = (float)(image->comps[0].data[i]) * sC;
871 M = (float)(image->comps[1].data[i]) * sM;
872 Y = (float)(image->comps[2].data[i]) * sY;
873 K = (float)(image->comps[3].data[i]) * sK;
875 /* Invert all CMYK values */
881 /* CMYK -> RGB : RGB results from 0 to 255 */
882 image->comps[0].data[i] = (int)(255.0F * C * K); /* R */
883 image->comps[1].data[i] = (int)(255.0F * M * K); /* G */
884 image->comps[2].data[i] = (int)(255.0F * Y * K); /* B */
887 free(image->comps[3].data); image->comps[3].data = NULL;
888 image->comps[0].prec = 8;
889 image->comps[1].prec = 8;
890 image->comps[2].prec = 8;
891 image->numcomps -= 1;
892 image->color_space = OPJ_CLRSPC_SRGB;
894 for (i = 3; i < image->numcomps; ++i) {
895 memcpy(&(image->comps[i]), &(image->comps[i+1]), sizeof(image->comps[i]));
898 }/* color_cmyk_to_rgb() */
901 * This code has been adopted from sjpx_openjpeg.c of ghostscript
903 void color_esycc_to_rgb(opj_image_t *image)
905 int y, cb, cr, sign1, sign2, val;
906 unsigned int w, h, max, i;
907 int flip_value = (1 << (image->comps[0].prec-1));
908 int max_value = (1 << image->comps[0].prec) - 1;
911 (image->numcomps < 3)
912 || (image->comps[0].dx != image->comps[1].dx) || (image->comps[0].dx != image->comps[2].dx)
913 || (image->comps[0].dy != image->comps[1].dy) || (image->comps[0].dy != image->comps[2].dy)
915 fprintf(stderr,"%s:%d:color_esycc_to_rgb\n\tCAN NOT CONVERT\n", __FILE__,__LINE__);
919 w = image->comps[0].w;
920 h = image->comps[0].h;
922 sign1 = (int)image->comps[1].sgnd;
923 sign2 = (int)image->comps[2].sgnd;
927 for(i = 0; i < max; ++i)
930 y = image->comps[0].data[i]; cb = image->comps[1].data[i]; cr = image->comps[2].data[i];
932 if( !sign1) cb -= flip_value;
933 if( !sign2) cr -= flip_value;
936 ((float)y - (float)0.0000368 * (float)cb
937 + (float)1.40199 * (float)cr + (float)0.5);
939 if(val > max_value) val = max_value; else if(val < 0) val = 0;
940 image->comps[0].data[i] = val;
943 ((float)1.0003 * (float)y - (float)0.344125 * (float)cb
944 - (float)0.7141128 * (float)cr + (float)0.5);
946 if(val > max_value) val = max_value; else if(val < 0) val = 0;
947 image->comps[1].data[i] = val;
950 ((float)0.999823 * (float)y + (float)1.77204 * (float)cb
951 - (float)0.000008 *(float)cr + (float)0.5);
953 if(val > max_value) val = max_value; else if(val < 0) val = 0;
954 image->comps[2].data[i] = val;
956 image->color_space = OPJ_CLRSPC_SRGB;
958 }/* color_esycc_to_rgb() */