1 /*
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.
6  *
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.
15  *
16  * Redistribution and use in source and binary forms, with or without
17  * modification, are permitted provided that the following conditions
18  * are met:
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.
24  *
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.
36  */
37 
38 #include <stdio.h>
39 #include <string.h>
40 #include <stdlib.h>
41 #include <math.h>
42 #include <assert.h>
43 
44 #include "openjpeg-2.4/openjpeg.h"
45 #include "color.h"
46 
47 
48 /*--------------------------------------------------------
49 Matrix for sYCC, Amendment 1 to IEC 61966-2-1
50 
51 Y :   0.299   0.587    0.114   :R
52 Cb:  -0.1687 -0.3312   0.5     :G
53 Cr:   0.5    -0.4187  -0.0812  :B
54 
55 Inverse:
56 
57 R: 1        -3.68213e-05    1.40199      :Y
58 G: 1.00003  -0.344125      -0.714128     :Cb - 2^(prec - 1)
59 B: 0.999823  1.77204       -8.04142e-06  :Cr - 2^(prec - 1)
60 
61 -----------------------------------------------------------*/
sycc_to_rgb(int offset,int upb,int y,int cb,int cr,int * out_r,int * out_g,int * out_b)62 static void sycc_to_rgb(int offset, int upb, int y, int cb, int cr,
63 	int *out_r, int *out_g, int *out_b)
64 {
65 	int r, g, b;
66 
67 	cb -= offset; cr -= offset;
68 	r = y + (int)(1.402 * (float)cr);
69 	if(r < 0) r = 0; else if(r > upb) r = upb; *out_r = r;
70 
71 	g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
72 	if(g < 0) g = 0; else if(g > upb) g = upb; *out_g = g;
73 
74 	b = y + (int)(1.772 * (float)cb);
75 	if(b < 0) b = 0; else if(b > upb) b = upb; *out_b = b;
76 }
77 
sycc444_to_rgb(opj_image_t * img)78 static void sycc444_to_rgb(opj_image_t *img)
79 {
80 	int *d0, *d1, *d2, *r, *g, *b;
81 	const int *y, *cb, *cr;
82 	unsigned int maxw, maxh, max, i;
83 	int offset, upb;
84 
85 	upb = (int)img->comps[0].prec;
86 	offset = 1<<(upb - 1); upb = (1<<upb)-1;
87 
88 	maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
89 	max = maxw * maxh;
90 
91 	y = img->comps[0].data;
92 	cb = img->comps[1].data;
93 	cr = img->comps[2].data;
94 
95 	d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
96 	d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
97 	d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
98 
99 	for(i = 0U; i < max; ++i)
100 	{
101 		sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
102 		++y; ++cb; ++cr; ++r; ++g; ++b;
103 	}
104 	free(img->comps[0].data); img->comps[0].data = d0;
105 	free(img->comps[1].data); img->comps[1].data = d1;
106 	free(img->comps[2].data); img->comps[2].data = d2;
107 
108 }/* sycc444_to_rgb() */
109 
sycc422_to_rgb(opj_image_t * img)110 static void sycc422_to_rgb(opj_image_t *img)
111 {
112 	int *d0, *d1, *d2, *r, *g, *b;
113 	const int *y, *cb, *cr;
114 	unsigned int maxw, maxh, max;
115 	int offset, upb;
116 	unsigned int i, j;
117 
118 	upb = (int)img->comps[0].prec;
119 	offset = 1<<(upb - 1); upb = (1<<upb)-1;
120 
121 	maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
122 	max = maxw * maxh;
123 
124 	y = img->comps[0].data;
125 	cb = img->comps[1].data;
126 	cr = img->comps[2].data;
127 
128 	d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
129 	d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
130 	d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
131 
132 	for(i=0U; i < maxh; ++i)
133 	{
134 		for(j=0U; j < (maxw & ~(unsigned int)1U); j += 2U)
135 		{
136 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
137 			++y; ++r; ++g; ++b;
138 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
139 			++y; ++r; ++g; ++b; ++cb; ++cr;
140 		}
141 		if (j < maxw) {
142 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
143 			++y; ++r; ++g; ++b; ++cb; ++cr;
144 		}
145 	}
146 	free(img->comps[0].data); img->comps[0].data = d0;
147 	free(img->comps[1].data); img->comps[1].data = d1;
148 	free(img->comps[2].data); img->comps[2].data = d2;
149 
150 #if defined(USE_JPWL) || defined(USE_MJ2)
151 	img->comps[1].w = maxw; img->comps[1].h = maxh;
152 	img->comps[2].w = maxw; img->comps[2].h = maxh;
153 #else
154 	img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh;
155 	img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh;
156 #endif
157 	img->comps[1].dx = img->comps[0].dx;
158 	img->comps[2].dx = img->comps[0].dx;
159 	img->comps[1].dy = img->comps[0].dy;
160 	img->comps[2].dy = img->comps[0].dy;
161 
162 }/* sycc422_to_rgb() */
163 
sycc420_to_rgb(opj_image_t * img)164 static void sycc420_to_rgb(opj_image_t *img)
165 {
166 	int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
167 	const int *y, *cb, *cr, *ny;
168 	unsigned int maxw, maxh, max;
169 	int offset, upb;
170 	unsigned int i, j;
171 
172 	upb = (int)img->comps[0].prec;
173 	offset = 1<<(upb - 1); upb = (1<<upb)-1;
174 
175 	maxw = (unsigned int)img->comps[0].w; maxh = (unsigned int)img->comps[0].h;
176 	max = maxw * maxh;
177 
178 	y = img->comps[0].data;
179 	cb = img->comps[1].data;
180 	cr = img->comps[2].data;
181 
182 	d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
183 	d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
184 	d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
185 
186 	for(i=0U; i < (maxh & ~(unsigned int)1U); i += 2U)
187 	{
188 		ny = y + maxw;
189 		nr = r + maxw; ng = g + maxw; nb = b + maxw;
190 
191 		for(j=0; j < (maxw & ~(unsigned int)1U); j += 2U)
192 		{
193 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
194 			++y; ++r; ++g; ++b;
195 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
196 			++y; ++r; ++g; ++b;
197 
198 			sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
199 			++ny; ++nr; ++ng; ++nb;
200 			sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
201 			++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
202 		}
203 		if(j < maxw)
204 		{
205 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
206 			++y; ++r; ++g; ++b;
207 
208 			sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
209 			++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
210 		}
211 		y += maxw; r += maxw; g += maxw; b += maxw;
212 	}
213 	if(i < maxh)
214 	{
215 		for(j=0U; j < (maxw & ~(unsigned int)1U); j += 2U)
216 		{
217 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
218 
219 			++y; ++r; ++g; ++b;
220 
221 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
222 
223 			++y; ++r; ++g; ++b; ++cb; ++cr;
224 		}
225 		if(j < maxw)
226 		{
227 			sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
228 		}
229 	}
230 
231 	free(img->comps[0].data); img->comps[0].data = d0;
232 	free(img->comps[1].data); img->comps[1].data = d1;
233 	free(img->comps[2].data); img->comps[2].data = d2;
234 
235 #if defined(USE_JPWL) || defined(USE_MJ2)
236 	img->comps[1].w = maxw; img->comps[1].h = maxh;
237 	img->comps[2].w = maxw; img->comps[2].h = maxh;
238 #else
239 	img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh;
240 	img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh;
241 #endif
242 	img->comps[1].dx = img->comps[0].dx;
243 	img->comps[2].dx = img->comps[0].dx;
244 	img->comps[1].dy = img->comps[0].dy;
245 	img->comps[2].dy = img->comps[0].dy;
246 
247 }/* sycc420_to_rgb() */
248 
color_sycc_to_rgb(opj_image_t * img)249 void color_sycc_to_rgb(opj_image_t *img)
250 {
251 	if(img->numcomps < 3)
252 	{
253 		img->color_space = OPJ_CLRSPC_GRAY;
254 		return;
255 	}
256 
257 	if((img->comps[0].dx == 1)
258 	&& (img->comps[1].dx == 2)
259 	&& (img->comps[2].dx == 2)
260 	&& (img->comps[0].dy == 1)
261 	&& (img->comps[1].dy == 2)
262 	&& (img->comps[2].dy == 2))/* horizontal and vertical sub-sample */
263   {
264 		sycc420_to_rgb(img);
265   }
266 	else
267 	if((img->comps[0].dx == 1)
268 	&& (img->comps[1].dx == 2)
269 	&& (img->comps[2].dx == 2)
270 	&& (img->comps[0].dy == 1)
271 	&& (img->comps[1].dy == 1)
272 	&& (img->comps[2].dy == 1))/* horizontal sub-sample only */
273   {
274 		sycc422_to_rgb(img);
275   }
276 	else
277 	if((img->comps[0].dx == 1)
278 	&& (img->comps[1].dx == 1)
279 	&& (img->comps[2].dx == 1)
280 	&& (img->comps[0].dy == 1)
281 	&& (img->comps[1].dy == 1)
282 	&& (img->comps[2].dy == 1))/* no sub-sample */
283   {
284 		sycc444_to_rgb(img);
285   }
286 	else
287   {
288 		fprintf(stderr,"%s:%d:color_sycc_to_rgb\n\tCAN NOT CONVERT\n", __FILE__,__LINE__);
289 		return;
290   }
291 	img->color_space = OPJ_CLRSPC_SRGB;
292 
293 }/* color_sycc_to_rgb() */
294 
295 #if defined(OPJ_HAVE_LIBLCMS2) || defined(OPJ_HAVE_LIBLCMS1)
296 
297 #ifdef OPJ_HAVE_LIBLCMS1
298 /* Bob Friesenhahn proposed:*/
299 #define cmsSigXYZData   icSigXYZData
300 #define cmsSigLabData   icSigLabData
301 #define cmsSigCmykData  icSigCmykData
302 #define cmsSigYCbCrData icSigYCbCrData
303 #define cmsSigLuvData   icSigLuvData
304 #define cmsSigGrayData  icSigGrayData
305 #define cmsSigRgbData   icSigRgbData
306 #define cmsUInt32Number DWORD
307 
308 #define cmsColorSpaceSignature icColorSpaceSignature
309 #define cmsGetHeaderRenderingIntent cmsTakeRenderingIntent
310 
311 #endif /* OPJ_HAVE_LIBLCMS1 */
312 
313 /*#define DEBUG_PROFILE*/
color_apply_icc_profile(opj_image_t * image)314 void color_apply_icc_profile(opj_image_t *image)
315 {
316 	cmsHPROFILE in_prof, out_prof;
317 	cmsHTRANSFORM transform;
318 	cmsColorSpaceSignature in_space, out_space;
319 	cmsUInt32Number intent, in_type, out_type, nr_samples;
320 	int *r, *g, *b;
321 	int prec, i, max, max_w, max_h;
322 	OPJ_COLOR_SPACE oldspace;
323 
324 	in_prof =
325 	 cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
326 #ifdef DEBUG_PROFILE
327   FILE *icm = fopen("debug.icm","wb");
328   fwrite( image->icc_profile_buf,1, image->icc_profile_len,icm);
329   fclose(icm);
330 #endif
331 
332 	if(in_prof == NULL) return;
333 
334 	in_space = cmsGetPCS(in_prof);
335 	out_space = cmsGetColorSpace(in_prof);
336 	intent = cmsGetHeaderRenderingIntent(in_prof);
337 
338 
339 	max_w = (int)image->comps[0].w;
340   max_h = (int)image->comps[0].h;
341 	prec = (int)image->comps[0].prec;
342 	oldspace = image->color_space;
343 
344 	if(out_space == cmsSigRgbData) /* enumCS 16 */
345    {
346 	if( prec <= 8 )
347   {
348 	in_type = TYPE_RGB_8;
349 	out_type = TYPE_RGB_8;
350   }
351 	else
352   {
353 	in_type = TYPE_RGB_16;
354 	out_type = TYPE_RGB_16;
355   }
356 	out_prof = cmsCreate_sRGBProfile();
357 	image->color_space = OPJ_CLRSPC_SRGB;
358    }
359 	else
360 	if(out_space == cmsSigGrayData) /* enumCS 17 */
361    {
362 	in_type = TYPE_GRAY_8;
363 	out_type = TYPE_RGB_8;
364 	out_prof = cmsCreate_sRGBProfile();
365 	image->color_space = OPJ_CLRSPC_SRGB;
366    }
367 	else
368 	if(out_space == cmsSigYCbCrData) /* enumCS 18 */
369    {
370 	in_type = TYPE_YCbCr_16;
371 	out_type = TYPE_RGB_16;
372 	out_prof = cmsCreate_sRGBProfile();
373 	image->color_space = OPJ_CLRSPC_SRGB;
374    }
375 	else
376    {
377 #ifdef DEBUG_PROFILE
378 fprintf(stderr,"%s:%d: color_apply_icc_profile\n\tICC Profile has unknown "
379 "output colorspace(%#x)(%c%c%c%c)\n\tICC Profile ignored.\n",
380 __FILE__,__LINE__,out_space,
381 	(out_space>>24) & 0xff,(out_space>>16) & 0xff,
382 	(out_space>>8) & 0xff, out_space & 0xff);
383 #endif
384 	return;
385    }
386 
387 #ifdef DEBUG_PROFILE
388 fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tchannels(%d) prec(%d) w(%d) h(%d)"
389 "\n\tprofile: in(%p) out(%p)\n",__FILE__,__LINE__,image->numcomps,prec,
390 	max_w,max_h, (void*)in_prof,(void*)out_prof);
391 
392 fprintf(stderr,"\trender_intent (%u)\n\t"
393 "color_space: in(%#x)(%c%c%c%c)   out:(%#x)(%c%c%c%c)\n\t"
394 "       type: in(%u)              out:(%u)\n",
395 	intent,
396 	in_space,
397 	(in_space>>24) & 0xff,(in_space>>16) & 0xff,
398 	(in_space>>8) & 0xff, in_space & 0xff,
399 
400 	out_space,
401 	(out_space>>24) & 0xff,(out_space>>16) & 0xff,
402 	(out_space>>8) & 0xff, out_space & 0xff,
403 
404 	in_type,out_type
405  );
406 #else
407   (void)prec;
408   (void)in_space;
409 #endif /* DEBUG_PROFILE */
410 
411 	transform = cmsCreateTransform(in_prof, in_type,
412 	 out_prof, out_type, intent, 0);
413 
414 #ifdef OPJ_HAVE_LIBLCMS2
415 /* Possible for: LCMS_VERSION >= 2000 :*/
416 	cmsCloseProfile(in_prof);
417 	cmsCloseProfile(out_prof);
418 #endif
419 
420 	if(transform == NULL)
421    {
422 #ifdef DEBUG_PROFILE
423 fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. "
424 "ICC Profile ignored.\n",__FILE__,__LINE__);
425 #endif
426 	image->color_space = oldspace;
427 #ifdef OPJ_HAVE_LIBLCMS1
428 	cmsCloseProfile(in_prof);
429 	cmsCloseProfile(out_prof);
430 #endif
431 	return;
432    }
433 
434 	if(image->numcomps > 2)/* RGB, RGBA */
435    {
436 	if( prec <= 8 )
437   {
438 	unsigned char *inbuf, *outbuf, *in, *out;
439 	max = max_w * max_h;
440 	nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char);
441 	in = inbuf = (unsigned char*)malloc(nr_samples);
442 	out = outbuf = (unsigned char*)malloc(nr_samples);
443 
444 	r = image->comps[0].data;
445 	g = image->comps[1].data;
446 	b = image->comps[2].data;
447 
448 	for(i = 0; i < max; ++i)
449  {
450 	*in++ = (unsigned char)*r++;
451 	*in++ = (unsigned char)*g++;
452 	*in++ = (unsigned char)*b++;
453  }
454 
455 	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
456 
457 	r = image->comps[0].data;
458 	g = image->comps[1].data;
459 	b = image->comps[2].data;
460 
461 	for(i = 0; i < max; ++i)
462  {
463 	*r++ = (int)*out++;
464 	*g++ = (int)*out++;
465 	*b++ = (int)*out++;
466  }
467 	free(inbuf); free(outbuf);
468   }
469 	else
470   {
471 	unsigned short *inbuf, *outbuf, *in, *out;
472 	max = max_w * max_h;
473 	nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short);
474 	in = inbuf = (unsigned short*)malloc(nr_samples);
475 	out = outbuf = (unsigned short*)malloc(nr_samples);
476 
477 	r = image->comps[0].data;
478 	g = image->comps[1].data;
479 	b = image->comps[2].data;
480 
481 	for(i = 0; i < max; ++i)
482  {
483 	*in++ = (unsigned short)*r++;
484 	*in++ = (unsigned short)*g++;
485 	*in++ = (unsigned short)*b++;
486  }
487 
488 	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
489 
490 	r = image->comps[0].data;
491 	g = image->comps[1].data;
492 	b = image->comps[2].data;
493 
494 	for(i = 0; i < max; ++i)
495  {
496 	*r++ = (int)*out++;
497 	*g++ = (int)*out++;
498 	*b++ = (int)*out++;
499  }
500 	free(inbuf); free(outbuf);
501   }
502    }
503 	else /* GRAY, GRAYA */
504    {
505 	unsigned char *in, *inbuf, *out, *outbuf;
506 	max = max_w * max_h;
507 	nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
508 	in = inbuf = (unsigned char*)malloc(nr_samples);
509 	out = outbuf = (unsigned char*)malloc(nr_samples);
510 
511 	image->comps = (opj_image_comp_t*)
512 	 realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
513 
514 	if(image->numcomps == 2)
515 	 image->comps[3] = image->comps[1];
516 
517 	image->comps[1] = image->comps[0];
518 	image->comps[2] = image->comps[0];
519 
520 	image->comps[1].data = (int*)calloc((size_t)max, sizeof(int));
521 	image->comps[2].data = (int*)calloc((size_t)max, sizeof(int));
522 
523 	image->numcomps += 2;
524 
525 	r = image->comps[0].data;
526 
527 	for(i = 0; i < max; ++i)
528   {
529 	*in++ = (unsigned char)*r++;
530   }
531 	cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
532 
533 	r = image->comps[0].data;
534 	g = image->comps[1].data;
535 	b = image->comps[2].data;
536 
537 	for(i = 0; i < max; ++i)
538   {
539 	*r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
540   }
541 	free(inbuf); free(outbuf);
542 
543    }/* if(image->numcomps */
544 
545 	cmsDeleteTransform(transform);
546 
547 #ifdef OPJ_HAVE_LIBLCMS1
548 	cmsCloseProfile(in_prof);
549 	cmsCloseProfile(out_prof);
550 #endif
551 }/* color_apply_icc_profile() */
552 
color_cielab_to_rgb(opj_image_t * image)553 void color_cielab_to_rgb(opj_image_t *image)
554 {
555 	int *row;
556 	int enumcs, numcomps;
557 
558 	image->color_space = OPJ_CLRSPC_SRGB;
559 
560 	numcomps = (int)image->numcomps;
561 
562 	if(numcomps != 3)
563 	{
564 		fprintf(stderr,"%s:%d:\n\tnumcomps %d not handled. Quitting.\n",
565 						__FILE__,__LINE__,numcomps);
566 		return;
567 	}
568 
569 	row = (int*)image->icc_profile_buf;
570 	enumcs = row[0];
571 
572 	if(enumcs == 14) /* CIELab */
573 	{
574 		int *L, *a, *b, *red, *green, *blue;
575 		int *src0, *src1, *src2, *dst0, *dst1, *dst2;
576 		double rl, ol, ra, oa, rb, ob, prec0, prec1, prec2;
577 		double minL, maxL, mina, maxa, minb, maxb;
578 		unsigned int default_type;
579 		unsigned int i, max;
580 		cmsHPROFILE in, out;
581 		cmsHTRANSFORM transform;
582 		cmsUInt16Number RGB[3];
583 		cmsCIELab Lab;
584 
585 		in = cmsCreateLab4Profile(NULL);
586 		out = cmsCreate_sRGBProfile();
587 
588 		transform = cmsCreateTransform(in, TYPE_Lab_DBL, out, TYPE_RGB_16, INTENT_PERCEPTUAL, 0);
589 
590 #ifdef OPJ_HAVE_LIBLCMS2
591 		cmsCloseProfile(in);
592 		cmsCloseProfile(out);
593 #endif
594 		if(transform == NULL)
595 		{
596 #ifdef OPJ_HAVE_LIBLCMS1
597 			cmsCloseProfile(in);
598 			cmsCloseProfile(out);
599 #endif
600 			return;
601 		}
602 		prec0 = (double)image->comps[0].prec;
603 		prec1 = (double)image->comps[1].prec;
604 		prec2 = (double)image->comps[2].prec;
605 
606 		default_type = (unsigned int)row[1];
607 
608 		if(default_type == 0x44454600)/* DEF : default */
609 		{
610 			rl = 100; ra = 170; rb = 200;
611 			ol = 0;
612 			oa = pow(2, prec1 - 1);
613 			ob = pow(2, prec2 - 2) +  pow(2, prec2 - 3);
614 		}
615 		else
616 		{
617 			rl = row[2]; ra = row[4]; rb = row[6];
618 			ol = row[3]; oa = row[5]; ob = row[7];
619 		}
620 
621 		L = src0 = image->comps[0].data;
622 		a = src1 = image->comps[1].data;
623 		b = src2 = image->comps[2].data;
624 
625 		max = image->comps[0].w * image->comps[0].h;
626 
627 		red = dst0 = (int*)malloc(max * sizeof(int));
628 		green = dst1 = (int*)malloc(max * sizeof(int));
629 		blue = dst2 = (int*)malloc(max * sizeof(int));
630 
631 		minL = -(rl * ol)/(pow(2, prec0)-1);
632 		maxL = minL + rl;
633 
634 		mina = -(ra * oa)/(pow(2, prec1)-1);
635 		maxa = mina + ra;
636 
637 		minb = -(rb * ob)/(pow(2, prec2)-1);
638 		maxb = minb + rb;
639 
640 		for(i = 0; i < max; ++i)
641 		{
642 			Lab.L = minL + (double)(*L) * (maxL - minL)/(pow(2, prec0)-1); ++L;
643 			Lab.a = mina + (double)(*a) * (maxa - mina)/(pow(2, prec1)-1); ++a;
644 			Lab.b = minb + (double)(*b) * (maxb - minb)/(pow(2, prec2)-1); ++b;
645 
646 			cmsDoTransform(transform, &Lab, RGB, 1);
647 
648 			*red++ = RGB[0];
649 			*green++ = RGB[1];
650 			*blue++ = RGB[2];
651 		}
652 		cmsDeleteTransform(transform);
653 #ifdef OPJ_HAVE_LIBLCMS1
654 		cmsCloseProfile(in);
655 		cmsCloseProfile(out);
656 #endif
657 		free(src0); image->comps[0].data = dst0;
658 		free(src1); image->comps[1].data = dst1;
659 		free(src2); image->comps[2].data = dst2;
660 
661 		image->color_space = OPJ_CLRSPC_SRGB;
662 		image->comps[0].prec = 16;
663 		image->comps[1].prec = 16;
664 		image->comps[2].prec = 16;
665 
666 		return;
667 	}
668 
669 	fprintf(stderr,"%s:%d:\n\tenumCS %d not handled. Ignoring.\n", __FILE__,__LINE__, enumcs);
670 }/* color_apply_conversion() */
671 
672 #endif /* OPJ_HAVE_LIBLCMS2 || OPJ_HAVE_LIBLCMS1 */
673 
color_cmyk_to_rgb(opj_image_t * image)674 void color_cmyk_to_rgb(opj_image_t *image)
675 {
676 	float C, M, Y, K;
677 	float sC, sM, sY, sK;
678 	unsigned int w, h, max, i;
679 
680 	w = image->comps[0].w;
681 	h = image->comps[0].h;
682 
683 	if(image->numcomps < 4) return;
684 
685 	max = w * h;
686 
687 	sC = 1.0F / (float)((1 << image->comps[0].prec) - 1);
688 	sM = 1.0F / (float)((1 << image->comps[1].prec) - 1);
689 	sY = 1.0F / (float)((1 << image->comps[2].prec) - 1);
690 	sK = 1.0F / (float)((1 << image->comps[3].prec) - 1);
691 
692 	for(i = 0; i < max; ++i)
693 	{
694 		/* CMYK values from 0 to 1 */
695 		C = (float)(image->comps[0].data[i]) * sC;
696 		M = (float)(image->comps[1].data[i]) * sM;
697 		Y = (float)(image->comps[2].data[i]) * sY;
698 		K = (float)(image->comps[3].data[i]) * sK;
699 
700 		/* Invert all CMYK values */
701 		C = 1.0F - C;
702 		M = 1.0F - M;
703 		Y = 1.0F - Y;
704 		K = 1.0F - K;
705 
706 		/* CMYK -> RGB : RGB results from 0 to 255 */
707 		image->comps[0].data[i] = (int)(255.0F * C * K); /* R */
708 		image->comps[1].data[i] = (int)(255.0F * M * K); /* G */
709 		image->comps[2].data[i] = (int)(255.0F * Y * K); /* B */
710 	}
711 
712 	free(image->comps[3].data); image->comps[3].data = NULL;
713 	image->comps[0].prec = 8;
714 	image->comps[1].prec = 8;
715 	image->comps[2].prec = 8;
716 	image->numcomps -= 1;
717 	image->color_space = OPJ_CLRSPC_SRGB;
718 
719 	for (i = 3; i < image->numcomps; ++i) {
720 		memcpy(&(image->comps[i]), &(image->comps[i+1]), sizeof(image->comps[i]));
721 	}
722 
723 }/* color_cmyk_to_rgb() */
724 
725 /*
726  * This code has been adopted from sjpx_openjpeg.c of ghostscript
727  */
color_esycc_to_rgb(opj_image_t * image)728 void color_esycc_to_rgb(opj_image_t *image)
729 {
730 	int y, cb, cr, sign1, sign2, val;
731 	unsigned int w, h, max, i;
732 	int flip_value = (1 << (image->comps[0].prec-1));
733 	int max_value = (1 << image->comps[0].prec) - 1;
734 
735 	if(image->numcomps < 3) return;
736 
737 	w = image->comps[0].w;
738 	h = image->comps[0].h;
739 
740 	sign1 = (int)image->comps[1].sgnd;
741 	sign2 = (int)image->comps[2].sgnd;
742 
743 	max = w * h;
744 
745 	for(i = 0; i < max; ++i)
746 	{
747 
748 		y = image->comps[0].data[i]; cb = image->comps[1].data[i]; cr = image->comps[2].data[i];
749 
750 		if( !sign1) cb -= flip_value;
751 		if( !sign2) cr -= flip_value;
752 
753 		val = (int)
754 		((float)y - (float)0.0000368 * (float)cb
755 		 + (float)1.40199 * (float)cr + (float)0.5);
756 
757 		if(val > max_value) val = max_value; else if(val < 0) val = 0;
758 		image->comps[0].data[i] = val;
759 
760 		val = (int)
761 		((float)1.0003 * (float)y - (float)0.344125 * (float)cb
762 		 - (float)0.7141128 * (float)cr + (float)0.5);
763 
764 		if(val > max_value) val = max_value; else if(val < 0) val = 0;
765 		image->comps[1].data[i] = val;
766 
767 		val = (int)
768 		((float)0.999823 * (float)y + (float)1.77204 * (float)cb
769 		 - (float)0.000008 *(float)cr + (float)0.5);
770 
771 		if(val > max_value) val = max_value; else if(val < 0) val = 0;
772 		image->comps[2].data[i] = val;
773 	}
774 	image->color_space = OPJ_CLRSPC_SRGB;
775 
776 }/* color_esycc_to_rgb() */
777