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