1 /*
2  * jdcolor.c
3  *
4  * Copyright (C) 1991-1997, Thomas G. Lane.
5  * Modified 2011-2017 by Guido Vollbeding.
6  * This file is part of the Independent JPEG Group's software.
7  * For conditions of distribution and use, see the accompanying README file.
8  *
9  * This file contains output colorspace conversion routines.
10  */
11 
12 #define JPEG_INTERNALS
13 #include "jinclude.h"
14 #include "jpeglib.h"
15 
16 
17 #if RANGE_BITS < 2
18   /* Deliberate syntax err */
19   Sorry, this code requires 2 or more range extension bits.
20 #endif
21 
22 
23 /* Private subobject */
24 
25 typedef struct {
26   struct jpeg_color_deconverter pub; /* public fields */
27 
28   /* Private state for YCbCr->RGB and BG_YCC->RGB conversion */
29   int * Cr_r_tab;		/* => table for Cr to R conversion */
30   int * Cb_b_tab;		/* => table for Cb to B conversion */
31   INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
32   INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
33 
34   /* Private state for RGB->Y conversion */
35   INT32 * rgb_y_tab;		/* => table for RGB to Y conversion */
36 } my_color_deconverter;
37 
38 typedef my_color_deconverter * my_cconvert_ptr;
39 
40 
41 /***************  YCbCr -> RGB conversion: most common case **************/
42 /*************** BG_YCC -> RGB conversion: less common case **************/
43 /***************    RGB -> Y   conversion: less common case **************/
44 
45 /*
46  * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011),
47  * previously known as Recommendation CCIR 601-1, except that Cb and Cr
48  * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
49  * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999.
50  * sYCC (standard luma-chroma-chroma color space with extended gamut)
51  * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F.
52  * bg-sRGB and bg-sYCC (big gamut standard color spaces)
53  * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G.
54  * Note that the derived conversion coefficients given in some of these
55  * documents are imprecise.  The general conversion equations are
56  *
57  *	R = Y + K * (1 - Kr) * Cr
58  *	G = Y - K * (Kb * (1 - Kb) * Cb + Kr * (1 - Kr) * Cr) / (1 - Kr - Kb)
59  *	B = Y + K * (1 - Kb) * Cb
60  *
61  *	Y = Kr * R + (1 - Kr - Kb) * G + Kb * B
62  *
63  * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993
64  * from the 1953 FCC NTSC primaries and CIE Illuminant C), K = 2 for sYCC,
65  * the conversion equations to be implemented are therefore
66  *
67  *	R = Y + 1.402 * Cr
68  *	G = Y - 0.344136286 * Cb - 0.714136286 * Cr
69  *	B = Y + 1.772 * Cb
70  *
71  *	Y = 0.299 * R + 0.587 * G + 0.114 * B
72  *
73  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
74  * For bg-sYCC, with K = 4, the equations are
75  *
76  *	R = Y + 2.804 * Cr
77  *	G = Y - 0.688272572 * Cb - 1.428272572 * Cr
78  *	B = Y + 3.544 * Cb
79  *
80  * To avoid floating-point arithmetic, we represent the fractional constants
81  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
82  * the products by 2^16, with appropriate rounding, to get the correct answer.
83  * Notice that Y, being an integral input, does not contribute any fraction
84  * so it need not participate in the rounding.
85  *
86  * For even more speed, we avoid doing any multiplications in the inner loop
87  * by precalculating the constants times Cb and Cr for all possible values.
88  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
89  * for 9-bit to 12-bit samples it is still acceptable.  It's not very
90  * reasonable for 16-bit samples, but if you want lossless storage you
91  * shouldn't be changing colorspace anyway.
92  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
93  * values for the G calculation are left scaled up, since we must add them
94  * together before rounding.
95  */
96 
97 #define SCALEBITS	16	/* speediest right-shift on some machines */
98 #define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
99 #define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
100 
101 /* We allocate one big table for RGB->Y conversion and divide it up into
102  * three parts, instead of doing three alloc_small requests.  This lets us
103  * use a single table base address, which can be held in a register in the
104  * inner loops on many machines (more than can hold all three addresses,
105  * anyway).
106  */
107 
108 #define R_Y_OFF		0			/* offset to R => Y section */
109 #define G_Y_OFF		(1*(MAXJSAMPLE+1))	/* offset to G => Y section */
110 #define B_Y_OFF		(2*(MAXJSAMPLE+1))	/* etc. */
111 #define TABLE_SIZE	(3*(MAXJSAMPLE+1))
112 
113 
114 /*
115  * Initialize tables for YCbCr->RGB and BG_YCC->RGB colorspace conversion.
116  */
117 
118 LOCAL(void)
build_ycc_rgb_table(j_decompress_ptr cinfo)119 build_ycc_rgb_table (j_decompress_ptr cinfo)
120 /* Normal case, sYCC */
121 {
122   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
123   int i;
124   INT32 x;
125   SHIFT_TEMPS
126 
127   cconvert->Cr_r_tab = (int *)
128     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
129 				(MAXJSAMPLE+1) * SIZEOF(int));
130   cconvert->Cb_b_tab = (int *)
131     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
132 				(MAXJSAMPLE+1) * SIZEOF(int));
133   cconvert->Cr_g_tab = (INT32 *)
134     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
135 				(MAXJSAMPLE+1) * SIZEOF(INT32));
136   cconvert->Cb_g_tab = (INT32 *)
137     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
138 				(MAXJSAMPLE+1) * SIZEOF(INT32));
139 
140   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
141     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
142     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
143     /* Cr=>R value is nearest int to 1.402 * x */
144     cconvert->Cr_r_tab[i] = (int)
145 		    RIGHT_SHIFT(FIX(1.402) * x + ONE_HALF, SCALEBITS);
146     /* Cb=>B value is nearest int to 1.772 * x */
147     cconvert->Cb_b_tab[i] = (int)
148 		    RIGHT_SHIFT(FIX(1.772) * x + ONE_HALF, SCALEBITS);
149     /* Cr=>G value is scaled-up -0.714136286 * x */
150     cconvert->Cr_g_tab[i] = (- FIX(0.714136286)) * x;
151     /* Cb=>G value is scaled-up -0.344136286 * x */
152     /* We also add in ONE_HALF so that need not do it in inner loop */
153     cconvert->Cb_g_tab[i] = (- FIX(0.344136286)) * x + ONE_HALF;
154   }
155 }
156 
157 
158 LOCAL(void)
build_bg_ycc_rgb_table(j_decompress_ptr cinfo)159 build_bg_ycc_rgb_table (j_decompress_ptr cinfo)
160 /* Wide gamut case, bg-sYCC */
161 {
162   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
163   int i;
164   INT32 x;
165   SHIFT_TEMPS
166 
167   cconvert->Cr_r_tab = (int *)
168     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
169 				(MAXJSAMPLE+1) * SIZEOF(int));
170   cconvert->Cb_b_tab = (int *)
171     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
172 				(MAXJSAMPLE+1) * SIZEOF(int));
173   cconvert->Cr_g_tab = (INT32 *)
174     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
175 				(MAXJSAMPLE+1) * SIZEOF(INT32));
176   cconvert->Cb_g_tab = (INT32 *)
177     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
178 				(MAXJSAMPLE+1) * SIZEOF(INT32));
179 
180   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
181     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
182     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
183     /* Cr=>R value is nearest int to 2.804 * x */
184     cconvert->Cr_r_tab[i] = (int)
185 		    RIGHT_SHIFT(FIX(2.804) * x + ONE_HALF, SCALEBITS);
186     /* Cb=>B value is nearest int to 3.544 * x */
187     cconvert->Cb_b_tab[i] = (int)
188 		    RIGHT_SHIFT(FIX(3.544) * x + ONE_HALF, SCALEBITS);
189     /* Cr=>G value is scaled-up -1.428272572 * x */
190     cconvert->Cr_g_tab[i] = (- FIX(1.428272572)) * x;
191     /* Cb=>G value is scaled-up -0.688272572 * x */
192     /* We also add in ONE_HALF so that need not do it in inner loop */
193     cconvert->Cb_g_tab[i] = (- FIX(0.688272572)) * x + ONE_HALF;
194   }
195 }
196 
197 
198 /*
199  * Convert some rows of samples to the output colorspace.
200  *
201  * Note that we change from noninterleaved, one-plane-per-component format
202  * to interleaved-pixel format.  The output buffer is therefore three times
203  * as wide as the input buffer.
204  * A starting row offset is provided only for the input buffer.  The caller
205  * can easily adjust the passed output_buf value to accommodate any row
206  * offset required on that side.
207  */
208 
209 METHODDEF(void)
ycc_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)210 ycc_rgb_convert (j_decompress_ptr cinfo,
211 		 JSAMPIMAGE input_buf, JDIMENSION input_row,
212 		 JSAMPARRAY output_buf, int num_rows)
213 {
214   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
215   register int y, cb, cr;
216   register JSAMPROW outptr;
217   register JSAMPROW inptr0, inptr1, inptr2;
218   register JDIMENSION col;
219   JDIMENSION num_cols = cinfo->output_width;
220   /* copy these pointers into registers if possible */
221   register JSAMPLE * range_limit = cinfo->sample_range_limit;
222   register int * Crrtab = cconvert->Cr_r_tab;
223   register int * Cbbtab = cconvert->Cb_b_tab;
224   register INT32 * Crgtab = cconvert->Cr_g_tab;
225   register INT32 * Cbgtab = cconvert->Cb_g_tab;
226   SHIFT_TEMPS
227 
228   while (--num_rows >= 0) {
229     inptr0 = input_buf[0][input_row];
230     inptr1 = input_buf[1][input_row];
231     inptr2 = input_buf[2][input_row];
232     input_row++;
233     outptr = *output_buf++;
234     for (col = 0; col < num_cols; col++) {
235       y  = GETJSAMPLE(inptr0[col]);
236       cb = GETJSAMPLE(inptr1[col]);
237       cr = GETJSAMPLE(inptr2[col]);
238       /* Range-limiting is essential due to noise introduced by DCT losses,
239        * for extended gamut (sYCC) and wide gamut (bg-sYCC) encodings.
240        */
241       outptr[RGB_RED]   = range_limit[y + Crrtab[cr]];
242       outptr[RGB_GREEN] = range_limit[y +
243 			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
244 						 SCALEBITS))];
245       outptr[RGB_BLUE]  = range_limit[y + Cbbtab[cb]];
246       outptr += RGB_PIXELSIZE;
247     }
248   }
249 }
250 
251 
252 /**************** Cases other than YCC -> RGB ****************/
253 
254 
255 /*
256  * Initialize for RGB->grayscale colorspace conversion.
257  */
258 
259 LOCAL(void)
build_rgb_y_table(j_decompress_ptr cinfo)260 build_rgb_y_table (j_decompress_ptr cinfo)
261 {
262   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
263   INT32 * rgb_y_tab;
264   INT32 i;
265 
266   /* Allocate and fill in the conversion tables. */
267   cconvert->rgb_y_tab = rgb_y_tab = (INT32 *)
268     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
269 				(TABLE_SIZE * SIZEOF(INT32)));
270 
271   for (i = 0; i <= MAXJSAMPLE; i++) {
272     rgb_y_tab[i+R_Y_OFF] = FIX(0.299) * i;
273     rgb_y_tab[i+G_Y_OFF] = FIX(0.587) * i;
274     rgb_y_tab[i+B_Y_OFF] = FIX(0.114) * i + ONE_HALF;
275   }
276 }
277 
278 
279 /*
280  * Convert RGB to grayscale.
281  */
282 
283 METHODDEF(void)
rgb_gray_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)284 rgb_gray_convert (j_decompress_ptr cinfo,
285 		  JSAMPIMAGE input_buf, JDIMENSION input_row,
286 		  JSAMPARRAY output_buf, int num_rows)
287 {
288   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
289   register INT32 * ctab = cconvert->rgb_y_tab;
290   register int r, g, b;
291   register JSAMPROW outptr;
292   register JSAMPROW inptr0, inptr1, inptr2;
293   register JDIMENSION col;
294   JDIMENSION num_cols = cinfo->output_width;
295 
296   while (--num_rows >= 0) {
297     inptr0 = input_buf[0][input_row];
298     inptr1 = input_buf[1][input_row];
299     inptr2 = input_buf[2][input_row];
300     input_row++;
301     outptr = *output_buf++;
302     for (col = 0; col < num_cols; col++) {
303       r = GETJSAMPLE(inptr0[col]);
304       g = GETJSAMPLE(inptr1[col]);
305       b = GETJSAMPLE(inptr2[col]);
306       /* Y */
307       outptr[col] = (JSAMPLE)
308 		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
309 		 >> SCALEBITS);
310     }
311   }
312 }
313 
314 
315 /*
316  * [R-G,G,B-G] to [R,G,B] conversion with modulo calculation
317  * (inverse color transform).
318  * This can be seen as an adaption of the general YCbCr->RGB
319  * conversion equation with Kr = Kb = 0, while replacing the
320  * normalization by modulo calculation.
321  */
322 
323 METHODDEF(void)
rgb1_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)324 rgb1_rgb_convert (j_decompress_ptr cinfo,
325 		  JSAMPIMAGE input_buf, JDIMENSION input_row,
326 		  JSAMPARRAY output_buf, int num_rows)
327 {
328   register int r, g, b;
329   register JSAMPROW outptr;
330   register JSAMPROW inptr0, inptr1, inptr2;
331   register JDIMENSION col;
332   JDIMENSION num_cols = cinfo->output_width;
333 
334   while (--num_rows >= 0) {
335     inptr0 = input_buf[0][input_row];
336     inptr1 = input_buf[1][input_row];
337     inptr2 = input_buf[2][input_row];
338     input_row++;
339     outptr = *output_buf++;
340     for (col = 0; col < num_cols; col++) {
341       r = GETJSAMPLE(inptr0[col]);
342       g = GETJSAMPLE(inptr1[col]);
343       b = GETJSAMPLE(inptr2[col]);
344       /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
345        * (modulo) operator is equivalent to the bitmask operator AND.
346        */
347       outptr[RGB_RED]   = (JSAMPLE) ((r + g - CENTERJSAMPLE) & MAXJSAMPLE);
348       outptr[RGB_GREEN] = (JSAMPLE) g;
349       outptr[RGB_BLUE]  = (JSAMPLE) ((b + g - CENTERJSAMPLE) & MAXJSAMPLE);
350       outptr += RGB_PIXELSIZE;
351     }
352   }
353 }
354 
355 
356 /*
357  * [R-G,G,B-G] to grayscale conversion with modulo calculation
358  * (inverse color transform).
359  */
360 
361 METHODDEF(void)
rgb1_gray_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)362 rgb1_gray_convert (j_decompress_ptr cinfo,
363 		   JSAMPIMAGE input_buf, JDIMENSION input_row,
364 		   JSAMPARRAY output_buf, int num_rows)
365 {
366   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
367   register INT32 * ctab = cconvert->rgb_y_tab;
368   register int r, g, b;
369   register JSAMPROW outptr;
370   register JSAMPROW inptr0, inptr1, inptr2;
371   register JDIMENSION col;
372   JDIMENSION num_cols = cinfo->output_width;
373 
374   while (--num_rows >= 0) {
375     inptr0 = input_buf[0][input_row];
376     inptr1 = input_buf[1][input_row];
377     inptr2 = input_buf[2][input_row];
378     input_row++;
379     outptr = *output_buf++;
380     for (col = 0; col < num_cols; col++) {
381       r = GETJSAMPLE(inptr0[col]);
382       g = GETJSAMPLE(inptr1[col]);
383       b = GETJSAMPLE(inptr2[col]);
384       /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
385        * (modulo) operator is equivalent to the bitmask operator AND.
386        */
387       r = (r + g - CENTERJSAMPLE) & MAXJSAMPLE;
388       b = (b + g - CENTERJSAMPLE) & MAXJSAMPLE;
389       /* Y */
390       outptr[col] = (JSAMPLE)
391 		((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
392 		 >> SCALEBITS);
393     }
394   }
395 }
396 
397 
398 /*
399  * No colorspace change, but conversion from separate-planes
400  * to interleaved representation.
401  */
402 
403 METHODDEF(void)
rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)404 rgb_convert (j_decompress_ptr cinfo,
405 	     JSAMPIMAGE input_buf, JDIMENSION input_row,
406 	     JSAMPARRAY output_buf, int num_rows)
407 {
408   register JSAMPROW outptr;
409   register JSAMPROW inptr0, inptr1, inptr2;
410   register JDIMENSION col;
411   JDIMENSION num_cols = cinfo->output_width;
412 
413   while (--num_rows >= 0) {
414     inptr0 = input_buf[0][input_row];
415     inptr1 = input_buf[1][input_row];
416     inptr2 = input_buf[2][input_row];
417     input_row++;
418     outptr = *output_buf++;
419     for (col = 0; col < num_cols; col++) {
420       /* We can dispense with GETJSAMPLE() here */
421       outptr[RGB_RED]   = inptr0[col];
422       outptr[RGB_GREEN] = inptr1[col];
423       outptr[RGB_BLUE]  = inptr2[col];
424       outptr += RGB_PIXELSIZE;
425     }
426   }
427 }
428 
429 
430 /*
431  * Color conversion for no colorspace change: just copy the data,
432  * converting from separate-planes to interleaved representation.
433  */
434 
435 METHODDEF(void)
null_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)436 null_convert (j_decompress_ptr cinfo,
437 	      JSAMPIMAGE input_buf, JDIMENSION input_row,
438 	      JSAMPARRAY output_buf, int num_rows)
439 {
440   int ci;
441   register int nc = cinfo->num_components;
442   register JSAMPROW outptr;
443   register JSAMPROW inptr;
444   register JDIMENSION col;
445   JDIMENSION num_cols = cinfo->output_width;
446 
447   while (--num_rows >= 0) {
448     for (ci = 0; ci < nc; ci++) {
449       inptr = input_buf[ci][input_row];
450       outptr = output_buf[0] + ci;
451       for (col = 0; col < num_cols; col++) {
452 	*outptr = *inptr++;	/* needn't bother with GETJSAMPLE() here */
453 	outptr += nc;
454       }
455     }
456     input_row++;
457     output_buf++;
458   }
459 }
460 
461 
462 /*
463  * Color conversion for grayscale: just copy the data.
464  * This also works for YCC -> grayscale conversion, in which
465  * we just copy the Y (luminance) component and ignore chrominance.
466  */
467 
468 METHODDEF(void)
grayscale_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)469 grayscale_convert (j_decompress_ptr cinfo,
470 		   JSAMPIMAGE input_buf, JDIMENSION input_row,
471 		   JSAMPARRAY output_buf, int num_rows)
472 {
473   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
474 		    num_rows, cinfo->output_width);
475 }
476 
477 
478 /*
479  * Convert grayscale to RGB: just duplicate the graylevel three times.
480  * This is provided to support applications that don't want to cope
481  * with grayscale as a separate case.
482  */
483 
484 METHODDEF(void)
gray_rgb_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)485 gray_rgb_convert (j_decompress_ptr cinfo,
486 		  JSAMPIMAGE input_buf, JDIMENSION input_row,
487 		  JSAMPARRAY output_buf, int num_rows)
488 {
489   register JSAMPROW outptr;
490   register JSAMPROW inptr;
491   register JDIMENSION col;
492   JDIMENSION num_cols = cinfo->output_width;
493 
494   while (--num_rows >= 0) {
495     inptr = input_buf[0][input_row++];
496     outptr = *output_buf++;
497     for (col = 0; col < num_cols; col++) {
498       /* We can dispense with GETJSAMPLE() here */
499       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
500       outptr += RGB_PIXELSIZE;
501     }
502   }
503 }
504 
505 
506 /*
507  * Adobe-style YCCK->CMYK conversion.
508  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
509  * conversion as above, while passing K (black) unchanged.
510  * We assume build_ycc_rgb_table has been called.
511  */
512 
513 METHODDEF(void)
ycck_cmyk_convert(j_decompress_ptr cinfo,JSAMPIMAGE input_buf,JDIMENSION input_row,JSAMPARRAY output_buf,int num_rows)514 ycck_cmyk_convert (j_decompress_ptr cinfo,
515 		   JSAMPIMAGE input_buf, JDIMENSION input_row,
516 		   JSAMPARRAY output_buf, int num_rows)
517 {
518   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
519   register int y, cb, cr;
520   register JSAMPROW outptr;
521   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
522   register JDIMENSION col;
523   JDIMENSION num_cols = cinfo->output_width;
524   /* copy these pointers into registers if possible */
525   register JSAMPLE * range_limit = cinfo->sample_range_limit;
526   register int * Crrtab = cconvert->Cr_r_tab;
527   register int * Cbbtab = cconvert->Cb_b_tab;
528   register INT32 * Crgtab = cconvert->Cr_g_tab;
529   register INT32 * Cbgtab = cconvert->Cb_g_tab;
530   SHIFT_TEMPS
531 
532   while (--num_rows >= 0) {
533     inptr0 = input_buf[0][input_row];
534     inptr1 = input_buf[1][input_row];
535     inptr2 = input_buf[2][input_row];
536     inptr3 = input_buf[3][input_row];
537     input_row++;
538     outptr = *output_buf++;
539     for (col = 0; col < num_cols; col++) {
540       y  = GETJSAMPLE(inptr0[col]);
541       cb = GETJSAMPLE(inptr1[col]);
542       cr = GETJSAMPLE(inptr2[col]);
543       /* Range-limiting is essential due to noise introduced by DCT losses,
544        * and for extended gamut encodings (sYCC).
545        */
546       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];	/* red */
547       outptr[1] = range_limit[MAXJSAMPLE - (y +			/* green */
548 			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
549 						 SCALEBITS)))];
550       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];	/* blue */
551       /* K passes through unchanged */
552       outptr[3] = inptr3[col];	/* don't need GETJSAMPLE here */
553       outptr += 4;
554     }
555   }
556 }
557 
558 
559 /*
560  * Empty method for start_pass.
561  */
562 
563 METHODDEF(void)
start_pass_dcolor(j_decompress_ptr cinfo)564 start_pass_dcolor (j_decompress_ptr cinfo)
565 {
566   /* no work needed */
567 }
568 
569 
570 /*
571  * Module initialization routine for output colorspace conversion.
572  */
573 
574 GLOBAL(void)
jinit_color_deconverter(j_decompress_ptr cinfo)575 jinit_color_deconverter (j_decompress_ptr cinfo)
576 {
577   my_cconvert_ptr cconvert;
578   int ci;
579 
580   cconvert = (my_cconvert_ptr)
581     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
582 				SIZEOF(my_color_deconverter));
583   cinfo->cconvert = &cconvert->pub;
584   cconvert->pub.start_pass = start_pass_dcolor;
585 
586   /* Make sure num_components agrees with jpeg_color_space */
587   switch (cinfo->jpeg_color_space) {
588   case JCS_GRAYSCALE:
589     if (cinfo->num_components != 1)
590       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
591     break;
592 
593   case JCS_RGB:
594   case JCS_YCbCr:
595   case JCS_BG_RGB:
596   case JCS_BG_YCC:
597     if (cinfo->num_components != 3)
598       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
599     break;
600 
601   case JCS_CMYK:
602   case JCS_YCCK:
603     if (cinfo->num_components != 4)
604       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
605     break;
606 
607   default:			/* JCS_UNKNOWN can be anything */
608     if (cinfo->num_components < 1)
609       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
610     break;
611   }
612 
613   /* Support color transform only for RGB colorspaces */
614   if (cinfo->color_transform &&
615       cinfo->jpeg_color_space != JCS_RGB &&
616       cinfo->jpeg_color_space != JCS_BG_RGB)
617     ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
618 
619   /* Set out_color_components and conversion method based on requested space.
620    * Also clear the component_needed flags for any unused components,
621    * so that earlier pipeline stages can avoid useless computation.
622    */
623 
624   switch (cinfo->out_color_space) {
625   case JCS_GRAYSCALE:
626     cinfo->out_color_components = 1;
627     switch (cinfo->jpeg_color_space) {
628     case JCS_GRAYSCALE:
629     case JCS_YCbCr:
630     case JCS_BG_YCC:
631       cconvert->pub.color_convert = grayscale_convert;
632       /* For color->grayscale conversion, only the Y (0) component is needed */
633       for (ci = 1; ci < cinfo->num_components; ci++)
634 	cinfo->comp_info[ci].component_needed = FALSE;
635       break;
636     case JCS_RGB:
637       switch (cinfo->color_transform) {
638       case JCT_NONE:
639 	cconvert->pub.color_convert = rgb_gray_convert;
640 	break;
641       case JCT_SUBTRACT_GREEN:
642 	cconvert->pub.color_convert = rgb1_gray_convert;
643 	break;
644       default:
645 	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
646       }
647       build_rgb_y_table(cinfo);
648       break;
649     default:
650       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
651     }
652     break;
653 
654   case JCS_RGB:
655     cinfo->out_color_components = RGB_PIXELSIZE;
656     switch (cinfo->jpeg_color_space) {
657     case JCS_GRAYSCALE:
658       cconvert->pub.color_convert = gray_rgb_convert;
659       break;
660     case JCS_YCbCr:
661       cconvert->pub.color_convert = ycc_rgb_convert;
662       build_ycc_rgb_table(cinfo);
663       break;
664     case JCS_BG_YCC:
665       cconvert->pub.color_convert = ycc_rgb_convert;
666       build_bg_ycc_rgb_table(cinfo);
667       break;
668     case JCS_RGB:
669       switch (cinfo->color_transform) {
670       case JCT_NONE:
671 	cconvert->pub.color_convert = rgb_convert;
672 	break;
673       case JCT_SUBTRACT_GREEN:
674 	cconvert->pub.color_convert = rgb1_rgb_convert;
675 	break;
676       default:
677 	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
678       }
679       break;
680     default:
681       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
682     }
683     break;
684 
685   case JCS_BG_RGB:
686     cinfo->out_color_components = RGB_PIXELSIZE;
687     if (cinfo->jpeg_color_space == JCS_BG_RGB) {
688       switch (cinfo->color_transform) {
689       case JCT_NONE:
690 	cconvert->pub.color_convert = rgb_convert;
691 	break;
692       case JCT_SUBTRACT_GREEN:
693 	cconvert->pub.color_convert = rgb1_rgb_convert;
694 	break;
695       default:
696 	ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
697       }
698     } else
699       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
700     break;
701 
702   case JCS_CMYK:
703     cinfo->out_color_components = 4;
704     switch (cinfo->jpeg_color_space) {
705     case JCS_YCCK:
706       cconvert->pub.color_convert = ycck_cmyk_convert;
707       build_ycc_rgb_table(cinfo);
708       break;
709     case JCS_CMYK:
710       cconvert->pub.color_convert = null_convert;
711       break;
712     default:
713       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
714     }
715     break;
716 
717   default:
718     /* Permit null conversion to same output space */
719     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
720       cinfo->out_color_components = cinfo->num_components;
721       cconvert->pub.color_convert = null_convert;
722     } else			/* unsupported non-null conversion */
723       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
724     break;
725   }
726 
727   if (cinfo->quantize_colors)
728     cinfo->output_components = 1; /* single colormapped output component */
729   else
730     cinfo->output_components = cinfo->out_color_components;
731 }
732