4 * Copyright (C) 1991-1997, Thomas G. Lane.
5 * This file is part of the Independent JPEG Group's software.
6 * For conditions of distribution and use, see the accompanying README file.
8 * This file contains output colorspace conversion routines.
11 #define JPEG_INTERNALS
15 #if defined(__VISAGECPP__)
16 /* Visual Age fixups for multiple declarations */
17 # define null_convert null_convert2 /* already in jcmaint.c */
18 # define grayscale_convert grayscale_convert2 /* already in jcmaint.c */
21 /* Private subobject */
24 struct jpeg_color_deconverter pub
; /* public fields */
26 /* Private state for YCC->RGB conversion */
27 int * Cr_r_tab
; /* => table for Cr to R conversion */
28 int * Cb_b_tab
; /* => table for Cb to B conversion */
29 JPEG_INT32
* Cr_g_tab
; /* => table for Cr to G conversion */
30 JPEG_INT32
* Cb_g_tab
; /* => table for Cb to G conversion */
31 } my_color_deconverter
;
33 typedef my_color_deconverter
* my_cconvert_ptr
;
36 /**************** YCbCr -> RGB conversion: most common case **************/
39 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
40 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
41 * The conversion equations to be implemented are therefore
42 * R = Y + 1.40200 * Cr
43 * G = Y - 0.34414 * Cb - 0.71414 * Cr
44 * B = Y + 1.77200 * Cb
45 * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
46 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
48 * To avoid floating-point arithmetic, we represent the fractional constants
49 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
50 * the products by 2^16, with appropriate rounding, to get the correct answer.
51 * Notice that Y, being an integral input, does not contribute any fraction
52 * so it need not participate in the rounding.
54 * For even more speed, we avoid doing any multiplications in the inner loop
55 * by precalculating the constants times Cb and Cr for all possible values.
56 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
57 * for 12-bit samples it is still acceptable. It's not very reasonable for
58 * 16-bit samples, but if you want lossless storage you shouldn't be changing
60 * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
61 * values for the G calculation are left scaled up, since we must add them
62 * together before rounding.
65 #define SCALEBITS 16 /* speediest right-shift on some machines */
66 #define ONE_HALF ((JPEG_INT32) 1 << (SCALEBITS-1))
67 #define FIX(x) ((JPEG_INT32) ((x) * (1L<<SCALEBITS) + 0.5))
71 * Initialize tables for YCC->RGB colorspace conversion.
75 build_ycc_rgb_table (j_decompress_ptr cinfo
)
77 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
82 cconvert
->Cr_r_tab
= (int *)
83 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
84 (MAXJSAMPLE
+1) * SIZEOF(int));
85 cconvert
->Cb_b_tab
= (int *)
86 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
87 (MAXJSAMPLE
+1) * SIZEOF(int));
88 cconvert
->Cr_g_tab
= (JPEG_INT32
*)
89 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
90 (MAXJSAMPLE
+1) * SIZEOF(JPEG_INT32
));
91 cconvert
->Cb_g_tab
= (JPEG_INT32
*)
92 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
93 (MAXJSAMPLE
+1) * SIZEOF(JPEG_INT32
));
95 for (i
= 0, x
= -CENTERJSAMPLE
; i
<= MAXJSAMPLE
; i
++, x
++) {
96 /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
97 /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
98 /* Cr=>R value is nearest int to 1.40200 * x */
99 cconvert
->Cr_r_tab
[i
] = (int)
100 RIGHT_SHIFT(FIX(1.40200) * x
+ ONE_HALF
, SCALEBITS
);
101 /* Cb=>B value is nearest int to 1.77200 * x */
102 cconvert
->Cb_b_tab
[i
] = (int)
103 RIGHT_SHIFT(FIX(1.77200) * x
+ ONE_HALF
, SCALEBITS
);
104 /* Cr=>G value is scaled-up -0.71414 * x */
105 cconvert
->Cr_g_tab
[i
] = (- FIX(0.71414)) * x
;
106 /* Cb=>G value is scaled-up -0.34414 * x */
107 /* We also add in ONE_HALF so that need not do it in inner loop */
108 cconvert
->Cb_g_tab
[i
] = (- FIX(0.34414)) * x
+ ONE_HALF
;
114 * Convert some rows of samples to the output colorspace.
116 * Note that we change from noninterleaved, one-plane-per-component format
117 * to interleaved-pixel format. The output buffer is therefore three times
118 * as wide as the input buffer.
119 * A starting row offset is provided only for the input buffer. The caller
120 * can easily adjust the passed output_buf value to accommodate any row
121 * offset required on that side.
125 ycc_rgb_convert (j_decompress_ptr cinfo
,
126 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
127 JSAMPARRAY output_buf
, int num_rows
)
129 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
130 register int y
, cb
, cr
;
131 register JSAMPROW outptr
;
132 register JSAMPROW inptr0
, inptr1
, inptr2
;
133 register JDIMENSION col
;
134 JDIMENSION num_cols
= cinfo
->output_width
;
135 /* copy these pointers into registers if possible */
136 register JSAMPLE
* range_limit
= cinfo
->sample_range_limit
;
137 register int * Crrtab
= cconvert
->Cr_r_tab
;
138 register int * Cbbtab
= cconvert
->Cb_b_tab
;
139 register JPEG_INT32
* Crgtab
= cconvert
->Cr_g_tab
;
140 register JPEG_INT32
* Cbgtab
= cconvert
->Cb_g_tab
;
143 while (--num_rows
>= 0) {
144 inptr0
= input_buf
[0][input_row
];
145 inptr1
= input_buf
[1][input_row
];
146 inptr2
= input_buf
[2][input_row
];
148 outptr
= *output_buf
++;
149 for (col
= 0; col
< num_cols
; col
++) {
150 y
= GETJSAMPLE(inptr0
[col
]);
151 cb
= GETJSAMPLE(inptr1
[col
]);
152 cr
= GETJSAMPLE(inptr2
[col
]);
153 /* Range-limiting is essential due to noise introduced by DCT losses. */
154 outptr
[RGB_RED
] = range_limit
[y
+ Crrtab
[cr
]];
155 outptr
[RGB_GREEN
] = range_limit
[y
+
156 ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
158 outptr
[RGB_BLUE
] = range_limit
[y
+ Cbbtab
[cb
]];
159 outptr
+= RGB_PIXELSIZE
;
165 /**************** Cases other than YCbCr -> RGB **************/
169 * Color conversion for no colorspace change: just copy the data,
170 * converting from separate-planes to interleaved representation.
174 null_convert (j_decompress_ptr cinfo
,
175 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
176 JSAMPARRAY output_buf
, int num_rows
)
178 register JSAMPROW inptr
, outptr
;
179 register JDIMENSION count
;
180 register int num_components
= cinfo
->num_components
;
181 JDIMENSION num_cols
= cinfo
->output_width
;
184 while (--num_rows
>= 0) {
185 for (ci
= 0; ci
< num_components
; ci
++) {
186 inptr
= input_buf
[ci
][input_row
];
187 outptr
= output_buf
[0] + ci
;
188 for (count
= num_cols
; count
> 0; count
--) {
189 *outptr
= *inptr
++; /* needn't bother with GETJSAMPLE() here */
190 outptr
+= num_components
;
200 * Color conversion for grayscale: just copy the data.
201 * This also works for YCbCr -> grayscale conversion, in which
202 * we just copy the Y (luminance) component and ignore chrominance.
206 grayscale_convert (j_decompress_ptr cinfo
,
207 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
208 JSAMPARRAY output_buf
, int num_rows
)
210 jcopy_sample_rows(input_buf
[0], (int) input_row
, output_buf
, 0,
211 num_rows
, cinfo
->output_width
);
216 * Convert grayscale to RGB: just duplicate the graylevel three times.
217 * This is provided to support applications that don't want to cope
218 * with grayscale as a separate case.
222 gray_rgb_convert (j_decompress_ptr cinfo
,
223 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
224 JSAMPARRAY output_buf
, int num_rows
)
226 register JSAMPROW inptr
, outptr
;
227 register JDIMENSION col
;
228 JDIMENSION num_cols
= cinfo
->output_width
;
230 while (--num_rows
>= 0) {
231 inptr
= input_buf
[0][input_row
++];
232 outptr
= *output_buf
++;
233 for (col
= 0; col
< num_cols
; col
++) {
234 /* We can dispense with GETJSAMPLE() here */
235 outptr
[RGB_RED
] = outptr
[RGB_GREEN
] = outptr
[RGB_BLUE
] = inptr
[col
];
236 outptr
+= RGB_PIXELSIZE
;
243 * Adobe-style YCCK->CMYK conversion.
244 * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
245 * conversion as above, while passing K (black) unchanged.
246 * We assume build_ycc_rgb_table has been called.
250 ycck_cmyk_convert (j_decompress_ptr cinfo
,
251 JSAMPIMAGE input_buf
, JDIMENSION input_row
,
252 JSAMPARRAY output_buf
, int num_rows
)
254 my_cconvert_ptr cconvert
= (my_cconvert_ptr
) cinfo
->cconvert
;
255 register int y
, cb
, cr
;
256 register JSAMPROW outptr
;
257 register JSAMPROW inptr0
, inptr1
, inptr2
, inptr3
;
258 register JDIMENSION col
;
259 JDIMENSION num_cols
= cinfo
->output_width
;
260 /* copy these pointers into registers if possible */
261 register JSAMPLE
* range_limit
= cinfo
->sample_range_limit
;
262 register int * Crrtab
= cconvert
->Cr_r_tab
;
263 register int * Cbbtab
= cconvert
->Cb_b_tab
;
264 register JPEG_INT32
* Crgtab
= cconvert
->Cr_g_tab
;
265 register JPEG_INT32
* Cbgtab
= cconvert
->Cb_g_tab
;
268 while (--num_rows
>= 0) {
269 inptr0
= input_buf
[0][input_row
];
270 inptr1
= input_buf
[1][input_row
];
271 inptr2
= input_buf
[2][input_row
];
272 inptr3
= input_buf
[3][input_row
];
274 outptr
= *output_buf
++;
275 for (col
= 0; col
< num_cols
; col
++) {
276 y
= GETJSAMPLE(inptr0
[col
]);
277 cb
= GETJSAMPLE(inptr1
[col
]);
278 cr
= GETJSAMPLE(inptr2
[col
]);
279 /* Range-limiting is essential due to noise introduced by DCT losses. */
280 outptr
[0] = range_limit
[MAXJSAMPLE
- (y
+ Crrtab
[cr
])]; /* red */
281 outptr
[1] = range_limit
[MAXJSAMPLE
- (y
+ /* green */
282 ((int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
284 outptr
[2] = range_limit
[MAXJSAMPLE
- (y
+ Cbbtab
[cb
])]; /* blue */
285 /* K passes through unchanged */
286 outptr
[3] = inptr3
[col
]; /* don't need GETJSAMPLE here */
294 * Empty method for start_pass.
298 start_pass_dcolor (j_decompress_ptr cinfo
)
305 * Module initialization routine for output colorspace conversion.
309 jinit_color_deconverter (j_decompress_ptr cinfo
)
311 my_cconvert_ptr cconvert
;
314 cconvert
= (my_cconvert_ptr
)
315 (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
,
316 SIZEOF(my_color_deconverter
));
317 cinfo
->cconvert
= (struct jpeg_color_deconverter
*) cconvert
;
318 cconvert
->pub
.start_pass
= start_pass_dcolor
;
320 /* Make sure num_components agrees with jpeg_color_space */
321 switch (cinfo
->jpeg_color_space
) {
323 if (cinfo
->num_components
!= 1)
324 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
329 if (cinfo
->num_components
!= 3)
330 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
335 if (cinfo
->num_components
!= 4)
336 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
339 default: /* JCS_UNKNOWN can be anything */
340 if (cinfo
->num_components
< 1)
341 ERREXIT(cinfo
, JERR_BAD_J_COLORSPACE
);
345 /* Set out_color_components and conversion method based on requested space.
346 * Also clear the component_needed flags for any unused components,
347 * so that earlier pipeline stages can avoid useless computation.
350 switch (cinfo
->out_color_space
) {
352 cinfo
->out_color_components
= 1;
353 if (cinfo
->jpeg_color_space
== JCS_GRAYSCALE
||
354 cinfo
->jpeg_color_space
== JCS_YCbCr
) {
355 cconvert
->pub
.color_convert
= grayscale_convert
;
356 /* For color->grayscale conversion, only the Y (0) component is needed */
357 for (ci
= 1; ci
< cinfo
->num_components
; ci
++)
358 cinfo
->comp_info
[ci
].component_needed
= FALSE
;
360 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
364 cinfo
->out_color_components
= RGB_PIXELSIZE
;
365 if (cinfo
->jpeg_color_space
== JCS_YCbCr
) {
366 cconvert
->pub
.color_convert
= ycc_rgb_convert
;
367 build_ycc_rgb_table(cinfo
);
368 } else if (cinfo
->jpeg_color_space
== JCS_GRAYSCALE
) {
369 cconvert
->pub
.color_convert
= gray_rgb_convert
;
370 } else if (cinfo
->jpeg_color_space
== JCS_RGB
&& RGB_PIXELSIZE
== 3) {
371 cconvert
->pub
.color_convert
= null_convert
;
373 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
377 cinfo
->out_color_components
= 4;
378 if (cinfo
->jpeg_color_space
== JCS_YCCK
) {
379 cconvert
->pub
.color_convert
= ycck_cmyk_convert
;
380 build_ycc_rgb_table(cinfo
);
381 } else if (cinfo
->jpeg_color_space
== JCS_CMYK
) {
382 cconvert
->pub
.color_convert
= null_convert
;
384 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
388 /* Permit null conversion to same output space */
389 if (cinfo
->out_color_space
== cinfo
->jpeg_color_space
) {
390 cinfo
->out_color_components
= cinfo
->num_components
;
391 cconvert
->pub
.color_convert
= null_convert
;
392 } else /* unsupported non-null conversion */
393 ERREXIT(cinfo
, JERR_CONVERSION_NOTIMPL
);
397 if (cinfo
->quantize_colors
)
398 cinfo
->output_components
= 1; /* single colormapped output component */
400 cinfo
->output_components
= cinfo
->out_color_components
;
403 #if defined(__VISAGECPP__)
404 # ifdef null_convert2
405 # undef null_convert2
407 # ifdef grayscale_convert2
408 # undef grayscale_convert2