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