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