4 * Copyright (C) 1991-1996, Thomas G. Lane.
5 * Modified 2011-2019 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.
9 * This file contains input colorspace conversion routines.
12 #define JPEG_INTERNALS
17 /* Private subobject */
20 struct jpeg_color_converter pub
; /* public fields */
22 /* Private state for RGB->YCC conversion */
23 INT32
* rgb_ycc_tab
; /* => table for RGB to YCbCr conversion */
26 typedef my_color_converter
* my_cconvert_ptr
;
29 /**************** RGB -> YCbCr conversion: most common case **************/
32 * YCbCr is defined per Recommendation ITU-R BT.601-7 (03/2011),
33 * previously known as Recommendation CCIR 601-1, except that Cb and Cr
34 * are normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
35 * sRGB (standard RGB color space) is defined per IEC 61966-2-1:1999.
36 * sYCC (standard luma-chroma-chroma color space with extended gamut)
37 * is defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex F.
38 * bg-sRGB and bg-sYCC (big gamut standard color spaces)
39 * are defined per IEC 61966-2-1:1999 Amendment A1:2003 Annex G.
40 * Note that the derived conversion coefficients given in some of these
41 * documents are imprecise. The general conversion equations are
42 * Y = Kr * R + (1 - Kr - Kb) * G + Kb * B
43 * Cb = 0.5 * (B - Y) / (1 - Kb)
44 * Cr = 0.5 * (R - Y) / (1 - Kr)
45 * With Kr = 0.299 and Kb = 0.114 (derived according to SMPTE RP 177-1993
46 * from the 1953 FCC NTSC primaries and CIE Illuminant C),
47 * the conversion equations to be implemented are therefore
48 * Y = 0.299 * R + 0.587 * G + 0.114 * B
49 * Cb = -0.168735892 * R - 0.331264108 * G + 0.5 * B + CENTERJSAMPLE
50 * Cr = 0.5 * R - 0.418687589 * G - 0.081312411 * B + CENTERJSAMPLE
51 * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
52 * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
53 * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
54 * were not represented exactly. Now we sacrifice exact representation of
55 * maximum red and maximum blue in order to get exact grayscales.
57 * To avoid floating-point arithmetic, we represent the fractional constants
58 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
59 * the products by 2^16, with appropriate rounding, to get the correct answer.
61 * For even more speed, we avoid doing any multiplications in the inner loop
62 * by precalculating the constants times R,G,B for all possible values.
63 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
64 * for 9-bit to 12-bit samples it is still acceptable. It's not very
65 * reasonable for 16-bit samples, but if you want lossless storage you
66 * shouldn't be changing colorspace anyway.
67 * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
68 * in the tables to save adding them separately in the inner loop.
71 #define SCALEBITS 16 /* speediest right-shift on some machines */
72 #define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
73 #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
74 #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
76 /* We allocate one big table and divide it up into eight parts, instead of
77 * doing eight alloc_small requests. This lets us use a single table base
78 * address, which can be held in a register in the inner loops on many
79 * machines (more than can hold all eight addresses, anyway).
82 #define R_Y_OFF 0 /* offset to R => Y section */
83 #define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
84 #define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
85 #define R_CB_OFF (3*(MAXJSAMPLE+1))
86 #define G_CB_OFF (4*(MAXJSAMPLE+1))
87 #define B_CB_OFF (5*(MAXJSAMPLE+1))
88 #define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
89 #define G_CR_OFF (6*(MAXJSAMPLE+1))
90 #define B_CR_OFF (7*(MAXJSAMPLE+1))
91 #define TABLE_SIZE (8*(MAXJSAMPLE+1))
95 * Initialize for RGB->YCC colorspace conversion.
99 rgb_ycc_start (j_compress_ptr cinfo
)
101 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
105 /* Allocate and fill in the conversion tables. */
106 cconvert
->rgb_ycc_tab
= rgb_ycc_tab
= (INT32
*)
107 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
108 TABLE_SIZE
* SIZEOF(INT32
));
110 for (i
= 0; i
<= MAXJSAMPLE
; i
++) {
111 rgb_ycc_tab
[i
+R_Y_OFF
] = FIX(0.299) * i
;
112 rgb_ycc_tab
[i
+G_Y_OFF
] = FIX(0.587) * i
;
113 rgb_ycc_tab
[i
+B_Y_OFF
] = FIX(0.114) * i
+ ONE_HALF
;
114 rgb_ycc_tab
[i
+R_CB_OFF
] = (- FIX(0.168735892)) * i
;
115 rgb_ycc_tab
[i
+G_CB_OFF
] = (- FIX(0.331264108)) * i
;
116 /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
117 * This ensures that the maximum output will round to MAXJSAMPLE
118 * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
120 rgb_ycc_tab
[i
+B_CB_OFF
] = FIX(0.5) * i
+ CBCR_OFFSET
+ ONE_HALF
-1;
121 /* B=>Cb and R=>Cr tables are the same
122 rgb_ycc_tab[i+R_CR_OFF] = FIX(0.5) * i + CBCR_OFFSET + ONE_HALF-1;
124 rgb_ycc_tab
[i
+G_CR_OFF
] = (- FIX(0.418687589)) * i
;
125 rgb_ycc_tab
[i
+B_CR_OFF
] = (- FIX(0.081312411)) * i
;
131 * Convert some rows of samples to the JPEG colorspace.
133 * Note that we change from the application's interleaved-pixel format
134 * to our internal noninterleaved, one-plane-per-component format. The
135 * input buffer is therefore three times as wide as the output buffer.
137 * A starting row offset is provided only for the output buffer. The
138 * caller can easily adjust the passed input_buf value to accommodate
139 * any row offset required on that side.
143 rgb_ycc_convert (j_compress_ptr cinfo
,
144 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
145 JDIMENSION output_row
, int num_rows
)
147 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
148 register int r
, g
, b
;
149 register INT32
* ctab
= cconvert
->rgb_ycc_tab
;
150 register JSAMPROW inptr
;
151 register JSAMPROW outptr0
, outptr1
, outptr2
;
152 register JDIMENSION col
;
153 JDIMENSION num_cols
= cinfo
->image_width
;
155 while (--num_rows
>= 0) {
156 inptr
= *input_buf
++;
157 outptr0
= output_buf
[0][output_row
];
158 outptr1
= output_buf
[1][output_row
];
159 outptr2
= output_buf
[2][output_row
];
161 for (col
= 0; col
< num_cols
; col
++) {
162 r
= GETJSAMPLE(inptr
[RGB_RED
]);
163 g
= GETJSAMPLE(inptr
[RGB_GREEN
]);
164 b
= GETJSAMPLE(inptr
[RGB_BLUE
]);
165 inptr
+= RGB_PIXELSIZE
;
166 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
167 * must be too; we do not need an explicit range-limiting operation.
168 * Hence the value being shifted is never negative, and we don't
169 * need the general RIGHT_SHIFT macro.
172 outptr0
[col
] = (JSAMPLE
)
173 ((ctab
[r
+R_Y_OFF
] + ctab
[g
+G_Y_OFF
] + ctab
[b
+B_Y_OFF
])
176 outptr1
[col
] = (JSAMPLE
)
177 ((ctab
[r
+R_CB_OFF
] + ctab
[g
+G_CB_OFF
] + ctab
[b
+B_CB_OFF
])
180 outptr2
[col
] = (JSAMPLE
)
181 ((ctab
[r
+R_CR_OFF
] + ctab
[g
+G_CR_OFF
] + ctab
[b
+B_CR_OFF
])
188 /**************** Cases other than RGB -> YCbCr **************/
192 * Convert some rows of samples to the JPEG colorspace.
193 * This version handles RGB->grayscale conversion, which is the same
194 * as the RGB->Y portion of RGB->YCbCr.
195 * We assume rgb_ycc_start has been called (we only use the Y tables).
199 rgb_gray_convert (j_compress_ptr cinfo
,
200 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
201 JDIMENSION output_row
, int num_rows
)
203 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
204 register int r
, g
, b
;
205 register INT32
* ctab
= cconvert
->rgb_ycc_tab
;
206 register JSAMPROW inptr
;
207 register JSAMPROW outptr
;
208 register JDIMENSION col
;
209 JDIMENSION num_cols
= cinfo
->image_width
;
211 while (--num_rows
>= 0) {
212 inptr
= *input_buf
++;
213 outptr
= output_buf
[0][output_row
++];
214 for (col
= 0; col
< num_cols
; col
++) {
215 r
= GETJSAMPLE(inptr
[RGB_RED
]);
216 g
= GETJSAMPLE(inptr
[RGB_GREEN
]);
217 b
= GETJSAMPLE(inptr
[RGB_BLUE
]);
218 inptr
+= RGB_PIXELSIZE
;
220 outptr
[col
] = (JSAMPLE
)
221 ((ctab
[r
+R_Y_OFF
] + ctab
[g
+G_Y_OFF
] + ctab
[b
+B_Y_OFF
])
229 * Convert some rows of samples to the JPEG colorspace.
230 * This version handles Adobe-style CMYK->YCCK conversion,
231 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the
232 * same conversion as above, while passing K (black) unchanged.
233 * We assume rgb_ycc_start has been called.
237 cmyk_ycck_convert (j_compress_ptr cinfo
,
238 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
239 JDIMENSION output_row
, int num_rows
)
241 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
242 register int r
, g
, b
;
243 register INT32
* ctab
= cconvert
->rgb_ycc_tab
;
244 register JSAMPROW inptr
;
245 register JSAMPROW outptr0
, outptr1
, outptr2
, outptr3
;
246 register JDIMENSION col
;
247 JDIMENSION num_cols
= cinfo
->image_width
;
249 while (--num_rows
>= 0) {
250 inptr
= *input_buf
++;
251 outptr0
= output_buf
[0][output_row
];
252 outptr1
= output_buf
[1][output_row
];
253 outptr2
= output_buf
[2][output_row
];
254 outptr3
= output_buf
[3][output_row
];
256 for (col
= 0; col
< num_cols
; col
++) {
257 r
= MAXJSAMPLE
- GETJSAMPLE(inptr
[0]);
258 g
= MAXJSAMPLE
- GETJSAMPLE(inptr
[1]);
259 b
= MAXJSAMPLE
- GETJSAMPLE(inptr
[2]);
260 /* K passes through as-is */
261 outptr3
[col
] = inptr
[3]; /* don't need GETJSAMPLE here */
263 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
264 * must be too; we do not need an explicit range-limiting operation.
265 * Hence the value being shifted is never negative, and we don't
266 * need the general RIGHT_SHIFT macro.
269 outptr0
[col
] = (JSAMPLE
)
270 ((ctab
[r
+R_Y_OFF
] + ctab
[g
+G_Y_OFF
] + ctab
[b
+B_Y_OFF
])
273 outptr1
[col
] = (JSAMPLE
)
274 ((ctab
[r
+R_CB_OFF
] + ctab
[g
+G_CB_OFF
] + ctab
[b
+B_CB_OFF
])
277 outptr2
[col
] = (JSAMPLE
)
278 ((ctab
[r
+R_CR_OFF
] + ctab
[g
+G_CR_OFF
] + ctab
[b
+B_CR_OFF
])
286 * Convert some rows of samples to the JPEG colorspace.
287 * [R,G,B] to [R-G,G,B-G] conversion with modulo calculation
288 * (forward reversible color transform).
289 * This can be seen as an adaption of the general RGB->YCbCr
290 * conversion equation with Kr = Kb = 0, while replacing the
291 * normalization by modulo calculation.
295 rgb_rgb1_convert (j_compress_ptr cinfo
,
296 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
297 JDIMENSION output_row
, int num_rows
)
299 register int r
, g
, b
;
300 register JSAMPROW inptr
;
301 register JSAMPROW outptr0
, outptr1
, outptr2
;
302 register JDIMENSION col
;
303 JDIMENSION num_cols
= cinfo
->image_width
;
305 while (--num_rows
>= 0) {
306 inptr
= *input_buf
++;
307 outptr0
= output_buf
[0][output_row
];
308 outptr1
= output_buf
[1][output_row
];
309 outptr2
= output_buf
[2][output_row
];
311 for (col
= 0; col
< num_cols
; col
++) {
312 r
= GETJSAMPLE(inptr
[RGB_RED
]);
313 g
= GETJSAMPLE(inptr
[RGB_GREEN
]);
314 b
= GETJSAMPLE(inptr
[RGB_BLUE
]);
315 inptr
+= RGB_PIXELSIZE
;
316 /* Assume that MAXJSAMPLE+1 is a power of 2, so that the MOD
317 * (modulo) operator is equivalent to the bitmask operator AND.
319 outptr0
[col
] = (JSAMPLE
) ((r
- g
+ CENTERJSAMPLE
) & MAXJSAMPLE
);
320 outptr1
[col
] = (JSAMPLE
) g
;
321 outptr2
[col
] = (JSAMPLE
) ((b
- g
+ CENTERJSAMPLE
) & MAXJSAMPLE
);
328 * Convert some rows of samples to the JPEG colorspace.
329 * This version handles grayscale output with no conversion.
330 * The source can be either plain grayscale or YCC (since Y == gray).
334 grayscale_convert (j_compress_ptr cinfo
,
335 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
336 JDIMENSION output_row
, int num_rows
)
338 register JSAMPROW inptr
;
339 register JSAMPROW outptr
;
340 register JDIMENSION count
;
341 register int instride
= cinfo
->input_components
;
342 JDIMENSION num_cols
= cinfo
->image_width
;
344 while (--num_rows
>= 0) {
345 inptr
= *input_buf
++;
346 outptr
= output_buf
[0][output_row
++];
347 for (count
= num_cols
; count
> 0; count
--) {
348 *outptr
++ = *inptr
; /* don't need GETJSAMPLE() here */
356 * Convert some rows of samples to the JPEG colorspace.
357 * No colorspace conversion, but change from interleaved
358 * to separate-planes representation.
362 rgb_convert (j_compress_ptr cinfo
,
363 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
364 JDIMENSION output_row
, int num_rows
)
366 register JSAMPROW inptr
;
367 register JSAMPROW outptr0
, outptr1
, outptr2
;
368 register JDIMENSION col
;
369 JDIMENSION num_cols
= cinfo
->image_width
;
371 while (--num_rows
>= 0) {
372 inptr
= *input_buf
++;
373 outptr0
= output_buf
[0][output_row
];
374 outptr1
= output_buf
[1][output_row
];
375 outptr2
= output_buf
[2][output_row
];
377 for (col
= 0; col
< num_cols
; col
++) {
378 /* We can dispense with GETJSAMPLE() here */
379 outptr0
[col
] = inptr
[RGB_RED
];
380 outptr1
[col
] = inptr
[RGB_GREEN
];
381 outptr2
[col
] = inptr
[RGB_BLUE
];
382 inptr
+= RGB_PIXELSIZE
;
389 * Convert some rows of samples to the JPEG colorspace.
390 * This version handles multi-component colorspaces without conversion.
391 * We assume input_components == num_components.
395 null_convert (j_compress_ptr cinfo
,
396 JSAMPARRAY input_buf
, JSAMPIMAGE output_buf
,
397 JDIMENSION output_row
, int num_rows
)
399 register JSAMPROW inptr
;
400 register JSAMPROW outptr
;
401 register JDIMENSION count
;
402 register int num_comps
= cinfo
->num_components
;
403 JDIMENSION num_cols
= cinfo
->image_width
;
406 while (--num_rows
>= 0) {
407 /* It seems fastest to make a separate pass for each component. */
408 for (ci
= 0; ci
< num_comps
; ci
++) {
409 inptr
= input_buf
[0] + ci
;
410 outptr
= output_buf
[ci
][output_row
];
411 for (count
= num_cols
; count
> 0; count
--) {
412 *outptr
++ = *inptr
; /* don't need GETJSAMPLE() here */
423 * Empty method for start_pass.
427 null_method (j_compress_ptr cinfo
)
434 * Module initialization routine for input colorspace conversion.
438 jinit_color_converter (j_compress_ptr cinfo
)
440 my_cconvert_ptr cconvert
;
442 cconvert
= (my_cconvert_ptr
) (*cinfo
->mem
->alloc_small
)
443 ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, SIZEOF(my_color_converter
));
444 cinfo
->cconvert
= &cconvert
->pub
;
445 /* set start_pass to null method until we find out differently */
446 cconvert
->pub
.start_pass
= null_method
;
448 /* Make sure input_components agrees with in_color_space */
449 switch (cinfo
->in_color_space
) {
451 if (cinfo
->input_components
!= 1)
452 ERREXIT(cinfo
, JERR_BAD_IN_COLORSPACE
);
457 #if RGB_PIXELSIZE != 3
458 if (cinfo
->input_components
!= RGB_PIXELSIZE
)
459 ERREXIT(cinfo
, JERR_BAD_IN_COLORSPACE
);
461 #endif /* else share code with YCbCr */
465 if (cinfo
->input_components
!= 3)
466 ERREXIT(cinfo
, JERR_BAD_IN_COLORSPACE
);
471 if (cinfo
->input_components
!= 4)
472 ERREXIT(cinfo
, JERR_BAD_IN_COLORSPACE
);
475 default: /* JCS_UNKNOWN can be anything */
476 if (cinfo
->input_components
< 1)
477 ERREXIT(cinfo
, JERR_BAD_IN_COLORSPACE
);
480 /* Support color transform only for RGB colorspaces */
481 if (cinfo
->color_transform
&&
482 cinfo
->jpeg_color_space
!= JCS_RGB
&&
483 cinfo
->jpeg_color_space
!= JCS_BG_RGB
)
484 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
486 /* Check num_components, set conversion method based on requested space */
487 switch (cinfo
->jpeg_color_space
) {
489 if (cinfo
->num_components
!= 1)
490 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
491 switch (cinfo
->in_color_space
) {
495 cconvert
->pub
.color_convert
= grayscale_convert
;
498 cconvert
->pub
.start_pass
= rgb_ycc_start
;
499 cconvert
->pub
.color_convert
= rgb_gray_convert
;
502 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
508 if (cinfo
->num_components
!= 3)
509 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
510 if (cinfo
->in_color_space
!= cinfo
->jpeg_color_space
)
511 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
512 switch (cinfo
->color_transform
) {
514 cconvert
->pub
.color_convert
= rgb_convert
;
516 case JCT_SUBTRACT_GREEN
:
517 cconvert
->pub
.color_convert
= rgb_rgb1_convert
;
520 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
525 if (cinfo
->num_components
!= 3)
526 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
527 switch (cinfo
->in_color_space
) {
529 cconvert
->pub
.start_pass
= rgb_ycc_start
;
530 cconvert
->pub
.color_convert
= rgb_ycc_convert
;
533 cconvert
->pub
.color_convert
= null_convert
;
536 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
541 if (cinfo
->num_components
!= 3)
542 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
543 switch (cinfo
->in_color_space
) {
545 /* For conversion from normal RGB input to BG_YCC representation,
546 * the Cb/Cr values are first computed as usual, and then
547 * quantized further after DCT processing by a factor of
548 * 2 in reference to the nominal quantization factor.
550 /* need quantization scale by factor of 2 after DCT */
551 cinfo
->comp_info
[1].component_needed
= TRUE
;
552 cinfo
->comp_info
[2].component_needed
= TRUE
;
553 /* compute normal YCC first */
554 cconvert
->pub
.start_pass
= rgb_ycc_start
;
555 cconvert
->pub
.color_convert
= rgb_ycc_convert
;
558 /* need quantization scale by factor of 2 after DCT */
559 cinfo
->comp_info
[1].component_needed
= TRUE
;
560 cinfo
->comp_info
[2].component_needed
= TRUE
;
563 /* Pass through for BG_YCC input */
564 cconvert
->pub
.color_convert
= null_convert
;
567 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
572 if (cinfo
->num_components
!= 4)
573 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
574 if (cinfo
->in_color_space
!= JCS_CMYK
)
575 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
576 cconvert
->pub
.color_convert
= null_convert
;
580 if (cinfo
->num_components
!= 4)
581 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
582 switch (cinfo
->in_color_space
) {
584 cconvert
->pub
.start_pass
= rgb_ycc_start
;
585 cconvert
->pub
.color_convert
= cmyk_ycck_convert
;
588 cconvert
->pub
.color_convert
= null_convert
;
591 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
595 default: /* allow null conversion of JCS_UNKNOWN */
596 if (cinfo
->jpeg_color_space
!= cinfo
->in_color_space
||
597 cinfo
->num_components
!= cinfo
->input_components
)
598 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
599 cconvert
->pub
.color_convert
= null_convert
;