Coverage Report

Created: 2023-06-07 06:03

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