Bug 1920241 - Update Persisted Search preferences text - r=daleharvey,fluent-reviewer...
[gecko.git] / media / libjpeg / jdcolor.c
blobe5c7b58ebfad0ccdf1ea17d26712fba858cd20e5
1 /*
2 * jdcolor.c
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.
14 * This file contains output colorspace conversion routines.
17 #define JPEG_INTERNALS
18 #include "jinclude.h"
19 #include "jpeglib.h"
20 #include "jsimd.h"
21 #include "jsamplecomp.h"
24 #if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
26 /* Private subobject */
28 typedef struct {
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 */
40 #endif
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
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.
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,
88 * anyway).
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 */
99 #include "jdcolext.c"
100 #undef RGB_RED
101 #undef RGB_GREEN
102 #undef RGB_BLUE
103 #undef RGB_PIXELSIZE
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
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
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
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
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
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
211 * Initialize tables for YCC->RGB colorspace conversion.
214 LOCAL(void)
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;
219 int i;
220 JLONG x;
221 SHIFT_TEMPS
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;
251 #else
252 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
253 #endif
258 * Convert some rows of samples to the output colorspace.
261 METHODDEF(void)
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) {
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;
302 /**************** Cases other than YCbCr -> RGB **************/
306 * Initialize for RGB->grayscale colorspace conversion.
309 LOCAL(void)
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;
314 JLONG *rgb_y_tab;
315 JLONG i;
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;
327 #else
328 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
329 #endif
334 * Convert RGB to grayscale.
337 METHODDEF(void)
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];
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);
365 #else
366 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
367 #endif
372 * Color conversion for no colorspace change: just copy the data,
373 * converting from separate-planes to interleaved representation.
376 METHODDEF(void)
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;
384 int ci;
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];
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];
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;
424 output_buf++;
425 input_row++;
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.
437 METHODDEF(void)
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
450 METHODDEF(void)
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) {
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;
492 * Convert plain RGB to extended RGB
495 METHODDEF(void)
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) {
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;
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.
543 METHODDEF(void)
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;
560 SHIFT_TEMPS
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;
584 #else
585 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
586 #endif
591 * RGB565 conversion
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] = {
620 0x0008020A,
621 0x0C040E06,
622 0x030B0109,
623 0x0F070D05
627 static INLINE boolean is_big_endian(void)
629 int test_value = 1;
630 if (*(char *)&test_value != 1)
631 return TRUE;
632 return FALSE;
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
675 METHODDEF(void)
676 ycc_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
677 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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);
686 METHODDEF(void)
687 ycc_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
688 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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);
697 METHODDEF(void)
698 rgb_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
699 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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);
708 METHODDEF(void)
709 rgb_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
710 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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);
719 METHODDEF(void)
720 gray_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
721 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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);
730 METHODDEF(void)
731 gray_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
732 JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
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);
742 * Empty method for start_pass.
745 METHODDEF(void)
746 start_pass_dcolor(j_decompress_ptr cinfo)
748 /* no work needed */
753 * Module initialization routine for output colorspace conversion.
756 GLOBAL(void)
757 _jinit_color_deconverter(j_decompress_ptr cinfo)
759 my_cconvert_ptr cconvert;
760 int ci;
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) {
773 case JCS_GRAYSCALE:
774 if (cinfo->num_components != 1)
775 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
776 break;
778 case JCS_RGB:
779 case JCS_YCbCr:
780 if (cinfo->num_components != 3)
781 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
782 break;
784 case JCS_CMYK:
785 case JCS_YCCK:
786 if (cinfo->num_components != 4)
787 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
788 break;
790 default: /* JCS_UNKNOWN can be anything */
791 if (cinfo->num_components < 1)
792 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
793 break;
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.
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;
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
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;
854 else
855 cconvert->pub._color_convert = rgb_rgb_convert;
856 } else
857 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
858 break;
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
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;
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);
893 break;
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;
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;
919 if (cinfo->quantize_colors)
920 cinfo->output_components = 1; /* single colormapped output component */
921 else
922 cinfo->output_components = cinfo->out_color_components;
925 #endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */