Imported Upstream version 2.0.1
[platform/upstream/libjpeg-turbo.git] / jdcol565.c
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 ycc_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
21                             JDIMENSION input_row, JSAMPARRAY output_buf,
22                             int num_rows)
23 {
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;
36   SHIFT_TEMPS
37
38   while (--num_rows >= 0) {
39     JLONG rgb;
40     unsigned int r, g, b;
41     inptr0 = input_buf[0][input_row];
42     inptr1 = input_buf[1][input_row];
43     inptr2 = input_buf[2][input_row];
44     input_row++;
45     outptr = *output_buf++;
46
47     if (PACK_NEED_ALIGNMENT(outptr)) {
48       y  = GETJSAMPLE(*inptr0++);
49       cb = GETJSAMPLE(*inptr1++);
50       cr = GETJSAMPLE(*inptr2++);
51       r = range_limit[y + Crrtab[cr]];
52       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
53                                             SCALEBITS))];
54       b = range_limit[y + Cbbtab[cb]];
55       rgb = PACK_SHORT_565(r, g, b);
56       *(INT16 *)outptr = (INT16)rgb;
57       outptr += 2;
58       num_cols--;
59     }
60     for (col = 0; col < (num_cols >> 1); col++) {
61       y  = GETJSAMPLE(*inptr0++);
62       cb = GETJSAMPLE(*inptr1++);
63       cr = GETJSAMPLE(*inptr2++);
64       r = range_limit[y + Crrtab[cr]];
65       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
66                                             SCALEBITS))];
67       b = range_limit[y + Cbbtab[cb]];
68       rgb = PACK_SHORT_565(r, g, b);
69
70       y  = GETJSAMPLE(*inptr0++);
71       cb = GETJSAMPLE(*inptr1++);
72       cr = GETJSAMPLE(*inptr2++);
73       r = range_limit[y + Crrtab[cr]];
74       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
75                                             SCALEBITS))];
76       b = range_limit[y + Cbbtab[cb]];
77       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
78
79       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
80       outptr += 4;
81     }
82     if (num_cols & 1) {
83       y  = GETJSAMPLE(*inptr0);
84       cb = GETJSAMPLE(*inptr1);
85       cr = GETJSAMPLE(*inptr2);
86       r = range_limit[y + Crrtab[cr]];
87       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
88                                             SCALEBITS))];
89       b = range_limit[y + Cbbtab[cb]];
90       rgb = PACK_SHORT_565(r, g, b);
91       *(INT16 *)outptr = (INT16)rgb;
92     }
93   }
94 }
95
96
97 INLINE
98 LOCAL(void)
99 ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
100                              JDIMENSION input_row, JSAMPARRAY output_buf,
101                              int num_rows)
102 {
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];
116   SHIFT_TEMPS
117
118   while (--num_rows >= 0) {
119     JLONG rgb;
120     unsigned int r, g, b;
121
122     inptr0 = input_buf[0][input_row];
123     inptr1 = input_buf[1][input_row];
124     inptr2 = input_buf[2][input_row];
125     input_row++;
126     outptr = *output_buf++;
127     if (PACK_NEED_ALIGNMENT(outptr)) {
128       y  = GETJSAMPLE(*inptr0++);
129       cb = GETJSAMPLE(*inptr1++);
130       cr = GETJSAMPLE(*inptr2++);
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],
134                                                      SCALEBITS)), d0)];
135       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
136       rgb = PACK_SHORT_565(r, g, b);
137       *(INT16 *)outptr = (INT16)rgb;
138       outptr += 2;
139       num_cols--;
140     }
141     for (col = 0; col < (num_cols >> 1); col++) {
142       y  = GETJSAMPLE(*inptr0++);
143       cb = GETJSAMPLE(*inptr1++);
144       cr = GETJSAMPLE(*inptr2++);
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],
148                                                      SCALEBITS)), d0)];
149       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
150       d0 = DITHER_ROTATE(d0);
151       rgb = PACK_SHORT_565(r, g, b);
152
153       y  = GETJSAMPLE(*inptr0++);
154       cb = GETJSAMPLE(*inptr1++);
155       cr = GETJSAMPLE(*inptr2++);
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],
159                                                      SCALEBITS)), d0)];
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));
163
164       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
165       outptr += 4;
166     }
167     if (num_cols & 1) {
168       y  = GETJSAMPLE(*inptr0);
169       cb = GETJSAMPLE(*inptr1);
170       cr = GETJSAMPLE(*inptr2);
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],
174                                                      SCALEBITS)), d0)];
175       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
176       rgb = PACK_SHORT_565(r, g, b);
177       *(INT16 *)outptr = (INT16)rgb;
178     }
179   }
180 }
181
182
183 INLINE
184 LOCAL(void)
185 rgb_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
186                             JDIMENSION input_row, JSAMPARRAY output_buf,
187                             int num_rows)
188 {
189   register JSAMPROW outptr;
190   register JSAMPROW inptr0, inptr1, inptr2;
191   register JDIMENSION col;
192   JDIMENSION num_cols = cinfo->output_width;
193   SHIFT_TEMPS
194
195   while (--num_rows >= 0) {
196     JLONG rgb;
197     unsigned int r, g, b;
198
199     inptr0 = input_buf[0][input_row];
200     inptr1 = input_buf[1][input_row];
201     inptr2 = input_buf[2][input_row];
202     input_row++;
203     outptr = *output_buf++;
204     if (PACK_NEED_ALIGNMENT(outptr)) {
205       r = GETJSAMPLE(*inptr0++);
206       g = GETJSAMPLE(*inptr1++);
207       b = GETJSAMPLE(*inptr2++);
208       rgb = PACK_SHORT_565(r, g, b);
209       *(INT16 *)outptr = (INT16)rgb;
210       outptr += 2;
211       num_cols--;
212     }
213     for (col = 0; col < (num_cols >> 1); col++) {
214       r = GETJSAMPLE(*inptr0++);
215       g = GETJSAMPLE(*inptr1++);
216       b = GETJSAMPLE(*inptr2++);
217       rgb = PACK_SHORT_565(r, g, b);
218
219       r = GETJSAMPLE(*inptr0++);
220       g = GETJSAMPLE(*inptr1++);
221       b = GETJSAMPLE(*inptr2++);
222       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
223
224       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
225       outptr += 4;
226     }
227     if (num_cols & 1) {
228       r = GETJSAMPLE(*inptr0);
229       g = GETJSAMPLE(*inptr1);
230       b = GETJSAMPLE(*inptr2);
231       rgb = PACK_SHORT_565(r, g, b);
232       *(INT16 *)outptr = (INT16)rgb;
233     }
234   }
235 }
236
237
238 INLINE
239 LOCAL(void)
240 rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
241                              JDIMENSION input_row, JSAMPARRAY output_buf,
242                              int num_rows)
243 {
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];
250   SHIFT_TEMPS
251
252   while (--num_rows >= 0) {
253     JLONG rgb;
254     unsigned int r, g, b;
255
256     inptr0 = input_buf[0][input_row];
257     inptr1 = input_buf[1][input_row];
258     inptr2 = input_buf[2][input_row];
259     input_row++;
260     outptr = *output_buf++;
261     if (PACK_NEED_ALIGNMENT(outptr)) {
262       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
263       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
264       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
265       rgb = PACK_SHORT_565(r, g, b);
266       *(INT16 *)outptr = (INT16)rgb;
267       outptr += 2;
268       num_cols--;
269     }
270     for (col = 0; col < (num_cols >> 1); col++) {
271       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
272       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
273       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
274       d0 = DITHER_ROTATE(d0);
275       rgb = PACK_SHORT_565(r, g, b);
276
277       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
278       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
279       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
280       d0 = DITHER_ROTATE(d0);
281       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
282
283       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
284       outptr += 4;
285     }
286     if (num_cols & 1) {
287       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
288       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
289       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
290       rgb = PACK_SHORT_565(r, g, b);
291       *(INT16 *)outptr = (INT16)rgb;
292     }
293   }
294 }
295
296
297 INLINE
298 LOCAL(void)
299 gray_rgb565_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
300                              JDIMENSION input_row, JSAMPARRAY output_buf,
301                              int num_rows)
302 {
303   register JSAMPROW inptr, outptr;
304   register JDIMENSION col;
305   JDIMENSION num_cols = cinfo->output_width;
306
307   while (--num_rows >= 0) {
308     JLONG rgb;
309     unsigned int g;
310
311     inptr = input_buf[0][input_row++];
312     outptr = *output_buf++;
313     if (PACK_NEED_ALIGNMENT(outptr)) {
314       g = *inptr++;
315       rgb = PACK_SHORT_565(g, g, g);
316       *(INT16 *)outptr = (INT16)rgb;
317       outptr += 2;
318       num_cols--;
319     }
320     for (col = 0; col < (num_cols >> 1); col++) {
321       g = *inptr++;
322       rgb = PACK_SHORT_565(g, g, g);
323       g = *inptr++;
324       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
325       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
326       outptr += 4;
327     }
328     if (num_cols & 1) {
329       g = *inptr;
330       rgb = PACK_SHORT_565(g, g, g);
331       *(INT16 *)outptr = (INT16)rgb;
332     }
333   }
334 }
335
336
337 INLINE
338 LOCAL(void)
339 gray_rgb565D_convert_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
340                               JDIMENSION input_row, JSAMPARRAY output_buf,
341                               int num_rows)
342 {
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];
348
349   while (--num_rows >= 0) {
350     JLONG rgb;
351     unsigned int g;
352
353     inptr = input_buf[0][input_row++];
354     outptr = *output_buf++;
355     if (PACK_NEED_ALIGNMENT(outptr)) {
356       g = *inptr++;
357       g = range_limit[DITHER_565_R(g, d0)];
358       rgb = PACK_SHORT_565(g, g, g);
359       *(INT16 *)outptr = (INT16)rgb;
360       outptr += 2;
361       num_cols--;
362     }
363     for (col = 0; col < (num_cols >> 1); col++) {
364       g = *inptr++;
365       g = range_limit[DITHER_565_R(g, d0)];
366       rgb = PACK_SHORT_565(g, g, g);
367       d0 = DITHER_ROTATE(d0);
368
369       g = *inptr++;
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);
373
374       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
375       outptr += 4;
376     }
377     if (num_cols & 1) {
378       g = *inptr;
379       g = range_limit[DITHER_565_R(g, d0)];
380       rgb = PACK_SHORT_565(g, g, g);
381       *(INT16 *)outptr = (INT16)rgb;
382     }
383   }
384 }