blob: 2e2bfd2a4207e86bfaa0e3cdfde1f12f16ee7ab3 [file] [log] [blame]
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +00001/*
2 * jccolor.c
3 *
Thomas G. Lane489583f1996-02-07 00:00:00 +00004 * Copyright (C) 1991-1996, Thomas G. Lane.
Pierre Ossman59a39382009-03-09 13:15:56 +00005 * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
DRCf25c0712009-04-03 12:00:51 +00006 * Copyright 2009 D. R. Commander
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +00007 * 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.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000011 */
12
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000013#define JPEG_INTERNALS
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000014#include "jinclude.h"
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000015#include "jpeglib.h"
Pierre Ossman59a39382009-03-09 13:15:56 +000016#include "jsimd.h"
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000017
18
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000019/* Private subobject */
20
21typedef struct {
22 struct jpeg_color_converter pub; /* public fields */
23
24 /* Private state for RGB->YCC conversion */
25 INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
26} my_color_converter;
27
28typedef my_color_converter * my_cconvert_ptr;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +000029
30
Thomas G. Lane88aeed41992-12-10 00:00:00 +000031/**************** RGB -> YCbCr conversion: most common case **************/
32
33/*
34 * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
35 * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
36 * The conversion equations to be implemented are therefore
37 * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000038 * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
39 * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
Thomas G. Lane88aeed41992-12-10 00:00:00 +000040 * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000041 * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
42 * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
43 * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
44 * were not represented exactly. Now we sacrifice exact representation of
45 * maximum red and maximum blue in order to get exact grayscales.
Thomas G. Lane88aeed41992-12-10 00:00:00 +000046 *
47 * To avoid floating-point arithmetic, we represent the fractional constants
48 * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
49 * the products by 2^16, with appropriate rounding, to get the correct answer.
50 *
51 * For even more speed, we avoid doing any multiplications in the inner loop
52 * by precalculating the constants times R,G,B for all possible values.
53 * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
54 * for 12-bit samples it is still acceptable. It's not very reasonable for
55 * 16-bit samples, but if you want lossless storage you shouldn't be changing
56 * colorspace anyway.
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000057 * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
Thomas G. Lane88aeed41992-12-10 00:00:00 +000058 * in the tables to save adding them separately in the inner loop.
59 */
60
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +000061#define SCALEBITS 16 /* speediest right-shift on some machines */
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +000062#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
Thomas G. Lane88aeed41992-12-10 00:00:00 +000063#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
64#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
65
66/* We allocate one big table and divide it up into eight parts, instead of
67 * doing eight alloc_small requests. This lets us use a single table base
68 * address, which can be held in a register in the inner loops on many
69 * machines (more than can hold all eight addresses, anyway).
70 */
71
Thomas G. Lane88aeed41992-12-10 00:00:00 +000072#define R_Y_OFF 0 /* offset to R => Y section */
73#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
74#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
75#define R_CB_OFF (3*(MAXJSAMPLE+1))
76#define G_CB_OFF (4*(MAXJSAMPLE+1))
77#define B_CB_OFF (5*(MAXJSAMPLE+1))
78#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
79#define G_CR_OFF (6*(MAXJSAMPLE+1))
80#define B_CR_OFF (7*(MAXJSAMPLE+1))
81#define TABLE_SIZE (8*(MAXJSAMPLE+1))
82
83
DRC6c0e1fc2009-09-24 06:18:25 +000084#if BITS_IN_JSAMPLE == 8
85
86const unsigned char red_lut[256] = {
87 0 , 0 , 1 , 1 , 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 , 4 , 4 , 4 , 4 ,
88 5 , 5 , 5 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 8 , 8 , 8 , 9 , 9 , 9 ,
89 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14,
90 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19,
91 19, 19, 20, 20, 20, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 24,
92 24, 24, 25, 25, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28,
93 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33,
94 33, 34, 34, 34, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38,
95 38, 39, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
96 43, 43, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 47, 47, 47, 48,
97 48, 48, 48, 49, 49, 49, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52,
98 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 56, 56, 56, 57, 57, 57,
99 57, 58, 58, 58, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 62, 62,
100 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67,
101 67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71,
102 72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76
103};
104
105const unsigned char green_lut[256] = {
106 0 , 1 , 1 , 2 , 2 , 3 , 4 , 4 , 5 , 5 , 6 , 6 ,
107 7 , 8 , 8 , 9 , 9 , 10 , 11 , 11 , 12 , 12 , 13 , 14 ,
108 14 , 15 , 15 , 16 , 16 , 17 , 18 , 18 , 19 , 19 , 20 , 21 ,
109 21 , 22 , 22 , 23 , 23 , 24 , 25 , 25 , 26 , 26 , 27 , 28 ,
110 28 , 29 , 29 , 30 , 31 , 31 , 32 , 32 , 33 , 33 , 34 , 35 ,
111 35 , 36 , 36 , 37 , 38 , 38 , 39 , 39 , 40 , 41 , 41 , 42 ,
112 42 , 43 , 43 , 44 , 45 , 45 , 46 , 46 , 47 , 48 , 48 , 49 ,
113 49 , 50 , 50 , 51 , 52 , 52 , 53 , 53 , 54 , 55 , 55 , 56 ,
114 56 , 57 , 58 , 58 , 59 , 59 , 60 , 60 , 61 , 62 , 62 , 63 ,
115 63 , 64 , 65 , 65 , 66 , 66 , 67 , 68 , 68 , 69 , 69 , 70 ,
116 70 , 71 , 72 , 72 , 73 , 73 , 74 , 75 , 75 , 76 , 76 , 77 ,
117 77 , 78 , 79 , 79 , 80 , 80 , 81 , 82 , 82 , 83 , 83 , 84 ,
118 85 , 85 , 86 , 86 , 87 , 87 , 88 , 89 , 89 , 90 , 90 , 91 ,
119 92 , 92 , 93 , 93 , 94 , 95 , 95 , 96 , 96 , 97 , 97 , 98 ,
120 99 , 99 , 100, 100, 101, 102, 102, 103, 103, 104, 104, 105,
121 106, 106, 107, 107, 108, 109, 109, 110, 110, 111, 112, 112,
122 113, 113, 114, 114, 115, 116, 116, 117, 117, 118, 119, 119,
123 120, 120, 121, 122, 122, 123, 123, 124, 124, 125, 126, 126,
124 127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 133, 133,
125 34, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140,
126 141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147,
127 148, 149, 149, 150
128};
129
130const unsigned char blue_lut[256] = {
131 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 2 , 2 ,
132 2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 4 ,
133 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
134 5 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 7 , 7 , 7 , 7 , 7 , 7 ,
135 7 , 7 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 9 , 9 , 9 , 9 ,
136 9 , 9 , 9 , 9 , 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
137 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13,
138 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14,
139 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
140 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18,
141 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
142 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22,
143 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24,
144 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25,
145 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27,
146 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29
147};
148
149#endif
150
151
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000152/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000153 * Initialize for RGB->YCC colorspace conversion.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000154 */
155
Thomas G. Lane489583f1996-02-07 00:00:00 +0000156METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000157rgb_ycc_start (j_compress_ptr cinfo)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000158{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000159 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
160 INT32 * rgb_ycc_tab;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000161 INT32 i;
162
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000163 /* Allocate and fill in the conversion tables. */
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000164 cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
165 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
166 (TABLE_SIZE * SIZEOF(INT32)));
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000167
168 for (i = 0; i <= MAXJSAMPLE; i++) {
169 rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
170 rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
171 rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
172 rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
173 rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000174 /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
175 * This ensures that the maximum output will round to MAXJSAMPLE
176 * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
177 */
178 rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000179/* B=>Cb and R=>Cr tables are the same
Thomas G. Lane9ba2f5e1994-12-07 00:00:00 +0000180 rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000181*/
182 rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
183 rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
184 }
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000185}
186
187
188/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000189 * Convert some rows of samples to the JPEG colorspace.
190 *
191 * Note that we change from the application's interleaved-pixel format
192 * to our internal noninterleaved, one-plane-per-component format.
193 * The input buffer is therefore three times as wide as the output buffer.
194 *
195 * A starting row offset is provided only for the output buffer. The caller
196 * can easily adjust the passed input_buf value to accommodate any row
197 * offset required on that side.
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000198 */
199
Thomas G. Lane489583f1996-02-07 00:00:00 +0000200METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000201rgb_ycc_convert (j_compress_ptr cinfo,
202 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
203 JDIMENSION output_row, int num_rows)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000204{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000205 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000206 register int r, g, b;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000207 register INT32 * ctab = cconvert->rgb_ycc_tab;
208 register JSAMPROW inptr;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000209 register JSAMPROW outptr0, outptr1, outptr2;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000210 register JDIMENSION col;
211 JDIMENSION num_cols = cinfo->image_width;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000212
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000213 while (--num_rows >= 0) {
214 inptr = *input_buf++;
215 outptr0 = output_buf[0][output_row];
216 outptr1 = output_buf[1][output_row];
217 outptr2 = output_buf[2][output_row];
218 output_row++;
219 for (col = 0; col < num_cols; col++) {
DRCf25c0712009-04-03 12:00:51 +0000220 r = GETJSAMPLE(inptr[rgb_red[cinfo->in_color_space]]);
221 g = GETJSAMPLE(inptr[rgb_green[cinfo->in_color_space]]);
222 b = GETJSAMPLE(inptr[rgb_blue[cinfo->in_color_space]]);
223 inptr += rgb_pixelsize[cinfo->in_color_space];
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000224 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
Thomas G. Lane4a6b7301992-03-17 00:00:00 +0000225 * must be too; we do not need an explicit range-limiting operation.
226 * Hence the value being shifted is never negative, and we don't
227 * need the general RIGHT_SHIFT macro.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000228 */
229 /* Y */
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000230 outptr0[col] = (JSAMPLE)
231 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
232 >> SCALEBITS);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000233 /* Cb */
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000234 outptr1[col] = (JSAMPLE)
235 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
236 >> SCALEBITS);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000237 /* Cr */
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000238 outptr2[col] = (JSAMPLE)
239 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
240 >> SCALEBITS);
241 }
242 }
243}
244
245
246/**************** Cases other than RGB -> YCbCr **************/
247
248
249/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000250 * Convert some rows of samples to the JPEG colorspace.
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000251 * This version handles RGB->grayscale conversion, which is the same
252 * as the RGB->Y portion of RGB->YCbCr.
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000253 * We assume rgb_ycc_start has been called (we only use the Y tables).
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000254 */
255
Thomas G. Lane489583f1996-02-07 00:00:00 +0000256METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000257rgb_gray_convert (j_compress_ptr cinfo,
258 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
259 JDIMENSION output_row, int num_rows)
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000260{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000261 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
DRC6c0e1fc2009-09-24 06:18:25 +0000262 #if BITS_IN_JSAMPLE != 8
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000263 register INT32 * ctab = cconvert->rgb_ycc_tab;
DRC6c0e1fc2009-09-24 06:18:25 +0000264 #endif
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000265 register JSAMPROW inptr;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000266 register JSAMPROW outptr;
DRC6c0e1fc2009-09-24 06:18:25 +0000267 JSAMPLE *maxoutptr;
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000268 register JDIMENSION col;
269 JDIMENSION num_cols = cinfo->image_width;
DRC6c0e1fc2009-09-24 06:18:25 +0000270 int rindex = rgb_red[cinfo->in_color_space];
271 int gindex = rgb_green[cinfo->in_color_space];
272 int bindex = rgb_blue[cinfo->in_color_space];
273 int rgbstride = rgb_pixelsize[cinfo->in_color_space];
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000274
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000275 while (--num_rows >= 0) {
276 inptr = *input_buf++;
277 outptr = output_buf[0][output_row];
DRC6c0e1fc2009-09-24 06:18:25 +0000278 maxoutptr = &outptr[num_cols];
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000279 output_row++;
DRC6c0e1fc2009-09-24 06:18:25 +0000280 for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000281 /* Y */
DRC6c0e1fc2009-09-24 06:18:25 +0000282 #if BITS_IN_JSAMPLE == 8
283 *outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
284 + blue_lut[inptr[bindex]];
285 #else
286 *outptr = (JSAMPLE)
287 ((ctab[GETJSAMPLE(inptr[rindex])+R_Y_OFF]
288 + ctab[GETJSAMPLE(inptr[gindex])+G_Y_OFF]
289 + ctab[GETJSAMPLE(inptr[bindex])+B_Y_OFF])
290 >> SCALEBITS);
291 #endif
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000292 }
293 }
294}
295
296
297/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000298 * Convert some rows of samples to the JPEG colorspace.
299 * This version handles Adobe-style CMYK->YCCK conversion,
300 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
301 * conversion as above, while passing K (black) unchanged.
302 * We assume rgb_ycc_start has been called.
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000303 */
304
Thomas G. Lane489583f1996-02-07 00:00:00 +0000305METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000306cmyk_ycck_convert (j_compress_ptr cinfo,
307 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
308 JDIMENSION output_row, int num_rows)
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000309{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000310 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
311 register int r, g, b;
312 register INT32 * ctab = cconvert->rgb_ycc_tab;
313 register JSAMPROW inptr;
314 register JSAMPROW outptr0, outptr1, outptr2, outptr3;
315 register JDIMENSION col;
316 JDIMENSION num_cols = cinfo->image_width;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000317
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000318 while (--num_rows >= 0) {
319 inptr = *input_buf++;
320 outptr0 = output_buf[0][output_row];
321 outptr1 = output_buf[1][output_row];
322 outptr2 = output_buf[2][output_row];
323 outptr3 = output_buf[3][output_row];
324 output_row++;
325 for (col = 0; col < num_cols; col++) {
326 r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
327 g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
328 b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
329 /* K passes through as-is */
330 outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
331 inptr += 4;
332 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
333 * must be too; we do not need an explicit range-limiting operation.
334 * Hence the value being shifted is never negative, and we don't
335 * need the general RIGHT_SHIFT macro.
336 */
337 /* Y */
338 outptr0[col] = (JSAMPLE)
339 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
340 >> SCALEBITS);
341 /* Cb */
342 outptr1[col] = (JSAMPLE)
343 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
344 >> SCALEBITS);
345 /* Cr */
346 outptr2[col] = (JSAMPLE)
347 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
348 >> SCALEBITS);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000349 }
350 }
351}
352
353
354/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000355 * Convert some rows of samples to the JPEG colorspace.
356 * This version handles grayscale output with no conversion.
357 * The source can be either plain grayscale or YCbCr (since Y == gray).
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000358 */
359
Thomas G. Lane489583f1996-02-07 00:00:00 +0000360METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000361grayscale_convert (j_compress_ptr cinfo,
362 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
363 JDIMENSION output_row, int num_rows)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000364{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000365 register JSAMPROW inptr;
366 register JSAMPROW outptr;
367 register JDIMENSION col;
368 JDIMENSION num_cols = cinfo->image_width;
369 int instride = cinfo->input_components;
370
371 while (--num_rows >= 0) {
372 inptr = *input_buf++;
373 outptr = output_buf[0][output_row];
374 output_row++;
375 for (col = 0; col < num_cols; col++) {
376 outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
377 inptr += instride;
378 }
379 }
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000380}
381
382
383/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000384 * Convert some rows of samples to the JPEG colorspace.
385 * This version handles multi-component colorspaces without conversion.
386 * We assume input_components == num_components.
387 */
388
Thomas G. Lane489583f1996-02-07 00:00:00 +0000389METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000390null_convert (j_compress_ptr cinfo,
391 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
392 JDIMENSION output_row, int num_rows)
393{
394 register JSAMPROW inptr;
395 register JSAMPROW outptr;
396 register JDIMENSION col;
397 register int ci;
398 int nc = cinfo->num_components;
399 JDIMENSION num_cols = cinfo->image_width;
400
401 while (--num_rows >= 0) {
402 /* It seems fastest to make a separate pass for each component. */
403 for (ci = 0; ci < nc; ci++) {
404 inptr = *input_buf;
405 outptr = output_buf[ci][output_row];
406 for (col = 0; col < num_cols; col++) {
407 outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
408 inptr += nc;
409 }
410 }
411 input_buf++;
412 output_row++;
413 }
414}
415
416
417/*
418 * Empty method for start_pass.
419 */
420
Thomas G. Lane489583f1996-02-07 00:00:00 +0000421METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000422null_method (j_compress_ptr cinfo)
423{
424 /* no work needed */
425}
426
427
428/*
429 * Module initialization routine for input colorspace conversion.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000430 */
431
Thomas G. Lane489583f1996-02-07 00:00:00 +0000432GLOBAL(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000433jinit_color_converter (j_compress_ptr cinfo)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000434{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000435 my_cconvert_ptr cconvert;
436
437 cconvert = (my_cconvert_ptr)
438 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
439 SIZEOF(my_color_converter));
440 cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
441 /* set start_pass to null method until we find out differently */
442 cconvert->pub.start_pass = null_method;
443
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000444 /* Make sure input_components agrees with in_color_space */
445 switch (cinfo->in_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000446 case JCS_GRAYSCALE:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000447 if (cinfo->input_components != 1)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000448 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000449 break;
450
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000451 case JCS_RGB:
DRCf25c0712009-04-03 12:00:51 +0000452 case JCS_EXT_RGB:
453 case JCS_EXT_RGBX:
454 case JCS_EXT_BGR:
455 case JCS_EXT_BGRX:
456 case JCS_EXT_XBGR:
457 case JCS_EXT_XRGB:
458 if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
459 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
460 break;
461
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000462 case JCS_YCbCr:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000463 if (cinfo->input_components != 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000464 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000465 break;
466
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000467 case JCS_CMYK:
468 case JCS_YCCK:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000469 if (cinfo->input_components != 4)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000470 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000471 break;
472
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000473 default: /* JCS_UNKNOWN can be anything */
474 if (cinfo->input_components < 1)
475 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000476 break;
477 }
478
479 /* Check num_components, set conversion method based on requested space */
480 switch (cinfo->jpeg_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000481 case JCS_GRAYSCALE:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000482 if (cinfo->num_components != 1)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000483 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
484 if (cinfo->in_color_space == JCS_GRAYSCALE)
485 cconvert->pub.color_convert = grayscale_convert;
DRCf25c0712009-04-03 12:00:51 +0000486 else if (cinfo->in_color_space == JCS_RGB ||
487 cinfo->in_color_space == JCS_EXT_RGB ||
488 cinfo->in_color_space == JCS_EXT_RGBX ||
489 cinfo->in_color_space == JCS_EXT_BGR ||
490 cinfo->in_color_space == JCS_EXT_BGRX ||
491 cinfo->in_color_space == JCS_EXT_XBGR ||
492 cinfo->in_color_space == JCS_EXT_XRGB) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000493 cconvert->pub.start_pass = rgb_ycc_start;
494 cconvert->pub.color_convert = rgb_gray_convert;
495 } else if (cinfo->in_color_space == JCS_YCbCr)
496 cconvert->pub.color_convert = grayscale_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000497 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000498 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000499 break;
500
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000501 case JCS_RGB:
DRCf25c0712009-04-03 12:00:51 +0000502 case JCS_EXT_RGB:
503 case JCS_EXT_RGBX:
504 case JCS_EXT_BGR:
505 case JCS_EXT_BGRX:
506 case JCS_EXT_XBGR:
507 case JCS_EXT_XRGB:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000508 if (cinfo->num_components != 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000509 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
DRCf25c0712009-04-03 12:00:51 +0000510 if (cinfo->in_color_space == cinfo->jpeg_color_space &&
511 rgb_pixelsize[cinfo->in_color_space] == 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000512 cconvert->pub.color_convert = null_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000513 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000514 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000515 break;
516
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000517 case JCS_YCbCr:
518 if (cinfo->num_components != 3)
519 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
DRCf25c0712009-04-03 12:00:51 +0000520 if (cinfo->in_color_space == JCS_RGB ||
521 cinfo->in_color_space == JCS_EXT_RGB ||
522 cinfo->in_color_space == JCS_EXT_RGBX ||
523 cinfo->in_color_space == JCS_EXT_BGR ||
524 cinfo->in_color_space == JCS_EXT_BGRX ||
525 cinfo->in_color_space == JCS_EXT_XBGR ||
526 cinfo->in_color_space == JCS_EXT_XRGB) {
Pierre Ossman59a39382009-03-09 13:15:56 +0000527 if (jsimd_can_rgb_ycc())
528 cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
529 else {
530 cconvert->pub.start_pass = rgb_ycc_start;
531 cconvert->pub.color_convert = rgb_ycc_convert;
532 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000533 } else if (cinfo->in_color_space == JCS_YCbCr)
534 cconvert->pub.color_convert = null_convert;
535 else
536 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
537 break;
538
539 case JCS_CMYK:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000540 if (cinfo->num_components != 4)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000541 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
542 if (cinfo->in_color_space == JCS_CMYK)
543 cconvert->pub.color_convert = null_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000544 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000545 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000546 break;
547
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000548 case JCS_YCCK:
549 if (cinfo->num_components != 4)
550 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
551 if (cinfo->in_color_space == JCS_CMYK) {
552 cconvert->pub.start_pass = rgb_ycc_start;
553 cconvert->pub.color_convert = cmyk_ycck_convert;
554 } else if (cinfo->in_color_space == JCS_YCCK)
555 cconvert->pub.color_convert = null_convert;
556 else
557 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
558 break;
559
560 default: /* allow null conversion of JCS_UNKNOWN */
561 if (cinfo->jpeg_color_space != cinfo->in_color_space ||
562 cinfo->num_components != cinfo->input_components)
563 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
564 cconvert->pub.color_convert = null_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000565 break;
566 }
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000567}