4 * Copyright (C) 1991-1996, 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 input colorspace conversion routines.
11 #define JPEG_INTERNALS
15 //#define USE_MOJAVE_CSC
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 CCIR 601-1, except that Cb and Cr are
33 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
34 * The conversion equations to be implemented are therefore
35 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
36 * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
37 * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
40 * The CSC was changed to the values below as per the Mojave
41 * specification. These values are enabled by the compile time flag
42 * USE_MOJAVE_CSC defined below.
44 * Y = 0.50000 * R + 0.00000 * G + 0.00000 * B
45 * Cb = 0.50000 * R - 0.50000 * G + 0.00000 * B + CENTERJSAMPLE
46 * Cr = 0.50000 * R + 0.00000 * G - 0.50000 * B + CENTERJSAMPLE
48 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
49 * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
50 * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
51 * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
52 * were not represented exactly. Now we sacrifice exact representation of
53 * maximum red and maximum blue in order to get exact grayscales.
55 * To avoid floating-point arithmetic, we represent the fractional constants
56 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
57 * the products by 2^16, with appropriate rounding, to get the correct answer.
59 * For even more speed, we avoid doing any multiplications in the inner loop
60 * by precalculating the constants times R,G,B for all possible values.
61 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
62 * for 12-bit samples it is still acceptable. It's not very reasonable for
63 * 16-bit samples, but if you want lossless storage you shouldn't be changing
65 * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
66 * in the tables to save adding them separately in the inner loop.
69 #define SCALEBITS 16 /* speediest right-shift on some machines */
70 #define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
71 #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
72 #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
74 /* We allocate one big table and divide it up into eight parts, instead of
75 * doing eight alloc_small requests. This lets us use a single table base
76 * address, which can be held in a register in the inner loops on many
77 * machines (more than can hold all eight addresses, anyway).
80 int iUseMojaveCsc = 1;
82 int R_Y_OFF; /* offset to R => Y section */
83 int G_Y_OFF; /* offset to G => Y section */
84 int B_Y_OFF; /* offset to B => Y section */
85 int R_CB_OFF; /* R=>Y, R=>Cb are the same */
86 int G_CB_OFF; /* offset to G => Cb section */
87 int B_CB_OFF; /* G=>Y, B=>Cb are the same */
88 int R_CR_OFF; /* R=>Y, R=>Cr are the same */
89 int G_CR_OFF; /* G=>Y, G=>Cr are the same */
90 int B_CR_OFF; /* G=>Cb, B=>Cr are the same */
93 void hp_rgb_ycc_setup (int iFlag)
95 iUseMojaveCsc = iFlag;
98 R_Y_OFF = 0; /* offset to R => Y section */
99 G_Y_OFF = (1*(MAXJSAMPLE+1)); /* offset to G => Y section */
100 B_Y_OFF = (2*(MAXJSAMPLE+1)); /* offset to B => Y section */
101 R_CB_OFF = R_Y_OFF; /* R=>Y, R=>Cb are the same */
102 G_CB_OFF = (3*(MAXJSAMPLE+1)); /* offset to G => Cb section */
103 B_CB_OFF = G_Y_OFF; /* G=>Y, B=>Cb are the same */
104 R_CR_OFF = R_Y_OFF; /* R=>Y, R=>Cr are the same */
105 G_CR_OFF = G_Y_OFF; /* G=>Y, G=>Cr are the same */
106 B_CR_OFF = G_CB_OFF; /* G=>Cb, B=>Cr are the same */
107 TABLE_SIZE = (4*(MAXJSAMPLE+1));
111 R_Y_OFF = 0; /* offset to R => Y section */
112 G_Y_OFF = (1*(MAXJSAMPLE+1)); /* offset to G => Y section */
113 B_Y_OFF= (2*(MAXJSAMPLE+1)); /* etc. */
114 R_CB_OFF= (3*(MAXJSAMPLE+1));
115 G_CB_OFF= (4*(MAXJSAMPLE+1));
116 B_CB_OFF= (5*(MAXJSAMPLE+1));
117 R_CR_OFF= B_CB_OFF; /* B=>Cb, R=>Cr are the same */
118 G_CR_OFF= (6*(MAXJSAMPLE+1));
119 B_CR_OFF= (7*(MAXJSAMPLE+1));
120 TABLE_SIZE =(8*(MAXJSAMPLE+1));
125 * Initialize for RGB->YCC colorspace conversion.
129 rgb_ycc_start (j_compress_ptr cinfo)
131 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
135 /* Allocate and fill in the conversion tables. */
136 cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
137 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
138 (TABLE_SIZE * SIZEOF(INT32)));
140 for (i = 0; i <= MAXJSAMPLE; i++)
144 rgb_ycc_tab[i+R_Y_OFF] = FIX(0.50000) * i;
145 rgb_ycc_tab[i+G_Y_OFF] = FIX(0.00000) * i;
146 rgb_ycc_tab[i+B_Y_OFF] = FIX(0.00000) * i + ONE_HALF;
147 /* R=>Y and R=>Cb tables are the same
148 rgb_ycc_tab[i+R_CB_OFF] = (FIX(0.50000)) * i;
150 rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.50000)) * i + CBCR_OFFSET + ONE_HALF-1;
151 /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
152 * This ensures that the maximum output will round to MAXJSAMPLE
153 * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
155 /* G=>Y and B=>Cb tables are the same
156 rgb_ycc_tab[i+B_CB_OFF] = FIX(0.00000) * i;
158 /* R=>Y and R=>Cr tables are the same
159 rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i;
161 /* G=>Y and G=>Cr tables are the same
162 rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.00000)) * i;
164 /* G=>Cb and B=>Cr tables are the same
165 rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.50000)) * i + CBCR_OFFSET + ONE_HALF-1;
170 rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
171 rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
172 rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
173 rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
174 rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
175 /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
176 * This ensures that the maximum output will round to MAXJSAMPLE
177 * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
179 rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
180 /* B=>Cb and R=>Cr tables are the same
181 rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
183 rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
184 rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
191 * Convert some rows of samples to the JPEG colorspace.
193 * Note that we change from the application's interleaved-pixel format
194 * to our internal noninterleaved, one-plane-per-component format.
195 * The input buffer is therefore three times as wide as the output buffer.
197 * A starting row offset is provided only for the output buffer. The caller
198 * can easily adjust the passed input_buf value to accommodate any row
199 * offset required on that side.
203 rgb_ycc_convert (j_compress_ptr cinfo,
204 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
205 JDIMENSION output_row, int num_rows)
207 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
208 register int r, g, b;
209 register INT32 * ctab = cconvert->rgb_ycc_tab;
210 register JSAMPROW inptr;
211 register JSAMPROW outptr0, outptr1, outptr2;
212 register JDIMENSION col;
213 JDIMENSION num_cols = cinfo->image_width;
215 while (--num_rows >= 0) {
216 inptr = *input_buf++;
217 outptr0 = output_buf[0][output_row];
218 outptr1 = output_buf[1][output_row];
219 outptr2 = output_buf[2][output_row];
221 for (col = 0; col < num_cols; col++) {
222 r = GETJSAMPLE(inptr[RGB_RED]);
223 g = GETJSAMPLE(inptr[RGB_GREEN]);
224 b = GETJSAMPLE(inptr[RGB_BLUE]);
225 inptr += RGB_PIXELSIZE;
226 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
227 * must be too; we do not need an explicit range-limiting operation.
228 * Hence the value being shifted is never negative, and we don't
229 * need the general RIGHT_SHIFT macro.
232 outptr0[col] = (JSAMPLE)
233 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
236 outptr1[col] = (JSAMPLE)
237 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
240 outptr2[col] = (JSAMPLE)
241 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
248 /**************** Cases other than RGB -> YCbCr **************/
252 * Convert some rows of samples to the JPEG colorspace.
253 * This version handles RGB->grayscale conversion, which is the same
254 * as the RGB->Y portion of RGB->YCbCr.
255 * We assume rgb_ycc_start has been called (we only use the Y tables).
259 rgb_gray_convert (j_compress_ptr cinfo,
260 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
261 JDIMENSION output_row, int num_rows)
263 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
264 register int r, g, b;
265 register INT32 * ctab = cconvert->rgb_ycc_tab;
266 register JSAMPROW inptr;
267 register JSAMPROW outptr;
268 register JDIMENSION col;
269 JDIMENSION num_cols = cinfo->image_width;
271 while (--num_rows >= 0) {
272 inptr = *input_buf++;
273 outptr = output_buf[0][output_row];
275 for (col = 0; col < num_cols; col++) {
276 r = GETJSAMPLE(inptr[RGB_RED]);
277 g = GETJSAMPLE(inptr[RGB_GREEN]);
278 b = GETJSAMPLE(inptr[RGB_BLUE]);
279 inptr += RGB_PIXELSIZE;
281 outptr[col] = (JSAMPLE)
282 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
290 * Convert some rows of samples to the JPEG colorspace.
291 * This version handles Adobe-style CMYK->YCCK conversion,
292 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
293 * conversion as above, while passing K (black) unchanged.
294 * We assume rgb_ycc_start has been called.
298 cmyk_ycck_convert (j_compress_ptr cinfo,
299 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
300 JDIMENSION output_row, int num_rows)
302 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
303 register int r, g, b;
304 register INT32 * ctab = cconvert->rgb_ycc_tab;
305 register JSAMPROW inptr;
306 register JSAMPROW outptr0, outptr1, outptr2, outptr3;
307 register JDIMENSION col;
308 JDIMENSION num_cols = cinfo->image_width;
310 while (--num_rows >= 0) {
311 inptr = *input_buf++;
312 outptr0 = output_buf[0][output_row];
313 outptr1 = output_buf[1][output_row];
314 outptr2 = output_buf[2][output_row];
315 outptr3 = output_buf[3][output_row];
317 for (col = 0; col < num_cols; col++) {
318 r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
319 g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
320 b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
321 /* K passes through as-is */
322 outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
324 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
325 * must be too; we do not need an explicit range-limiting operation.
326 * Hence the value being shifted is never negative, and we don't
327 * need the general RIGHT_SHIFT macro.
330 outptr0[col] = (JSAMPLE)
331 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
334 outptr1[col] = (JSAMPLE)
335 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
338 outptr2[col] = (JSAMPLE)
339 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
347 * Convert some rows of samples to the JPEG colorspace.
348 * This version handles grayscale output with no conversion.
349 * The source can be either plain grayscale or YCbCr (since Y == gray).
353 grayscale_convert (j_compress_ptr cinfo,
354 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
355 JDIMENSION output_row, int num_rows)
357 register JSAMPROW inptr;
358 register JSAMPROW outptr;
359 register JDIMENSION col;
360 JDIMENSION num_cols = cinfo->image_width;
361 int instride = cinfo->input_components;
363 while (--num_rows >= 0) {
364 inptr = *input_buf++;
365 outptr = output_buf[0][output_row];
367 for (col = 0; col < num_cols; col++) {
368 outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
376 * Convert some rows of samples to the JPEG colorspace.
377 * This version handles multi-component colorspaces without conversion.
378 * We assume input_components == num_components.
382 null_convert (j_compress_ptr cinfo,
383 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
384 JDIMENSION output_row, int num_rows)
386 register JSAMPROW inptr;
387 register JSAMPROW outptr;
388 register JDIMENSION col;
390 int nc = cinfo->num_components;
391 JDIMENSION num_cols = cinfo->image_width;
393 while (--num_rows >= 0) {
394 /* It seems fastest to make a separate pass for each component. */
395 for (ci = 0; ci < nc; ci++) {
397 outptr = output_buf[ci][output_row];
398 for (col = 0; col < num_cols; col++) {
399 outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
410 * Empty method for start_pass.
414 null_method (j_compress_ptr cinfo)
421 * Module initialization routine for input colorspace conversion.
425 jinit_color_converter (j_compress_ptr cinfo)
427 my_cconvert_ptr cconvert;
429 cconvert = (my_cconvert_ptr)
430 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
431 SIZEOF(my_color_converter));
432 cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
433 /* set start_pass to null method until we find out differently */
434 cconvert->pub.start_pass = null_method;
436 /* Make sure input_components agrees with in_color_space */
437 switch (cinfo->in_color_space) {
439 if (cinfo->input_components != 1)
440 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
444 #if RGB_PIXELSIZE != 3
445 if (cinfo->input_components != RGB_PIXELSIZE)
446 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
448 #endif /* else share code with YCbCr */
451 if (cinfo->input_components != 3)
452 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
457 if (cinfo->input_components != 4)
458 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
461 default: /* JCS_UNKNOWN can be anything */
462 if (cinfo->input_components < 1)
463 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
467 /* Check num_components, set conversion method based on requested space */
468 switch (cinfo->jpeg_color_space) {
470 if (cinfo->num_components != 1)
471 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
472 if (cinfo->in_color_space == JCS_GRAYSCALE)
473 cconvert->pub.color_convert = grayscale_convert;
474 else if (cinfo->in_color_space == JCS_RGB) {
475 cconvert->pub.start_pass = rgb_ycc_start;
476 cconvert->pub.color_convert = rgb_gray_convert;
477 } else if (cinfo->in_color_space == JCS_YCbCr)
478 cconvert->pub.color_convert = grayscale_convert;
480 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
484 if (cinfo->num_components != 3)
485 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
486 if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
487 cconvert->pub.color_convert = null_convert;
489 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
493 if (cinfo->num_components != 3)
494 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
495 if (cinfo->in_color_space == JCS_RGB) {
496 cconvert->pub.start_pass = rgb_ycc_start;
497 cconvert->pub.color_convert = rgb_ycc_convert;
498 } else if (cinfo->in_color_space == JCS_YCbCr)
499 cconvert->pub.color_convert = null_convert;
501 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
505 if (cinfo->num_components != 4)
506 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
507 if (cinfo->in_color_space == JCS_CMYK)
508 cconvert->pub.color_convert = null_convert;
510 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
514 if (cinfo->num_components != 4)
515 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
516 if (cinfo->in_color_space == JCS_CMYK) {
517 cconvert->pub.start_pass = rgb_ycc_start;
518 cconvert->pub.color_convert = cmyk_ycck_convert;
519 } else if (cinfo->in_color_space == JCS_YCCK)
520 cconvert->pub.color_convert = null_convert;
522 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
525 default: /* allow null conversion of JCS_UNKNOWN */
526 if (cinfo->jpeg_color_space != cinfo->in_color_space ||
527 cinfo->num_components != cinfo->input_components)
528 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
529 cconvert->pub.color_convert = null_convert;