Merge branch 'upstream' into tizen_base
[platform/upstream/libjpeg-turbo.git] / jdmrg565.c
1 /*
2  * jdmrg565.c
3  *
4  * This file was part of the Independent JPEG Group's software:
5  * Copyright (C) 1994-1996, Thomas G. Lane.
6  * libjpeg-turbo Modifications:
7  * Copyright (C) 2013, Linaro Limited.
8  * Copyright (C) 2014-2015, 2018, 2020, 2022, D. R. Commander.
9  * For conditions of distribution and use, see the accompanying README.ijg
10  * file.
11  *
12  * This file contains code for merged upsampling/color conversion.
13  */
14
15
16 INLINE
17 LOCAL(void)
18 h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo,
19                                   _JSAMPIMAGE input_buf,
20                                   JDIMENSION in_row_group_ctr,
21                                   _JSAMPARRAY output_buf)
22 {
23   my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
24   register int y, cred, cgreen, cblue;
25   int cb, cr;
26   register _JSAMPROW outptr;
27   _JSAMPROW inptr0, inptr1, inptr2;
28   JDIMENSION col;
29   /* copy these pointers into registers if possible */
30   register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
31   int *Crrtab = upsample->Cr_r_tab;
32   int *Cbbtab = upsample->Cb_b_tab;
33   JLONG *Crgtab = upsample->Cr_g_tab;
34   JLONG *Cbgtab = upsample->Cb_g_tab;
35   unsigned int r, g, b;
36   JLONG rgb;
37   SHIFT_TEMPS
38
39   inptr0 = input_buf[0][in_row_group_ctr];
40   inptr1 = input_buf[1][in_row_group_ctr];
41   inptr2 = input_buf[2][in_row_group_ctr];
42   outptr = output_buf[0];
43
44   /* Loop for each pair of output pixels */
45   for (col = cinfo->output_width >> 1; col > 0; col--) {
46     /* Do the chroma part of the calculation */
47     cb = *inptr1++;
48     cr = *inptr2++;
49     cred = Crrtab[cr];
50     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
51     cblue = Cbbtab[cb];
52
53     /* Fetch 2 Y values and emit 2 pixels */
54     y  = *inptr0++;
55     r = range_limit[y + cred];
56     g = range_limit[y + cgreen];
57     b = range_limit[y + cblue];
58     rgb = PACK_SHORT_565(r, g, b);
59
60     y  = *inptr0++;
61     r = range_limit[y + cred];
62     g = range_limit[y + cgreen];
63     b = range_limit[y + cblue];
64     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
65
66     WRITE_TWO_PIXELS(outptr, rgb);
67     outptr += 4;
68   }
69
70   /* If image width is odd, do the last output column separately */
71   if (cinfo->output_width & 1) {
72     cb = *inptr1;
73     cr = *inptr2;
74     cred = Crrtab[cr];
75     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
76     cblue = Cbbtab[cb];
77     y  = *inptr0;
78     r = range_limit[y + cred];
79     g = range_limit[y + cgreen];
80     b = range_limit[y + cblue];
81     rgb = PACK_SHORT_565(r, g, b);
82     *(INT16 *)outptr = (INT16)rgb;
83   }
84 }
85
86
87 INLINE
88 LOCAL(void)
89 h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
90                                    _JSAMPIMAGE input_buf,
91                                    JDIMENSION in_row_group_ctr,
92                                    _JSAMPARRAY output_buf)
93 {
94   my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
95   register int y, cred, cgreen, cblue;
96   int cb, cr;
97   register _JSAMPROW outptr;
98   _JSAMPROW inptr0, inptr1, inptr2;
99   JDIMENSION col;
100   /* copy these pointers into registers if possible */
101   register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
102   int *Crrtab = upsample->Cr_r_tab;
103   int *Cbbtab = upsample->Cb_b_tab;
104   JLONG *Crgtab = upsample->Cr_g_tab;
105   JLONG *Cbgtab = upsample->Cb_g_tab;
106   JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
107   unsigned int r, g, b;
108   JLONG rgb;
109   SHIFT_TEMPS
110
111   inptr0 = input_buf[0][in_row_group_ctr];
112   inptr1 = input_buf[1][in_row_group_ctr];
113   inptr2 = input_buf[2][in_row_group_ctr];
114   outptr = output_buf[0];
115
116   /* Loop for each pair of output pixels */
117   for (col = cinfo->output_width >> 1; col > 0; col--) {
118     /* Do the chroma part of the calculation */
119     cb = *inptr1++;
120     cr = *inptr2++;
121     cred = Crrtab[cr];
122     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
123     cblue = Cbbtab[cb];
124
125     /* Fetch 2 Y values and emit 2 pixels */
126     y  = *inptr0++;
127     r = range_limit[DITHER_565_R(y + cred, d0)];
128     g = range_limit[DITHER_565_G(y + cgreen, d0)];
129     b = range_limit[DITHER_565_B(y + cblue, d0)];
130     d0 = DITHER_ROTATE(d0);
131     rgb = PACK_SHORT_565(r, g, b);
132
133     y  = *inptr0++;
134     r = range_limit[DITHER_565_R(y + cred, d0)];
135     g = range_limit[DITHER_565_G(y + cgreen, d0)];
136     b = range_limit[DITHER_565_B(y + cblue, d0)];
137     d0 = DITHER_ROTATE(d0);
138     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
139
140     WRITE_TWO_PIXELS(outptr, rgb);
141     outptr += 4;
142   }
143
144   /* If image width is odd, do the last output column separately */
145   if (cinfo->output_width & 1) {
146     cb = *inptr1;
147     cr = *inptr2;
148     cred = Crrtab[cr];
149     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
150     cblue = Cbbtab[cb];
151     y  = *inptr0;
152     r = range_limit[DITHER_565_R(y + cred, d0)];
153     g = range_limit[DITHER_565_G(y + cgreen, d0)];
154     b = range_limit[DITHER_565_B(y + cblue, d0)];
155     rgb = PACK_SHORT_565(r, g, b);
156     *(INT16 *)outptr = (INT16)rgb;
157   }
158 }
159
160
161 INLINE
162 LOCAL(void)
163 h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
164                                   JDIMENSION in_row_group_ctr,
165                                   _JSAMPARRAY output_buf)
166 {
167   my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
168   register int y, cred, cgreen, cblue;
169   int cb, cr;
170   register _JSAMPROW outptr0, outptr1;
171   _JSAMPROW inptr00, inptr01, inptr1, inptr2;
172   JDIMENSION col;
173   /* copy these pointers into registers if possible */
174   register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
175   int *Crrtab = upsample->Cr_r_tab;
176   int *Cbbtab = upsample->Cb_b_tab;
177   JLONG *Crgtab = upsample->Cr_g_tab;
178   JLONG *Cbgtab = upsample->Cb_g_tab;
179   unsigned int r, g, b;
180   JLONG rgb;
181   SHIFT_TEMPS
182
183   inptr00 = input_buf[0][in_row_group_ctr * 2];
184   inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
185   inptr1 = input_buf[1][in_row_group_ctr];
186   inptr2 = input_buf[2][in_row_group_ctr];
187   outptr0 = output_buf[0];
188   outptr1 = output_buf[1];
189
190   /* Loop for each group of output pixels */
191   for (col = cinfo->output_width >> 1; col > 0; col--) {
192     /* Do the chroma part of the calculation */
193     cb = *inptr1++;
194     cr = *inptr2++;
195     cred = Crrtab[cr];
196     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
197     cblue = Cbbtab[cb];
198
199     /* Fetch 4 Y values and emit 4 pixels */
200     y  = *inptr00++;
201     r = range_limit[y + cred];
202     g = range_limit[y + cgreen];
203     b = range_limit[y + cblue];
204     rgb = PACK_SHORT_565(r, g, b);
205
206     y  = *inptr00++;
207     r = range_limit[y + cred];
208     g = range_limit[y + cgreen];
209     b = range_limit[y + cblue];
210     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
211
212     WRITE_TWO_PIXELS(outptr0, rgb);
213     outptr0 += 4;
214
215     y  = *inptr01++;
216     r = range_limit[y + cred];
217     g = range_limit[y + cgreen];
218     b = range_limit[y + cblue];
219     rgb = PACK_SHORT_565(r, g, b);
220
221     y  = *inptr01++;
222     r = range_limit[y + cred];
223     g = range_limit[y + cgreen];
224     b = range_limit[y + cblue];
225     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
226
227     WRITE_TWO_PIXELS(outptr1, rgb);
228     outptr1 += 4;
229   }
230
231   /* If image width is odd, do the last output column separately */
232   if (cinfo->output_width & 1) {
233     cb = *inptr1;
234     cr = *inptr2;
235     cred = Crrtab[cr];
236     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
237     cblue = Cbbtab[cb];
238
239     y  = *inptr00;
240     r = range_limit[y + cred];
241     g = range_limit[y + cgreen];
242     b = range_limit[y + cblue];
243     rgb = PACK_SHORT_565(r, g, b);
244     *(INT16 *)outptr0 = (INT16)rgb;
245
246     y  = *inptr01;
247     r = range_limit[y + cred];
248     g = range_limit[y + cgreen];
249     b = range_limit[y + cblue];
250     rgb = PACK_SHORT_565(r, g, b);
251     *(INT16 *)outptr1 = (INT16)rgb;
252   }
253 }
254
255
256 INLINE
257 LOCAL(void)
258 h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
259                                    _JSAMPIMAGE input_buf,
260                                    JDIMENSION in_row_group_ctr,
261                                    _JSAMPARRAY output_buf)
262 {
263   my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
264   register int y, cred, cgreen, cblue;
265   int cb, cr;
266   register _JSAMPROW outptr0, outptr1;
267   _JSAMPROW inptr00, inptr01, inptr1, inptr2;
268   JDIMENSION col;
269   /* copy these pointers into registers if possible */
270   register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;
271   int *Crrtab = upsample->Cr_r_tab;
272   int *Cbbtab = upsample->Cb_b_tab;
273   JLONG *Crgtab = upsample->Cr_g_tab;
274   JLONG *Cbgtab = upsample->Cb_g_tab;
275   JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
276   JLONG d1 = dither_matrix[(cinfo->output_scanline + 1) & DITHER_MASK];
277   unsigned int r, g, b;
278   JLONG rgb;
279   SHIFT_TEMPS
280
281   inptr00 = input_buf[0][in_row_group_ctr * 2];
282   inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
283   inptr1 = input_buf[1][in_row_group_ctr];
284   inptr2 = input_buf[2][in_row_group_ctr];
285   outptr0 = output_buf[0];
286   outptr1 = output_buf[1];
287
288   /* Loop for each group of output pixels */
289   for (col = cinfo->output_width >> 1; col > 0; col--) {
290     /* Do the chroma part of the calculation */
291     cb = *inptr1++;
292     cr = *inptr2++;
293     cred = Crrtab[cr];
294     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
295     cblue = Cbbtab[cb];
296
297     /* Fetch 4 Y values and emit 4 pixels */
298     y  = *inptr00++;
299     r = range_limit[DITHER_565_R(y + cred, d0)];
300     g = range_limit[DITHER_565_G(y + cgreen, d0)];
301     b = range_limit[DITHER_565_B(y + cblue, d0)];
302     d0 = DITHER_ROTATE(d0);
303     rgb = PACK_SHORT_565(r, g, b);
304
305     y  = *inptr00++;
306     r = range_limit[DITHER_565_R(y + cred, d0)];
307     g = range_limit[DITHER_565_G(y + cgreen, d0)];
308     b = range_limit[DITHER_565_B(y + cblue, d0)];
309     d0 = DITHER_ROTATE(d0);
310     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
311
312     WRITE_TWO_PIXELS(outptr0, rgb);
313     outptr0 += 4;
314
315     y  = *inptr01++;
316     r = range_limit[DITHER_565_R(y + cred, d1)];
317     g = range_limit[DITHER_565_G(y + cgreen, d1)];
318     b = range_limit[DITHER_565_B(y + cblue, d1)];
319     d1 = DITHER_ROTATE(d1);
320     rgb = PACK_SHORT_565(r, g, b);
321
322     y  = *inptr01++;
323     r = range_limit[DITHER_565_R(y + cred, d1)];
324     g = range_limit[DITHER_565_G(y + cgreen, d1)];
325     b = range_limit[DITHER_565_B(y + cblue, d1)];
326     d1 = DITHER_ROTATE(d1);
327     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
328
329     WRITE_TWO_PIXELS(outptr1, rgb);
330     outptr1 += 4;
331   }
332
333   /* If image width is odd, do the last output column separately */
334   if (cinfo->output_width & 1) {
335     cb = *inptr1;
336     cr = *inptr2;
337     cred = Crrtab[cr];
338     cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
339     cblue = Cbbtab[cb];
340
341     y  = *inptr00;
342     r = range_limit[DITHER_565_R(y + cred, d0)];
343     g = range_limit[DITHER_565_G(y + cgreen, d0)];
344     b = range_limit[DITHER_565_B(y + cblue, d0)];
345     rgb = PACK_SHORT_565(r, g, b);
346     *(INT16 *)outptr0 = (INT16)rgb;
347
348     y  = *inptr01;
349     r = range_limit[DITHER_565_R(y + cred, d1)];
350     g = range_limit[DITHER_565_G(y + cgreen, d1)];
351     b = range_limit[DITHER_565_B(y + cblue, d1)];
352     rgb = PACK_SHORT_565(r, g, b);
353     *(INT16 *)outptr1 = (INT16)rgb;
354   }
355 }