Coverage Report

Created: 2022-11-14 06:33

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