Merge branch 'upstream' into tizen_base
[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, 2022, 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 #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;
37   SHIFT_TEMPS
38
39   while (--num_rows >= 0) {
40     JLONG rgb;
41     unsigned int r, g, b;
42     inptr0 = input_buf[0][input_row];
43     inptr1 = input_buf[1][input_row];
44     inptr2 = input_buf[2][input_row];
45     input_row++;
46     outptr = *output_buf++;
47
48     if (PACK_NEED_ALIGNMENT(outptr)) {
49       y  = *inptr0++;
50       cb = *inptr1++;
51       cr = *inptr2++;
52       r = range_limit[y + Crrtab[cr]];
53       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
54                                             SCALEBITS))];
55       b = range_limit[y + Cbbtab[cb]];
56       rgb = PACK_SHORT_565(r, g, b);
57       *(INT16 *)outptr = (INT16)rgb;
58       outptr += 2;
59       num_cols--;
60     }
61     for (col = 0; col < (num_cols >> 1); col++) {
62       y  = *inptr0++;
63       cb = *inptr1++;
64       cr = *inptr2++;
65       r = range_limit[y + Crrtab[cr]];
66       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
67                                             SCALEBITS))];
68       b = range_limit[y + Cbbtab[cb]];
69       rgb = PACK_SHORT_565(r, g, b);
70
71       y  = *inptr0++;
72       cb = *inptr1++;
73       cr = *inptr2++;
74       r = range_limit[y + Crrtab[cr]];
75       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
76                                             SCALEBITS))];
77       b = range_limit[y + Cbbtab[cb]];
78       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
79
80       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
81       outptr += 4;
82     }
83     if (num_cols & 1) {
84       y  = *inptr0;
85       cb = *inptr1;
86       cr = *inptr2;
87       r = range_limit[y + Crrtab[cr]];
88       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
89                                             SCALEBITS))];
90       b = range_limit[y + Cbbtab[cb]];
91       rgb = PACK_SHORT_565(r, g, b);
92       *(INT16 *)outptr = (INT16)rgb;
93     }
94   }
95 #else
96   ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
97 #endif
98 }
99
100
101 INLINE
102 LOCAL(void)
103 ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
104                              JDIMENSION input_row, _JSAMPARRAY output_buf,
105                              int num_rows)
106 {
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];
121   SHIFT_TEMPS
122
123   while (--num_rows >= 0) {
124     JLONG rgb;
125     unsigned int r, g, b;
126
127     inptr0 = input_buf[0][input_row];
128     inptr1 = input_buf[1][input_row];
129     inptr2 = input_buf[2][input_row];
130     input_row++;
131     outptr = *output_buf++;
132     if (PACK_NEED_ALIGNMENT(outptr)) {
133       y  = *inptr0++;
134       cb = *inptr1++;
135       cr = *inptr2++;
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],
139                                                      SCALEBITS)), d0)];
140       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
141       rgb = PACK_SHORT_565(r, g, b);
142       *(INT16 *)outptr = (INT16)rgb;
143       outptr += 2;
144       num_cols--;
145     }
146     for (col = 0; col < (num_cols >> 1); col++) {
147       y  = *inptr0++;
148       cb = *inptr1++;
149       cr = *inptr2++;
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],
153                                                      SCALEBITS)), d0)];
154       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
155       d0 = DITHER_ROTATE(d0);
156       rgb = PACK_SHORT_565(r, g, b);
157
158       y  = *inptr0++;
159       cb = *inptr1++;
160       cr = *inptr2++;
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],
164                                                      SCALEBITS)), d0)];
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));
168
169       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
170       outptr += 4;
171     }
172     if (num_cols & 1) {
173       y  = *inptr0;
174       cb = *inptr1;
175       cr = *inptr2;
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],
179                                                      SCALEBITS)), d0)];
180       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
181       rgb = PACK_SHORT_565(r, g, b);
182       *(INT16 *)outptr = (INT16)rgb;
183     }
184   }
185 #else
186   ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
187 #endif
188 }
189
190
191 INLINE
192 LOCAL(void)
193 rgb_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
194                             JDIMENSION input_row, _JSAMPARRAY output_buf,
195                             int num_rows)
196 {
197   register _JSAMPROW outptr;
198   register _JSAMPROW inptr0, inptr1, inptr2;
199   register JDIMENSION col;
200   JDIMENSION num_cols = cinfo->output_width;
201   SHIFT_TEMPS
202
203   while (--num_rows >= 0) {
204     JLONG rgb;
205     unsigned int r, g, b;
206
207     inptr0 = input_buf[0][input_row];
208     inptr1 = input_buf[1][input_row];
209     inptr2 = input_buf[2][input_row];
210     input_row++;
211     outptr = *output_buf++;
212     if (PACK_NEED_ALIGNMENT(outptr)) {
213       r = *inptr0++;
214       g = *inptr1++;
215       b = *inptr2++;
216       rgb = PACK_SHORT_565(r, g, b);
217       *(INT16 *)outptr = (INT16)rgb;
218       outptr += 2;
219       num_cols--;
220     }
221     for (col = 0; col < (num_cols >> 1); col++) {
222       r = *inptr0++;
223       g = *inptr1++;
224       b = *inptr2++;
225       rgb = PACK_SHORT_565(r, g, b);
226
227       r = *inptr0++;
228       g = *inptr1++;
229       b = *inptr2++;
230       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
231
232       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
233       outptr += 4;
234     }
235     if (num_cols & 1) {
236       r = *inptr0;
237       g = *inptr1;
238       b = *inptr2;
239       rgb = PACK_SHORT_565(r, g, b);
240       *(INT16 *)outptr = (INT16)rgb;
241     }
242   }
243 }
244
245
246 INLINE
247 LOCAL(void)
248 rgb_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
249                              JDIMENSION input_row, _JSAMPARRAY output_buf,
250                              int num_rows)
251 {
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];
258   SHIFT_TEMPS
259
260   while (--num_rows >= 0) {
261     JLONG rgb;
262     unsigned int r, g, b;
263
264     inptr0 = input_buf[0][input_row];
265     inptr1 = input_buf[1][input_row];
266     inptr2 = input_buf[2][input_row];
267     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;
275       outptr += 2;
276       num_cols--;
277     }
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);
284
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));
290
291       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
292       outptr += 4;
293     }
294     if (num_cols & 1) {
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;
300     }
301   }
302 }
303
304
305 INLINE
306 LOCAL(void)
307 gray_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
308                              JDIMENSION input_row, _JSAMPARRAY output_buf,
309                              int num_rows)
310 {
311   register _JSAMPROW inptr, outptr;
312   register JDIMENSION col;
313   JDIMENSION num_cols = cinfo->output_width;
314
315   while (--num_rows >= 0) {
316     JLONG rgb;
317     unsigned int g;
318
319     inptr = input_buf[0][input_row++];
320     outptr = *output_buf++;
321     if (PACK_NEED_ALIGNMENT(outptr)) {
322       g = *inptr++;
323       rgb = PACK_SHORT_565(g, g, g);
324       *(INT16 *)outptr = (INT16)rgb;
325       outptr += 2;
326       num_cols--;
327     }
328     for (col = 0; col < (num_cols >> 1); col++) {
329       g = *inptr++;
330       rgb = PACK_SHORT_565(g, g, g);
331       g = *inptr++;
332       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
333       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
334       outptr += 4;
335     }
336     if (num_cols & 1) {
337       g = *inptr;
338       rgb = PACK_SHORT_565(g, g, g);
339       *(INT16 *)outptr = (INT16)rgb;
340     }
341   }
342 }
343
344
345 INLINE
346 LOCAL(void)
347 gray_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
348                               JDIMENSION input_row, _JSAMPARRAY output_buf,
349                               int num_rows)
350 {
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];
356
357   while (--num_rows >= 0) {
358     JLONG rgb;
359     unsigned int g;
360
361     inptr = input_buf[0][input_row++];
362     outptr = *output_buf++;
363     if (PACK_NEED_ALIGNMENT(outptr)) {
364       g = *inptr++;
365       g = range_limit[DITHER_565_R(g, d0)];
366       rgb = PACK_SHORT_565(g, g, g);
367       *(INT16 *)outptr = (INT16)rgb;
368       outptr += 2;
369       num_cols--;
370     }
371     for (col = 0; col < (num_cols >> 1); col++) {
372       g = *inptr++;
373       g = range_limit[DITHER_565_R(g, d0)];
374       rgb = PACK_SHORT_565(g, g, g);
375       d0 = DITHER_ROTATE(d0);
376
377       g = *inptr++;
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);
381
382       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
383       outptr += 4;
384     }
385     if (num_cols & 1) {
386       g = *inptr;
387       g = range_limit[DITHER_565_R(g, d0)];
388       rgb = PACK_SHORT_565(g, g, g);
389       *(INT16 *)outptr = (INT16)rgb;
390     }
391   }
392 }