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