OLD | NEW |
(Empty) | |
| 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, D. R. Commander. |
| 9 * For conditions of distribution and use, see the accompanying README file. |
| 10 * |
| 11 * This file contains code for merged upsampling/color conversion. |
| 12 */ |
| 13 |
| 14 |
| 15 INLINE |
| 16 LOCAL(void) |
| 17 h2v1_merged_upsample_565_internal (j_decompress_ptr cinfo, |
| 18 JSAMPIMAGE input_buf, |
| 19 JDIMENSION in_row_group_ctr, |
| 20 JSAMPARRAY output_buf) |
| 21 { |
| 22 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; |
| 23 register int y, cred, cgreen, cblue; |
| 24 int cb, cr; |
| 25 register JSAMPROW outptr; |
| 26 JSAMPROW inptr0, inptr1, inptr2; |
| 27 JDIMENSION col; |
| 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 INT32 * Crgtab = upsample->Cr_g_tab; |
| 33 INT32 * Cbgtab = upsample->Cb_g_tab; |
| 34 unsigned int r, g, b; |
| 35 INT32 rgb; |
| 36 SHIFT_TEMPS |
| 37 |
| 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]; |
| 42 |
| 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 */ |
| 46 cb = GETJSAMPLE(*inptr1++); |
| 47 cr = GETJSAMPLE(*inptr2++); |
| 48 cred = Crrtab[cr]; |
| 49 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 50 cblue = Cbbtab[cb]; |
| 51 |
| 52 /* Fetch 2 Y values and emit 2 pixels */ |
| 53 y = GETJSAMPLE(*inptr0++); |
| 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); |
| 58 |
| 59 y = GETJSAMPLE(*inptr0++); |
| 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)); |
| 64 |
| 65 WRITE_TWO_PIXELS(outptr, rgb); |
| 66 outptr += 4; |
| 67 } |
| 68 |
| 69 /* If image width is odd, do the last output column separately */ |
| 70 if (cinfo->output_width & 1) { |
| 71 cb = GETJSAMPLE(*inptr1); |
| 72 cr = GETJSAMPLE(*inptr2); |
| 73 cred = Crrtab[cr]; |
| 74 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 75 cblue = Cbbtab[cb]; |
| 76 y = GETJSAMPLE(*inptr0); |
| 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 = rgb; |
| 82 } |
| 83 } |
| 84 |
| 85 |
| 86 INLINE |
| 87 LOCAL(void) |
| 88 h2v1_merged_upsample_565D_internal (j_decompress_ptr cinfo, |
| 89 JSAMPIMAGE input_buf, |
| 90 JDIMENSION in_row_group_ctr, |
| 91 JSAMPARRAY output_buf) |
| 92 { |
| 93 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; |
| 94 register int y, cred, cgreen, cblue; |
| 95 int cb, cr; |
| 96 register JSAMPROW outptr; |
| 97 JSAMPROW inptr0, inptr1, inptr2; |
| 98 JDIMENSION col; |
| 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 INT32 * Crgtab = upsample->Cr_g_tab; |
| 104 INT32 * Cbgtab = upsample->Cb_g_tab; |
| 105 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK]; |
| 106 unsigned int r, g, b; |
| 107 INT32 rgb; |
| 108 SHIFT_TEMPS |
| 109 |
| 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]; |
| 114 |
| 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 */ |
| 118 cb = GETJSAMPLE(*inptr1++); |
| 119 cr = GETJSAMPLE(*inptr2++); |
| 120 cred = Crrtab[cr]; |
| 121 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 122 cblue = Cbbtab[cb]; |
| 123 |
| 124 /* Fetch 2 Y values and emit 2 pixels */ |
| 125 y = GETJSAMPLE(*inptr0++); |
| 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); |
| 131 |
| 132 y = GETJSAMPLE(*inptr0++); |
| 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)); |
| 138 |
| 139 WRITE_TWO_PIXELS(outptr, rgb); |
| 140 outptr += 4; |
| 141 } |
| 142 |
| 143 /* If image width is odd, do the last output column separately */ |
| 144 if (cinfo->output_width & 1) { |
| 145 cb = GETJSAMPLE(*inptr1); |
| 146 cr = GETJSAMPLE(*inptr2); |
| 147 cred = Crrtab[cr]; |
| 148 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 149 cblue = Cbbtab[cb]; |
| 150 y = GETJSAMPLE(*inptr0); |
| 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 = rgb; |
| 156 } |
| 157 } |
| 158 |
| 159 |
| 160 INLINE |
| 161 LOCAL(void) |
| 162 h2v2_merged_upsample_565_internal (j_decompress_ptr cinfo, |
| 163 JSAMPIMAGE input_buf, |
| 164 JDIMENSION in_row_group_ctr, |
| 165 JSAMPARRAY output_buf) |
| 166 { |
| 167 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; |
| 168 register int y, cred, cgreen, cblue; |
| 169 int cb, cr; |
| 170 register JSAMPROW outptr0, outptr1; |
| 171 JSAMPROW inptr00, inptr01, inptr1, inptr2; |
| 172 JDIMENSION col; |
| 173 /* copy these pointers into registers if possible */ |
| 174 register JSAMPLE * range_limit = cinfo->sample_range_limit; |
| 175 int * Crrtab = upsample->Cr_r_tab; |
| 176 int * Cbbtab = upsample->Cb_b_tab; |
| 177 INT32 * Crgtab = upsample->Cr_g_tab; |
| 178 INT32 * Cbgtab = upsample->Cb_g_tab; |
| 179 unsigned int r, g, b; |
| 180 INT32 rgb; |
| 181 SHIFT_TEMPS |
| 182 |
| 183 inptr00 = input_buf[0][in_row_group_ctr * 2]; |
| 184 inptr01 = input_buf[0][in_row_group_ctr * 2 + 1]; |
| 185 inptr1 = input_buf[1][in_row_group_ctr]; |
| 186 inptr2 = input_buf[2][in_row_group_ctr]; |
| 187 outptr0 = output_buf[0]; |
| 188 outptr1 = output_buf[1]; |
| 189 |
| 190 /* Loop for each group of output pixels */ |
| 191 for (col = cinfo->output_width >> 1; col > 0; col--) { |
| 192 /* Do the chroma part of the calculation */ |
| 193 cb = GETJSAMPLE(*inptr1++); |
| 194 cr = GETJSAMPLE(*inptr2++); |
| 195 cred = Crrtab[cr]; |
| 196 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 197 cblue = Cbbtab[cb]; |
| 198 |
| 199 /* Fetch 4 Y values and emit 4 pixels */ |
| 200 y = GETJSAMPLE(*inptr00++); |
| 201 r = range_limit[y + cred]; |
| 202 g = range_limit[y + cgreen]; |
| 203 b = range_limit[y + cblue]; |
| 204 rgb = PACK_SHORT_565(r, g, b); |
| 205 |
| 206 y = GETJSAMPLE(*inptr00++); |
| 207 r = range_limit[y + cred]; |
| 208 g = range_limit[y + cgreen]; |
| 209 b = range_limit[y + cblue]; |
| 210 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); |
| 211 |
| 212 WRITE_TWO_PIXELS(outptr0, rgb); |
| 213 outptr0 += 4; |
| 214 |
| 215 y = GETJSAMPLE(*inptr01++); |
| 216 r = range_limit[y + cred]; |
| 217 g = range_limit[y + cgreen]; |
| 218 b = range_limit[y + cblue]; |
| 219 rgb = PACK_SHORT_565(r, g, b); |
| 220 |
| 221 y = GETJSAMPLE(*inptr01++); |
| 222 r = range_limit[y + cred]; |
| 223 g = range_limit[y + cgreen]; |
| 224 b = range_limit[y + cblue]; |
| 225 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); |
| 226 |
| 227 WRITE_TWO_PIXELS(outptr1, rgb); |
| 228 outptr1 += 4; |
| 229 } |
| 230 |
| 231 /* If image width is odd, do the last output column separately */ |
| 232 if (cinfo->output_width & 1) { |
| 233 cb = GETJSAMPLE(*inptr1); |
| 234 cr = GETJSAMPLE(*inptr2); |
| 235 cred = Crrtab[cr]; |
| 236 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 237 cblue = Cbbtab[cb]; |
| 238 |
| 239 y = GETJSAMPLE(*inptr00); |
| 240 r = range_limit[y + cred]; |
| 241 g = range_limit[y + cgreen]; |
| 242 b = range_limit[y + cblue]; |
| 243 rgb = PACK_SHORT_565(r, g, b); |
| 244 *(INT16*)outptr0 = rgb; |
| 245 |
| 246 y = GETJSAMPLE(*inptr01); |
| 247 r = range_limit[y + cred]; |
| 248 g = range_limit[y + cgreen]; |
| 249 b = range_limit[y + cblue]; |
| 250 rgb = PACK_SHORT_565(r, g, b); |
| 251 *(INT16*)outptr1 = rgb; |
| 252 } |
| 253 } |
| 254 |
| 255 |
| 256 INLINE |
| 257 LOCAL(void) |
| 258 h2v2_merged_upsample_565D_internal (j_decompress_ptr cinfo, |
| 259 JSAMPIMAGE input_buf, |
| 260 JDIMENSION in_row_group_ctr, |
| 261 JSAMPARRAY output_buf) |
| 262 { |
| 263 my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; |
| 264 register int y, cred, cgreen, cblue; |
| 265 int cb, cr; |
| 266 register JSAMPROW outptr0, outptr1; |
| 267 JSAMPROW inptr00, inptr01, inptr1, inptr2; |
| 268 JDIMENSION col; |
| 269 /* copy these pointers into registers if possible */ |
| 270 register JSAMPLE * range_limit = cinfo->sample_range_limit; |
| 271 int * Crrtab = upsample->Cr_r_tab; |
| 272 int * Cbbtab = upsample->Cb_b_tab; |
| 273 INT32 * Crgtab = upsample->Cr_g_tab; |
| 274 INT32 * Cbgtab = upsample->Cb_g_tab; |
| 275 INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK]; |
| 276 INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK]; |
| 277 unsigned int r, g, b; |
| 278 INT32 rgb; |
| 279 SHIFT_TEMPS |
| 280 |
| 281 inptr00 = input_buf[0][in_row_group_ctr*2]; |
| 282 inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; |
| 283 inptr1 = input_buf[1][in_row_group_ctr]; |
| 284 inptr2 = input_buf[2][in_row_group_ctr]; |
| 285 outptr0 = output_buf[0]; |
| 286 outptr1 = output_buf[1]; |
| 287 |
| 288 /* Loop for each group of output pixels */ |
| 289 for (col = cinfo->output_width >> 1; col > 0; col--) { |
| 290 /* Do the chroma part of the calculation */ |
| 291 cb = GETJSAMPLE(*inptr1++); |
| 292 cr = GETJSAMPLE(*inptr2++); |
| 293 cred = Crrtab[cr]; |
| 294 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 295 cblue = Cbbtab[cb]; |
| 296 |
| 297 /* Fetch 4 Y values and emit 4 pixels */ |
| 298 y = GETJSAMPLE(*inptr00++); |
| 299 r = range_limit[DITHER_565_R(y + cred, d0)]; |
| 300 g = range_limit[DITHER_565_G(y + cgreen, d0)]; |
| 301 b = range_limit[DITHER_565_B(y + cblue, d0)]; |
| 302 d0 = DITHER_ROTATE(d0); |
| 303 rgb = PACK_SHORT_565(r, g, b); |
| 304 |
| 305 y = GETJSAMPLE(*inptr00++); |
| 306 r = range_limit[DITHER_565_R(y + cred, d1)]; |
| 307 g = range_limit[DITHER_565_G(y + cgreen, d1)]; |
| 308 b = range_limit[DITHER_565_B(y + cblue, d1)]; |
| 309 d1 = DITHER_ROTATE(d1); |
| 310 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); |
| 311 |
| 312 WRITE_TWO_PIXELS(outptr0, rgb); |
| 313 outptr0 += 4; |
| 314 |
| 315 y = GETJSAMPLE(*inptr01++); |
| 316 r = range_limit[DITHER_565_R(y + cred, d0)]; |
| 317 g = range_limit[DITHER_565_G(y + cgreen, d0)]; |
| 318 b = range_limit[DITHER_565_B(y + cblue, d0)]; |
| 319 d0 = DITHER_ROTATE(d0); |
| 320 rgb = PACK_SHORT_565(r, g, b); |
| 321 |
| 322 y = GETJSAMPLE(*inptr01++); |
| 323 r = range_limit[DITHER_565_R(y + cred, d1)]; |
| 324 g = range_limit[DITHER_565_G(y + cgreen, d1)]; |
| 325 b = range_limit[DITHER_565_B(y + cblue, d1)]; |
| 326 d1 = DITHER_ROTATE(d1); |
| 327 rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b)); |
| 328 |
| 329 WRITE_TWO_PIXELS(outptr1, rgb); |
| 330 outptr1 += 4; |
| 331 } |
| 332 |
| 333 /* If image width is odd, do the last output column separately */ |
| 334 if (cinfo->output_width & 1) { |
| 335 cb = GETJSAMPLE(*inptr1); |
| 336 cr = GETJSAMPLE(*inptr2); |
| 337 cred = Crrtab[cr]; |
| 338 cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); |
| 339 cblue = Cbbtab[cb]; |
| 340 |
| 341 y = GETJSAMPLE(*inptr00); |
| 342 r = range_limit[DITHER_565_R(y + cred, d0)]; |
| 343 g = range_limit[DITHER_565_G(y + cgreen, d0)]; |
| 344 b = range_limit[DITHER_565_B(y + cblue, d0)]; |
| 345 rgb = PACK_SHORT_565(r, g, b); |
| 346 *(INT16*)outptr0 = rgb; |
| 347 |
| 348 y = GETJSAMPLE(*inptr01); |
| 349 r = range_limit[DITHER_565_R(y + cred, d1)]; |
| 350 g = range_limit[DITHER_565_G(y + cgreen, d1)]; |
| 351 b = range_limit[DITHER_565_B(y + cblue, d1)]; |
| 352 rgb = PACK_SHORT_565(r, g, b); |
| 353 *(INT16*)outptr1 = rgb; |
| 354 } |
| 355 } |
OLD | NEW |