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