00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <math.h>
00042 #include <assert.h>
00043
00044 #include "Jpeg2000Color.h"
00045
00046 #ifdef OPJ_USE_LEGACY
00047 #define OPJ_CLRSPC_GRAY CLRSPC_GRAY
00048 #define OPJ_CLRSPC_SRGB CLRSPC_SRGB
00049 #endif
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 void sycc_to_rgb(int offset, int upb, int y, int cb, int cr,
00066 int *out_r, int *out_g, int *out_b)
00067 {
00068 int r, g, b;
00069
00070 cb -= offset; cr -= offset;
00071 r = y + (int)(1.402 * (float)cr);
00072 if(r < 0) r = 0; else if(r > upb) r = upb; *out_r = r;
00073
00074 g = y - (int)(0.344 * (float)cb + 0.714 * (float)cr);
00075 if(g < 0) g = 0; else if(g > upb) g = upb; *out_g = g;
00076
00077 b = y + (int)(1.772 * (float)cb);
00078 if(b < 0) b = 0; else if(b > upb) b = upb; *out_b = b;
00079 }
00080
00081 void sycc444_to_rgb(opj_image_t *img)
00082 {
00083 int *d0, *d1, *d2, *r, *g, *b;
00084 const int *y, *cb, *cr;
00085 int maxw, maxh, max, i, offset, upb;
00086
00087 i = (int)img->comps[0].prec;
00088 offset = 1<<(i - 1); upb = (1<<i)-1;
00089
00090 maxw = (int)img->comps[0].w; maxh = (int)img->comps[0].h;
00091 max = maxw * maxh;
00092
00093 y = img->comps[0].data;
00094 cb = img->comps[1].data;
00095 cr = img->comps[2].data;
00096
00097 d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
00098 d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
00099 d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
00100
00101 for(i = 0; i < max; ++i)
00102 {
00103 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
00104
00105 ++y; ++cb; ++cr; ++r; ++g; ++b;
00106 }
00107 free(img->comps[0].data); img->comps[0].data = d0;
00108 free(img->comps[1].data); img->comps[1].data = d1;
00109 free(img->comps[2].data); img->comps[2].data = d2;
00110
00111 }
00112
00113 void sycc422_to_rgb(opj_image_t *img)
00114 {
00115 int *d0, *d1, *d2, *r, *g, *b;
00116 const int *y, *cb, *cr;
00117 int maxw, maxh, max, offset, upb;
00118 int i, j;
00119
00120 i = (int)img->comps[0].prec;
00121 offset = 1<<(i - 1); upb = (1<<i)-1;
00122
00123 maxw = (int)img->comps[0].w; maxh = (int)img->comps[0].h;
00124 max = maxw * maxh;
00125
00126 y = img->comps[0].data;
00127 cb = img->comps[1].data;
00128 cr = img->comps[2].data;
00129
00130 d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
00131 d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
00132 d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
00133
00134 for(i=0; i < maxh; ++i)
00135 {
00136 for(j=0; j < maxw; j += 2)
00137 {
00138 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
00139
00140 ++y; ++r; ++g; ++b;
00141
00142 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
00143
00144 ++y; ++r; ++g; ++b; ++cb; ++cr;
00145 }
00146 }
00147 free(img->comps[0].data); img->comps[0].data = d0;
00148 free(img->comps[1].data); img->comps[1].data = d1;
00149 free(img->comps[2].data); img->comps[2].data = d2;
00150
00151 #if defined(USE_JPWL) || defined(USE_MJ2)
00152 img->comps[1].w = maxw; img->comps[1].h = maxh;
00153 img->comps[2].w = maxw; img->comps[2].h = maxh;
00154 #else
00155 img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh;
00156 img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh;
00157 #endif
00158 img->comps[1].dx = img->comps[0].dx;
00159 img->comps[2].dx = img->comps[0].dx;
00160 img->comps[1].dy = img->comps[0].dy;
00161 img->comps[2].dy = img->comps[0].dy;
00162
00163 }
00164
00165 void sycc420_to_rgb(opj_image_t *img)
00166 {
00167 int *d0, *d1, *d2, *r, *g, *b, *nr, *ng, *nb;
00168 const int *y, *cb, *cr, *ny;
00169 int maxw, maxh, max, offset, upb;
00170 int i, j;
00171
00172 i = (int)img->comps[0].prec;
00173 offset = 1<<(i - 1); upb = (1<<i)-1;
00174
00175 maxw = (int)img->comps[0].w; maxh = (int)img->comps[0].h;
00176 max = maxw * maxh;
00177
00178 y = img->comps[0].data;
00179 cb = img->comps[1].data;
00180 cr = img->comps[2].data;
00181
00182 d0 = r = (int*)malloc(sizeof(int) * (size_t)max);
00183 d1 = g = (int*)malloc(sizeof(int) * (size_t)max);
00184 d2 = b = (int*)malloc(sizeof(int) * (size_t)max);
00185
00186 for(i=0; i < maxh; i += 2)
00187 {
00188 ny = y + maxw;
00189 nr = r + maxw; ng = g + maxw; nb = b + maxw;
00190
00191 for(j=0; j < maxw; j += 2)
00192 {
00193 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
00194
00195 ++y; ++r; ++g; ++b;
00196
00197 sycc_to_rgb(offset, upb, *y, *cb, *cr, r, g, b);
00198
00199 ++y; ++r; ++g; ++b;
00200
00201 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
00202
00203 ++ny; ++nr; ++ng; ++nb;
00204
00205 sycc_to_rgb(offset, upb, *ny, *cb, *cr, nr, ng, nb);
00206
00207 ++ny; ++nr; ++ng; ++nb; ++cb; ++cr;
00208 }
00209 y += maxw; r += maxw; g += maxw; b += maxw;
00210 }
00211 free(img->comps[0].data); img->comps[0].data = d0;
00212 free(img->comps[1].data); img->comps[1].data = d1;
00213 free(img->comps[2].data); img->comps[2].data = d2;
00214
00215 #if defined(USE_JPWL) || defined(USE_MJ2)
00216 img->comps[1].w = maxw; img->comps[1].h = maxh;
00217 img->comps[2].w = maxw; img->comps[2].h = maxh;
00218 #else
00219 img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh;
00220 img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh;
00221 #endif
00222 img->comps[1].dx = img->comps[0].dx;
00223 img->comps[2].dx = img->comps[0].dx;
00224 img->comps[1].dy = img->comps[0].dy;
00225 img->comps[2].dy = img->comps[0].dy;
00226
00227 }
00228
00229 void color_sycc_to_rgb(opj_image_t *img)
00230 {
00231 if(img->numcomps < 3)
00232 {
00233 img->color_space = OPJ_CLRSPC_GRAY;
00234 return;
00235 }
00236
00237 if((img->comps[0].dx == 1)
00238 && (img->comps[1].dx == 2)
00239 && (img->comps[2].dx == 2)
00240 && (img->comps[0].dy == 1)
00241 && (img->comps[1].dy == 2)
00242 && (img->comps[2].dy == 2))
00243 {
00244 sycc420_to_rgb(img);
00245 }
00246 else {
00247 if((img->comps[0].dx == 1)
00248 && (img->comps[1].dx == 2)
00249 && (img->comps[2].dx == 2)
00250 && (img->comps[0].dy == 1)
00251 && (img->comps[1].dy == 1)
00252 && (img->comps[2].dy == 1))
00253 {
00254 sycc422_to_rgb(img);
00255 }
00256 else {
00257 if((img->comps[0].dx == 1)
00258 && (img->comps[1].dx == 1)
00259 && (img->comps[2].dx == 1)
00260 && (img->comps[0].dy == 1)
00261 && (img->comps[1].dy == 1)
00262 && (img->comps[2].dy == 1))
00263 {
00264 sycc444_to_rgb(img);
00265 }
00266 else
00267 {
00268 fprintf(stderr,"%s:%d:color_sycc_to_rgb\n\tCAN NOT CONVERT\n",
00269 __FILE__,__LINE__);
00270 return;
00271 }
00272 }
00273 }
00274 img->color_space = OPJ_CLRSPC_SRGB;
00275 }
00276
00277 #if defined(OPJ_HAVE_LIBLCMS2) || defined(OPJ_HAVE_LIBLCMS1)
00278 #ifdef OPJ_HAVE_LIBLCMS1
00279
00280 #define cmsSigXYZData icSigXYZData
00281 #define cmsSigLabData icSigLabData
00282 #define cmsSigCmykData icSigCmykData
00283 #define cmsSigYCbCrData icSigYCbCrData
00284 #define cmsSigLuvData icSigLuvData
00285 #define cmsSigGrayData icSigGrayData
00286 #define cmsSigRgbData icSigRgbData
00287 #define cmsUInt32Number DWORD
00288
00289 #define cmsColorSpaceSignature icColorSpaceSignature
00290 #define cmsGetHeaderRenderingIntent cmsTakeRenderingIntent
00291
00292 #endif
00293
00294 void color_apply_icc_profile(opj_image_t *image)
00295 {
00296 cmsHPROFILE in_prof, out_prof;
00297 cmsHTRANSFORM transform;
00298 cmsColorSpaceSignature in_space, out_space;
00299 cmsUInt32Number intent, in_type, out_type, nr_samples;
00300 int *r, *g, *b;
00301 int prec, i, max, max_w, max_h;
00302 OPJ_COLOR_SPACE oldspace;
00303
00304 in_prof =
00305 cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len);
00306
00307 if(in_prof == NULL) return;
00308
00309 in_space = cmsGetPCS(in_prof);
00310 out_space = cmsGetColorSpace(in_prof);
00311 intent = cmsGetHeaderRenderingIntent(in_prof);
00312
00313
00314 max_w = (int)image->comps[0].w;
00315 max_h = (int)image->comps[0].h;
00316 prec = (int)image->comps[0].prec;
00317 oldspace = image->color_space;
00318
00319 if(out_space == cmsSigRgbData)
00320 {
00321 if( prec <= 8 )
00322 {
00323 in_type = TYPE_RGB_8;
00324 out_type = TYPE_RGB_8;
00325 }
00326 else
00327 {
00328 in_type = TYPE_RGB_16;
00329 out_type = TYPE_RGB_16;
00330 }
00331 out_prof = cmsCreate_sRGBProfile();
00332 image->color_space = OPJ_CLRSPC_SRGB;
00333 }
00334 else
00335 if(out_space == cmsSigGrayData)
00336 {
00337 in_type = TYPE_GRAY_8;
00338 out_type = TYPE_RGB_8;
00339 out_prof = cmsCreate_sRGBProfile();
00340 image->color_space = OPJ_CLRSPC_SRGB;
00341 }
00342 else
00343 if(out_space == cmsSigYCbCrData)
00344 {
00345 in_type = TYPE_YCbCr_16;
00346 out_type = TYPE_RGB_16;
00347 out_prof = cmsCreate_sRGBProfile();
00348 image->color_space = OPJ_CLRSPC_SRGB;
00349 }
00350 else
00351 {
00352 return;
00353 }
00354
00355 (void)prec;
00356 (void)in_space;
00357
00358 transform = cmsCreateTransform(in_prof, in_type,
00359 out_prof, out_type, intent, 0);
00360
00361 #ifdef OPJ_HAVE_LIBLCMS2
00362
00363 cmsCloseProfile(in_prof);
00364 cmsCloseProfile(out_prof);
00365 #endif
00366
00367 if(transform == NULL)
00368 {
00369 image->color_space = oldspace;
00370 #ifdef OPJ_HAVE_LIBLCMS1
00371 cmsCloseProfile(in_prof);
00372 cmsCloseProfile(out_prof);
00373 #endif
00374 return;
00375 }
00376
00377 if(image->numcomps > 2)
00378 {
00379 if( prec <= 8 )
00380 {
00381 unsigned char *inbuf, *outbuf, *in, *out;
00382 max = max_w * max_h;
00383 nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char);
00384 in = inbuf = (unsigned char*)malloc(nr_samples);
00385 out = outbuf = (unsigned char*)malloc(nr_samples);
00386
00387 r = image->comps[0].data;
00388 g = image->comps[1].data;
00389 b = image->comps[2].data;
00390
00391 for(i = 0; i < max; ++i)
00392 {
00393 *in++ = (unsigned char)*r++;
00394 *in++ = (unsigned char)*g++;
00395 *in++ = (unsigned char)*b++;
00396 }
00397
00398 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
00399
00400 r = image->comps[0].data;
00401 g = image->comps[1].data;
00402 b = image->comps[2].data;
00403
00404 for(i = 0; i < max; ++i)
00405 {
00406 *r++ = (int)*out++;
00407 *g++ = (int)*out++;
00408 *b++ = (int)*out++;
00409 }
00410 free(inbuf); free(outbuf);
00411 }
00412 else
00413 {
00414 unsigned short *inbuf, *outbuf, *in, *out;
00415 max = max_w * max_h;
00416 nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short);
00417 in = inbuf = (unsigned short*)malloc(nr_samples);
00418 out = outbuf = (unsigned short*)malloc(nr_samples);
00419
00420 r = image->comps[0].data;
00421 g = image->comps[1].data;
00422 b = image->comps[2].data;
00423
00424 for(i = 0; i < max; ++i)
00425 {
00426 *in++ = (unsigned short)*r++;
00427 *in++ = (unsigned short)*g++;
00428 *in++ = (unsigned short)*b++;
00429 }
00430
00431 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
00432
00433 r = image->comps[0].data;
00434 g = image->comps[1].data;
00435 b = image->comps[2].data;
00436
00437 for(i = 0; i < max; ++i)
00438 {
00439 *r++ = (int)*out++;
00440 *g++ = (int)*out++;
00441 *b++ = (int)*out++;
00442 }
00443 free(inbuf); free(outbuf);
00444 }
00445 }
00446 else
00447 {
00448 unsigned char *in, *inbuf, *out, *outbuf;
00449 max = max_w * max_h;
00450 nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char);
00451 in = inbuf = (unsigned char*)malloc(nr_samples);
00452 out = outbuf = (unsigned char*)malloc(nr_samples);
00453
00454 image->comps = (opj_image_comp_t*)
00455 realloc(image->comps, (image->numcomps+2)*sizeof(opj_image_comp_t));
00456
00457 if(image->numcomps == 2)
00458 image->comps[3] = image->comps[1];
00459
00460 image->comps[1] = image->comps[0];
00461 image->comps[2] = image->comps[0];
00462
00463 image->comps[1].data = (int*)calloc((size_t)max, sizeof(int));
00464 image->comps[2].data = (int*)calloc((size_t)max, sizeof(int));
00465
00466 image->numcomps += 2;
00467
00468 r = image->comps[0].data;
00469
00470 for(i = 0; i < max; ++i)
00471 {
00472 *in++ = (unsigned char)*r++;
00473 }
00474 cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max);
00475
00476 r = image->comps[0].data;
00477 g = image->comps[1].data;
00478 b = image->comps[2].data;
00479
00480 for(i = 0; i < max; ++i)
00481 {
00482 *r++ = (int)*out++; *g++ = (int)*out++; *b++ = (int)*out++;
00483 }
00484 free(inbuf); free(outbuf);
00485
00486 }
00487
00488 cmsDeleteTransform(transform);
00489
00490 #ifdef OPJ_HAVE_LIBLCMS1
00491 cmsCloseProfile(in_prof);
00492 cmsCloseProfile(out_prof);
00493 #endif
00494 }
00495
00496 #endif