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