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