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
;