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