blob: b374c8b247aad6fa2974061817af84718b3d5160 [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
DRC66df5ec2011-02-27 09:48:48 +00006 * Copyright 2009-2011 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
DRCa46830b2010-11-23 18:00:46 +000086static const unsigned char red_lut[256] = {
DRC6c0e1fc2009-09-24 06:18:25 +000087 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
DRCa46830b2010-11-23 18:00:46 +0000105static const unsigned char green_lut[256] = {
DRC6c0e1fc2009-09-24 06:18:25 +0000106 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,
DRCe2f37182011-02-17 07:53:46 +0000125 134, 134, 135, 136, 136, 137, 137, 138, 139, 139, 140, 140,
DRC6c0e1fc2009-09-24 06:18:25 +0000126 141, 141, 142, 143, 143, 144, 144, 145, 146, 146, 147, 147,
127 148, 149, 149, 150
128};
129
DRCa46830b2010-11-23 18:00:46 +0000130static const unsigned char blue_lut[256] = {
DRC6c0e1fc2009-09-24 06:18:25 +0000131 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{
DRC6c0e1fc2009-09-24 06:18:25 +0000261 #if BITS_IN_JSAMPLE != 8
DRC66df5ec2011-02-27 09:48:48 +0000262 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
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 JDIMENSION num_cols = cinfo->image_width;
DRC6c0e1fc2009-09-24 06:18:25 +0000269 int rindex = rgb_red[cinfo->in_color_space];
270 int gindex = rgb_green[cinfo->in_color_space];
271 int bindex = rgb_blue[cinfo->in_color_space];
272 int rgbstride = rgb_pixelsize[cinfo->in_color_space];
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000273
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000274 while (--num_rows >= 0) {
275 inptr = *input_buf++;
276 outptr = output_buf[0][output_row];
DRC6c0e1fc2009-09-24 06:18:25 +0000277 maxoutptr = &outptr[num_cols];
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000278 output_row++;
DRC6c0e1fc2009-09-24 06:18:25 +0000279 for (; outptr < maxoutptr; outptr++, inptr += rgbstride) {
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000280 /* Y */
DRC6c0e1fc2009-09-24 06:18:25 +0000281 #if BITS_IN_JSAMPLE == 8
282 *outptr = red_lut[inptr[rindex]] + green_lut[inptr[gindex]]
283 + blue_lut[inptr[bindex]];
284 #else
285 *outptr = (JSAMPLE)
286 ((ctab[GETJSAMPLE(inptr[rindex])+R_Y_OFF]
287 + ctab[GETJSAMPLE(inptr[gindex])+G_Y_OFF]
288 + ctab[GETJSAMPLE(inptr[bindex])+B_Y_OFF])
289 >> SCALEBITS);
290 #endif
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000291 }
292 }
293}
294
295
296/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000297 * Convert some rows of samples to the JPEG colorspace.
298 * This version handles Adobe-style CMYK->YCCK conversion,
299 * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
300 * conversion as above, while passing K (black) unchanged.
301 * We assume rgb_ycc_start has been called.
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000302 */
303
Thomas G. Lane489583f1996-02-07 00:00:00 +0000304METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000305cmyk_ycck_convert (j_compress_ptr cinfo,
306 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
307 JDIMENSION output_row, int num_rows)
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000308{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000309 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
310 register int r, g, b;
311 register INT32 * ctab = cconvert->rgb_ycc_tab;
312 register JSAMPROW inptr;
313 register JSAMPROW outptr0, outptr1, outptr2, outptr3;
314 register JDIMENSION col;
315 JDIMENSION num_cols = cinfo->image_width;
Thomas G. Lane88aeed41992-12-10 00:00:00 +0000316
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000317 while (--num_rows >= 0) {
318 inptr = *input_buf++;
319 outptr0 = output_buf[0][output_row];
320 outptr1 = output_buf[1][output_row];
321 outptr2 = output_buf[2][output_row];
322 outptr3 = output_buf[3][output_row];
323 output_row++;
324 for (col = 0; col < num_cols; col++) {
325 r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
326 g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
327 b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
328 /* K passes through as-is */
329 outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
330 inptr += 4;
331 /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
332 * must be too; we do not need an explicit range-limiting operation.
333 * Hence the value being shifted is never negative, and we don't
334 * need the general RIGHT_SHIFT macro.
335 */
336 /* Y */
337 outptr0[col] = (JSAMPLE)
338 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
339 >> SCALEBITS);
340 /* Cb */
341 outptr1[col] = (JSAMPLE)
342 ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
343 >> SCALEBITS);
344 /* Cr */
345 outptr2[col] = (JSAMPLE)
346 ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
347 >> SCALEBITS);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000348 }
349 }
350}
351
352
353/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000354 * Convert some rows of samples to the JPEG colorspace.
355 * This version handles grayscale output with no conversion.
356 * The source can be either plain grayscale or YCbCr (since Y == gray).
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000357 */
358
Thomas G. Lane489583f1996-02-07 00:00:00 +0000359METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000360grayscale_convert (j_compress_ptr cinfo,
361 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
362 JDIMENSION output_row, int num_rows)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000363{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000364 register JSAMPROW inptr;
365 register JSAMPROW outptr;
366 register JDIMENSION col;
367 JDIMENSION num_cols = cinfo->image_width;
368 int instride = cinfo->input_components;
369
370 while (--num_rows >= 0) {
371 inptr = *input_buf++;
372 outptr = output_buf[0][output_row];
373 output_row++;
374 for (col = 0; col < num_cols; col++) {
375 outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
376 inptr += instride;
377 }
378 }
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000379}
380
381
382/*
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000383 * Convert some rows of samples to the JPEG colorspace.
384 * This version handles multi-component colorspaces without conversion.
385 * We assume input_components == num_components.
386 */
387
Thomas G. Lane489583f1996-02-07 00:00:00 +0000388METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000389null_convert (j_compress_ptr cinfo,
390 JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
391 JDIMENSION output_row, int num_rows)
392{
393 register JSAMPROW inptr;
394 register JSAMPROW outptr;
395 register JDIMENSION col;
396 register int ci;
397 int nc = cinfo->num_components;
398 JDIMENSION num_cols = cinfo->image_width;
399
400 while (--num_rows >= 0) {
401 /* It seems fastest to make a separate pass for each component. */
402 for (ci = 0; ci < nc; ci++) {
403 inptr = *input_buf;
404 outptr = output_buf[ci][output_row];
405 for (col = 0; col < num_cols; col++) {
406 outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
407 inptr += nc;
408 }
409 }
410 input_buf++;
411 output_row++;
412 }
413}
414
415
416/*
417 * Empty method for start_pass.
418 */
419
Thomas G. Lane489583f1996-02-07 00:00:00 +0000420METHODDEF(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000421null_method (j_compress_ptr cinfo)
422{
423 /* no work needed */
424}
425
426
427/*
428 * Module initialization routine for input colorspace conversion.
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000429 */
430
Thomas G. Lane489583f1996-02-07 00:00:00 +0000431GLOBAL(void)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000432jinit_color_converter (j_compress_ptr cinfo)
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000433{
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000434 my_cconvert_ptr cconvert;
435
436 cconvert = (my_cconvert_ptr)
437 (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
438 SIZEOF(my_color_converter));
439 cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
440 /* set start_pass to null method until we find out differently */
441 cconvert->pub.start_pass = null_method;
442
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000443 /* Make sure input_components agrees with in_color_space */
444 switch (cinfo->in_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000445 case JCS_GRAYSCALE:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000446 if (cinfo->input_components != 1)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000447 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000448 break;
449
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000450 case JCS_RGB:
DRCf25c0712009-04-03 12:00:51 +0000451 case JCS_EXT_RGB:
452 case JCS_EXT_RGBX:
453 case JCS_EXT_BGR:
454 case JCS_EXT_BGRX:
455 case JCS_EXT_XBGR:
456 case JCS_EXT_XRGB:
457 if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])
458 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
459 break;
460
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000461 case JCS_YCbCr:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000462 if (cinfo->input_components != 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000463 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000464 break;
465
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000466 case JCS_CMYK:
467 case JCS_YCCK:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000468 if (cinfo->input_components != 4)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000469 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000470 break;
471
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000472 default: /* JCS_UNKNOWN can be anything */
473 if (cinfo->input_components < 1)
474 ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000475 break;
476 }
477
478 /* Check num_components, set conversion method based on requested space */
479 switch (cinfo->jpeg_color_space) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000480 case JCS_GRAYSCALE:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000481 if (cinfo->num_components != 1)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000482 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
483 if (cinfo->in_color_space == JCS_GRAYSCALE)
484 cconvert->pub.color_convert = grayscale_convert;
DRCf25c0712009-04-03 12:00:51 +0000485 else if (cinfo->in_color_space == JCS_RGB ||
486 cinfo->in_color_space == JCS_EXT_RGB ||
487 cinfo->in_color_space == JCS_EXT_RGBX ||
488 cinfo->in_color_space == JCS_EXT_BGR ||
489 cinfo->in_color_space == JCS_EXT_BGRX ||
490 cinfo->in_color_space == JCS_EXT_XBGR ||
491 cinfo->in_color_space == JCS_EXT_XRGB) {
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000492 cconvert->pub.start_pass = rgb_ycc_start;
493 cconvert->pub.color_convert = rgb_gray_convert;
494 } else if (cinfo->in_color_space == JCS_YCbCr)
495 cconvert->pub.color_convert = grayscale_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000496 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000497 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000498 break;
499
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000500 case JCS_RGB:
DRCf25c0712009-04-03 12:00:51 +0000501 case JCS_EXT_RGB:
502 case JCS_EXT_RGBX:
503 case JCS_EXT_BGR:
504 case JCS_EXT_BGRX:
505 case JCS_EXT_XBGR:
506 case JCS_EXT_XRGB:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000507 if (cinfo->num_components != 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000508 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
DRCf25c0712009-04-03 12:00:51 +0000509 if (cinfo->in_color_space == cinfo->jpeg_color_space &&
510 rgb_pixelsize[cinfo->in_color_space] == 3)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000511 cconvert->pub.color_convert = null_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000512 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000513 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000514 break;
515
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000516 case JCS_YCbCr:
517 if (cinfo->num_components != 3)
518 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
DRCf25c0712009-04-03 12:00:51 +0000519 if (cinfo->in_color_space == JCS_RGB ||
520 cinfo->in_color_space == JCS_EXT_RGB ||
521 cinfo->in_color_space == JCS_EXT_RGBX ||
522 cinfo->in_color_space == JCS_EXT_BGR ||
523 cinfo->in_color_space == JCS_EXT_BGRX ||
524 cinfo->in_color_space == JCS_EXT_XBGR ||
525 cinfo->in_color_space == JCS_EXT_XRGB) {
Pierre Ossman59a39382009-03-09 13:15:56 +0000526 if (jsimd_can_rgb_ycc())
527 cconvert->pub.color_convert = jsimd_rgb_ycc_convert;
528 else {
529 cconvert->pub.start_pass = rgb_ycc_start;
530 cconvert->pub.color_convert = rgb_ycc_convert;
531 }
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000532 } else if (cinfo->in_color_space == JCS_YCbCr)
533 cconvert->pub.color_convert = null_convert;
534 else
535 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
536 break;
537
538 case JCS_CMYK:
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000539 if (cinfo->num_components != 4)
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000540 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
541 if (cinfo->in_color_space == JCS_CMYK)
542 cconvert->pub.color_convert = null_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000543 else
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000544 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000545 break;
546
Thomas G. Lane36a4ccc1994-09-24 00:00:00 +0000547 case JCS_YCCK:
548 if (cinfo->num_components != 4)
549 ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
550 if (cinfo->in_color_space == JCS_CMYK) {
551 cconvert->pub.start_pass = rgb_ycc_start;
552 cconvert->pub.color_convert = cmyk_ycck_convert;
553 } else if (cinfo->in_color_space == JCS_YCCK)
554 cconvert->pub.color_convert = null_convert;
555 else
556 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
557 break;
558
559 default: /* allow null conversion of JCS_UNKNOWN */
560 if (cinfo->jpeg_color_space != cinfo->in_color_space ||
561 cinfo->num_components != cinfo->input_components)
562 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
563 cconvert->pub.color_convert = null_convert;
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000564 break;
565 }
Thomas G. Lane2cbeb8a1991-10-07 00:00:00 +0000566}