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
15INLINE
16LOCAL(void)
17h2v1_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
86INLINE
87LOCAL(void)
88h2v1_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
160INLINE
161LOCAL(void)
162h2v2_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
256INLINE
257LOCAL(void)
258h2v2_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