1 : /*
2 : * jccolor.c
3 : *
4 : * Copyright (C) 1991-1996, Thomas G. Lane.
5 : * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
6 : * Copyright (C) 2009-2011, D. R. Commander.
7 : * This file is part of the Independent JPEG Group's software.
8 : * For conditions of distribution and use, see the accompanying README file.
9 : *
10 : * This file contains input colorspace conversion routines.
11 : */
12 :
13 : #define JPEG_INTERNALS
14 : #include "jinclude.h"
15 : #include "jpeglib.h"
16 : #include "jsimd.h"
17 : #include "config.h"
18 :
19 :
20 : /* Private subobject */
21 :
22 : typedef struct {
23 : struct jpeg_color_converter pub; /* public fields */
24 :
25 : /* Private state for RGB->YCC conversion */
26 : INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
27 : } my_color_converter;
28 :
29 : typedef my_color_converter * my_cconvert_ptr;
30 :
31 :
32 : /**************** RGB -> YCbCr conversion: most common case **************/
33 :
34 : /*
35 : * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
36 : * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
37 : * The conversion equations to be implemented are therefore
38 : * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
39 : * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
40 : * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
41 : * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
42 : * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
43 : * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
44 : * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
45 : * were not represented exactly. Now we sacrifice exact representation of
46 : * maximum red and maximum blue in order to get exact grayscales.
47 : *
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 : *
52 : * For even more speed, we avoid doing any multiplications in the inner loop
53 : * by precalculating the constants times R,G,B for all possible values.
54 : * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
55 : * for 12-bit samples it is still acceptable. It's not very reasonable for
56 : * 16-bit samples, but if you want lossless storage you shouldn't be changing
57 : * colorspace anyway.
58 : * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
59 : * in the tables to save adding them separately in the inner loop.
60 : */
61 :
62 : #define SCALEBITS 16 /* speediest right-shift on some machines */
63 : #define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
64 : #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
65 : #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
66 :
67 : /* We allocate one big table and divide it up into eight parts, instead of
68 : * doing eight alloc_small requests. This lets us use a single table base
69 : * address, which can be held in a register in the inner loops on many
70 : * machines (more than can hold all eight addresses, anyway).
71 : */
72 :
73 : #define R_Y_OFF 0 /* offset to R => Y section */
74 : #define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
75 : #define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
76 : #define R_CB_OFF (3*(MAXJSAMPLE+1))
77 : #define G_CB_OFF (4*(MAXJSAMPLE+1))
78 : #define B_CB_OFF (5*(MAXJSAMPLE+1))
79 : #define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
80 : #define G_CR_OFF (6*(MAXJSAMPLE+1))
81 : #define B_CR_OFF (7*(MAXJSAMPLE+1))
82 : #define TABLE_SIZE (8*(MAXJSAMPLE+1))
83 :
84 :
85 : /* Include inline routines for colorspace extensions */
86 :
87 : #include "jccolext.c"
88 : #undef RGB_RED
89 : #undef RGB_GREEN
90 : #undef RGB_BLUE
91 : #undef RGB_PIXELSIZE
92 :
93 : #define RGB_RED EXT_RGB_RED
94 : #define RGB_GREEN EXT_RGB_GREEN
95 : #define RGB_BLUE EXT_RGB_BLUE
96 : #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
97 : #define rgb_ycc_convert_internal extrgb_ycc_convert_internal
98 : #define rgb_gray_convert_internal extrgb_gray_convert_internal
99 : #include "jccolext.c"
100 : #undef RGB_RED
101 : #undef RGB_GREEN
102 : #undef RGB_BLUE
103 : #undef RGB_PIXELSIZE
104 : #undef rgb_ycc_convert_internal
105 : #undef rgb_gray_convert_internal
106 :
107 : #define RGB_RED EXT_RGBX_RED
108 : #define RGB_GREEN EXT_RGBX_GREEN
109 : #define RGB_BLUE EXT_RGBX_BLUE
110 : #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
111 : #define rgb_ycc_convert_internal extrgbx_ycc_convert_internal
112 : #define rgb_gray_convert_internal extrgbx_gray_convert_internal
113 : #include "jccolext.c"
114 : #undef RGB_RED
115 : #undef RGB_GREEN
116 : #undef RGB_BLUE
117 : #undef RGB_PIXELSIZE
118 : #undef rgb_ycc_convert_internal
119 : #undef rgb_gray_convert_internal
120 :
121 : #define RGB_RED EXT_BGR_RED
122 : #define RGB_GREEN EXT_BGR_GREEN
123 : #define RGB_BLUE EXT_BGR_BLUE
124 : #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
125 : #define rgb_ycc_convert_internal extbgr_ycc_convert_internal
126 : #define rgb_gray_convert_internal extbgr_gray_convert_internal
127 : #include "jccolext.c"
128 : #undef RGB_RED
129 : #undef RGB_GREEN
130 : #undef RGB_BLUE
131 : #undef RGB_PIXELSIZE
132 : #undef rgb_ycc_convert_internal
133 : #undef rgb_gray_convert_internal
134 :
135 : #define RGB_RED EXT_BGRX_RED
136 : #define RGB_GREEN EXT_BGRX_GREEN
137 : #define RGB_BLUE EXT_BGRX_BLUE
138 : #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
139 : #define rgb_ycc_convert_internal extbgrx_ycc_convert_internal
140 : #define rgb_gray_convert_internal extbgrx_gray_convert_internal
141 : #include "jccolext.c"
142 : #undef RGB_RED
143 : #undef RGB_GREEN
144 : #undef RGB_BLUE
145 : #undef RGB_PIXELSIZE
146 : #undef rgb_ycc_convert_internal
147 : #undef rgb_gray_convert_internal
148 :
149 : #define RGB_RED EXT_XBGR_RED
150 : #define RGB_GREEN EXT_XBGR_GREEN
151 : #define RGB_BLUE EXT_XBGR_BLUE
152 : #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
153 : #define rgb_ycc_convert_internal extxbgr_ycc_convert_internal
154 : #define rgb_gray_convert_internal extxbgr_gray_convert_internal
155 : #include "jccolext.c"
156 : #undef RGB_RED
157 : #undef RGB_GREEN
158 : #undef RGB_BLUE
159 : #undef RGB_PIXELSIZE
160 : #undef rgb_ycc_convert_internal
161 : #undef rgb_gray_convert_internal
162 :
163 : #define RGB_RED EXT_XRGB_RED
164 : #define RGB_GREEN EXT_XRGB_GREEN
165 : #define RGB_BLUE EXT_XRGB_BLUE
166 : #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
167 : #define rgb_ycc_convert_internal extxrgb_ycc_convert_internal
168 : #define rgb_gray_convert_internal extxrgb_gray_convert_internal
169 : #include "jccolext.c"
170 : #undef RGB_RED
171 : #undef RGB_GREEN
172 : #undef RGB_BLUE
173 : #undef RGB_PIXELSIZE
174 : #undef rgb_ycc_convert_internal
175 : #undef rgb_gray_convert_internal
176 :
177 :
178 : /*
179 : * Initialize for RGB->YCC colorspace conversion.
180 : */
181 :
182 : METHODDEF(void)
183 0 : rgb_ycc_start (j_compress_ptr cinfo)
184 : {
185 0 : my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
186 : INT32 * rgb_ycc_tab;
187 : INT32 i;
188 :
189 : /* Allocate and fill in the conversion tables. */
190 0 : cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
191 0 : (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
192 : (TABLE_SIZE * SIZEOF(INT32)));
193 :
194 0 : for (i = 0; i <= MAXJSAMPLE; i++) {
195 0 : rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
196 0 : rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
197 0 : rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
198 0 : rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
199 0 : rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
200 : /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
201 : * This ensures that the maximum output will round to MAXJSAMPLE
202 : * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
203 : */
204 0 : rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
205 : /* B=>Cb and R=>Cr tables are the same
206 : rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
207 : */
208 0 : rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
209 0 : rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
210 : }
211 0 : }
212 :
213 :
214 : /*
215 : * Convert some rows of samples to the JPEG colorspace.
216 : */
217 :
218 : METHODDEF(void)
219 0 : rgb_ycc_convert (j_compress_ptr cinfo,
220 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
221 : JDIMENSION output_row, int num_rows)
222 : {
223 0 : switch (cinfo->in_color_space) {
224 : case JCS_EXT_RGB:
225 : extrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
226 : num_rows);
227 0 : break;
228 : case JCS_EXT_RGBX:
229 : case JCS_EXT_RGBA:
230 : extrgbx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
231 : num_rows);
232 0 : break;
233 : case JCS_EXT_BGR:
234 : extbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
235 : num_rows);
236 0 : break;
237 : case JCS_EXT_BGRX:
238 : case JCS_EXT_BGRA:
239 : extbgrx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
240 : num_rows);
241 0 : break;
242 : case JCS_EXT_XBGR:
243 : case JCS_EXT_ABGR:
244 : extxbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
245 : num_rows);
246 0 : break;
247 : case JCS_EXT_XRGB:
248 : case JCS_EXT_ARGB:
249 : extxrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
250 : num_rows);
251 0 : break;
252 : default:
253 : rgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,
254 : num_rows);
255 0 : break;
256 : }
257 0 : }
258 :
259 :
260 : /**************** Cases other than RGB -> YCbCr **************/
261 :
262 :
263 : /*
264 : * Convert some rows of samples to the JPEG colorspace.
265 : */
266 :
267 : METHODDEF(void)
268 0 : rgb_gray_convert (j_compress_ptr cinfo,
269 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
270 : JDIMENSION output_row, int num_rows)
271 : {
272 0 : switch (cinfo->in_color_space) {
273 : case JCS_EXT_RGB:
274 : extrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
275 : num_rows);
276 0 : break;
277 : case JCS_EXT_RGBX:
278 : case JCS_EXT_RGBA:
279 : extrgbx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
280 : num_rows);
281 0 : break;
282 : case JCS_EXT_BGR:
283 : extbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
284 : num_rows);
285 0 : break;
286 : case JCS_EXT_BGRX:
287 : case JCS_EXT_BGRA:
288 : extbgrx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
289 : num_rows);
290 0 : break;
291 : case JCS_EXT_XBGR:
292 : case JCS_EXT_ABGR:
293 : extxbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
294 : num_rows);
295 0 : break;
296 : case JCS_EXT_XRGB:
297 : case JCS_EXT_ARGB:
298 : extxrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
299 : num_rows);
300 0 : break;
301 : default:
302 : rgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,
303 : num_rows);
304 0 : break;
305 : }
306 0 : }
307 :
308 :
309 : /*
310 : * Convert some rows of samples to the JPEG colorspace.
311 : * This version handles Adobe-style CMYK->YCCK conversion,
312 : * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
313 : * conversion as above, while passing K (black) unchanged.
314 : * We assume rgb_ycc_start has been called.
315 : */
316 :
317 : METHODDEF(void)
318 0 : cmyk_ycck_convert (j_compress_ptr cinfo,
319 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
320 : JDIMENSION output_row, int num_rows)
321 : {
322 0 : my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
323 : register int r, g, b;
324 0 : register INT32 * ctab = cconvert->rgb_ycc_tab;
325 : register JSAMPROW inptr;
326 : register JSAMPROW outptr0, outptr1, outptr2, outptr3;
327 : register JDIMENSION col;
328 0 : JDIMENSION num_cols = cinfo->image_width;
329 :
330 0 : while (--num_rows >= 0) {
331 0 : inptr = *input_buf++;
332 0 : outptr0 = output_buf[0][output_row];
333 0 : outptr1 = output_buf[1][output_row];
334 0 : outptr2 = output_buf[2][output_row];
335 0 : outptr3 = output_buf[3][output_row];
336 0 : output_row++;
337 0 : for (col = 0; col < num_cols; col++) {
338 0 : r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
339 0 : g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
340 0 : b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
341 : /* K passes through as-is */
342 0 : outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
343 0 : inptr += 4;
344 : /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
345 : * must be too; we do not need an explicit range-limiting operation.
346 : * Hence the value being shifted is never negative, and we don't
347 : * need the general RIGHT_SHIFT macro.
348 : */
349 : /* Y */
350 0 : outptr0[col] = (JSAMPLE)
351 0 : ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
352 0 : >> SCALEBITS);
353 : /* Cb */
354 0 : outptr1[col] = (JSAMPLE)
355 0 : ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
356 0 : >> SCALEBITS);
357 : /* Cr */
358 0 : outptr2[col] = (JSAMPLE)
359 0 : ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
360 0 : >> SCALEBITS);
361 : }
362 : }
363 0 : }
364 :
365 :
366 : /*
367 : * Convert some rows of samples to the JPEG colorspace.
368 : * This version handles grayscale output with no conversion.
369 : * The source can be either plain grayscale or YCbCr (since Y == gray).
370 : */
371 :
372 : METHODDEF(void)
373 0 : grayscale_convert (j_compress_ptr cinfo,
374 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
375 : JDIMENSION output_row, int num_rows)
376 : {
377 : register JSAMPROW inptr;
378 : register JSAMPROW outptr;
379 : register JDIMENSION col;
380 0 : JDIMENSION num_cols = cinfo->image_width;
381 0 : int instride = cinfo->input_components;
382 :
383 0 : while (--num_rows >= 0) {
384 0 : inptr = *input_buf++;
385 0 : outptr = output_buf[0][output_row];
386 0 : output_row++;
387 0 : for (col = 0; col < num_cols; col++) {
388 0 : outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
389 0 : inptr += instride;
390 : }
391 : }
392 0 : }
393 :
394 :
395 : /*
396 : * Convert some rows of samples to the JPEG colorspace.
397 : * This version handles multi-component colorspaces without conversion.
398 : * We assume input_components == num_components.
399 : */
400 :
401 : METHODDEF(void)
402 0 : null_convert (j_compress_ptr cinfo,
403 : JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
404 : JDIMENSION output_row, int num_rows)
405 : {
406 : register JSAMPROW inptr;
407 : register JSAMPROW outptr;
408 : register JDIMENSION col;
409 : register int ci;
410 0 : int nc = cinfo->num_components;
411 0 : JDIMENSION num_cols = cinfo->image_width;
412 :
413 0 : while (--num_rows >= 0) {
414 : /* It seems fastest to make a separate pass for each component. */
415 0 : for (ci = 0; ci < nc; ci++) {
416 0 : inptr = *input_buf;
417 0 : outptr = output_buf[ci][output_row];
418 0 : for (col = 0; col < num_cols; col++) {
419 0 : outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
420 0 : inptr += nc;
421 : }
422 : }
423 0 : input_buf++;
424 0 : output_row++;
425 : }
426 0 : }
427 :
428 :
429 : /*
430 : * Empty method for start_pass.
431 : */
432 :
433 : METHODDEF(void)
434 3 : null_method (j_compress_ptr cinfo)
435 : {
436 : /* no work needed */
437 3 : }
438 :
439 :
440 : /*
441 : * Module initialization routine for input colorspace conversion.
442 : */
443 :
444 : GLOBAL(void)
445 3 : jinit_color_converter (j_compress_ptr cinfo)
446 : {
447 : my_cconvert_ptr cconvert;
448 :
449 3 : cconvert = (my_cconvert_ptr)
450 3 : (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
451 : SIZEOF(my_color_converter));
452 3 : cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
453 : /* set start_pass to null method until we find out differently */
454 3 : cconvert->pub.start_pass = null_method;
455 :
456 : /* Make sure input_components agrees with in_color_space */
457 3 : switch (cinfo->in_color_space) {
458 : case JCS_GRAYSCALE:
459 0 : if (cinfo->input_components != 1)
460 0 : ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
461 0 : break;
462 :
463 : case JCS_RGB:
464 : case JCS_EXT_RGB:
465 : case JCS_EXT_RGBX:
466 : case JCS_EXT_BGR:
467 : case JCS_EXT_BGRX:
468 : case JCS_EXT_XBGR:
469 : case JCS_EXT_XRGB:
470 : case JCS_EXT_RGBA:
471 : case JCS_EXT_BGRA:
472 : case JCS_EXT_ABGR:
473 : case JCS_EXT_ARGB:
474 3 : if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
475 0 : ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
476 3 : break;
477 :
478 : case JCS_YCbCr:
479 0 : if (cinfo->input_components != 3)
480 0 : ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
481 0 : break;
482 :
483 : case JCS_CMYK:
484 : case JCS_YCCK:
485 0 : if (cinfo->input_components != 4)
486 0 : ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
487 0 : break;
488 :
489 : default: /* JCS_UNKNOWN can be anything */
490 0 : if (cinfo->input_components < 1)
491 0 : ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
492 0 : break;
493 : }
494 :
495 : /* Check num_components, set conversion method based on requested space */
496 3 : switch (cinfo->jpeg_color_space) {
497 : case JCS_GRAYSCALE:
498 0 : if (cinfo->num_components != 1)
499 0 : ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
500 0 : if (cinfo->in_color_space == JCS_GRAYSCALE)
501 0 : cconvert->pub.color_convert = grayscale_convert;
502 0 : else if (cinfo->in_color_space == JCS_RGB ||
503 0 : cinfo->in_color_space == JCS_EXT_RGB ||
504 0 : cinfo->in_color_space == JCS_EXT_RGBX ||
505 0 : cinfo->in_color_space == JCS_EXT_BGR ||
506 0 : cinfo->in_color_space == JCS_EXT_BGRX ||
507 0 : cinfo->in_color_space == JCS_EXT_XBGR ||
508 0 : cinfo->in_color_space == JCS_EXT_XRGB ||
509 0 : cinfo->in_color_space == JCS_EXT_RGBA ||
510 0 : cinfo->in_color_space == JCS_EXT_BGRA ||
511 0 : cinfo->in_color_space == JCS_EXT_ABGR ||
512 0 : cinfo->in_color_space == JCS_EXT_ARGB) {
513 0 : if (jsimd_can_rgb_gray())
514 0 : cconvert->pub.color_convert = jsimd_rgb_gray_convert;
515 : else {
516 0 : cconvert->pub.start_pass = rgb_ycc_start;
517 0 : cconvert->pub.color_convert = rgb_gray_convert;
518 : }
519 0 : } else if (cinfo->in_color_space == JCS_YCbCr)
520 0 : cconvert->pub.color_convert = grayscale_convert;
521 : else
522 0 : ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
523 0 : break;
524 :
525 : case JCS_RGB:
526 : case JCS_EXT_RGB:
527 : case JCS_EXT_RGBX:
528 : case JCS_EXT_BGR:
529 : case JCS_EXT_BGRX:
530 : case JCS_EXT_XBGR:
531 : case JCS_EXT_XRGB:
532 : case JCS_EXT_RGBA:
533 : case JCS_EXT_BGRA:
534 : case JCS_EXT_ABGR:
535 : case JCS_EXT_ARGB:
536 0 : if (cinfo->num_components != 3)
537 0 : ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
538 0 : if (cinfo->in_color_space == cinfo->jpeg_color_space &&
539 0 : rgb_pixelsize[cinfo->in_color_space] == 3)
540 0 : cconvert->pub.color_convert = null_convert;
541 : else
542 0 : ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
543 0 : break;
544 :
545 : case JCS_YCbCr:
546 3 : if (cinfo->num_components != 3)
547 0 : ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
548 3 : if (cinfo->in_color_space == JCS_RGB ||
549 0 : cinfo->in_color_space == JCS_EXT_RGB ||
550 0 : cinfo->in_color_space == JCS_EXT_RGBX ||
551 0 : cinfo->in_color_space == JCS_EXT_BGR ||
552 0 : cinfo->in_color_space == JCS_EXT_BGRX ||
553 0 : cinfo->in_color_space == JCS_EXT_XBGR ||
554 0 : cinfo->in_color_space == JCS_EXT_XRGB ||
555 0 : cinfo->in_color_space == JCS_EXT_RGBA ||
556 0 : cinfo->in_color_space == JCS_EXT_BGRA ||
557 0 : cinfo->in_color_space == JCS_EXT_ABGR ||
558 0 : cinfo->in_color_space == JCS_EXT_ARGB) {
559 6 : if (jsimd_can_rgb_ycc())
560 3 : cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
561 : else {
562 0 : cconvert->pub.start_pass = rgb_ycc_start;
563 0 : cconvert->pub.color_convert = rgb_ycc_convert;
564 : }
565 0 : } else if (cinfo->in_color_space == JCS_YCbCr)
566 0 : cconvert->pub.color_convert = null_convert;
567 : else
568 0 : ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
569 3 : break;
570 :
571 : case JCS_CMYK:
572 0 : if (cinfo->num_components != 4)
573 0 : ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
574 0 : if (cinfo->in_color_space == JCS_CMYK)
575 0 : cconvert->pub.color_convert = null_convert;
576 : else
577 0 : ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
578 0 : break;
579 :
580 : case JCS_YCCK:
581 0 : if (cinfo->num_components != 4)
582 0 : ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
583 0 : if (cinfo->in_color_space == JCS_CMYK) {
584 0 : cconvert->pub.start_pass = rgb_ycc_start;
585 0 : cconvert->pub.color_convert = cmyk_ycck_convert;
586 0 : } else if (cinfo->in_color_space == JCS_YCCK)
587 0 : cconvert->pub.color_convert = null_convert;
588 : else
589 0 : ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
590 0 : break;
591 :
592 : default: /* allow null conversion of JCS_UNKNOWN */
593 0 : if (cinfo->jpeg_color_space != cinfo->in_color_space ||
594 0 : cinfo->num_components != cinfo->input_components)
595 0 : ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
596 0 : cconvert->pub.color_convert = null_convert;
597 0 : break;
598 : }
599 3 : }
|