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
14 * This file contains output colorspace conversion routines.
17 #define JPEG_INTERNALS
21 #include "jsamplecomp.h"
24 #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
26 /* Private subobject */
29 struct jpeg_color_deconverter pub; /* public fields */
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 */
38 /* Private state for RGB->Y conversion */
39 JLONG *rgb_y_tab; /* => table for RGB to Y conversion */
41 } my_color_deconverter;
43 typedef my_color_deconverter *my_cconvert_ptr;
46 /**************** YCbCr -> RGB conversion: most common case **************/
47 /**************** RGB -> Y conversion: less common case **************/
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
54 * R = Y + 1.40200 * Cr
55 * G = Y - 0.34414 * Cb - 0.71414 * Cr
56 * B = Y + 1.77200 * Cb
58 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
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.)
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.
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
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.
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))
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,
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))
97 /* Include inline routines for colorspace extensions */
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"
117 #undef ycc_rgb_convert_internal
118 #undef gray_rgb_convert_internal
119 #undef rgb_rgb_convert_internal
121 #define RGB_RED EXT_RGBX_RED
122 #define RGB_GREEN EXT_RGBX_GREEN
123 #define RGB_BLUE EXT_RGBX_BLUE
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"
135 #undef ycc_rgb_convert_internal
136 #undef gray_rgb_convert_internal
137 #undef rgb_rgb_convert_internal
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"
151 #undef ycc_rgb_convert_internal
152 #undef gray_rgb_convert_internal
153 #undef rgb_rgb_convert_internal
155 #define RGB_RED EXT_BGRX_RED
156 #define RGB_GREEN EXT_BGRX_GREEN
157 #define RGB_BLUE EXT_BGRX_BLUE
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"
169 #undef ycc_rgb_convert_internal
170 #undef gray_rgb_convert_internal
171 #undef rgb_rgb_convert_internal
173 #define RGB_RED EXT_XBGR_RED
174 #define RGB_GREEN EXT_XBGR_GREEN
175 #define RGB_BLUE EXT_XBGR_BLUE
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"
187 #undef ycc_rgb_convert_internal
188 #undef gray_rgb_convert_internal
189 #undef rgb_rgb_convert_internal
191 #define RGB_RED EXT_XRGB_RED
192 #define RGB_GREEN EXT_XRGB_GREEN
193 #define RGB_BLUE EXT_XRGB_BLUE
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"
205 #undef ycc_rgb_convert_internal
206 #undef gray_rgb_convert_internal
207 #undef rgb_rgb_convert_internal
211 * Initialize tables for YCC->RGB colorspace conversion.
215 build_ycc_rgb_table(j_decompress_ptr cinfo)
217 #if BITS_IN_JSAMPLE != 16
218 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
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));
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;
252 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
258 * Convert some rows of samples to the output colorspace.
262 ycc_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
263 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
265 switch (cinfo->out_color_space) {
267 ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
272 ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
276 ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
281 ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
286 ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
291 ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
295 ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
302 /**************** Cases other than YCbCr -> RGB **************/
306 * Initialize for RGB->grayscale colorspace conversion.
310 build_rgb_y_table(j_decompress_ptr cinfo)
312 #if BITS_IN_JSAMPLE != 16
313 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
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)));
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;
328 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
334 * Convert RGB to grayscale.
338 rgb_gray_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
339 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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;
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];
355 outptr = *output_buf++;
356 for (col = 0; col < num_cols; col++) {
361 outptr[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +
362 ctab[b + B_Y_OFF]) >> SCALEBITS);
366 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
372 * Color conversion for no colorspace change: just copy the data,
373 * converting from separate-planes to interleaved representation.
377 null_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
378 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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;
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];
392 outptr = *output_buf++;
393 for (col = 0; col < num_cols; col++) {
394 *outptr++ = inptr0[col];
395 *outptr++ = inptr1[col];
396 *outptr++ = inptr2[col];
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];
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];
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;
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.
438 grayscale_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
439 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
441 _jcopy_sample_rows(input_buf[0], (int)input_row, output_buf, 0, num_rows,
442 cinfo->output_width);
447 * Convert grayscale to RGB
451 gray_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
452 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
454 switch (cinfo->out_color_space) {
456 gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
461 gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
465 gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
470 gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
475 gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
480 gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
484 gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
492 * Convert plain RGB to extended RGB
496 rgb_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
497 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
499 switch (cinfo->out_color_space) {
501 rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
506 rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
510 rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
515 rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
520 rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
525 rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
529 rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
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.
544 ycck_cmyk_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
545 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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;
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];
568 outptr = *output_buf++;
569 for (col = 0; col < num_cols; 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],
578 outptr[2] = range_limit[_MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
579 /* K passes through unchanged */
580 outptr[3] = inptr3[col];
585 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
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))
599 #define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l)
600 #define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r)
602 #define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3)
604 #define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(int *)(addr)) = pixels)
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))
611 /* Declarations for ordered dithering
613 * We use a 4x4 ordered dither array packed into 32 bits. This array is
614 * sufficient for dithering RGB888 to RGB565.
617 #define DITHER_MASK 0x3
618 #define DITHER_ROTATE(x) ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))
619 static const JLONG dither_matrix[4] = {
627 static INLINE boolean is_big_endian(void)
630 if (*(char *)&test_value != 1)
636 /* Include inline routines for RGB565 conversion */
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
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
676 ycc_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
677 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
680 ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
682 ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
687 ycc_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
688 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
691 ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
693 ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
698 rgb_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
699 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
702 rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
704 rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
709 rgb_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
710 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
713 rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
715 rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
720 gray_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
721 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
724 gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
726 gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
731 gray_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
732 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
735 gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
737 gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
742 * Empty method for start_pass.
746 start_pass_dcolor(j_decompress_ptr cinfo)
753 * Module initialization routine for output colorspace conversion.
757 _jinit_color_deconverter(j_decompress_ptr cinfo)
759 my_cconvert_ptr cconvert;
762 if (cinfo->data_precision != BITS_IN_JSAMPLE)
763 ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
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;
771 /* Make sure num_components agrees with jpeg_color_space */
772 switch (cinfo->jpeg_color_space) {
774 if (cinfo->num_components != 1)
775 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
780 if (cinfo->num_components != 3)
781 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
786 if (cinfo->num_components != 4)
787 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
790 default: /* JCS_UNKNOWN can be anything */
791 if (cinfo->num_components < 1)
792 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
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
803 switch (cinfo->out_color_space) {
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);
819 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
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) {
838 if (jsimd_can_ycc_rgb())
839 cconvert->pub._color_convert = jsimd_ycc_rgb_convert;
843 cconvert->pub._color_convert = ycc_rgb_convert;
844 build_ycc_rgb_table(cinfo);
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;
855 cconvert->pub._color_convert = rgb_rgb_convert;
857 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
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) {
867 if (jsimd_can_ycc_rgb565())
868 cconvert->pub._color_convert = jsimd_ycc_rgb565_convert;
872 cconvert->pub._color_convert = ycc_rgb565_convert;
873 build_ycc_rgb_table(cinfo);
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;
880 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
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;
891 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
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;
906 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
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);
919 if (cinfo->quantize_colors)
920 cinfo->output_components = 1; /* single colormapped output component */
922 cinfo->output_components = cinfo->out_color_components;
925 #endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */