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, 2018, 2020, D. R. Commander.
9 * For conditions of distribution and use, see the accompanying README.ijg
12 * This file contains code for merged upsampling/color conversion.
18 h2v1_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
19 JDIMENSION in_row_group_ctr,
20 JSAMPARRAY output_buf)
22 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
23 register int y, cred, cgreen, cblue;
25 register JSAMPROW outptr;
26 JSAMPROW inptr0, inptr1, inptr2;
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 JLONG *Crgtab = upsample->Cr_g_tab;
33 JLONG *Cbgtab = upsample->Cb_g_tab;
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];
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 */
49 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
52 /* Fetch 2 Y values and emit 2 pixels */
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);
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));
65 WRITE_TWO_PIXELS(outptr, rgb);
69 /* If image width is odd, do the last output column separately */
70 if (cinfo->output_width & 1) {
74 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
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 = (INT16)rgb;
88 h2v1_merged_upsample_565D_internal(j_decompress_ptr cinfo,
90 JDIMENSION in_row_group_ctr,
91 JSAMPARRAY output_buf)
93 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
94 register int y, cred, cgreen, cblue;
96 register JSAMPROW outptr;
97 JSAMPROW inptr0, inptr1, inptr2;
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 JLONG *Crgtab = upsample->Cr_g_tab;
104 JLONG *Cbgtab = upsample->Cb_g_tab;
105 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
106 unsigned int r, g, b;
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];
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 */
121 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
124 /* Fetch 2 Y values and emit 2 pixels */
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);
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));
139 WRITE_TWO_PIXELS(outptr, rgb);
143 /* If image width is odd, do the last output column separately */
144 if (cinfo->output_width & 1) {
148 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
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 = (INT16)rgb;
162 h2v2_merged_upsample_565_internal(j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
163 JDIMENSION in_row_group_ctr,
164 JSAMPARRAY output_buf)
166 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
167 register int y, cred, cgreen, cblue;
169 register JSAMPROW outptr0, outptr1;
170 JSAMPROW inptr00, inptr01, inptr1, inptr2;
172 /* copy these pointers into registers if possible */
173 register JSAMPLE *range_limit = cinfo->sample_range_limit;
174 int *Crrtab = upsample->Cr_r_tab;
175 int *Cbbtab = upsample->Cb_b_tab;
176 JLONG *Crgtab = upsample->Cr_g_tab;
177 JLONG *Cbgtab = upsample->Cb_g_tab;
178 unsigned int r, g, b;
182 inptr00 = input_buf[0][in_row_group_ctr * 2];
183 inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
184 inptr1 = input_buf[1][in_row_group_ctr];
185 inptr2 = input_buf[2][in_row_group_ctr];
186 outptr0 = output_buf[0];
187 outptr1 = output_buf[1];
189 /* Loop for each group of output pixels */
190 for (col = cinfo->output_width >> 1; col > 0; col--) {
191 /* Do the chroma part of the calculation */
195 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
198 /* Fetch 4 Y values and emit 4 pixels */
200 r = range_limit[y + cred];
201 g = range_limit[y + cgreen];
202 b = range_limit[y + cblue];
203 rgb = PACK_SHORT_565(r, g, b);
206 r = range_limit[y + cred];
207 g = range_limit[y + cgreen];
208 b = range_limit[y + cblue];
209 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
211 WRITE_TWO_PIXELS(outptr0, rgb);
215 r = range_limit[y + cred];
216 g = range_limit[y + cgreen];
217 b = range_limit[y + cblue];
218 rgb = PACK_SHORT_565(r, g, b);
221 r = range_limit[y + cred];
222 g = range_limit[y + cgreen];
223 b = range_limit[y + cblue];
224 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
226 WRITE_TWO_PIXELS(outptr1, rgb);
230 /* If image width is odd, do the last output column separately */
231 if (cinfo->output_width & 1) {
235 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
239 r = range_limit[y + cred];
240 g = range_limit[y + cgreen];
241 b = range_limit[y + cblue];
242 rgb = PACK_SHORT_565(r, g, b);
243 *(INT16 *)outptr0 = (INT16)rgb;
246 r = range_limit[y + cred];
247 g = range_limit[y + cgreen];
248 b = range_limit[y + cblue];
249 rgb = PACK_SHORT_565(r, g, b);
250 *(INT16 *)outptr1 = (INT16)rgb;
257 h2v2_merged_upsample_565D_internal(j_decompress_ptr cinfo,
258 JSAMPIMAGE input_buf,
259 JDIMENSION in_row_group_ctr,
260 JSAMPARRAY output_buf)
262 my_merged_upsample_ptr upsample = (my_merged_upsample_ptr)cinfo->upsample;
263 register int y, cred, cgreen, cblue;
265 register JSAMPROW outptr0, outptr1;
266 JSAMPROW inptr00, inptr01, inptr1, inptr2;
268 /* copy these pointers into registers if possible */
269 register JSAMPLE *range_limit = cinfo->sample_range_limit;
270 int *Crrtab = upsample->Cr_r_tab;
271 int *Cbbtab = upsample->Cb_b_tab;
272 JLONG *Crgtab = upsample->Cr_g_tab;
273 JLONG *Cbgtab = upsample->Cb_g_tab;
274 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
275 JLONG d1 = dither_matrix[(cinfo->output_scanline + 1) & DITHER_MASK];
276 unsigned int r, g, b;
280 inptr00 = input_buf[0][in_row_group_ctr * 2];
281 inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
282 inptr1 = input_buf[1][in_row_group_ctr];
283 inptr2 = input_buf[2][in_row_group_ctr];
284 outptr0 = output_buf[0];
285 outptr1 = output_buf[1];
287 /* Loop for each group of output pixels */
288 for (col = cinfo->output_width >> 1; col > 0; col--) {
289 /* Do the chroma part of the calculation */
293 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
296 /* Fetch 4 Y values and emit 4 pixels */
298 r = range_limit[DITHER_565_R(y + cred, d0)];
299 g = range_limit[DITHER_565_G(y + cgreen, d0)];
300 b = range_limit[DITHER_565_B(y + cblue, d0)];
301 d0 = DITHER_ROTATE(d0);
302 rgb = PACK_SHORT_565(r, g, b);
305 r = range_limit[DITHER_565_R(y + cred, d0)];
306 g = range_limit[DITHER_565_G(y + cgreen, d0)];
307 b = range_limit[DITHER_565_B(y + cblue, d0)];
308 d0 = DITHER_ROTATE(d0);
309 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
311 WRITE_TWO_PIXELS(outptr0, rgb);
315 r = range_limit[DITHER_565_R(y + cred, d1)];
316 g = range_limit[DITHER_565_G(y + cgreen, d1)];
317 b = range_limit[DITHER_565_B(y + cblue, d1)];
318 d1 = DITHER_ROTATE(d1);
319 rgb = PACK_SHORT_565(r, g, b);
322 r = range_limit[DITHER_565_R(y + cred, d1)];
323 g = range_limit[DITHER_565_G(y + cgreen, d1)];
324 b = range_limit[DITHER_565_B(y + cblue, d1)];
325 d1 = DITHER_ROTATE(d1);
326 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
328 WRITE_TWO_PIXELS(outptr1, rgb);
332 /* If image width is odd, do the last output column separately */
333 if (cinfo->output_width & 1) {
337 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
341 r = range_limit[DITHER_565_R(y + cred, d0)];
342 g = range_limit[DITHER_565_G(y + cgreen, d0)];
343 b = range_limit[DITHER_565_B(y + cblue, d0)];
344 rgb = PACK_SHORT_565(r, g, b);
345 *(INT16 *)outptr0 = (INT16)rgb;
348 r = range_limit[DITHER_565_R(y + cred, d1)];
349 g = range_limit[DITHER_565_G(y + cgreen, d1)];
350 b = range_limit[DITHER_565_B(y + cblue, d1)];
351 rgb = PACK_SHORT_565(r, g, b);
352 *(INT16 *)outptr1 = (INT16)rgb;