1 /*
2 * jdcol565.c
3 *
4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1991-1997, Thomas G. Lane.
6 * Modifications:
7 * Copyright (C) 2013, Linaro Limited.
8 * Copyright (C) 2014, D. R. Commander.
9 * For conditions of distribution and use, see the accompanying README file.
10 *
11 * This file contains output colorspace conversion routines.
12 */
13
14 /* This file is included by jdcolor.c */
15
16
17 INLINE
LOCAL(void)18 LOCAL(void)
19 ycc_rgb565_convert_internal (j_decompress_ptr cinfo,
20 JSAMPIMAGE input_buf, JDIMENSION input_row,
21 JSAMPARRAY output_buf, int num_rows)
22 {
23 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
24 register int y, cb, cr;
25 register JSAMPROW outptr;
26 register JSAMPROW inptr0, inptr1, inptr2;
27 register JDIMENSION col;
28 JDIMENSION num_cols = cinfo->output_width;
29 /* copy these pointers into registers if possible */
30 register JSAMPLE * range_limit = cinfo->sample_range_limit;
31 register int * Crrtab = cconvert->Cr_r_tab;
32 register int * Cbbtab = cconvert->Cb_b_tab;
33 register INT32 * Crgtab = cconvert->Cr_g_tab;
34 register INT32 * Cbgtab = cconvert->Cb_g_tab;
35 SHIFT_TEMPS
36
37 while (--num_rows >= 0) {
38 INT32 rgb;
39 unsigned int r, g, b;
40 inptr0 = input_buf[0][input_row];
41 inptr1 = input_buf[1][input_row];
42 inptr2 = input_buf[2][input_row];
43 input_row++;
44 outptr = *output_buf++;
45
46 if (PACK_NEED_ALIGNMENT(outptr)) {
47 y = GETJSAMPLE(*inptr0++);
48 cb = GETJSAMPLE(*inptr1++);
49 cr = GETJSAMPLE(*inptr2++);
50 r = range_limit[y + Crrtab[cr]];
51 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
52 SCALEBITS))];
53 b = range_limit[y + Cbbtab[cb]];
54 rgb = PACK_SHORT_565(r, g, b);
55 *(INT16*)outptr = rgb;
56 outptr += 2;
57 num_cols--;
58 }
59 for (col = 0; col < (num_cols >> 1); col++) {
60 y = GETJSAMPLE(*inptr0++);
61 cb = GETJSAMPLE(*inptr1++);
62 cr = GETJSAMPLE(*inptr2++);
63 r = range_limit[y + Crrtab[cr]];
64 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
65 SCALEBITS))];
66 b = range_limit[y + Cbbtab[cb]];
67 rgb = PACK_SHORT_565(r, g, b);
68
69 y = GETJSAMPLE(*inptr0++);
70 cb = GETJSAMPLE(*inptr1++);
71 cr = GETJSAMPLE(*inptr2++);
72 r = range_limit[y + Crrtab[cr]];
73 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
74 SCALEBITS))];
75 b = range_limit[y + Cbbtab[cb]];
76 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
77
78 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
79 outptr += 4;
80 }
81 if (num_cols & 1) {
82 y = GETJSAMPLE(*inptr0);
83 cb = GETJSAMPLE(*inptr1);
84 cr = GETJSAMPLE(*inptr2);
85 r = range_limit[y + Crrtab[cr]];
86 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
87 SCALEBITS))];
88 b = range_limit[y + Cbbtab[cb]];
89 rgb = PACK_SHORT_565(r, g, b);
90 *(INT16*)outptr = rgb;
91 }
92 }
93 }
94
95
96 INLINE
LOCAL(void)97 LOCAL(void)
98 ycc_rgb565D_convert_internal (j_decompress_ptr cinfo,
99 JSAMPIMAGE input_buf, JDIMENSION input_row,
100 JSAMPARRAY output_buf, int num_rows)
101 {
102 my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
103 register int y, cb, cr;
104 register JSAMPROW outptr;
105 register JSAMPROW inptr0, inptr1, inptr2;
106 register JDIMENSION col;
107 JDIMENSION num_cols = cinfo->output_width;
108 /* copy these pointers into registers if possible */
109 register JSAMPLE * range_limit = cinfo->sample_range_limit;
110 register int * Crrtab = cconvert->Cr_r_tab;
111 register int * Cbbtab = cconvert->Cb_b_tab;
112 register INT32 * Crgtab = cconvert->Cr_g_tab;
113 register INT32 * Cbgtab = cconvert->Cb_g_tab;
114 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
115 SHIFT_TEMPS
116
117 while (--num_rows >= 0) {
118 INT32 rgb;
119 unsigned int r, g, b;
120
121 inptr0 = input_buf[0][input_row];
122 inptr1 = input_buf[1][input_row];
123 inptr2 = input_buf[2][input_row];
124 input_row++;
125 outptr = *output_buf++;
126 if (PACK_NEED_ALIGNMENT(outptr)) {
127 y = GETJSAMPLE(*inptr0++);
128 cb = GETJSAMPLE(*inptr1++);
129 cr = GETJSAMPLE(*inptr2++);
130 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
131 g = range_limit[DITHER_565_G(y +
132 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
133 SCALEBITS)), d0)];
134 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
135 rgb = PACK_SHORT_565(r, g, b);
136 *(INT16*)outptr = rgb;
137 outptr += 2;
138 num_cols--;
139 }
140 for (col = 0; col < (num_cols >> 1); col++) {
141 y = GETJSAMPLE(*inptr0++);
142 cb = GETJSAMPLE(*inptr1++);
143 cr = GETJSAMPLE(*inptr2++);
144 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
145 g = range_limit[DITHER_565_G(y +
146 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
147 SCALEBITS)), d0)];
148 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
149 d0 = DITHER_ROTATE(d0);
150 rgb = PACK_SHORT_565(r, g, b);
151
152 y = GETJSAMPLE(*inptr0++);
153 cb = GETJSAMPLE(*inptr1++);
154 cr = GETJSAMPLE(*inptr2++);
155 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
156 g = range_limit[DITHER_565_G(y +
157 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
158 SCALEBITS)), d0)];
159 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
160 d0 = DITHER_ROTATE(d0);
161 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
162
163 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
164 outptr += 4;
165 }
166 if (num_cols & 1) {
167 y = GETJSAMPLE(*inptr0);
168 cb = GETJSAMPLE(*inptr1);
169 cr = GETJSAMPLE(*inptr2);
170 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
171 g = range_limit[DITHER_565_G(y +
172 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
173 SCALEBITS)), d0)];
174 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
175 rgb = PACK_SHORT_565(r, g, b);
176 *(INT16*)outptr = rgb;
177 }
178 }
179 }
180
181
182 INLINE
LOCAL(void)183 LOCAL(void)
184 rgb_rgb565_convert_internal (j_decompress_ptr cinfo,
185 JSAMPIMAGE input_buf, JDIMENSION input_row,
186 JSAMPARRAY output_buf, int num_rows)
187 {
188 register JSAMPROW outptr;
189 register JSAMPROW inptr0, inptr1, inptr2;
190 register JDIMENSION col;
191 JDIMENSION num_cols = cinfo->output_width;
192 SHIFT_TEMPS
193
194 while (--num_rows >= 0) {
195 INT32 rgb;
196 unsigned int r, g, b;
197
198 inptr0 = input_buf[0][input_row];
199 inptr1 = input_buf[1][input_row];
200 inptr2 = input_buf[2][input_row];
201 input_row++;
202 outptr = *output_buf++;
203 if (PACK_NEED_ALIGNMENT(outptr)) {
204 r = GETJSAMPLE(*inptr0++);
205 g = GETJSAMPLE(*inptr1++);
206 b = GETJSAMPLE(*inptr2++);
207 rgb = PACK_SHORT_565(r, g, b);
208 *(INT16*)outptr = rgb;
209 outptr += 2;
210 num_cols--;
211 }
212 for (col = 0; col < (num_cols >> 1); col++) {
213 r = GETJSAMPLE(*inptr0++);
214 g = GETJSAMPLE(*inptr1++);
215 b = GETJSAMPLE(*inptr2++);
216 rgb = PACK_SHORT_565(r, g, b);
217
218 r = GETJSAMPLE(*inptr0++);
219 g = GETJSAMPLE(*inptr1++);
220 b = GETJSAMPLE(*inptr2++);
221 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
222
223 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
224 outptr += 4;
225 }
226 if (num_cols & 1) {
227 r = GETJSAMPLE(*inptr0);
228 g = GETJSAMPLE(*inptr1);
229 b = GETJSAMPLE(*inptr2);
230 rgb = PACK_SHORT_565(r, g, b);
231 *(INT16*)outptr = rgb;
232 }
233 }
234 }
235
236
237 INLINE
LOCAL(void)238 LOCAL(void)
239 rgb_rgb565D_convert_internal (j_decompress_ptr cinfo,
240 JSAMPIMAGE input_buf, JDIMENSION input_row,
241 JSAMPARRAY output_buf, int num_rows)
242 {
243 register JSAMPROW outptr;
244 register JSAMPROW inptr0, inptr1, inptr2;
245 register JDIMENSION col;
246 register JSAMPLE * range_limit = cinfo->sample_range_limit;
247 JDIMENSION num_cols = cinfo->output_width;
248 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
249 SHIFT_TEMPS
250
251 while (--num_rows >= 0) {
252 INT32 rgb;
253 unsigned int r, g, b;
254
255 inptr0 = input_buf[0][input_row];
256 inptr1 = input_buf[1][input_row];
257 inptr2 = input_buf[2][input_row];
258 input_row++;
259 outptr = *output_buf++;
260 if (PACK_NEED_ALIGNMENT(outptr)) {
261 r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
262 g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
263 b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
264 rgb = PACK_SHORT_565(r, g, b);
265 *(INT16*)outptr = rgb;
266 outptr += 2;
267 num_cols--;
268 }
269 for (col = 0; col < (num_cols >> 1); col++) {
270 r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
271 g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
272 b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
273 d0 = DITHER_ROTATE(d0);
274 rgb = PACK_SHORT_565(r, g, b);
275
276 r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
277 g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
278 b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
279 d0 = DITHER_ROTATE(d0);
280 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
281
282 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
283 outptr += 4;
284 }
285 if (num_cols & 1) {
286 r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
287 g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
288 b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
289 rgb = PACK_SHORT_565(r, g, b);
290 *(INT16*)outptr = rgb;
291 }
292 }
293 }
294
295
296 INLINE
LOCAL(void)297 LOCAL(void)
298 gray_rgb565_convert_internal (j_decompress_ptr cinfo,
299 JSAMPIMAGE input_buf, JDIMENSION input_row,
300 JSAMPARRAY output_buf, int num_rows)
301 {
302 register JSAMPROW inptr, outptr;
303 register JDIMENSION col;
304 JDIMENSION num_cols = cinfo->output_width;
305
306 while (--num_rows >= 0) {
307 INT32 rgb;
308 unsigned int g;
309
310 inptr = input_buf[0][input_row++];
311 outptr = *output_buf++;
312 if (PACK_NEED_ALIGNMENT(outptr)) {
313 g = *inptr++;
314 rgb = PACK_SHORT_565(g, g, g);
315 *(INT16*)outptr = rgb;
316 outptr += 2;
317 num_cols--;
318 }
319 for (col = 0; col < (num_cols >> 1); col++) {
320 g = *inptr++;
321 rgb = PACK_SHORT_565(g, g, g);
322 g = *inptr++;
323 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
324 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
325 outptr += 4;
326 }
327 if (num_cols & 1) {
328 g = *inptr;
329 rgb = PACK_SHORT_565(g, g, g);
330 *(INT16*)outptr = rgb;
331 }
332 }
333 }
334
335
336 INLINE
LOCAL(void)337 LOCAL(void)
338 gray_rgb565D_convert_internal (j_decompress_ptr cinfo,
339 JSAMPIMAGE input_buf, JDIMENSION input_row,
340 JSAMPARRAY output_buf, int num_rows)
341 {
342 register JSAMPROW inptr, outptr;
343 register JDIMENSION col;
344 register JSAMPLE * range_limit = cinfo->sample_range_limit;
345 JDIMENSION num_cols = cinfo->output_width;
346 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
347
348 while (--num_rows >= 0) {
349 INT32 rgb;
350 unsigned int g;
351
352 inptr = input_buf[0][input_row++];
353 outptr = *output_buf++;
354 if (PACK_NEED_ALIGNMENT(outptr)) {
355 g = *inptr++;
356 g = range_limit[DITHER_565_R(g, d0)];
357 rgb = PACK_SHORT_565(g, g, g);
358 *(INT16*)outptr = rgb;
359 outptr += 2;
360 num_cols--;
361 }
362 for (col = 0; col < (num_cols >> 1); col++) {
363 g = *inptr++;
364 g = range_limit[DITHER_565_R(g, d0)];
365 rgb = PACK_SHORT_565(g, g, g);
366 d0 = DITHER_ROTATE(d0);
367
368 g = *inptr++;
369 g = range_limit[DITHER_565_R(g, d0)];
370 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
371 d0 = DITHER_ROTATE(d0);
372
373 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
374 outptr += 4;
375 }
376 if (num_cols & 1) {
377 g = *inptr;
378 g = range_limit[DITHER_565_R(g, d0)];
379 rgb = PACK_SHORT_565(g, g, g);
380 *(INT16*)outptr = rgb;
381 }
382 }
383 }
384