Coverage Report

Created: 2023-06-07 06:03

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