jdcolor.c (29866B)
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@cendio.se> for Cendio AB 9 * Copyright (C) 2009, 2011-2012, 2014-2015, 2022, D. R. Commander. 10 * Copyright (C) 2013, Linaro Limited. 11 * For conditions of distribution and use, see the accompanying README.ijg 12 * file. 13 * 14 * This file contains output colorspace conversion routines. 15 */ 16 17 #define JPEG_INTERNALS 18 #include "jinclude.h" 19 #include "jpeglib.h" 20 #include "jsimd.h" 21 #include "jsamplecomp.h" 22 23 24 #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) 25 26 /* Private subobject */ 27 28 typedef struct { 29 struct jpeg_color_deconverter pub; /* public fields */ 30 31 #if BITS_IN_JSAMPLE != 16 32 /* Private state for YCC->RGB conversion */ 33 int *Cr_r_tab; /* => table for Cr to R conversion */ 34 int *Cb_b_tab; /* => table for Cb to B conversion */ 35 JLONG *Cr_g_tab; /* => table for Cr to G conversion */ 36 JLONG *Cb_g_tab; /* => table for Cb to G conversion */ 37 38 /* Private state for RGB->Y conversion */ 39 JLONG *rgb_y_tab; /* => table for RGB to Y conversion */ 40 #endif 41 } my_color_deconverter; 42 43 typedef my_color_deconverter *my_cconvert_ptr; 44 45 46 /**************** YCbCr -> RGB conversion: most common case **************/ 47 /**************** RGB -> Y conversion: less common case **************/ 48 49 /* 50 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are 51 * normalized to the range 0.._MAXJSAMPLE rather than -0.5 .. 0.5. 52 * The conversion equations to be implemented are therefore 53 * 54 * R = Y + 1.40200 * Cr 55 * G = Y - 0.34414 * Cb - 0.71414 * Cr 56 * B = Y + 1.77200 * Cb 57 * 58 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B 59 * 60 * where Cb and Cr represent the incoming values less _CENTERJSAMPLE. 61 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) 62 * 63 * To avoid floating-point arithmetic, we represent the fractional constants 64 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide 65 * the products by 2^16, with appropriate rounding, to get the correct answer. 66 * Notice that Y, being an integral input, does not contribute any fraction 67 * so it need not participate in the rounding. 68 * 69 * For even more speed, we avoid doing any multiplications in the inner loop 70 * by precalculating the constants times Cb and Cr for all possible values. 71 * For 8-bit samples this is very reasonable (only 256 entries per table); 72 * for 12-bit samples it is still acceptable. It's not very reasonable for 73 * 16-bit samples, but if you want lossless storage you shouldn't be changing 74 * colorspace anyway. 75 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the 76 * values for the G calculation are left scaled up, since we must add them 77 * together before rounding. 78 */ 79 80 #define SCALEBITS 16 /* speediest right-shift on some machines */ 81 #define ONE_HALF ((JLONG)1 << (SCALEBITS - 1)) 82 #define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5)) 83 84 /* We allocate one big table for RGB->Y conversion and divide it up into 85 * three parts, instead of doing three alloc_small requests. This lets us 86 * use a single table base address, which can be held in a register in the 87 * inner loops on many machines (more than can hold all three addresses, 88 * anyway). 89 */ 90 91 #define R_Y_OFF 0 /* offset to R => Y section */ 92 #define G_Y_OFF (1 * (_MAXJSAMPLE + 1)) /* offset to G => Y section */ 93 #define B_Y_OFF (2 * (_MAXJSAMPLE + 1)) /* etc. */ 94 #define TABLE_SIZE (3 * (_MAXJSAMPLE + 1)) 95 96 97 /* Include inline routines for colorspace extensions */ 98 99 #include "jdcolext.c" 100 #undef RGB_RED 101 #undef RGB_GREEN 102 #undef RGB_BLUE 103 #undef RGB_PIXELSIZE 104 105 #define RGB_RED EXT_RGB_RED 106 #define RGB_GREEN EXT_RGB_GREEN 107 #define RGB_BLUE EXT_RGB_BLUE 108 #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE 109 #define ycc_rgb_convert_internal ycc_extrgb_convert_internal 110 #define gray_rgb_convert_internal gray_extrgb_convert_internal 111 #define rgb_rgb_convert_internal rgb_extrgb_convert_internal 112 #include "jdcolext.c" 113 #undef RGB_RED 114 #undef RGB_GREEN 115 #undef RGB_BLUE 116 #undef RGB_PIXELSIZE 117 #undef ycc_rgb_convert_internal 118 #undef gray_rgb_convert_internal 119 #undef rgb_rgb_convert_internal 120 121 #define RGB_RED EXT_RGBX_RED 122 #define RGB_GREEN EXT_RGBX_GREEN 123 #define RGB_BLUE EXT_RGBX_BLUE 124 #define RGB_ALPHA 3 125 #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE 126 #define ycc_rgb_convert_internal ycc_extrgbx_convert_internal 127 #define gray_rgb_convert_internal gray_extrgbx_convert_internal 128 #define rgb_rgb_convert_internal rgb_extrgbx_convert_internal 129 #include "jdcolext.c" 130 #undef RGB_RED 131 #undef RGB_GREEN 132 #undef RGB_BLUE 133 #undef RGB_ALPHA 134 #undef RGB_PIXELSIZE 135 #undef ycc_rgb_convert_internal 136 #undef gray_rgb_convert_internal 137 #undef rgb_rgb_convert_internal 138 139 #define RGB_RED EXT_BGR_RED 140 #define RGB_GREEN EXT_BGR_GREEN 141 #define RGB_BLUE EXT_BGR_BLUE 142 #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE 143 #define ycc_rgb_convert_internal ycc_extbgr_convert_internal 144 #define gray_rgb_convert_internal gray_extbgr_convert_internal 145 #define rgb_rgb_convert_internal rgb_extbgr_convert_internal 146 #include "jdcolext.c" 147 #undef RGB_RED 148 #undef RGB_GREEN 149 #undef RGB_BLUE 150 #undef RGB_PIXELSIZE 151 #undef ycc_rgb_convert_internal 152 #undef gray_rgb_convert_internal 153 #undef rgb_rgb_convert_internal 154 155 #define RGB_RED EXT_BGRX_RED 156 #define RGB_GREEN EXT_BGRX_GREEN 157 #define RGB_BLUE EXT_BGRX_BLUE 158 #define RGB_ALPHA 3 159 #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE 160 #define ycc_rgb_convert_internal ycc_extbgrx_convert_internal 161 #define gray_rgb_convert_internal gray_extbgrx_convert_internal 162 #define rgb_rgb_convert_internal rgb_extbgrx_convert_internal 163 #include "jdcolext.c" 164 #undef RGB_RED 165 #undef RGB_GREEN 166 #undef RGB_BLUE 167 #undef RGB_ALPHA 168 #undef RGB_PIXELSIZE 169 #undef ycc_rgb_convert_internal 170 #undef gray_rgb_convert_internal 171 #undef rgb_rgb_convert_internal 172 173 #define RGB_RED EXT_XBGR_RED 174 #define RGB_GREEN EXT_XBGR_GREEN 175 #define RGB_BLUE EXT_XBGR_BLUE 176 #define RGB_ALPHA 0 177 #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE 178 #define ycc_rgb_convert_internal ycc_extxbgr_convert_internal 179 #define gray_rgb_convert_internal gray_extxbgr_convert_internal 180 #define rgb_rgb_convert_internal rgb_extxbgr_convert_internal 181 #include "jdcolext.c" 182 #undef RGB_RED 183 #undef RGB_GREEN 184 #undef RGB_BLUE 185 #undef RGB_ALPHA 186 #undef RGB_PIXELSIZE 187 #undef ycc_rgb_convert_internal 188 #undef gray_rgb_convert_internal 189 #undef rgb_rgb_convert_internal 190 191 #define RGB_RED EXT_XRGB_RED 192 #define RGB_GREEN EXT_XRGB_GREEN 193 #define RGB_BLUE EXT_XRGB_BLUE 194 #define RGB_ALPHA 0 195 #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE 196 #define ycc_rgb_convert_internal ycc_extxrgb_convert_internal 197 #define gray_rgb_convert_internal gray_extxrgb_convert_internal 198 #define rgb_rgb_convert_internal rgb_extxrgb_convert_internal 199 #include "jdcolext.c" 200 #undef RGB_RED 201 #undef RGB_GREEN 202 #undef RGB_BLUE 203 #undef RGB_ALPHA 204 #undef RGB_PIXELSIZE 205 #undef ycc_rgb_convert_internal 206 #undef gray_rgb_convert_internal 207 #undef rgb_rgb_convert_internal 208 209 210 /* 211 * Initialize tables for YCC->RGB colorspace conversion. 212 */ 213 214 LOCAL(void) 215 build_ycc_rgb_table(j_decompress_ptr cinfo) 216 { 217 #if BITS_IN_JSAMPLE != 16 218 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 219 int i; 220 JLONG x; 221 SHIFT_TEMPS 222 223 cconvert->Cr_r_tab = (int *) 224 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 225 (_MAXJSAMPLE + 1) * sizeof(int)); 226 cconvert->Cb_b_tab = (int *) 227 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 228 (_MAXJSAMPLE + 1) * sizeof(int)); 229 cconvert->Cr_g_tab = (JLONG *) 230 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 231 (_MAXJSAMPLE + 1) * sizeof(JLONG)); 232 cconvert->Cb_g_tab = (JLONG *) 233 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 234 (_MAXJSAMPLE + 1) * sizeof(JLONG)); 235 236 for (i = 0, x = -_CENTERJSAMPLE; i <= _MAXJSAMPLE; i++, x++) { 237 /* i is the actual input pixel value, in the range 0.._MAXJSAMPLE */ 238 /* The Cb or Cr value we are thinking of is x = i - _CENTERJSAMPLE */ 239 /* Cr=>R value is nearest int to 1.40200 * x */ 240 cconvert->Cr_r_tab[i] = (int) 241 RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); 242 /* Cb=>B value is nearest int to 1.77200 * x */ 243 cconvert->Cb_b_tab[i] = (int) 244 RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); 245 /* Cr=>G value is scaled-up -0.71414 * x */ 246 cconvert->Cr_g_tab[i] = (-FIX(0.71414)) * x; 247 /* Cb=>G value is scaled-up -0.34414 * x */ 248 /* We also add in ONE_HALF so that need not do it in inner loop */ 249 cconvert->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF; 250 } 251 #else 252 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 253 #endif 254 } 255 256 257 /* 258 * Convert some rows of samples to the output colorspace. 259 */ 260 261 METHODDEF(void) 262 ycc_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 263 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 264 { 265 switch (cinfo->out_color_space) { 266 case JCS_EXT_RGB: 267 ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 268 num_rows); 269 break; 270 case JCS_EXT_RGBX: 271 case JCS_EXT_RGBA: 272 ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, 273 num_rows); 274 break; 275 case JCS_EXT_BGR: 276 ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 277 num_rows); 278 break; 279 case JCS_EXT_BGRX: 280 case JCS_EXT_BGRA: 281 ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, 282 num_rows); 283 break; 284 case JCS_EXT_XBGR: 285 case JCS_EXT_ABGR: 286 ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 287 num_rows); 288 break; 289 case JCS_EXT_XRGB: 290 case JCS_EXT_ARGB: 291 ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 292 num_rows); 293 break; 294 default: 295 ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, 296 num_rows); 297 break; 298 } 299 } 300 301 302 /**************** Cases other than YCbCr -> RGB **************/ 303 304 305 /* 306 * Initialize for RGB->grayscale colorspace conversion. 307 */ 308 309 LOCAL(void) 310 build_rgb_y_table(j_decompress_ptr cinfo) 311 { 312 #if BITS_IN_JSAMPLE != 16 313 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 314 JLONG *rgb_y_tab; 315 JLONG i; 316 317 /* Allocate and fill in the conversion tables. */ 318 cconvert->rgb_y_tab = rgb_y_tab = (JLONG *) 319 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 320 (TABLE_SIZE * sizeof(JLONG))); 321 322 for (i = 0; i <= _MAXJSAMPLE; i++) { 323 rgb_y_tab[i + R_Y_OFF] = FIX(0.29900) * i; 324 rgb_y_tab[i + G_Y_OFF] = FIX(0.58700) * i; 325 rgb_y_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; 326 } 327 #else 328 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 329 #endif 330 } 331 332 333 /* 334 * Convert RGB to grayscale. 335 */ 336 337 METHODDEF(void) 338 rgb_gray_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 339 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 340 { 341 #if BITS_IN_JSAMPLE != 16 342 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 343 register int r, g, b; 344 register JLONG *ctab = cconvert->rgb_y_tab; 345 register _JSAMPROW outptr; 346 register _JSAMPROW inptr0, inptr1, inptr2; 347 register JDIMENSION col; 348 JDIMENSION num_cols = cinfo->output_width; 349 350 while (--num_rows >= 0) { 351 inptr0 = input_buf[0][input_row]; 352 inptr1 = input_buf[1][input_row]; 353 inptr2 = input_buf[2][input_row]; 354 input_row++; 355 outptr = *output_buf++; 356 for (col = 0; col < num_cols; col++) { 357 r = inptr0[col]; 358 g = inptr1[col]; 359 b = inptr2[col]; 360 /* Y */ 361 outptr[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] + 362 ctab[b + B_Y_OFF]) >> SCALEBITS); 363 } 364 } 365 #else 366 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 367 #endif 368 } 369 370 371 /* 372 * Color conversion for no colorspace change: just copy the data, 373 * converting from separate-planes to interleaved representation. 374 */ 375 376 METHODDEF(void) 377 null_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 378 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 379 { 380 register _JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr; 381 register JDIMENSION col; 382 register int num_components = cinfo->num_components; 383 JDIMENSION num_cols = cinfo->output_width; 384 int ci; 385 386 if (num_components == 3) { 387 while (--num_rows >= 0) { 388 inptr0 = input_buf[0][input_row]; 389 inptr1 = input_buf[1][input_row]; 390 inptr2 = input_buf[2][input_row]; 391 input_row++; 392 outptr = *output_buf++; 393 for (col = 0; col < num_cols; col++) { 394 *outptr++ = inptr0[col]; 395 *outptr++ = inptr1[col]; 396 *outptr++ = inptr2[col]; 397 } 398 } 399 } else if (num_components == 4) { 400 while (--num_rows >= 0) { 401 inptr0 = input_buf[0][input_row]; 402 inptr1 = input_buf[1][input_row]; 403 inptr2 = input_buf[2][input_row]; 404 inptr3 = input_buf[3][input_row]; 405 input_row++; 406 outptr = *output_buf++; 407 for (col = 0; col < num_cols; col++) { 408 *outptr++ = inptr0[col]; 409 *outptr++ = inptr1[col]; 410 *outptr++ = inptr2[col]; 411 *outptr++ = inptr3[col]; 412 } 413 } 414 } else { 415 while (--num_rows >= 0) { 416 for (ci = 0; ci < num_components; ci++) { 417 inptr = input_buf[ci][input_row]; 418 outptr = *output_buf; 419 for (col = 0; col < num_cols; col++) { 420 outptr[ci] = inptr[col]; 421 outptr += num_components; 422 } 423 } 424 output_buf++; 425 input_row++; 426 } 427 } 428 } 429 430 431 /* 432 * Color conversion for grayscale: just copy the data. 433 * This also works for YCbCr -> grayscale conversion, in which 434 * we just copy the Y (luminance) component and ignore chrominance. 435 */ 436 437 METHODDEF(void) 438 grayscale_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 439 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 440 { 441 _jcopy_sample_rows(input_buf[0], (int)input_row, output_buf, 0, num_rows, 442 cinfo->output_width); 443 } 444 445 446 /* 447 * Convert grayscale to RGB 448 */ 449 450 METHODDEF(void) 451 gray_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 452 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 453 { 454 switch (cinfo->out_color_space) { 455 case JCS_EXT_RGB: 456 gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 457 num_rows); 458 break; 459 case JCS_EXT_RGBX: 460 case JCS_EXT_RGBA: 461 gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, 462 num_rows); 463 break; 464 case JCS_EXT_BGR: 465 gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 466 num_rows); 467 break; 468 case JCS_EXT_BGRX: 469 case JCS_EXT_BGRA: 470 gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, 471 num_rows); 472 break; 473 case JCS_EXT_XBGR: 474 case JCS_EXT_ABGR: 475 gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 476 num_rows); 477 break; 478 case JCS_EXT_XRGB: 479 case JCS_EXT_ARGB: 480 gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 481 num_rows); 482 break; 483 default: 484 gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, 485 num_rows); 486 break; 487 } 488 } 489 490 491 /* 492 * Convert plain RGB to extended RGB 493 */ 494 495 METHODDEF(void) 496 rgb_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 497 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 498 { 499 switch (cinfo->out_color_space) { 500 case JCS_EXT_RGB: 501 rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 502 num_rows); 503 break; 504 case JCS_EXT_RGBX: 505 case JCS_EXT_RGBA: 506 rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, 507 num_rows); 508 break; 509 case JCS_EXT_BGR: 510 rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 511 num_rows); 512 break; 513 case JCS_EXT_BGRX: 514 case JCS_EXT_BGRA: 515 rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, 516 num_rows); 517 break; 518 case JCS_EXT_XBGR: 519 case JCS_EXT_ABGR: 520 rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, 521 num_rows); 522 break; 523 case JCS_EXT_XRGB: 524 case JCS_EXT_ARGB: 525 rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, 526 num_rows); 527 break; 528 default: 529 rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, 530 num_rows); 531 break; 532 } 533 } 534 535 536 /* 537 * Adobe-style YCCK->CMYK conversion. 538 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same 539 * conversion as above, while passing K (black) unchanged. 540 * We assume build_ycc_rgb_table has been called. 541 */ 542 543 METHODDEF(void) 544 ycck_cmyk_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 545 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 546 { 547 #if BITS_IN_JSAMPLE != 16 548 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert; 549 register int y, cb, cr; 550 register _JSAMPROW outptr; 551 register _JSAMPROW inptr0, inptr1, inptr2, inptr3; 552 register JDIMENSION col; 553 JDIMENSION num_cols = cinfo->output_width; 554 /* copy these pointers into registers if possible */ 555 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit; 556 register int *Crrtab = cconvert->Cr_r_tab; 557 register int *Cbbtab = cconvert->Cb_b_tab; 558 register JLONG *Crgtab = cconvert->Cr_g_tab; 559 register JLONG *Cbgtab = cconvert->Cb_g_tab; 560 SHIFT_TEMPS 561 562 while (--num_rows >= 0) { 563 inptr0 = input_buf[0][input_row]; 564 inptr1 = input_buf[1][input_row]; 565 inptr2 = input_buf[2][input_row]; 566 inptr3 = input_buf[3][input_row]; 567 input_row++; 568 outptr = *output_buf++; 569 for (col = 0; col < num_cols; col++) { 570 y = inptr0[col]; 571 cb = inptr1[col]; 572 cr = inptr2[col]; 573 /* Range-limiting is essential due to noise introduced by DCT losses. */ 574 outptr[0] = range_limit[_MAXJSAMPLE - (y + Crrtab[cr])]; /* red */ 575 outptr[1] = range_limit[_MAXJSAMPLE - (y + /* green */ 576 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], 577 SCALEBITS)))]; 578 outptr[2] = range_limit[_MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */ 579 /* K passes through unchanged */ 580 outptr[3] = inptr3[col]; 581 outptr += 4; 582 } 583 } 584 #else 585 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 586 #endif 587 } 588 589 590 /* 591 * RGB565 conversion 592 */ 593 594 #define PACK_SHORT_565_LE(r, g, b) \ 595 ((((r) << 8) & 0xF800) | (((g) << 3) & 0x7E0) | ((b) >> 3)) 596 #define PACK_SHORT_565_BE(r, g, b) \ 597 (((r) & 0xF8) | ((g) >> 5) | (((g) << 11) & 0xE000) | (((b) << 5) & 0x1F00)) 598 599 #define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l) 600 #define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r) 601 602 #define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3) 603 604 #define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(int *)(addr)) = pixels) 605 606 #define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF)) 607 #define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1)) 608 #define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF)) 609 610 611 /* Declarations for ordered dithering 612 * 613 * We use a 4x4 ordered dither array packed into 32 bits. This array is 614 * sufficient for dithering RGB888 to RGB565. 615 */ 616 617 #define DITHER_MASK 0x3 618 #define DITHER_ROTATE(x) ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF)) 619 static const JLONG dither_matrix[4] = { 620 0x0008020A, 621 0x0C040E06, 622 0x030B0109, 623 0x0F070D05 624 }; 625 626 627 static INLINE boolean is_big_endian(void) 628 { 629 int test_value = 1; 630 if (*(char *)&test_value != 1) 631 return TRUE; 632 return FALSE; 633 } 634 635 636 /* Include inline routines for RGB565 conversion */ 637 638 #define PACK_SHORT_565 PACK_SHORT_565_LE 639 #define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE 640 #define ycc_rgb565_convert_internal ycc_rgb565_convert_le 641 #define ycc_rgb565D_convert_internal ycc_rgb565D_convert_le 642 #define rgb_rgb565_convert_internal rgb_rgb565_convert_le 643 #define rgb_rgb565D_convert_internal rgb_rgb565D_convert_le 644 #define gray_rgb565_convert_internal gray_rgb565_convert_le 645 #define gray_rgb565D_convert_internal gray_rgb565D_convert_le 646 #include "jdcol565.c" 647 #undef PACK_SHORT_565 648 #undef PACK_TWO_PIXELS 649 #undef ycc_rgb565_convert_internal 650 #undef ycc_rgb565D_convert_internal 651 #undef rgb_rgb565_convert_internal 652 #undef rgb_rgb565D_convert_internal 653 #undef gray_rgb565_convert_internal 654 #undef gray_rgb565D_convert_internal 655 656 #define PACK_SHORT_565 PACK_SHORT_565_BE 657 #define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE 658 #define ycc_rgb565_convert_internal ycc_rgb565_convert_be 659 #define ycc_rgb565D_convert_internal ycc_rgb565D_convert_be 660 #define rgb_rgb565_convert_internal rgb_rgb565_convert_be 661 #define rgb_rgb565D_convert_internal rgb_rgb565D_convert_be 662 #define gray_rgb565_convert_internal gray_rgb565_convert_be 663 #define gray_rgb565D_convert_internal gray_rgb565D_convert_be 664 #include "jdcol565.c" 665 #undef PACK_SHORT_565 666 #undef PACK_TWO_PIXELS 667 #undef ycc_rgb565_convert_internal 668 #undef ycc_rgb565D_convert_internal 669 #undef rgb_rgb565_convert_internal 670 #undef rgb_rgb565D_convert_internal 671 #undef gray_rgb565_convert_internal 672 #undef gray_rgb565D_convert_internal 673 674 675 METHODDEF(void) 676 ycc_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 677 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 678 { 679 if (is_big_endian()) 680 ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); 681 else 682 ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); 683 } 684 685 686 METHODDEF(void) 687 ycc_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 688 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 689 { 690 if (is_big_endian()) 691 ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); 692 else 693 ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); 694 } 695 696 697 METHODDEF(void) 698 rgb_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 699 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 700 { 701 if (is_big_endian()) 702 rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); 703 else 704 rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); 705 } 706 707 708 METHODDEF(void) 709 rgb_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 710 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 711 { 712 if (is_big_endian()) 713 rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); 714 else 715 rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); 716 } 717 718 719 METHODDEF(void) 720 gray_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 721 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 722 { 723 if (is_big_endian()) 724 gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); 725 else 726 gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); 727 } 728 729 730 METHODDEF(void) 731 gray_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf, 732 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows) 733 { 734 if (is_big_endian()) 735 gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows); 736 else 737 gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows); 738 } 739 740 741 /* 742 * Empty method for start_pass. 743 */ 744 745 METHODDEF(void) 746 start_pass_dcolor(j_decompress_ptr cinfo) 747 { 748 /* no work needed */ 749 } 750 751 752 /* 753 * Module initialization routine for output colorspace conversion. 754 */ 755 756 GLOBAL(void) 757 _jinit_color_deconverter(j_decompress_ptr cinfo) 758 { 759 my_cconvert_ptr cconvert; 760 int ci; 761 762 if (cinfo->data_precision != BITS_IN_JSAMPLE) 763 ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); 764 765 cconvert = (my_cconvert_ptr) 766 (*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE, 767 sizeof(my_color_deconverter)); 768 cinfo->cconvert = (struct jpeg_color_deconverter *)cconvert; 769 cconvert->pub.start_pass = start_pass_dcolor; 770 771 /* Make sure num_components agrees with jpeg_color_space */ 772 switch (cinfo->jpeg_color_space) { 773 case JCS_GRAYSCALE: 774 if (cinfo->num_components != 1) 775 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 776 break; 777 778 case JCS_RGB: 779 case JCS_YCbCr: 780 if (cinfo->num_components != 3) 781 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 782 break; 783 784 case JCS_CMYK: 785 case JCS_YCCK: 786 if (cinfo->num_components != 4) 787 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 788 break; 789 790 default: /* JCS_UNKNOWN can be anything */ 791 if (cinfo->num_components < 1) 792 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); 793 break; 794 } 795 796 /* Set out_color_components and conversion method based on requested space. 797 * Also clear the component_needed flags for any unused components, 798 * so that earlier pipeline stages can avoid useless computation. 799 * NOTE: We do not allow any lossy color conversion algorithms in lossless 800 * mode. 801 */ 802 803 switch (cinfo->out_color_space) { 804 case JCS_GRAYSCALE: 805 if (cinfo->master->lossless && 806 cinfo->jpeg_color_space != cinfo->out_color_space) 807 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 808 cinfo->out_color_components = 1; 809 if (cinfo->jpeg_color_space == JCS_GRAYSCALE || 810 cinfo->jpeg_color_space == JCS_YCbCr) { 811 cconvert->pub._color_convert = grayscale_convert; 812 /* For color->grayscale conversion, only the Y (0) component is needed */ 813 for (ci = 1; ci < cinfo->num_components; ci++) 814 cinfo->comp_info[ci].component_needed = FALSE; 815 } else if (cinfo->jpeg_color_space == JCS_RGB) { 816 cconvert->pub._color_convert = rgb_gray_convert; 817 build_rgb_y_table(cinfo); 818 } else 819 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 820 break; 821 822 case JCS_RGB: 823 case JCS_EXT_RGB: 824 case JCS_EXT_RGBX: 825 case JCS_EXT_BGR: 826 case JCS_EXT_BGRX: 827 case JCS_EXT_XBGR: 828 case JCS_EXT_XRGB: 829 case JCS_EXT_RGBA: 830 case JCS_EXT_BGRA: 831 case JCS_EXT_ABGR: 832 case JCS_EXT_ARGB: 833 if (cinfo->master->lossless && cinfo->jpeg_color_space != JCS_RGB) 834 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 835 cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space]; 836 if (cinfo->jpeg_color_space == JCS_YCbCr) { 837 #ifdef WITH_SIMD 838 if (jsimd_can_ycc_rgb()) 839 cconvert->pub._color_convert = jsimd_ycc_rgb_convert; 840 else 841 #endif 842 { 843 cconvert->pub._color_convert = ycc_rgb_convert; 844 build_ycc_rgb_table(cinfo); 845 } 846 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { 847 cconvert->pub._color_convert = gray_rgb_convert; 848 } else if (cinfo->jpeg_color_space == JCS_RGB) { 849 if (rgb_red[cinfo->out_color_space] == 0 && 850 rgb_green[cinfo->out_color_space] == 1 && 851 rgb_blue[cinfo->out_color_space] == 2 && 852 rgb_pixelsize[cinfo->out_color_space] == 3) 853 cconvert->pub._color_convert = null_convert; 854 else 855 cconvert->pub._color_convert = rgb_rgb_convert; 856 } else 857 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 858 break; 859 860 case JCS_RGB565: 861 if (cinfo->master->lossless) 862 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 863 cinfo->out_color_components = 3; 864 if (cinfo->dither_mode == JDITHER_NONE) { 865 if (cinfo->jpeg_color_space == JCS_YCbCr) { 866 #ifdef WITH_SIMD 867 if (jsimd_can_ycc_rgb565()) 868 cconvert->pub._color_convert = jsimd_ycc_rgb565_convert; 869 else 870 #endif 871 { 872 cconvert->pub._color_convert = ycc_rgb565_convert; 873 build_ycc_rgb_table(cinfo); 874 } 875 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { 876 cconvert->pub._color_convert = gray_rgb565_convert; 877 } else if (cinfo->jpeg_color_space == JCS_RGB) { 878 cconvert->pub._color_convert = rgb_rgb565_convert; 879 } else 880 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 881 } else { 882 /* only ordered dithering is supported */ 883 if (cinfo->jpeg_color_space == JCS_YCbCr) { 884 cconvert->pub._color_convert = ycc_rgb565D_convert; 885 build_ycc_rgb_table(cinfo); 886 } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { 887 cconvert->pub._color_convert = gray_rgb565D_convert; 888 } else if (cinfo->jpeg_color_space == JCS_RGB) { 889 cconvert->pub._color_convert = rgb_rgb565D_convert; 890 } else 891 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 892 } 893 break; 894 895 case JCS_CMYK: 896 if (cinfo->master->lossless && 897 cinfo->jpeg_color_space != cinfo->out_color_space) 898 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 899 cinfo->out_color_components = 4; 900 if (cinfo->jpeg_color_space == JCS_YCCK) { 901 cconvert->pub._color_convert = ycck_cmyk_convert; 902 build_ycc_rgb_table(cinfo); 903 } else if (cinfo->jpeg_color_space == JCS_CMYK) { 904 cconvert->pub._color_convert = null_convert; 905 } else 906 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 907 break; 908 909 default: 910 /* Permit null conversion to same output space */ 911 if (cinfo->out_color_space == cinfo->jpeg_color_space) { 912 cinfo->out_color_components = cinfo->num_components; 913 cconvert->pub._color_convert = null_convert; 914 } else /* unsupported non-null conversion */ 915 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); 916 break; 917 } 918 919 if (cinfo->quantize_colors) 920 cinfo->output_components = 1; /* single colormapped output component */ 921 else 922 cinfo->output_components = cinfo->out_color_components; 923 } 924 925 #endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */