jccolor.c (23875B)
1 /* 2 * jccolor.c 3 * 4 * This file was part of the Independent JPEG Group's software: 5 * Copyright (C) 1991-1996, Thomas G. Lane. 6 * libjpeg-turbo Modifications: 7 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB 8 * Copyright (C) 2009-2012, 2015, 2022, D. R. Commander. 9 * Copyright (C) 2014, MIPS Technologies, Inc., California. 10 * For conditions of distribution and use, see the accompanying README.ijg 11 * file. 12 * 13 * This file contains input colorspace conversion routines. 14 */ 15 16 #define JPEG_INTERNALS 17 #include "jinclude.h" 18 #include "jpeglib.h" 19 #include "jsimd.h" 20 #include "jsamplecomp.h" 21 22 23 #if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) 24 25 /* Private subobject */ 26 27 typedef struct { 28 struct jpeg_color_converter pub; /* public fields */ 29 30 #if BITS_IN_JSAMPLE != 16 31 /* Private state for RGB->YCC conversion */ 32 JLONG *rgb_ycc_tab; /* => table for RGB to YCbCr conversion */ 33 #endif 34 } my_color_converter; 35 36 typedef my_color_converter *my_cconvert_ptr; 37 38 39 /**************** RGB -> YCbCr conversion: most common case **************/ 40 41 /* 42 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are 43 * normalized to the range 0.._MAXJSAMPLE rather than -0.5 .. 0.5. 44 * The conversion equations to be implemented are therefore 45 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B 46 * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + _CENTERJSAMPLE 47 * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + _CENTERJSAMPLE 48 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) 49 * Note: older versions of the IJG code used a zero offset of _MAXJSAMPLE/2, 50 * rather than _CENTERJSAMPLE, for Cb and Cr. This gave equal positive and 51 * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0) 52 * were not represented exactly. Now we sacrifice exact representation of 53 * maximum red and maximum blue in order to get exact grayscales. 54 * 55 * To avoid floating-point arithmetic, we represent the fractional constants 56 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide 57 * the products by 2^16, with appropriate rounding, to get the correct answer. 58 * 59 * For even more speed, we avoid doing any multiplications in the inner loop 60 * by precalculating the constants times R,G,B for all possible values. 61 * For 8-bit samples this is very reasonable (only 256 entries per table); 62 * for 12-bit samples it is still acceptable. It's not very reasonable for 63 * 16-bit samples, but if you want lossless storage you shouldn't be changing 64 * colorspace anyway. 65 * The _CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included 66 * in the tables to save adding them separately in the inner loop. 67 */ 68 69 #define SCALEBITS 16 /* speediest right-shift on some machines */ 70 #define CBCR_OFFSET ((JLONG)_CENTERJSAMPLE << SCALEBITS) 71 #define ONE_HALF ((JLONG)1 << (SCALEBITS - 1)) 72 #define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5)) 73 74 /* We allocate one big table and divide it up into eight parts, instead of 75 * doing eight alloc_small requests. This lets us use a single table base 76 * address, which can be held in a register in the inner loops on many 77 * machines (more than can hold all eight addresses, anyway). 78 */ 79 80 #define R_Y_OFF 0 /* offset to R => Y section */ 81 #define G_Y_OFF (1 * (_MAXJSAMPLE + 1)) /* offset to G => Y section */ 82 #define B_Y_OFF (2 * (_MAXJSAMPLE + 1)) /* etc. */ 83 #define R_CB_OFF (3 * (_MAXJSAMPLE + 1)) 84 #define G_CB_OFF (4 * (_MAXJSAMPLE + 1)) 85 #define B_CB_OFF (5 * (_MAXJSAMPLE + 1)) 86 #define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ 87 #define G_CR_OFF (6 * (_MAXJSAMPLE + 1)) 88 #define B_CR_OFF (7 * (_MAXJSAMPLE + 1)) 89 #define TABLE_SIZE (8 * (_MAXJSAMPLE + 1)) 90 91 /* 12-bit samples use a 16-bit data type, so it is possible to pass 92 * out-of-range sample values (< 0 or > 4095) to jpeg_write_scanlines(). 93 * Thus, we mask the incoming 12-bit samples to guard against overrunning 94 * or underrunning the conversion tables. 95 */ 96 97 #if BITS_IN_JSAMPLE == 12 98 #define RANGE_LIMIT(value) ((value) & 0xFFF) 99 #else 100 #define RANGE_LIMIT(value) (value) 101 #endif 102 103 104 /* Include inline routines for colorspace extensions */ 105 106 #include "jccolext.c" 107 #undef RGB_RED 108 #undef RGB_GREEN 109 #undef RGB_BLUE 110 #undef RGB_PIXELSIZE 111 112 #define RGB_RED EXT_RGB_RED 113 #define RGB_GREEN EXT_RGB_GREEN 114 #define RGB_BLUE EXT_RGB_BLUE 115 #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE 116 #define rgb_ycc_convert_internal extrgb_ycc_convert_internal 117 #define rgb_gray_convert_internal extrgb_gray_convert_internal 118 #define rgb_rgb_convert_internal extrgb_rgb_convert_internal 119 #include "jccolext.c" 120 #undef RGB_RED 121 #undef RGB_GREEN 122 #undef RGB_BLUE 123 #undef RGB_PIXELSIZE 124 #undef rgb_ycc_convert_internal 125 #undef rgb_gray_convert_internal 126 #undef rgb_rgb_convert_internal 127 128 #define RGB_RED EXT_RGBX_RED 129 #define RGB_GREEN EXT_RGBX_GREEN 130 #define RGB_BLUE EXT_RGBX_BLUE 131 #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE 132 #define rgb_ycc_convert_internal extrgbx_ycc_convert_internal 133 #define rgb_gray_convert_internal extrgbx_gray_convert_internal 134 #define rgb_rgb_convert_internal extrgbx_rgb_convert_internal 135 #include "jccolext.c" 136 #undef RGB_RED 137 #undef RGB_GREEN 138 #undef RGB_BLUE 139 #undef RGB_PIXELSIZE 140 #undef rgb_ycc_convert_internal 141 #undef rgb_gray_convert_internal 142 #undef rgb_rgb_convert_internal 143 144 #define RGB_RED EXT_BGR_RED 145 #define RGB_GREEN EXT_BGR_GREEN 146 #define RGB_BLUE EXT_BGR_BLUE 147 #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE 148 #define rgb_ycc_convert_internal extbgr_ycc_convert_internal 149 #define rgb_gray_convert_internal extbgr_gray_convert_internal 150 #define rgb_rgb_convert_internal extbgr_rgb_convert_internal 151 #include "jccolext.c" 152 #undef RGB_RED 153 #undef RGB_GREEN 154 #undef RGB_BLUE 155 #undef RGB_PIXELSIZE 156 #undef rgb_ycc_convert_internal 157 #undef rgb_gray_convert_internal 158 #undef rgb_rgb_convert_internal 159 160 #define RGB_RED EXT_BGRX_RED 161 #define RGB_GREEN EXT_BGRX_GREEN 162 #define RGB_BLUE EXT_BGRX_BLUE 163 #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE 164 #define rgb_ycc_convert_internal extbgrx_ycc_convert_internal 165 #define rgb_gray_convert_internal extbgrx_gray_convert_internal 166 #define rgb_rgb_convert_internal extbgrx_rgb_convert_internal 167 #include "jccolext.c" 168 #undef RGB_RED 169 #undef RGB_GREEN 170 #undef RGB_BLUE 171 #undef RGB_PIXELSIZE 172 #undef rgb_ycc_convert_internal 173 #undef rgb_gray_convert_internal 174 #undef rgb_rgb_convert_internal 175 176 #define RGB_RED EXT_XBGR_RED 177 #define RGB_GREEN EXT_XBGR_GREEN 178 #define RGB_BLUE EXT_XBGR_BLUE 179 #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE 180 #define rgb_ycc_convert_internal extxbgr_ycc_convert_internal 181 #define rgb_gray_convert_internal extxbgr_gray_convert_internal 182 #define rgb_rgb_convert_internal extxbgr_rgb_convert_internal 183 #include "jccolext.c" 184 #undef RGB_RED 185 #undef RGB_GREEN 186 #undef RGB_BLUE 187 #undef RGB_PIXELSIZE 188 #undef rgb_ycc_convert_internal 189 #undef rgb_gray_convert_internal 190 #undef rgb_rgb_convert_internal 191 192 #define RGB_RED EXT_XRGB_RED 193 #define RGB_GREEN EXT_XRGB_GREEN 194 #define RGB_BLUE EXT_XRGB_BLUE 195 #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE 196 #define rgb_ycc_convert_internal extxrgb_ycc_convert_internal 197 #define rgb_gray_convert_internal extxrgb_gray_convert_internal 198 #define rgb_rgb_convert_internal extxrgb_rgb_convert_internal 199 #include "jccolext.c" 200 #undef RGB_RED 201 #undef RGB_GREEN 202 #undef RGB_BLUE 203 #undef RGB_PIXELSIZE 204 #undef rgb_ycc_convert_internal 205 #undef rgb_gray_convert_internal 206 #undef rgb_rgb_convert_internal 207 208 209 /* 210 * Initialize for RGB->YCC colorspace conversion. 211 */ 212 213 METHODDEF(void) 214 rgb_ycc_start(j_compress_ptr cinfo) 215 { 216 #if BITS_IN_JSAMPLE != 16 217 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 218 JLONG *rgb_ycc_tab; 219 JLONG i; 220 221 /* Allocate and fill in the conversion tables. */ 222 cconvert->rgb_ycc_tab = rgb_ycc_tab = (JLONG *) 223 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 224 (TABLE_SIZE * sizeof(JLONG))); 225 226 for (i = 0; i <= _MAXJSAMPLE; i++) { 227 rgb_ycc_tab[i + R_Y_OFF] = FIX(0.29900) * i; 228 rgb_ycc_tab[i + G_Y_OFF] = FIX(0.58700) * i; 229 rgb_ycc_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; 230 rgb_ycc_tab[i + R_CB_OFF] = (-FIX(0.16874)) * i; 231 rgb_ycc_tab[i + G_CB_OFF] = (-FIX(0.33126)) * i; 232 /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. 233 * This ensures that the maximum output will round to _MAXJSAMPLE 234 * not _MAXJSAMPLE+1, and thus that we don't have to range-limit. 235 */ 236 rgb_ycc_tab[i + B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF - 1; 237 /* B=>Cb and R=>Cr tables are the same 238 rgb_ycc_tab[i + R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF - 1; 239 */ 240 rgb_ycc_tab[i + G_CR_OFF] = (-FIX(0.41869)) * i; 241 rgb_ycc_tab[i + B_CR_OFF] = (-FIX(0.08131)) * i; 242 } 243 #else 244 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 245 #endif 246 } 247 248 249 /* 250 * Convert some rows of samples to the JPEG colorspace. 251 */ 252 253 METHODDEF(void) 254 rgb_ycc_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf, 255 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) 256 { 257 switch (cinfo->in_color_space) { 258 case JCS_EXT_RGB: 259 extrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 260 num_rows); 261 break; 262 case JCS_EXT_RGBX: 263 case JCS_EXT_RGBA: 264 extrgbx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 265 num_rows); 266 break; 267 case JCS_EXT_BGR: 268 extbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 269 num_rows); 270 break; 271 case JCS_EXT_BGRX: 272 case JCS_EXT_BGRA: 273 extbgrx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 274 num_rows); 275 break; 276 case JCS_EXT_XBGR: 277 case JCS_EXT_ABGR: 278 extxbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 279 num_rows); 280 break; 281 case JCS_EXT_XRGB: 282 case JCS_EXT_ARGB: 283 extxrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 284 num_rows); 285 break; 286 default: 287 rgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row, 288 num_rows); 289 break; 290 } 291 } 292 293 294 /**************** Cases other than RGB -> YCbCr **************/ 295 296 297 /* 298 * Convert some rows of samples to the JPEG colorspace. 299 */ 300 301 METHODDEF(void) 302 rgb_gray_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf, 303 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) 304 { 305 switch (cinfo->in_color_space) { 306 case JCS_EXT_RGB: 307 extrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 308 num_rows); 309 break; 310 case JCS_EXT_RGBX: 311 case JCS_EXT_RGBA: 312 extrgbx_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 313 num_rows); 314 break; 315 case JCS_EXT_BGR: 316 extbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 317 num_rows); 318 break; 319 case JCS_EXT_BGRX: 320 case JCS_EXT_BGRA: 321 extbgrx_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 322 num_rows); 323 break; 324 case JCS_EXT_XBGR: 325 case JCS_EXT_ABGR: 326 extxbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 327 num_rows); 328 break; 329 case JCS_EXT_XRGB: 330 case JCS_EXT_ARGB: 331 extxrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 332 num_rows); 333 break; 334 default: 335 rgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row, 336 num_rows); 337 break; 338 } 339 } 340 341 342 /* 343 * Extended RGB to plain RGB conversion 344 */ 345 346 METHODDEF(void) 347 rgb_rgb_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf, 348 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) 349 { 350 switch (cinfo->in_color_space) { 351 case JCS_EXT_RGB: 352 extrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 353 num_rows); 354 break; 355 case JCS_EXT_RGBX: 356 case JCS_EXT_RGBA: 357 extrgbx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 358 num_rows); 359 break; 360 case JCS_EXT_BGR: 361 extbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 362 num_rows); 363 break; 364 case JCS_EXT_BGRX: 365 case JCS_EXT_BGRA: 366 extbgrx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 367 num_rows); 368 break; 369 case JCS_EXT_XBGR: 370 case JCS_EXT_ABGR: 371 extxbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 372 num_rows); 373 break; 374 case JCS_EXT_XRGB: 375 case JCS_EXT_ARGB: 376 extxrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 377 num_rows); 378 break; 379 default: 380 rgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, 381 num_rows); 382 break; 383 } 384 } 385 386 387 /* 388 * Convert some rows of samples to the JPEG colorspace. 389 * This version handles Adobe-style CMYK->YCCK conversion, 390 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same 391 * conversion as above, while passing K (black) unchanged. 392 * We assume rgb_ycc_start has been called. 393 */ 394 395 METHODDEF(void) 396 cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf, 397 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) 398 { 399 #if BITS_IN_JSAMPLE != 16 400 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 401 register int r, g, b; 402 register JLONG *ctab = cconvert->rgb_ycc_tab; 403 register _JSAMPROW inptr; 404 register _JSAMPROW outptr0, outptr1, outptr2, outptr3; 405 register JDIMENSION col; 406 JDIMENSION num_cols = cinfo->image_width; 407 408 while (--num_rows >= 0) { 409 inptr = *input_buf++; 410 outptr0 = output_buf[0][output_row]; 411 outptr1 = output_buf[1][output_row]; 412 outptr2 = output_buf[2][output_row]; 413 outptr3 = output_buf[3][output_row]; 414 output_row++; 415 for (col = 0; col < num_cols; col++) { 416 r = _MAXJSAMPLE - RANGE_LIMIT(inptr[0]); 417 g = _MAXJSAMPLE - RANGE_LIMIT(inptr[1]); 418 b = _MAXJSAMPLE - RANGE_LIMIT(inptr[2]); 419 /* K passes through as-is */ 420 outptr3[col] = inptr[3]; 421 inptr += 4; 422 /* If the inputs are 0.._MAXJSAMPLE, the outputs of these equations 423 * must be too; we do not need an explicit range-limiting operation. 424 * Hence the value being shifted is never negative, and we don't 425 * need the general RIGHT_SHIFT macro. 426 */ 427 /* Y */ 428 outptr0[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] + 429 ctab[b + B_Y_OFF]) >> SCALEBITS); 430 /* Cb */ 431 outptr1[col] = (_JSAMPLE)((ctab[r + R_CB_OFF] + ctab[g + G_CB_OFF] + 432 ctab[b + B_CB_OFF]) >> SCALEBITS); 433 /* Cr */ 434 outptr2[col] = (_JSAMPLE)((ctab[r + R_CR_OFF] + ctab[g + G_CR_OFF] + 435 ctab[b + B_CR_OFF]) >> SCALEBITS); 436 } 437 } 438 #else 439 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 440 #endif 441 } 442 443 444 /* 445 * Convert some rows of samples to the JPEG colorspace. 446 * This version handles grayscale output with no conversion. 447 * The source can be either plain grayscale or YCbCr (since Y == gray). 448 */ 449 450 METHODDEF(void) 451 grayscale_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf, 452 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) 453 { 454 register _JSAMPROW inptr; 455 register _JSAMPROW outptr; 456 register JDIMENSION col; 457 JDIMENSION num_cols = cinfo->image_width; 458 int instride = cinfo->input_components; 459 460 while (--num_rows >= 0) { 461 inptr = *input_buf++; 462 outptr = output_buf[0][output_row]; 463 output_row++; 464 for (col = 0; col < num_cols; col++) { 465 outptr[col] = inptr[0]; 466 inptr += instride; 467 } 468 } 469 } 470 471 472 /* 473 * Convert some rows of samples to the JPEG colorspace. 474 * This version handles multi-component colorspaces without conversion. 475 * We assume input_components == num_components. 476 */ 477 478 METHODDEF(void) 479 null_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf, 480 _JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows) 481 { 482 register _JSAMPROW inptr; 483 register _JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3; 484 register JDIMENSION col; 485 register int ci; 486 int nc = cinfo->num_components; 487 JDIMENSION num_cols = cinfo->image_width; 488 489 if (nc == 3) { 490 while (--num_rows >= 0) { 491 inptr = *input_buf++; 492 outptr0 = output_buf[0][output_row]; 493 outptr1 = output_buf[1][output_row]; 494 outptr2 = output_buf[2][output_row]; 495 output_row++; 496 for (col = 0; col < num_cols; col++) { 497 outptr0[col] = *inptr++; 498 outptr1[col] = *inptr++; 499 outptr2[col] = *inptr++; 500 } 501 } 502 } else if (nc == 4) { 503 while (--num_rows >= 0) { 504 inptr = *input_buf++; 505 outptr0 = output_buf[0][output_row]; 506 outptr1 = output_buf[1][output_row]; 507 outptr2 = output_buf[2][output_row]; 508 outptr3 = output_buf[3][output_row]; 509 output_row++; 510 for (col = 0; col < num_cols; col++) { 511 outptr0[col] = *inptr++; 512 outptr1[col] = *inptr++; 513 outptr2[col] = *inptr++; 514 outptr3[col] = *inptr++; 515 } 516 } 517 } else { 518 while (--num_rows >= 0) { 519 /* It seems fastest to make a separate pass for each component. */ 520 for (ci = 0; ci < nc; ci++) { 521 inptr = *input_buf; 522 outptr = output_buf[ci][output_row]; 523 for (col = 0; col < num_cols; col++) { 524 outptr[col] = inptr[ci]; 525 inptr += nc; 526 } 527 } 528 input_buf++; 529 output_row++; 530 } 531 } 532 } 533 534 535 /* 536 * Empty method for start_pass. 537 */ 538 539 METHODDEF(void) 540 null_method(j_compress_ptr cinfo) 541 { 542 /* no work needed */ 543 } 544 545 546 /* 547 * Module initialization routine for input colorspace conversion. 548 */ 549 550 GLOBAL(void) 551 _jinit_color_converter(j_compress_ptr cinfo) 552 { 553 my_cconvert_ptr cconvert; 554 555 if (cinfo->data_precision != BITS_IN_JSAMPLE) 556 ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); 557 558 cconvert = (my_cconvert_ptr) 559 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 560 sizeof(my_color_converter)); 561 cinfo->cconvert = (struct jpeg_color_converter *)cconvert; 562 /* set start_pass to null method until we find out differently */ 563 cconvert->pub.start_pass = null_method; 564 565 /* Make sure input_components agrees with in_color_space */ 566 switch (cinfo->in_color_space) { 567 case JCS_GRAYSCALE: 568 if (cinfo->input_components != 1) 569 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); 570 break; 571 572 case JCS_RGB: 573 case JCS_EXT_RGB: 574 case JCS_EXT_RGBX: 575 case JCS_EXT_BGR: 576 case JCS_EXT_BGRX: 577 case JCS_EXT_XBGR: 578 case JCS_EXT_XRGB: 579 case JCS_EXT_RGBA: 580 case JCS_EXT_BGRA: 581 case JCS_EXT_ABGR: 582 case JCS_EXT_ARGB: 583 if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space]) 584 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); 585 break; 586 587 case JCS_YCbCr: 588 if (cinfo->input_components != 3) 589 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); 590 break; 591 592 case JCS_CMYK: 593 case JCS_YCCK: 594 if (cinfo->input_components != 4) 595 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); 596 break; 597 598 default: /* JCS_UNKNOWN can be anything */ 599 if (cinfo->input_components < 1) 600 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); 601 break; 602 } 603 604 /* Check num_components, set conversion method based on requested space. 605 * NOTE: We do not allow any lossy color conversion algorithms in lossless 606 * mode. 607 */ 608 switch (cinfo->jpeg_color_space) { 609 case JCS_GRAYSCALE: 610 if (cinfo->master->lossless && 611 cinfo->in_color_space != cinfo->jpeg_color_space) 612 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 613 if (cinfo->num_components != 1) 614 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 615 if (cinfo->in_color_space == JCS_GRAYSCALE) 616 cconvert->pub._color_convert = grayscale_convert; 617 else if (IsExtRGB(cinfo->in_color_space)) { 618 #ifdef WITH_SIMD 619 if (jsimd_can_rgb_gray()) 620 cconvert->pub._color_convert = jsimd_rgb_gray_convert; 621 else 622 #endif 623 { 624 cconvert->pub.start_pass = rgb_ycc_start; 625 cconvert->pub._color_convert = rgb_gray_convert; 626 } 627 } else if (cinfo->in_color_space == JCS_YCbCr) 628 cconvert->pub._color_convert = grayscale_convert; 629 else 630 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 631 break; 632 633 case JCS_RGB: 634 if (cinfo->master->lossless && !IsExtRGB(cinfo->in_color_space)) 635 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 636 if (cinfo->num_components != 3) 637 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 638 if (rgb_red[cinfo->in_color_space] == 0 && 639 rgb_green[cinfo->in_color_space] == 1 && 640 rgb_blue[cinfo->in_color_space] == 2 && 641 rgb_pixelsize[cinfo->in_color_space] == 3) { 642 #if defined(WITH_SIMD) && defined(__mips__) 643 if (jsimd_c_can_null_convert()) 644 cconvert->pub._color_convert = jsimd_c_null_convert; 645 else 646 #endif 647 cconvert->pub._color_convert = null_convert; 648 } else if (IsExtRGB(cinfo->in_color_space)) 649 cconvert->pub._color_convert = rgb_rgb_convert; 650 else 651 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 652 break; 653 654 case JCS_YCbCr: 655 if (cinfo->master->lossless && 656 cinfo->in_color_space != cinfo->jpeg_color_space) 657 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 658 if (cinfo->num_components != 3) 659 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 660 if (IsExtRGB(cinfo->in_color_space)) { 661 #ifdef WITH_SIMD 662 if (jsimd_can_rgb_ycc()) 663 cconvert->pub._color_convert = jsimd_rgb_ycc_convert; 664 else 665 #endif 666 { 667 cconvert->pub.start_pass = rgb_ycc_start; 668 cconvert->pub._color_convert = rgb_ycc_convert; 669 } 670 } else if (cinfo->in_color_space == JCS_YCbCr) { 671 #if defined(WITH_SIMD) && defined(__mips__) 672 if (jsimd_c_can_null_convert()) 673 cconvert->pub._color_convert = jsimd_c_null_convert; 674 else 675 #endif 676 cconvert->pub._color_convert = null_convert; 677 } else 678 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 679 break; 680 681 case JCS_CMYK: 682 if (cinfo->master->lossless && 683 cinfo->in_color_space != cinfo->jpeg_color_space) 684 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 685 if (cinfo->num_components != 4) 686 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 687 if (cinfo->in_color_space == JCS_CMYK) { 688 #if defined(WITH_SIMD) && defined(__mips__) 689 if (jsimd_c_can_null_convert()) 690 cconvert->pub._color_convert = jsimd_c_null_convert; 691 else 692 #endif 693 cconvert->pub._color_convert = null_convert; 694 } else 695 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 696 break; 697 698 case JCS_YCCK: 699 if (cinfo->master->lossless && 700 cinfo->in_color_space != cinfo->jpeg_color_space) 701 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 702 if (cinfo->num_components != 4) 703 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 704 if (cinfo->in_color_space == JCS_CMYK) { 705 cconvert->pub.start_pass = rgb_ycc_start; 706 cconvert->pub._color_convert = cmyk_ycck_convert; 707 } else if (cinfo->in_color_space == JCS_YCCK) { 708 #if defined(WITH_SIMD) && defined(__mips__) 709 if (jsimd_c_can_null_convert()) 710 cconvert->pub._color_convert = jsimd_c_null_convert; 711 else 712 #endif 713 cconvert->pub._color_convert = null_convert; 714 } else 715 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 716 break; 717 718 default: /* allow null conversion of JCS_UNKNOWN */ 719 if (cinfo->jpeg_color_space != cinfo->in_color_space || 720 cinfo->num_components != cinfo->input_components) 721 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 722 #if defined(WITH_SIMD) && defined(__mips__) 723 if (jsimd_c_can_null_convert()) 724 cconvert->pub._color_convert = jsimd_c_null_convert; 725 else 726 #endif 727 cconvert->pub._color_convert = null_convert; 728 break; 729 } 730 } 731 732 #endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */