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