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 } 356