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, D. R. Commander.
9  * For conditions of distribution and use, see the accompanying README file.
10  *
11  * This file contains code for merged upsampling/color conversion.
12  */
13 
14 
15 INLINE
LOCAL(void)16 LOCAL(void)
17 h2v1_merged_upsample_565_internal (j_decompress_ptr cinfo,
18                                    JSAMPIMAGE input_buf,
19                                    JDIMENSION in_row_group_ctr,
20                                    JSAMPARRAY output_buf)
21 {
22   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
23   register int y, cred, cgreen, cblue;
24   int cb, cr;
25   register JSAMPROW outptr;
26   JSAMPROW inptr0, inptr1, inptr2;
27   JDIMENSION col;
28   /* copy these pointers into registers if possible */
29   register JSAMPLE * range_limit = cinfo->sample_range_limit;
30   int * Crrtab = upsample->Cr_r_tab;
31   int * Cbbtab = upsample->Cb_b_tab;
32   INT32 * Crgtab = upsample->Cr_g_tab;
33   INT32 * Cbgtab = upsample->Cb_g_tab;
34   unsigned int r, g, b;
35   INT32 rgb;
36   SHIFT_TEMPS
37 
38   inptr0 = input_buf[0][in_row_group_ctr];
39   inptr1 = input_buf[1][in_row_group_ctr];
40   inptr2 = input_buf[2][in_row_group_ctr];
41   outptr = output_buf[0];
42 
43   /* Loop for each pair of output pixels */
44   for (col = cinfo->output_width >> 1; col > 0; col--) {
45     /* Do the chroma part of the calculation */
46     cb = GETJSAMPLE(*inptr1++);
47     cr = GETJSAMPLE(*inptr2++);
48     cred = Crrtab[cr];
49     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
50     cblue = Cbbtab[cb];
51 
52     /* Fetch 2 Y values and emit 2 pixels */
53     y  = GETJSAMPLE(*inptr0++);
54     r = range_limit[y + cred];
55     g = range_limit[y + cgreen];
56     b = range_limit[y + cblue];
57     rgb = PACK_SHORT_565(r, g, b);
58 
59     y  = GETJSAMPLE(*inptr0++);
60     r = range_limit[y + cred];
61     g = range_limit[y + cgreen];
62     b = range_limit[y + cblue];
63     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
64 
65     WRITE_TWO_PIXELS(outptr, rgb);
66     outptr += 4;
67   }
68 
69   /* If image width is odd, do the last output column separately */
70   if (cinfo->output_width & 1) {
71     cb = GETJSAMPLE(*inptr1);
72     cr = GETJSAMPLE(*inptr2);
73     cred = Crrtab[cr];
74     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
75     cblue = Cbbtab[cb];
76     y  = GETJSAMPLE(*inptr0);
77     r = range_limit[y + cred];
78     g = range_limit[y + cgreen];
79     b = range_limit[y + cblue];
80     rgb = PACK_SHORT_565(r, g, b);
81     *(INT16*)outptr = rgb;
82    }
83  }
84 
85 
86 INLINE
LOCAL(void)87 LOCAL(void)
88 h2v1_merged_upsample_565D_internal (j_decompress_ptr cinfo,
89                                     JSAMPIMAGE input_buf,
90                                     JDIMENSION in_row_group_ctr,
91                                     JSAMPARRAY output_buf)
92 {
93   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
94   register int y, cred, cgreen, cblue;
95   int cb, cr;
96   register JSAMPROW outptr;
97   JSAMPROW inptr0, inptr1, inptr2;
98   JDIMENSION col;
99   /* copy these pointers into registers if possible */
100   register JSAMPLE * range_limit = cinfo->sample_range_limit;
101   int * Crrtab = upsample->Cr_r_tab;
102   int * Cbbtab = upsample->Cb_b_tab;
103   INT32 * Crgtab = upsample->Cr_g_tab;
104   INT32 * Cbgtab = upsample->Cb_g_tab;
105   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
106   unsigned int r, g, b;
107   INT32 rgb;
108   SHIFT_TEMPS
109 
110   inptr0 = input_buf[0][in_row_group_ctr];
111   inptr1 = input_buf[1][in_row_group_ctr];
112   inptr2 = input_buf[2][in_row_group_ctr];
113   outptr = output_buf[0];
114 
115   /* Loop for each pair of output pixels */
116   for (col = cinfo->output_width >> 1; col > 0; col--) {
117     /* Do the chroma part of the calculation */
118     cb = GETJSAMPLE(*inptr1++);
119     cr = GETJSAMPLE(*inptr2++);
120     cred = Crrtab[cr];
121     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
122     cblue = Cbbtab[cb];
123 
124     /* Fetch 2 Y values and emit 2 pixels */
125     y  = GETJSAMPLE(*inptr0++);
126     r = range_limit[DITHER_565_R(y + cred, d0)];
127     g = range_limit[DITHER_565_G(y + cgreen, d0)];
128     b = range_limit[DITHER_565_B(y + cblue, d0)];
129     d0 = DITHER_ROTATE(d0);
130     rgb = PACK_SHORT_565(r, g, b);
131 
132     y  = GETJSAMPLE(*inptr0++);
133     r = range_limit[DITHER_565_R(y + cred, d0)];
134     g = range_limit[DITHER_565_G(y + cgreen, d0)];
135     b = range_limit[DITHER_565_B(y + cblue, d0)];
136     d0 = DITHER_ROTATE(d0);
137     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
138 
139     WRITE_TWO_PIXELS(outptr, rgb);
140     outptr += 4;
141   }
142 
143   /* If image width is odd, do the last output column separately */
144   if (cinfo->output_width & 1) {
145     cb = GETJSAMPLE(*inptr1);
146     cr = GETJSAMPLE(*inptr2);
147     cred = Crrtab[cr];
148     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
149     cblue = Cbbtab[cb];
150     y  = GETJSAMPLE(*inptr0);
151     r = range_limit[DITHER_565_R(y + cred, d0)];
152     g = range_limit[DITHER_565_G(y + cgreen, d0)];
153     b = range_limit[DITHER_565_B(y + cblue, d0)];
154     rgb = PACK_SHORT_565(r, g, b);
155     *(INT16*)outptr = rgb;
156   }
157 }
158 
159 
160 INLINE
LOCAL(void)161 LOCAL(void)
162 h2v2_merged_upsample_565_internal (j_decompress_ptr cinfo,
163                                    JSAMPIMAGE input_buf,
164                                    JDIMENSION in_row_group_ctr,
165                                    JSAMPARRAY output_buf)
166 {
167   my_upsample_ptr upsample = (my_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 = cinfo->sample_range_limit;
175   int * Crrtab = upsample->Cr_r_tab;
176   int * Cbbtab = upsample->Cb_b_tab;
177   INT32 * Crgtab = upsample->Cr_g_tab;
178   INT32 * Cbgtab = upsample->Cb_g_tab;
179   unsigned int r, g, b;
180   INT32 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 = GETJSAMPLE(*inptr1++);
194     cr = GETJSAMPLE(*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  = GETJSAMPLE(*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  = GETJSAMPLE(*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  = GETJSAMPLE(*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  = GETJSAMPLE(*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 = GETJSAMPLE(*inptr1);
234     cr = GETJSAMPLE(*inptr2);
235     cred = Crrtab[cr];
236     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
237     cblue = Cbbtab[cb];
238 
239     y  = GETJSAMPLE(*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 = rgb;
245 
246     y  = GETJSAMPLE(*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 = rgb;
252   }
253 }
254 
255 
256 INLINE
LOCAL(void)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_upsample_ptr upsample = (my_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 = cinfo->sample_range_limit;
271   int * Crrtab = upsample->Cr_r_tab;
272   int * Cbbtab = upsample->Cb_b_tab;
273   INT32 * Crgtab = upsample->Cr_g_tab;
274   INT32 * Cbgtab = upsample->Cb_g_tab;
275   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
276   INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
277   unsigned int r, g, b;
278   INT32 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 = GETJSAMPLE(*inptr1++);
292     cr = GETJSAMPLE(*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  = GETJSAMPLE(*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  = GETJSAMPLE(*inptr00++);
306     r = range_limit[DITHER_565_R(y + cred, d1)];
307     g = range_limit[DITHER_565_G(y + cgreen, d1)];
308     b = range_limit[DITHER_565_B(y + cblue, d1)];
309     d1 = DITHER_ROTATE(d1);
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  = GETJSAMPLE(*inptr01++);
316     r = range_limit[DITHER_565_R(y + cred, d0)];
317     g = range_limit[DITHER_565_G(y + cgreen, d0)];
318     b = range_limit[DITHER_565_B(y + cblue, d0)];
319     d0 = DITHER_ROTATE(d0);
320     rgb = PACK_SHORT_565(r, g, b);
321 
322     y  = GETJSAMPLE(*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 = GETJSAMPLE(*inptr1);
336     cr = GETJSAMPLE(*inptr2);
337     cred = Crrtab[cr];
338     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
339     cblue = Cbbtab[cb];
340 
341     y  = GETJSAMPLE(*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 = rgb;
347 
348     y  = GETJSAMPLE(*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 = rgb;
354   }
355 }
356