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) */