• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, 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
LOCAL(void)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_upsample_ptr upsample = (my_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 = 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 = GETJSAMPLE(*inptr1++);
48     cr = GETJSAMPLE(*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  = GETJSAMPLE(*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  = GETJSAMPLE(*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 = GETJSAMPLE(*inptr1);
73     cr = GETJSAMPLE(*inptr2);
74     cred = Crrtab[cr];
75     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
76     cblue = Cbbtab[cb];
77     y  = GETJSAMPLE(*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
LOCAL(void)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_upsample_ptr upsample = (my_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 = 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 = GETJSAMPLE(*inptr1++);
120     cr = GETJSAMPLE(*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  = GETJSAMPLE(*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  = GETJSAMPLE(*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 = GETJSAMPLE(*inptr1);
147     cr = GETJSAMPLE(*inptr2);
148     cred = Crrtab[cr];
149     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
150     cblue = Cbbtab[cb];
151     y  = GETJSAMPLE(*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
LOCAL(void)162 LOCAL(void)
163 h2v2_merged_upsample_565_internal (j_decompress_ptr cinfo,
164                                    JSAMPIMAGE input_buf,
165                                    JDIMENSION in_row_group_ctr,
166                                    JSAMPARRAY output_buf)
167 {
168   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
169   register int y, cred, cgreen, cblue;
170   int cb, cr;
171   register JSAMPROW outptr0, outptr1;
172   JSAMPROW inptr00, inptr01, inptr1, inptr2;
173   JDIMENSION col;
174   /* copy these pointers into registers if possible */
175   register JSAMPLE * range_limit = cinfo->sample_range_limit;
176   int * Crrtab = upsample->Cr_r_tab;
177   int * Cbbtab = upsample->Cb_b_tab;
178   JLONG * Crgtab = upsample->Cr_g_tab;
179   JLONG * Cbgtab = upsample->Cb_g_tab;
180   unsigned int r, g, b;
181   JLONG rgb;
182   SHIFT_TEMPS
183 
184   inptr00 = input_buf[0][in_row_group_ctr * 2];
185   inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
186   inptr1 = input_buf[1][in_row_group_ctr];
187   inptr2 = input_buf[2][in_row_group_ctr];
188   outptr0 = output_buf[0];
189   outptr1 = output_buf[1];
190 
191   /* Loop for each group of output pixels */
192   for (col = cinfo->output_width >> 1; col > 0; col--) {
193     /* Do the chroma part of the calculation */
194     cb = GETJSAMPLE(*inptr1++);
195     cr = GETJSAMPLE(*inptr2++);
196     cred = Crrtab[cr];
197     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
198     cblue = Cbbtab[cb];
199 
200     /* Fetch 4 Y values and emit 4 pixels */
201     y  = GETJSAMPLE(*inptr00++);
202     r = range_limit[y + cred];
203     g = range_limit[y + cgreen];
204     b = range_limit[y + cblue];
205     rgb = PACK_SHORT_565(r, g, b);
206 
207     y  = GETJSAMPLE(*inptr00++);
208     r = range_limit[y + cred];
209     g = range_limit[y + cgreen];
210     b = range_limit[y + cblue];
211     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
212 
213     WRITE_TWO_PIXELS(outptr0, rgb);
214     outptr0 += 4;
215 
216     y  = GETJSAMPLE(*inptr01++);
217     r = range_limit[y + cred];
218     g = range_limit[y + cgreen];
219     b = range_limit[y + cblue];
220     rgb = PACK_SHORT_565(r, g, b);
221 
222     y  = GETJSAMPLE(*inptr01++);
223     r = range_limit[y + cred];
224     g = range_limit[y + cgreen];
225     b = range_limit[y + cblue];
226     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
227 
228     WRITE_TWO_PIXELS(outptr1, rgb);
229     outptr1 += 4;
230   }
231 
232   /* If image width is odd, do the last output column separately */
233   if (cinfo->output_width & 1) {
234     cb = GETJSAMPLE(*inptr1);
235     cr = GETJSAMPLE(*inptr2);
236     cred = Crrtab[cr];
237     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
238     cblue = Cbbtab[cb];
239 
240     y  = GETJSAMPLE(*inptr00);
241     r = range_limit[y + cred];
242     g = range_limit[y + cgreen];
243     b = range_limit[y + cblue];
244     rgb = PACK_SHORT_565(r, g, b);
245     *(INT16*)outptr0 = (INT16)rgb;
246 
247     y  = GETJSAMPLE(*inptr01);
248     r = range_limit[y + cred];
249     g = range_limit[y + cgreen];
250     b = range_limit[y + cblue];
251     rgb = PACK_SHORT_565(r, g, b);
252     *(INT16*)outptr1 = (INT16)rgb;
253   }
254 }
255 
256 
257 INLINE
LOCAL(void)258 LOCAL(void)
259 h2v2_merged_upsample_565D_internal (j_decompress_ptr cinfo,
260                                     JSAMPIMAGE input_buf,
261                                     JDIMENSION in_row_group_ctr,
262                                     JSAMPARRAY output_buf)
263 {
264   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
265   register int y, cred, cgreen, cblue;
266   int cb, cr;
267   register JSAMPROW outptr0, outptr1;
268   JSAMPROW inptr00, inptr01, inptr1, inptr2;
269   JDIMENSION col;
270   /* copy these pointers into registers if possible */
271   register JSAMPLE * range_limit = cinfo->sample_range_limit;
272   int * Crrtab = upsample->Cr_r_tab;
273   int * Cbbtab = upsample->Cb_b_tab;
274   JLONG * Crgtab = upsample->Cr_g_tab;
275   JLONG * Cbgtab = upsample->Cb_g_tab;
276   JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
277   JLONG d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
278   unsigned int r, g, b;
279   JLONG rgb;
280   SHIFT_TEMPS
281 
282   inptr00 = input_buf[0][in_row_group_ctr*2];
283   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
284   inptr1 = input_buf[1][in_row_group_ctr];
285   inptr2 = input_buf[2][in_row_group_ctr];
286   outptr0 = output_buf[0];
287   outptr1 = output_buf[1];
288 
289   /* Loop for each group of output pixels */
290   for (col = cinfo->output_width >> 1; col > 0; col--) {
291     /* Do the chroma part of the calculation */
292     cb = GETJSAMPLE(*inptr1++);
293     cr = GETJSAMPLE(*inptr2++);
294     cred = Crrtab[cr];
295     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
296     cblue = Cbbtab[cb];
297 
298     /* Fetch 4 Y values and emit 4 pixels */
299     y  = GETJSAMPLE(*inptr00++);
300     r = range_limit[DITHER_565_R(y + cred, d0)];
301     g = range_limit[DITHER_565_G(y + cgreen, d0)];
302     b = range_limit[DITHER_565_B(y + cblue, d0)];
303     d0 = DITHER_ROTATE(d0);
304     rgb = PACK_SHORT_565(r, g, b);
305 
306     y  = GETJSAMPLE(*inptr00++);
307     r = range_limit[DITHER_565_R(y + cred, d1)];
308     g = range_limit[DITHER_565_G(y + cgreen, d1)];
309     b = range_limit[DITHER_565_B(y + cblue, d1)];
310     d1 = DITHER_ROTATE(d1);
311     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
312 
313     WRITE_TWO_PIXELS(outptr0, rgb);
314     outptr0 += 4;
315 
316     y  = GETJSAMPLE(*inptr01++);
317     r = range_limit[DITHER_565_R(y + cred, d0)];
318     g = range_limit[DITHER_565_G(y + cgreen, d0)];
319     b = range_limit[DITHER_565_B(y + cblue, d0)];
320     d0 = DITHER_ROTATE(d0);
321     rgb = PACK_SHORT_565(r, g, b);
322 
323     y  = GETJSAMPLE(*inptr01++);
324     r = range_limit[DITHER_565_R(y + cred, d1)];
325     g = range_limit[DITHER_565_G(y + cgreen, d1)];
326     b = range_limit[DITHER_565_B(y + cblue, d1)];
327     d1 = DITHER_ROTATE(d1);
328     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
329 
330     WRITE_TWO_PIXELS(outptr1, rgb);
331     outptr1 += 4;
332   }
333 
334   /* If image width is odd, do the last output column separately */
335   if (cinfo->output_width & 1) {
336     cb = GETJSAMPLE(*inptr1);
337     cr = GETJSAMPLE(*inptr2);
338     cred = Crrtab[cr];
339     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
340     cblue = Cbbtab[cb];
341 
342     y  = GETJSAMPLE(*inptr00);
343     r = range_limit[DITHER_565_R(y + cred, d0)];
344     g = range_limit[DITHER_565_G(y + cgreen, d0)];
345     b = range_limit[DITHER_565_B(y + cblue, d0)];
346     rgb = PACK_SHORT_565(r, g, b);
347     *(INT16*)outptr0 = (INT16)rgb;
348 
349     y  = GETJSAMPLE(*inptr01);
350     r = range_limit[DITHER_565_R(y + cred, d1)];
351     g = range_limit[DITHER_565_G(y + cgreen, d1)];
352     b = range_limit[DITHER_565_B(y + cblue, d1)];
353     rgb = PACK_SHORT_565(r, g, b);
354     *(INT16*)outptr1 = (INT16)rgb;
355   }
356 }
357