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