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, 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 my_cconvert_ptr cconvert
= (my_cconvert_ptr
)cinfo
->cconvert
;
25 register int y
, cb
, cr
;
26 register JSAMPROW outptr
;
27 register JSAMPROW inptr0
, inptr1
, inptr2
;
28 register JDIMENSION col
;
29 JDIMENSION num_cols
= cinfo
->output_width
;
30 /* copy these pointers into registers if possible */
31 register JSAMPLE
*range_limit
= cinfo
->sample_range_limit
;
32 register int *Crrtab
= cconvert
->Cr_r_tab
;
33 register int *Cbbtab
= cconvert
->Cb_b_tab
;
34 register JLONG
*Crgtab
= cconvert
->Cr_g_tab
;
35 register JLONG
*Cbgtab
= cconvert
->Cb_g_tab
;
38 while (--num_rows
>= 0) {
41 inptr0
= input_buf
[0][input_row
];
42 inptr1
= input_buf
[1][input_row
];
43 inptr2
= input_buf
[2][input_row
];
45 outptr
= *output_buf
++;
47 if (PACK_NEED_ALIGNMENT(outptr
)) {
51 r
= range_limit
[y
+ Crrtab
[cr
]];
52 g
= range_limit
[y
+ ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
54 b
= range_limit
[y
+ Cbbtab
[cb
]];
55 rgb
= PACK_SHORT_565(r
, g
, b
);
56 *(INT16
*)outptr
= (INT16
)rgb
;
60 for (col
= 0; col
< (num_cols
>> 1); col
++) {
64 r
= range_limit
[y
+ Crrtab
[cr
]];
65 g
= range_limit
[y
+ ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
67 b
= range_limit
[y
+ Cbbtab
[cb
]];
68 rgb
= PACK_SHORT_565(r
, g
, b
);
73 r
= range_limit
[y
+ Crrtab
[cr
]];
74 g
= range_limit
[y
+ ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
76 b
= range_limit
[y
+ Cbbtab
[cb
]];
77 rgb
= PACK_TWO_PIXELS(rgb
, PACK_SHORT_565(r
, g
, b
));
79 WRITE_TWO_ALIGNED_PIXELS(outptr
, rgb
);
86 r
= range_limit
[y
+ Crrtab
[cr
]];
87 g
= range_limit
[y
+ ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
89 b
= range_limit
[y
+ Cbbtab
[cb
]];
90 rgb
= PACK_SHORT_565(r
, g
, b
);
91 *(INT16
*)outptr
= (INT16
)rgb
;
99 ycc_rgb565D_convert_internal(j_decompress_ptr cinfo
, JSAMPIMAGE input_buf
,
100 JDIMENSION input_row
, JSAMPARRAY output_buf
,
103 my_cconvert_ptr cconvert
= (my_cconvert_ptr
)cinfo
->cconvert
;
104 register int y
, cb
, cr
;
105 register JSAMPROW outptr
;
106 register JSAMPROW inptr0
, inptr1
, inptr2
;
107 register JDIMENSION col
;
108 JDIMENSION num_cols
= cinfo
->output_width
;
109 /* copy these pointers into registers if possible */
110 register JSAMPLE
*range_limit
= cinfo
->sample_range_limit
;
111 register int *Crrtab
= cconvert
->Cr_r_tab
;
112 register int *Cbbtab
= cconvert
->Cb_b_tab
;
113 register JLONG
*Crgtab
= cconvert
->Cr_g_tab
;
114 register JLONG
*Cbgtab
= cconvert
->Cb_g_tab
;
115 JLONG d0
= dither_matrix
[cinfo
->output_scanline
& DITHER_MASK
];
118 while (--num_rows
>= 0) {
120 unsigned int r
, g
, b
;
122 inptr0
= input_buf
[0][input_row
];
123 inptr1
= input_buf
[1][input_row
];
124 inptr2
= input_buf
[2][input_row
];
126 outptr
= *output_buf
++;
127 if (PACK_NEED_ALIGNMENT(outptr
)) {
131 r
= range_limit
[DITHER_565_R(y
+ Crrtab
[cr
], d0
)];
132 g
= range_limit
[DITHER_565_G(y
+
133 ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
135 b
= range_limit
[DITHER_565_B(y
+ Cbbtab
[cb
], d0
)];
136 rgb
= PACK_SHORT_565(r
, g
, b
);
137 *(INT16
*)outptr
= (INT16
)rgb
;
141 for (col
= 0; col
< (num_cols
>> 1); col
++) {
145 r
= range_limit
[DITHER_565_R(y
+ Crrtab
[cr
], d0
)];
146 g
= range_limit
[DITHER_565_G(y
+
147 ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
149 b
= range_limit
[DITHER_565_B(y
+ Cbbtab
[cb
], d0
)];
150 d0
= DITHER_ROTATE(d0
);
151 rgb
= PACK_SHORT_565(r
, g
, b
);
156 r
= range_limit
[DITHER_565_R(y
+ Crrtab
[cr
], d0
)];
157 g
= range_limit
[DITHER_565_G(y
+
158 ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
160 b
= range_limit
[DITHER_565_B(y
+ Cbbtab
[cb
], d0
)];
161 d0
= DITHER_ROTATE(d0
);
162 rgb
= PACK_TWO_PIXELS(rgb
, PACK_SHORT_565(r
, g
, b
));
164 WRITE_TWO_ALIGNED_PIXELS(outptr
, rgb
);
171 r
= range_limit
[DITHER_565_R(y
+ Crrtab
[cr
], d0
)];
172 g
= range_limit
[DITHER_565_G(y
+
173 ((int)RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
],
175 b
= range_limit
[DITHER_565_B(y
+ Cbbtab
[cb
], d0
)];
176 rgb
= PACK_SHORT_565(r
, g
, b
);
177 *(INT16
*)outptr
= (INT16
)rgb
;
185 rgb_rgb565_convert_internal(j_decompress_ptr cinfo
, JSAMPIMAGE input_buf
,
186 JDIMENSION input_row
, JSAMPARRAY output_buf
,
189 register JSAMPROW outptr
;
190 register JSAMPROW inptr0
, inptr1
, inptr2
;
191 register JDIMENSION col
;
192 JDIMENSION num_cols
= cinfo
->output_width
;
195 while (--num_rows
>= 0) {
197 unsigned int r
, g
, b
;
199 inptr0
= input_buf
[0][input_row
];
200 inptr1
= input_buf
[1][input_row
];
201 inptr2
= input_buf
[2][input_row
];
203 outptr
= *output_buf
++;
204 if (PACK_NEED_ALIGNMENT(outptr
)) {
208 rgb
= PACK_SHORT_565(r
, g
, b
);
209 *(INT16
*)outptr
= (INT16
)rgb
;
213 for (col
= 0; col
< (num_cols
>> 1); col
++) {
217 rgb
= PACK_SHORT_565(r
, g
, b
);
222 rgb
= PACK_TWO_PIXELS(rgb
, PACK_SHORT_565(r
, g
, b
));
224 WRITE_TWO_ALIGNED_PIXELS(outptr
, rgb
);
231 rgb
= PACK_SHORT_565(r
, g
, b
);
232 *(INT16
*)outptr
= (INT16
)rgb
;
240 rgb_rgb565D_convert_internal(j_decompress_ptr cinfo
, JSAMPIMAGE input_buf
,
241 JDIMENSION input_row
, JSAMPARRAY output_buf
,
244 register JSAMPROW outptr
;
245 register JSAMPROW inptr0
, inptr1
, inptr2
;
246 register JDIMENSION col
;
247 register JSAMPLE
*range_limit
= cinfo
->sample_range_limit
;
248 JDIMENSION num_cols
= cinfo
->output_width
;
249 JLONG d0
= dither_matrix
[cinfo
->output_scanline
& DITHER_MASK
];
252 while (--num_rows
>= 0) {
254 unsigned int r
, g
, b
;
256 inptr0
= input_buf
[0][input_row
];
257 inptr1
= input_buf
[1][input_row
];
258 inptr2
= input_buf
[2][input_row
];
260 outptr
= *output_buf
++;
261 if (PACK_NEED_ALIGNMENT(outptr
)) {
262 r
= range_limit
[DITHER_565_R(*inptr0
++, d0
)];
263 g
= range_limit
[DITHER_565_G(*inptr1
++, d0
)];
264 b
= range_limit
[DITHER_565_B(*inptr2
++, d0
)];
265 rgb
= PACK_SHORT_565(r
, g
, b
);
266 *(INT16
*)outptr
= (INT16
)rgb
;
270 for (col
= 0; col
< (num_cols
>> 1); col
++) {
271 r
= range_limit
[DITHER_565_R(*inptr0
++, d0
)];
272 g
= range_limit
[DITHER_565_G(*inptr1
++, d0
)];
273 b
= range_limit
[DITHER_565_B(*inptr2
++, d0
)];
274 d0
= DITHER_ROTATE(d0
);
275 rgb
= PACK_SHORT_565(r
, g
, b
);
277 r
= range_limit
[DITHER_565_R(*inptr0
++, d0
)];
278 g
= range_limit
[DITHER_565_G(*inptr1
++, d0
)];
279 b
= range_limit
[DITHER_565_B(*inptr2
++, d0
)];
280 d0
= DITHER_ROTATE(d0
);
281 rgb
= PACK_TWO_PIXELS(rgb
, PACK_SHORT_565(r
, g
, b
));
283 WRITE_TWO_ALIGNED_PIXELS(outptr
, rgb
);
287 r
= range_limit
[DITHER_565_R(*inptr0
, d0
)];
288 g
= range_limit
[DITHER_565_G(*inptr1
, d0
)];
289 b
= range_limit
[DITHER_565_B(*inptr2
, d0
)];
290 rgb
= PACK_SHORT_565(r
, g
, b
);
291 *(INT16
*)outptr
= (INT16
)rgb
;
299 gray_rgb565_convert_internal(j_decompress_ptr cinfo
, JSAMPIMAGE input_buf
,
300 JDIMENSION input_row
, JSAMPARRAY output_buf
,
303 register JSAMPROW inptr
, outptr
;
304 register JDIMENSION col
;
305 JDIMENSION num_cols
= cinfo
->output_width
;
307 while (--num_rows
>= 0) {
311 inptr
= input_buf
[0][input_row
++];
312 outptr
= *output_buf
++;
313 if (PACK_NEED_ALIGNMENT(outptr
)) {
315 rgb
= PACK_SHORT_565(g
, g
, g
);
316 *(INT16
*)outptr
= (INT16
)rgb
;
320 for (col
= 0; col
< (num_cols
>> 1); col
++) {
322 rgb
= PACK_SHORT_565(g
, g
, g
);
324 rgb
= PACK_TWO_PIXELS(rgb
, PACK_SHORT_565(g
, g
, g
));
325 WRITE_TWO_ALIGNED_PIXELS(outptr
, rgb
);
330 rgb
= PACK_SHORT_565(g
, g
, g
);
331 *(INT16
*)outptr
= (INT16
)rgb
;
339 gray_rgb565D_convert_internal(j_decompress_ptr cinfo
, JSAMPIMAGE input_buf
,
340 JDIMENSION input_row
, JSAMPARRAY output_buf
,
343 register JSAMPROW inptr
, outptr
;
344 register JDIMENSION col
;
345 register JSAMPLE
*range_limit
= cinfo
->sample_range_limit
;
346 JDIMENSION num_cols
= cinfo
->output_width
;
347 JLONG d0
= dither_matrix
[cinfo
->output_scanline
& DITHER_MASK
];
349 while (--num_rows
>= 0) {
353 inptr
= input_buf
[0][input_row
++];
354 outptr
= *output_buf
++;
355 if (PACK_NEED_ALIGNMENT(outptr
)) {
357 g
= range_limit
[DITHER_565_R(g
, d0
)];
358 rgb
= PACK_SHORT_565(g
, g
, g
);
359 *(INT16
*)outptr
= (INT16
)rgb
;
363 for (col
= 0; col
< (num_cols
>> 1); col
++) {
365 g
= range_limit
[DITHER_565_R(g
, d0
)];
366 rgb
= PACK_SHORT_565(g
, g
, g
);
367 d0
= DITHER_ROTATE(d0
);
370 g
= range_limit
[DITHER_565_R(g
, d0
)];
371 rgb
= PACK_TWO_PIXELS(rgb
, PACK_SHORT_565(g
, g
, g
));
372 d0
= DITHER_ROTATE(d0
);
374 WRITE_TWO_ALIGNED_PIXELS(outptr
, rgb
);
379 g
= range_limit
[DITHER_565_R(g
, d0
)];
380 rgb
= PACK_SHORT_565(g
, g
, g
);
381 *(INT16
*)outptr
= (INT16
)rgb
;