|
1 /* |
|
2 * jdmrgext.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) 2011, D. R. Commander. |
|
8 * For conditions of distribution and use, see the accompanying README file. |
|
9 * |
|
10 * This file contains code for merged upsampling/color conversion. |
|
11 */ |
|
12 |
|
13 |
|
14 /* This file is included by jdmerge.c */ |
|
15 |
|
16 |
|
17 /* |
|
18 * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. |
|
19 */ |
|
20 |
|
21 INLINE |
|
22 LOCAL(void) |
|
23 h2v1_merged_upsample_internal (j_decompress_ptr cinfo, |
|
24 JSAMPIMAGE input_buf, |
|
25 JDIMENSION in_row_group_ctr, |
|
26 JSAMPARRAY output_buf) |
|
27 { |
|
28 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; |
|
29 register int y, cred, cgreen, cblue; |
|
30 int cb, cr; |
|
31 register JSAMPROW outptr; |
|
32 JSAMPROW inptr0, inptr1, inptr2; |
|
33 JDIMENSION col; |
|
34 /* copy these pointers into registers if possible */ |
|
35 register JSAMPLE * range_limit = cinfo->sample_range_limit; |
|
36 int * Crrtab = upsample->Cr_r_tab; |
|
37 int * Cbbtab = upsample->Cb_b_tab; |
|
38 INT32 * Crgtab = upsample->Cr_g_tab; |
|
39 INT32 * Cbgtab = upsample->Cb_g_tab; |
|
40 SHIFT_TEMPS |
|
41 |
|
42 inptr0 = input_buf[0][in_row_group_ctr]; |
|
43 inptr1 = input_buf[1][in_row_group_ctr]; |
|
44 inptr2 = input_buf[2][in_row_group_ctr]; |
|
45 outptr = output_buf[0]; |
|
46 /* Loop for each pair of output pixels */ |
|
47 for (col = cinfo->output_width >> 1; col > 0; col--) { |
|
48 /* Do the chroma part of the calculation */ |
|
49 cb = GETJSAMPLE(*inptr1++); |
|
50 cr = GETJSAMPLE(*inptr2++); |
|
51 cred = Crrtab[cr]; |
|
52 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
|
53 cblue = Cbbtab[cb]; |
|
54 /* Fetch 2 Y values and emit 2 pixels */ |
|
55 y = GETJSAMPLE(*inptr0++); |
|
56 outptr[RGB_RED] = range_limit[y + cred]; |
|
57 outptr[RGB_GREEN] = range_limit[y + cgreen]; |
|
58 outptr[RGB_BLUE] = range_limit[y + cblue]; |
|
59 #ifdef RGB_ALPHA |
|
60 outptr[RGB_ALPHA] = 0xFF; |
|
61 #endif |
|
62 outptr += RGB_PIXELSIZE; |
|
63 y = GETJSAMPLE(*inptr0++); |
|
64 outptr[RGB_RED] = range_limit[y + cred]; |
|
65 outptr[RGB_GREEN] = range_limit[y + cgreen]; |
|
66 outptr[RGB_BLUE] = range_limit[y + cblue]; |
|
67 #ifdef RGB_ALPHA |
|
68 outptr[RGB_ALPHA] = 0xFF; |
|
69 #endif |
|
70 outptr += RGB_PIXELSIZE; |
|
71 } |
|
72 /* If image width is odd, do the last output column separately */ |
|
73 if (cinfo->output_width & 1) { |
|
74 cb = GETJSAMPLE(*inptr1); |
|
75 cr = GETJSAMPLE(*inptr2); |
|
76 cred = Crrtab[cr]; |
|
77 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
|
78 cblue = Cbbtab[cb]; |
|
79 y = GETJSAMPLE(*inptr0); |
|
80 outptr[RGB_RED] = range_limit[y + cred]; |
|
81 outptr[RGB_GREEN] = range_limit[y + cgreen]; |
|
82 outptr[RGB_BLUE] = range_limit[y + cblue]; |
|
83 #ifdef RGB_ALPHA |
|
84 outptr[RGB_ALPHA] = 0xFF; |
|
85 #endif |
|
86 } |
|
87 } |
|
88 |
|
89 |
|
90 /* |
|
91 * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. |
|
92 */ |
|
93 |
|
94 INLINE |
|
95 LOCAL(void) |
|
96 h2v2_merged_upsample_internal (j_decompress_ptr cinfo, |
|
97 JSAMPIMAGE input_buf, |
|
98 JDIMENSION in_row_group_ctr, |
|
99 JSAMPARRAY output_buf) |
|
100 { |
|
101 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; |
|
102 register int y, cred, cgreen, cblue; |
|
103 int cb, cr; |
|
104 register JSAMPROW outptr0, outptr1; |
|
105 JSAMPROW inptr00, inptr01, inptr1, inptr2; |
|
106 JDIMENSION col; |
|
107 /* copy these pointers into registers if possible */ |
|
108 register JSAMPLE * range_limit = cinfo->sample_range_limit; |
|
109 int * Crrtab = upsample->Cr_r_tab; |
|
110 int * Cbbtab = upsample->Cb_b_tab; |
|
111 INT32 * Crgtab = upsample->Cr_g_tab; |
|
112 INT32 * Cbgtab = upsample->Cb_g_tab; |
|
113 SHIFT_TEMPS |
|
114 |
|
115 inptr00 = input_buf[0][in_row_group_ctr*2]; |
|
116 inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; |
|
117 inptr1 = input_buf[1][in_row_group_ctr]; |
|
118 inptr2 = input_buf[2][in_row_group_ctr]; |
|
119 outptr0 = output_buf[0]; |
|
120 outptr1 = output_buf[1]; |
|
121 /* Loop for each group of output pixels */ |
|
122 for (col = cinfo->output_width >> 1; col > 0; col--) { |
|
123 /* Do the chroma part of the calculation */ |
|
124 cb = GETJSAMPLE(*inptr1++); |
|
125 cr = GETJSAMPLE(*inptr2++); |
|
126 cred = Crrtab[cr]; |
|
127 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
|
128 cblue = Cbbtab[cb]; |
|
129 /* Fetch 4 Y values and emit 4 pixels */ |
|
130 y = GETJSAMPLE(*inptr00++); |
|
131 outptr0[RGB_RED] = range_limit[y + cred]; |
|
132 outptr0[RGB_GREEN] = range_limit[y + cgreen]; |
|
133 outptr0[RGB_BLUE] = range_limit[y + cblue]; |
|
134 #ifdef RGB_ALPHA |
|
135 outptr0[RGB_ALPHA] = 0xFF; |
|
136 #endif |
|
137 outptr0 += RGB_PIXELSIZE; |
|
138 y = GETJSAMPLE(*inptr00++); |
|
139 outptr0[RGB_RED] = range_limit[y + cred]; |
|
140 outptr0[RGB_GREEN] = range_limit[y + cgreen]; |
|
141 outptr0[RGB_BLUE] = range_limit[y + cblue]; |
|
142 #ifdef RGB_ALPHA |
|
143 outptr0[RGB_ALPHA] = 0xFF; |
|
144 #endif |
|
145 outptr0 += RGB_PIXELSIZE; |
|
146 y = GETJSAMPLE(*inptr01++); |
|
147 outptr1[RGB_RED] = range_limit[y + cred]; |
|
148 outptr1[RGB_GREEN] = range_limit[y + cgreen]; |
|
149 outptr1[RGB_BLUE] = range_limit[y + cblue]; |
|
150 #ifdef RGB_ALPHA |
|
151 outptr1[RGB_ALPHA] = 0xFF; |
|
152 #endif |
|
153 outptr1 += RGB_PIXELSIZE; |
|
154 y = GETJSAMPLE(*inptr01++); |
|
155 outptr1[RGB_RED] = range_limit[y + cred]; |
|
156 outptr1[RGB_GREEN] = range_limit[y + cgreen]; |
|
157 outptr1[RGB_BLUE] = range_limit[y + cblue]; |
|
158 #ifdef RGB_ALPHA |
|
159 outptr1[RGB_ALPHA] = 0xFF; |
|
160 #endif |
|
161 outptr1 += RGB_PIXELSIZE; |
|
162 } |
|
163 /* If image width is odd, do the last output column separately */ |
|
164 if (cinfo->output_width & 1) { |
|
165 cb = GETJSAMPLE(*inptr1); |
|
166 cr = GETJSAMPLE(*inptr2); |
|
167 cred = Crrtab[cr]; |
|
168 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
|
169 cblue = Cbbtab[cb]; |
|
170 y = GETJSAMPLE(*inptr00); |
|
171 outptr0[RGB_RED] = range_limit[y + cred]; |
|
172 outptr0[RGB_GREEN] = range_limit[y + cgreen]; |
|
173 outptr0[RGB_BLUE] = range_limit[y + cblue]; |
|
174 #ifdef RGB_ALPHA |
|
175 outptr0[RGB_ALPHA] = 0xFF; |
|
176 #endif |
|
177 y = GETJSAMPLE(*inptr01); |
|
178 outptr1[RGB_RED] = range_limit[y + cred]; |
|
179 outptr1[RGB_GREEN] = range_limit[y + cgreen]; |
|
180 outptr1[RGB_BLUE] = range_limit[y + cblue]; |
|
181 #ifdef RGB_ALPHA |
|
182 outptr1[RGB_ALPHA] = 0xFF; |
|
183 #endif |
|
184 } |
|
185 } |