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
16INLINE
17LOCAL(void)
18h2v1_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
87INLINE
88LOCAL(void)
89h2v1_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
161INLINE
162LOCAL(void)
163h2v2_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
257INLINE
258LOCAL(void)
259h2v2_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