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