1 /* 2 * jdcolor.c 3 * 4 * This file was part of the Independent JPEG Group's software: 5 * Copyright (C) 1991-1997, Thomas G. Lane. 6 * Modified 2011 by Guido Vollbeding. 7 * libjpeg-turbo Modifications: 8 * Copyright 2009 Pierre Ossman <ossman (at) cendio.se> for Cendio AB 9 * Copyright (C) 2009, 2011-2012, D. R. Commander. 10 * For conditions of distribution and use, see the accompanying README file. 11 * 12 * This file contains output colorspace conversion routines. 13 */ 14 15 #define JPEG_INTERNALS 16 #include "jinclude.h" 17 #include "jpeglib.h" 18 #include "jsimd.h" 19 #include "config.h" 20 21 22 /* Private subobject */ 23 24 typedef struct { 25 struct jpeg_color_deconverter pub; /* public fields */ 26 27 /* Private state for YCC->RGB conversion */ 28 int * Cr_r_tab; /* => table for Cr to R conversion */ 29 int * Cb_b_tab; /* => table for Cb to B conversion */ 30 INT32 * Cr_g_tab; /* => table for Cr to G conversion */ 31 INT32 * Cb_g_tab; /* => table for Cb to G conversion */ 32 33 /* Private state for RGB->Y conversion */ 34 INT32 * rgb_y_tab; /* => table for RGB to Y conversion */ 35 } my_color_deconverter; 36 37 typedef my_color_deconverter * my_cconvert_ptr; 38 39 40 /**************** YCbCr -> RGB conversion: most common case **************/ 41 /**************** RGB -> Y conversion: less common case **************/ 42 43 /* 44 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are 45 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5. 46 * The conversion equations to be implemented are therefore 47 * 48 * R = Y + 1.40200 * Cr 49 * G = Y - 0.34414 * Cb - 0.71414 * Cr 50 * B = Y + 1.77200 * Cb 51 * 52 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B 53 * 54 * where Cb and Cr represent the incoming values less CENTERJSAMPLE. 55 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) 56 * 57 * To avoid floating-point arithmetic, we represent the fractional constants 58 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide 59 * the products by 2^16, with appropriate rounding, to get the correct answer. 60 * Notice that Y, being an integral input, does not contribute any fraction 61 * so it need not participate in the rounding. 62 * 63 * For even more speed, we avoid doing any multiplications in the inner loop 64 * by precalculating the constants times Cb and Cr for all possible values. 65 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table); 66 * for 12-bit samples it is still acceptable. It's not very reasonable for 67 * 16-bit samples, but if you want lossless storage you shouldn't be changing 68 * colorspace anyway. 69 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the 70 * values for the G calculation are left scaled up, since we must add them 71 * together before rounding. 72 */ 73 74 #define SCALEBITS 16 /* speediest right-shift on some machines */ 75 #define ONE_HALF ((INT32) 1 << (SCALEBITS-1)) 76 #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) 77 78 /* We allocate one big table for RGB->Y conversion and divide it up into 79 * three parts, instead of doing three alloc_small requests. This lets us 80 * use a single table base address, which can be held in a register in the 81 * inner loops on many machines (more than can hold all three addresses, 82 * anyway). 83 */ 84 85 #define R_Y_OFF 0 /* offset to R => Y section */ 86 #define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */ 87 #define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */ 88 #define TABLE_SIZE (3*(MAXJSAMPLE+1)) 89 90 91 /* Include inline routines for colorspace extensions */ 92 93 #include "jdcolext.c" 94 #undef RGB_RED 95 #undef RGB_GREEN 96 #undef RGB_BLUE 97 #undef RGB_PIXELSIZE 98 99 #define RGB_RED EXT_RGB_RED 100 #define RGB_GREEN EXT_RGB_GREEN 101 #define RGB_BLUE EXT_RGB_BLUE 102 #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE 103 #define ycc_rgb_convert_internal ycc_extrgb_convert_internal 104 #define gray_rgb_convert_internal gray_extrgb_convert_internal 105 #define rgb_rgb_convert_internal rgb_extrgb_convert_internal 106 #include "jdcolext.c" 107 #undef RGB_RED 108 #undef RGB_GREEN 109 #undef RGB_BLUE 110 #undef RGB_PIXELSIZE 111 #undef ycc_rgb_convert_internal 112 #undef gray_rgb_convert_internal 113 #undef rgb_rgb_convert_internal 114 115 #define RGB_RED EXT_RGBX_RED 116 #define RGB_GREEN EXT_RGBX_GREEN 117 #define RGB_BLUE EXT_RGBX_BLUE 118 #define RGB_ALPHA 3 119 #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE 120 #define ycc_rgb_convert_internal ycc_extrgbx_convert_internal 121 #define gray_rgb_convert_internal gray_extrgbx_convert_internal 122 #define rgb_rgb_convert_internal rgb_extrgbx_convert_internal 123 #include "jdcolext.c" 124 #undef RGB_RED 125 #undef RGB_GREEN 126 #undef RGB_BLUE 127 #undef RGB_ALPHA 128 #undef RGB_PIXELSIZE 129 #undef ycc_rgb_convert_internal 130 #undef gray_rgb_convert_internal 131 #undef rgb_rgb_convert_internal 132 133 #define RGB_RED EXT_BGR_RED 134 #define RGB_GREEN EXT_BGR_GREEN 135 #define RGB_BLUE EXT_BGR_BLUE 136 #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE 137 #define ycc_rgb_convert_internal ycc_extbgr_convert_internal 138 #define gray_rgb_convert_internal gray_extbgr_convert_internal 139 #define rgb_rgb_convert_internal rgb_extbgr_convert_internal 140 #include "jdcolext.c" 141 #undef RGB_RED 142 #undef RGB_GREEN 143 #undef RGB_BLUE 144 #undef RGB_PIXELSIZE 145 #undef ycc_rgb_convert_internal 146 #undef gray_rgb_convert_internal 147 #undef rgb_rgb_convert_internal 148 149 #define RGB_RED EXT_BGRX_RED 150 #define RGB_GREEN EXT_BGRX_GREEN 151 #define RGB_BLUE EXT_BGRX_BLUE 152 #define RGB_ALPHA 3 153 #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE 154 #define ycc_rgb_convert_internal ycc_extbgrx_convert_internal 155 #define gray_rgb_convert_internal gray_extbgrx_convert_internal 156 #define rgb_rgb_convert_internal rgb_extbgrx_convert_internal 157 #include "jdcolext.c" 158 #undef RGB_RED 159 #undef RGB_GREEN 160 #undef RGB_BLUE 161 #undef RGB_ALPHA 162 #undef RGB_PIXELSIZE 163 #undef ycc_rgb_convert_internal 164 #undef gray_rgb_convert_internal 165 #undef rgb_rgb_convert_internal 166 167 #define RGB_RED EXT_XBGR_RED 168 #define RGB_GREEN EXT_XBGR_GREEN 169 #define RGB_BLUE EXT_XBGR_BLUE 170 #define RGB_ALPHA 0 171 #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE 172 #define ycc_rgb_convert_internal ycc_extxbgr_convert_internal 173 #define gray_rgb_convert_internal gray_extxbgr_convert_internal 174 #define rgb_rgb_convert_internal rgb_extxbgr_convert_internal 175 #include "jdcolext.c" 176 #undef RGB_RED 177 #undef RGB_GREEN 178 #undef RGB_BLUE 179 #undef RGB_ALPHA 180 #undef RGB_PIXELSIZE 181 #undef ycc_rgb_convert_internal 182 #undef gray_rgb_convert_internal 183 #undef rgb_rgb_convert_internal 184 185 #define RGB_RED EXT_XRGB_RED 186 #define RGB_GREEN EXT_XRGB_GREEN 187 #define RGB_BLUE EXT_XRGB_BLUE 188 #define RGB_ALPHA 0 189 #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE 190 #define ycc_rgb_convert_internal ycc_extxrgb_convert_internal 191 #define gray_rgb_convert_internal gray_extxrgb_convert_internal 192 #define rgb_rgb_convert_internal rgb_extxrgb_convert_internal 193 #include "jdcolext.c" 194 #undef RGB_RED 195 #undef RGB_GREEN 196 #undef RGB_BLUE 197 #undef RGB_ALPHA 198 #undef RGB_PIXELSIZE 199 #undef ycc_rgb_convert_internal 200 #undef gray_rgb_convert_internal 201 #undef rgb_rgb_convert_internal 202 203 204 /* 205 * Initialize tables for YCC->RGB colorspace conversion. 206 */ 207 208 LOCAL(void) 209 build_ycc_rgb_table (j_decompress_ptr cinfo) 210 { 211 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 212 int i; 213 INT32 x; 214 SHIFT_TEMPS 215 216 cconvert->Cr_r_tab = (int *) 217 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 218 (MAXJSAMPLE+1) * SIZEOF(int)); 219 cconvert->Cb_b_tab = (int *) 220 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 221 (MAXJSAMPLE+1) * SIZEOF(int)); 222 cconvert->Cr_g_tab = (INT32 *) 223 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 224 (MAXJSAMPLE+1) * SIZEOF(INT32)); 225 cconvert->Cb_g_tab = (INT32 *) 226 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 227 (MAXJSAMPLE+1) * SIZEOF(INT32)); 228 229 for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { 230 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ 231 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ 232 /* Cr=>R value is nearest int to 1.40200 * x */ 233 cconvert->Cr_r_tab[i] = (int) 234 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); 235 /* Cb=>B value is nearest int to 1.77200 * x */ 236 cconvert->Cb_b_tab[i] = (int) 237 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); 238 /* Cr=>G value is scaled-up -0.71414 * x */ 239 cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; 240 /* Cb=>G value is scaled-up -0.34414 * x */ 241 /* We also add in ONE_HALF so that need not do it in inner loop */ 242 cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF; 243 } 244 } 245 246 247 /* 248 * Convert some rows of samples to the output colorspace. 249 */ 250 251 METHODDEF(void) 252 ycc_rgb_convert (j_decompress_ptr cinfo, 253 JSAMPIMAGE input_buf, JDIMENSION input_row, 254 JSAMPARRAY output_buf, int num_rows) 255 { 256 switch (cinfo->out_color_space) { 257 case JCS_EXT_RGB: 258 ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 259 num_rows); 260 break; 261 case JCS_EXT_RGBX: 262 case JCS_EXT_RGBA: 263 ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, 264 num_rows); 265 break; 266 case JCS_EXT_BGR: 267 ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 268 num_rows); 269 break; 270 case JCS_EXT_BGRX: 271 case JCS_EXT_BGRA: 272 ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, 273 num_rows); 274 break; 275 case JCS_EXT_XBGR: 276 case JCS_EXT_ABGR: 277 ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 278 num_rows); 279 break; 280 case JCS_EXT_XRGB: 281 case JCS_EXT_ARGB: 282 ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 283 num_rows); 284 break; 285 default: 286 ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, 287 num_rows); 288 break; 289 } 290 } 291 292 293 /**************** Cases other than YCbCr -> RGB **************/ 294 295 296 /* 297 * Initialize for RGB->grayscale colorspace conversion. 298 */ 299 300 LOCAL(void) 301 build_rgb_y_table (j_decompress_ptr cinfo) 302 { 303 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 304 INT32 * rgb_y_tab; 305 INT32 i; 306 307 /* Allocate and fill in the conversion tables. */ 308 cconvert->rgb_y_tab = rgb_y_tab = (INT32 *) 309 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 310 (TABLE_SIZE * SIZEOF(INT32))); 311 312 for (i = 0; i <= MAXJSAMPLE; i++) { 313 rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i; 314 rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i; 315 rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; 316 } 317 } 318 319 320 /* 321 * Convert RGB to grayscale. 322 */ 323 324 METHODDEF(void) 325 rgb_gray_convert (j_decompress_ptr cinfo, 326 JSAMPIMAGE input_buf, JDIMENSION input_row, 327 JSAMPARRAY output_buf, int num_rows) 328 { 329 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 330 register int r, g, b; 331 register INT32 * ctab = cconvert->rgb_y_tab; 332 register JSAMPROW outptr; 333 register JSAMPROW inptr0, inptr1, inptr2; 334 register JDIMENSION col; 335 JDIMENSION num_cols = cinfo->output_width; 336 337 while (--num_rows >= 0) { 338 inptr0 = input_buf[0][input_row]; 339 inptr1 = input_buf[1][input_row]; 340 inptr2 = input_buf[2][input_row]; 341 input_row++; 342 outptr = *output_buf++; 343 for (col = 0; col < num_cols; col++) { 344 r = GETJSAMPLE(inptr0[col]); 345 g = GETJSAMPLE(inptr1[col]); 346 b = GETJSAMPLE(inptr2[col]); 347 /* Y */ 348 outptr[col] = (JSAMPLE) 349 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) 350 >> SCALEBITS); 351 } 352 } 353 } 354 355 356 /* 357 * Color conversion for no colorspace change: just copy the data, 358 * converting from separate-planes to interleaved representation. 359 */ 360 361 METHODDEF(void) 362 null_convert (j_decompress_ptr cinfo, 363 JSAMPIMAGE input_buf, JDIMENSION input_row, 364 JSAMPARRAY output_buf, int num_rows) 365 { 366 register JSAMPROW inptr, outptr; 367 register JDIMENSION count; 368 register int num_components = cinfo->num_components; 369 JDIMENSION num_cols = cinfo->output_width; 370 int ci; 371 372 while (--num_rows >= 0) { 373 for (ci = 0; ci < num_components; ci++) { 374 inptr = input_buf[ci][input_row]; 375 outptr = output_buf[0] + ci; 376 for (count = num_cols; count > 0; count--) { 377 *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */ 378 outptr += num_components; 379 } 380 } 381 input_row++; 382 output_buf++; 383 } 384 } 385 386 387 /* 388 * Color conversion for grayscale: just copy the data. 389 * This also works for YCbCr -> grayscale conversion, in which 390 * we just copy the Y (luminance) component and ignore chrominance. 391 */ 392 393 METHODDEF(void) 394 grayscale_convert (j_decompress_ptr cinfo, 395 JSAMPIMAGE input_buf, JDIMENSION input_row, 396 JSAMPARRAY output_buf, int num_rows) 397 { 398 jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0, 399 num_rows, cinfo->output_width); 400 } 401 402 403 /* 404 * Convert grayscale to RGB 405 */ 406 407 METHODDEF(void) 408 gray_rgb_convert (j_decompress_ptr cinfo, 409 JSAMPIMAGE input_buf, JDIMENSION input_row, 410 JSAMPARRAY output_buf, int num_rows) 411 { 412 switch (cinfo->out_color_space) { 413 case JCS_EXT_RGB: 414 gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 415 num_rows); 416 break; 417 case JCS_EXT_RGBX: 418 case JCS_EXT_RGBA: 419 gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, 420 num_rows); 421 break; 422 case JCS_EXT_BGR: 423 gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 424 num_rows); 425 break; 426 case JCS_EXT_BGRX: 427 case JCS_EXT_BGRA: 428 gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, 429 num_rows); 430 break; 431 case JCS_EXT_XBGR: 432 case JCS_EXT_ABGR: 433 gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 434 num_rows); 435 break; 436 case JCS_EXT_XRGB: 437 case JCS_EXT_ARGB: 438 gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 439 num_rows); 440 break; 441 default: 442 gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, 443 num_rows); 444 break; 445 } 446 } 447 448 449 /* 450 * Convert plain RGB to extended RGB 451 */ 452 453 METHODDEF(void) 454 rgb_rgb_convert (j_decompress_ptr cinfo, 455 JSAMPIMAGE input_buf, JDIMENSION input_row, 456 JSAMPARRAY output_buf, int num_rows) 457 { 458 switch (cinfo->out_color_space) { 459 case JCS_EXT_RGB: 460 rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 461 num_rows); 462 break; 463 case JCS_EXT_RGBX: 464 case JCS_EXT_RGBA: 465 rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, 466 num_rows); 467 break; 468 case JCS_EXT_BGR: 469 rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 470 num_rows); 471 break; 472 case JCS_EXT_BGRX: 473 case JCS_EXT_BGRA: 474 rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, 475 num_rows); 476 break; 477 case JCS_EXT_XBGR: 478 case JCS_EXT_ABGR: 479 rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 480 num_rows); 481 break; 482 case JCS_EXT_XRGB: 483 case JCS_EXT_ARGB: 484 rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 485 num_rows); 486 break; 487 default: 488 rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, 489 num_rows); 490 break; 491 } 492 } 493 494 495 /* 496 * Adobe-style YCCK->CMYK conversion. 497 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same 498 * conversion as above, while passing K (black) unchanged. 499 * We assume build_ycc_rgb_table has been called. 500 */ 501 502 METHODDEF(void) 503 ycck_cmyk_convert (j_decompress_ptr cinfo, 504 JSAMPIMAGE input_buf, JDIMENSION input_row, 505 JSAMPARRAY output_buf, int num_rows) 506 { 507 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; 508 register int y, cb, cr; 509 register JSAMPROW outptr; 510 register JSAMPROW inptr0, inptr1, inptr2, inptr3; 511 register JDIMENSION col; 512 JDIMENSION num_cols = cinfo->output_width; 513 /* copy these pointers into registers if possible */ 514 register JSAMPLE * range_limit = cinfo->sample_range_limit; 515 register int * Crrtab = cconvert->Cr_r_tab; 516 register int * Cbbtab = cconvert->Cb_b_tab; 517 register INT32 * Crgtab = cconvert->Cr_g_tab; 518 register INT32 * Cbgtab = cconvert->Cb_g_tab; 519 SHIFT_TEMPS 520 521 while (--num_rows >= 0) { 522 inptr0 = input_buf[0][input_row]; 523 inptr1 = input_buf[1][input_row]; 524 inptr2 = input_buf[2][input_row]; 525 inptr3 = input_buf[3][input_row]; 526 input_row++; 527 outptr = *output_buf++; 528 for (col = 0; col < num_cols; col++) { 529 y = GETJSAMPLE(inptr0[col]); 530 cb = GETJSAMPLE(inptr1[col]); 531 cr = GETJSAMPLE(inptr2[col]); 532 /* Range-limiting is essential due to noise introduced by DCT losses. */ 533 outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ 534 outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */ 535 ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 536 SCALEBITS)))]; 537 outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ 538 /* K passes through unchanged */ 539 outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */ 540 outptr += 4; 541 } 542 } 543 } 544 545 546 /* 547 * Empty method for start_pass. 548 */ 549 550 METHODDEF(void) 551 start_pass_dcolor (j_decompress_ptr cinfo) 552 { 553 /* no work needed */ 554 } 555 556 557 /* 558 * Module initialization routine for output colorspace conversion. 559 */ 560 561 GLOBAL(void) 562 jinit_color_deconverter (j_decompress_ptr cinfo) 563 { 564 my_cconvert_ptr cconvert; 565 int ci; 566 567 cconvert = (my_cconvert_ptr) 568 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 569 SIZEOF(my_color_deconverter)); 570 cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert; 571 cconvert->pub.start_pass = start_pass_dcolor; 572 573 /* Make sure num_components agrees with jpeg_color_space */ 574 switch (cinfo->jpeg_color_space) { 575 case JCS_GRAYSCALE: 576 if (cinfo->num_components != 1) 577 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 578 break; 579 580 case JCS_RGB: 581 case JCS_YCbCr: 582 if (cinfo->num_components != 3) 583 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 584 break; 585 586 case JCS_CMYK: 587 case JCS_YCCK: 588 if (cinfo->num_components != 4) 589 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 590 break; 591 592 default: /* JCS_UNKNOWN can be anything */ 593 if (cinfo->num_components < 1) 594 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 595 break; 596 } 597 598 /* Set out_color_components and conversion method based on requested space. 599 * Also clear the component_needed flags for any unused components, 600 * so that earlier pipeline stages can avoid useless computation. 601 */ 602 603 switch (cinfo->out_color_space) { 604 case JCS_GRAYSCALE: 605 cinfo->out_color_components = 1; 606 if (cinfo->jpeg_color_space == JCS_GRAYSCALE || 607 cinfo->jpeg_color_space == JCS_YCbCr) { 608 cconvert->pub.color_convert = grayscale_convert; 609 /* For color->grayscale conversion, only the Y (0) component is needed */ 610 for (ci = 1; ci < cinfo->num_components; ci++) 611 cinfo->comp_info[ci].component_needed = FALSE; 612 } else if (cinfo->jpeg_color_space == JCS_RGB) { 613 cconvert->pub.color_convert = rgb_gray_convert; 614 build_rgb_y_table(cinfo); 615 } else 616 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 617 break; 618 619 case JCS_RGB: 620 case JCS_EXT_RGB: 621 case JCS_EXT_RGBX: 622 case JCS_EXT_BGR: 623 case JCS_EXT_BGRX: 624 case JCS_EXT_XBGR: 625 case JCS_EXT_XRGB: 626 case JCS_EXT_RGBA: 627 case JCS_EXT_BGRA: 628 case JCS_EXT_ABGR: 629 case JCS_EXT_ARGB: 630 cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space]; 631 if (cinfo->jpeg_color_space == JCS_YCbCr) { 632 if (jsimd_can_ycc_rgb()) 633 cconvert->pub.color_convert = jsimd_ycc_rgb_convert; 634 else { 635 cconvert->pub.color_convert = ycc_rgb_convert; 636 build_ycc_rgb_table(cinfo); 637 } 638 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { 639 cconvert->pub.color_convert = gray_rgb_convert; 640 } else if (cinfo->jpeg_color_space == JCS_RGB) { 641 if (rgb_red[cinfo->out_color_space] == 0 && 642 rgb_green[cinfo->out_color_space] == 1 && 643 rgb_blue[cinfo->out_color_space] == 2 && 644 rgb_pixelsize[cinfo->out_color_space] == 3) 645 cconvert->pub.color_convert = null_convert; 646 else 647 cconvert->pub.color_convert = rgb_rgb_convert; 648 } else 649 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 650 break; 651 652 case JCS_CMYK: 653 cinfo->out_color_components = 4; 654 if (cinfo->jpeg_color_space == JCS_YCCK) { 655 cconvert->pub.color_convert = ycck_cmyk_convert; 656 build_ycc_rgb_table(cinfo); 657 } else if (cinfo->jpeg_color_space == JCS_CMYK) { 658 cconvert->pub.color_convert = null_convert; 659 } else 660 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 661 break; 662 663 default: 664 /* Permit null conversion to same output space */ 665 if (cinfo->out_color_space == cinfo->jpeg_color_space) { 666 cinfo->out_color_components = cinfo->num_components; 667 cconvert->pub.color_convert = null_convert; 668 } else /* unsupported non-null conversion */ 669 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 670 break; 671 } 672 673 if (cinfo->quantize_colors) 674 cinfo->output_components = 1; /* single colormapped output component */ 675 else 676 cinfo->output_components = cinfo->out_color_components; 677 } 678