4 * This file was part of the Independent JPEG Group's software:
5 * Copyright (C) 1991-1997, Thomas G. Lane.
7 * Copyright (C) 2013, Linaro Limited.
8 * Copyright (C) 2014-2015, 2022, D. R. Commander.
9 * For conditions of distribution and use, see the accompanying README.ijg
12 * This file contains output colorspace conversion routines.
15 /* This file is included by jdcolor.c */
20 ycc_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
21 JDIMENSION input_row, _JSAMPARRAY output_buf,
24 #if BITS_IN_JSAMPLE != 16
25 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
26 register int y, cb, cr;
27 register _JSAMPROW outptr;
28 register _JSAMPROW inptr0, inptr1, inptr2;
29 register JDIMENSION col;
30 JDIMENSION num_cols = cinfo->output_width;
31 /* copy these pointers into registers if possible */
32 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
33 register int *Crrtab = cconvert->Cr_r_tab;
34 register int *Cbbtab = cconvert->Cb_b_tab;
35 register JLONG *Crgtab = cconvert->Cr_g_tab;
36 register JLONG *Cbgtab = cconvert->Cb_g_tab;
39 while (--num_rows >= 0) {
42 inptr0 = input_buf[0][input_row];
43 inptr1 = input_buf[1][input_row];
44 inptr2 = input_buf[2][input_row];
46 outptr = *output_buf++;
48 if (PACK_NEED_ALIGNMENT(outptr)) {
52 r = range_limit[y + Crrtab[cr]];
53 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
55 b = range_limit[y + Cbbtab[cb]];
56 rgb = PACK_SHORT_565(r, g, b);
57 *(INT16 *)outptr = (INT16)rgb;
61 for (col = 0; col < (num_cols >> 1); col++) {
65 r = range_limit[y + Crrtab[cr]];
66 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
68 b = range_limit[y + Cbbtab[cb]];
69 rgb = PACK_SHORT_565(r, g, b);
74 r = range_limit[y + Crrtab[cr]];
75 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
77 b = range_limit[y + Cbbtab[cb]];
78 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
80 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
87 r = range_limit[y + Crrtab[cr]];
88 g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
90 b = range_limit[y + Cbbtab[cb]];
91 rgb = PACK_SHORT_565(r, g, b);
92 *(INT16 *)outptr = (INT16)rgb;
96 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
103 ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
104 JDIMENSION input_row, _JSAMPARRAY output_buf,
107 #if BITS_IN_JSAMPLE != 16
108 my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
109 register int y, cb, cr;
110 register _JSAMPROW outptr;
111 register _JSAMPROW inptr0, inptr1, inptr2;
112 register JDIMENSION col;
113 JDIMENSION num_cols = cinfo->output_width;
114 /* copy these pointers into registers if possible */
115 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
116 register int *Crrtab = cconvert->Cr_r_tab;
117 register int *Cbbtab = cconvert->Cb_b_tab;
118 register JLONG *Crgtab = cconvert->Cr_g_tab;
119 register JLONG *Cbgtab = cconvert->Cb_g_tab;
120 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
123 while (--num_rows >= 0) {
125 unsigned int r, g, b;
127 inptr0 = input_buf[0][input_row];
128 inptr1 = input_buf[1][input_row];
129 inptr2 = input_buf[2][input_row];
131 outptr = *output_buf++;
132 if (PACK_NEED_ALIGNMENT(outptr)) {
136 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
137 g = range_limit[DITHER_565_G(y +
138 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
140 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
141 rgb = PACK_SHORT_565(r, g, b);
142 *(INT16 *)outptr = (INT16)rgb;
146 for (col = 0; col < (num_cols >> 1); col++) {
150 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
151 g = range_limit[DITHER_565_G(y +
152 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
154 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
155 d0 = DITHER_ROTATE(d0);
156 rgb = PACK_SHORT_565(r, g, b);
161 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
162 g = range_limit[DITHER_565_G(y +
163 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
165 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
166 d0 = DITHER_ROTATE(d0);
167 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
169 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
176 r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
177 g = range_limit[DITHER_565_G(y +
178 ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
180 b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
181 rgb = PACK_SHORT_565(r, g, b);
182 *(INT16 *)outptr = (INT16)rgb;
186 ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
193 rgb_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
194 JDIMENSION input_row, _JSAMPARRAY output_buf,
197 register _JSAMPROW outptr;
198 register _JSAMPROW inptr0, inptr1, inptr2;
199 register JDIMENSION col;
200 JDIMENSION num_cols = cinfo->output_width;
203 while (--num_rows >= 0) {
205 unsigned int r, g, b;
207 inptr0 = input_buf[0][input_row];
208 inptr1 = input_buf[1][input_row];
209 inptr2 = input_buf[2][input_row];
211 outptr = *output_buf++;
212 if (PACK_NEED_ALIGNMENT(outptr)) {
216 rgb = PACK_SHORT_565(r, g, b);
217 *(INT16 *)outptr = (INT16)rgb;
221 for (col = 0; col < (num_cols >> 1); col++) {
225 rgb = PACK_SHORT_565(r, g, b);
230 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
232 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
239 rgb = PACK_SHORT_565(r, g, b);
240 *(INT16 *)outptr = (INT16)rgb;
248 rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
249 JDIMENSION input_row, _JSAMPARRAY output_buf,
252 register _JSAMPROW outptr;
253 register _JSAMPROW inptr0, inptr1, inptr2;
254 register JDIMENSION col;
255 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
256 JDIMENSION num_cols = cinfo->output_width;
257 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
260 while (--num_rows >= 0) {
262 unsigned int r, g, b;
264 inptr0 = input_buf[0][input_row];
265 inptr1 = input_buf[1][input_row];
266 inptr2 = input_buf[2][input_row];
268 outptr = *output_buf++;
269 if (PACK_NEED_ALIGNMENT(outptr)) {
270 r = range_limit[DITHER_565_R(*inptr0++, d0)];
271 g = range_limit[DITHER_565_G(*inptr1++, d0)];
272 b = range_limit[DITHER_565_B(*inptr2++, d0)];
273 rgb = PACK_SHORT_565(r, g, b);
274 *(INT16 *)outptr = (INT16)rgb;
278 for (col = 0; col < (num_cols >> 1); col++) {
279 r = range_limit[DITHER_565_R(*inptr0++, d0)];
280 g = range_limit[DITHER_565_G(*inptr1++, d0)];
281 b = range_limit[DITHER_565_B(*inptr2++, d0)];
282 d0 = DITHER_ROTATE(d0);
283 rgb = PACK_SHORT_565(r, g, b);
285 r = range_limit[DITHER_565_R(*inptr0++, d0)];
286 g = range_limit[DITHER_565_G(*inptr1++, d0)];
287 b = range_limit[DITHER_565_B(*inptr2++, d0)];
288 d0 = DITHER_ROTATE(d0);
289 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
291 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
295 r = range_limit[DITHER_565_R(*inptr0, d0)];
296 g = range_limit[DITHER_565_G(*inptr1, d0)];
297 b = range_limit[DITHER_565_B(*inptr2, d0)];
298 rgb = PACK_SHORT_565(r, g, b);
299 *(INT16 *)outptr = (INT16)rgb;
307 gray_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
308 JDIMENSION input_row, _JSAMPARRAY output_buf,
311 register _JSAMPROW inptr, outptr;
312 register JDIMENSION col;
313 JDIMENSION num_cols = cinfo->output_width;
315 while (--num_rows >= 0) {
319 inptr = input_buf[0][input_row++];
320 outptr = *output_buf++;
321 if (PACK_NEED_ALIGNMENT(outptr)) {
323 rgb = PACK_SHORT_565(g, g, g);
324 *(INT16 *)outptr = (INT16)rgb;
328 for (col = 0; col < (num_cols >> 1); col++) {
330 rgb = PACK_SHORT_565(g, g, g);
332 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
333 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
338 rgb = PACK_SHORT_565(g, g, g);
339 *(INT16 *)outptr = (INT16)rgb;
347 gray_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
348 JDIMENSION input_row, _JSAMPARRAY output_buf,
351 register _JSAMPROW inptr, outptr;
352 register JDIMENSION col;
353 register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
354 JDIMENSION num_cols = cinfo->output_width;
355 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
357 while (--num_rows >= 0) {
361 inptr = input_buf[0][input_row++];
362 outptr = *output_buf++;
363 if (PACK_NEED_ALIGNMENT(outptr)) {
365 g = range_limit[DITHER_565_R(g, d0)];
366 rgb = PACK_SHORT_565(g, g, g);
367 *(INT16 *)outptr = (INT16)rgb;
371 for (col = 0; col < (num_cols >> 1); col++) {
373 g = range_limit[DITHER_565_R(g, d0)];
374 rgb = PACK_SHORT_565(g, g, g);
375 d0 = DITHER_ROTATE(d0);
378 g = range_limit[DITHER_565_R(g, d0)];
379 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
380 d0 = DITHER_ROTATE(d0);
382 WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
387 g = range_limit[DITHER_565_R(g, d0)];
388 rgb = PACK_SHORT_565(g, g, g);
389 *(INT16 *)outptr = (INT16)rgb;