jdmrg565.c (11138B)
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, 2018, 2020, 2022, 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_merged_upsample_ptr upsample = (my_merged_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 = (_JSAMPLE *)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 = *inptr1++; 48 cr = *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 = *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 = *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 = *inptr1; 73 cr = *inptr2; 74 cred = Crrtab[cr]; 75 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); 76 cblue = Cbbtab[cb]; 77 y = *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_merged_upsample_ptr upsample = (my_merged_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 = (_JSAMPLE *)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 = *inptr1++; 120 cr = *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 = *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 = *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 = *inptr1; 147 cr = *inptr2; 148 cred = Crrtab[cr]; 149 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); 150 cblue = Cbbtab[cb]; 151 y = *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, _JSAMPIMAGE input_buf, 164 JDIMENSION in_row_group_ctr, 165 _JSAMPARRAY output_buf) 166 { 167 my_merged_upsample_ptr upsample = (my_merged_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 = (_JSAMPLE *)cinfo->sample_range_limit; 175 int *Crrtab = upsample->Cr_r_tab; 176 int *Cbbtab = upsample->Cb_b_tab; 177 JLONG *Crgtab = upsample->Cr_g_tab; 178 JLONG *Cbgtab = upsample->Cb_g_tab; 179 unsigned int r, g, b; 180 JLONG 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 = *inptr1++; 194 cr = *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 = *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 = *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 = *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 = *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 = *inptr1; 234 cr = *inptr2; 235 cred = Crrtab[cr]; 236 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); 237 cblue = Cbbtab[cb]; 238 239 y = *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 = (INT16)rgb; 245 246 y = *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 = (INT16)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_merged_upsample_ptr upsample = (my_merged_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 = (_JSAMPLE *)cinfo->sample_range_limit; 271 int *Crrtab = upsample->Cr_r_tab; 272 int *Cbbtab = upsample->Cb_b_tab; 273 JLONG *Crgtab = upsample->Cr_g_tab; 274 JLONG *Cbgtab = upsample->Cb_g_tab; 275 JLONG d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK]; 276 JLONG d1 = dither_matrix[(cinfo->output_scanline + 1) & DITHER_MASK]; 277 unsigned int r, g, b; 278 JLONG 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 = *inptr1++; 292 cr = *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 = *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 = *inptr00++; 306 r = range_limit[DITHER_565_R(y + cred, d0)]; 307 g = range_limit[DITHER_565_G(y + cgreen, d0)]; 308 b = range_limit[DITHER_565_B(y + cblue, d0)]; 309 d0 = DITHER_ROTATE(d0); 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 = *inptr01++; 316 r = range_limit[DITHER_565_R(y + cred, d1)]; 317 g = range_limit[DITHER_565_G(y + cgreen, d1)]; 318 b = range_limit[DITHER_565_B(y + cblue, d1)]; 319 d1 = DITHER_ROTATE(d1); 320 rgb = PACK_SHORT_565(r, g, b); 321 322 y = *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 = *inptr1; 336 cr = *inptr2; 337 cred = Crrtab[cr]; 338 cgreen = (int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); 339 cblue = Cbbtab[cb]; 340 341 y = *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 = (INT16)rgb; 347 348 y = *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 = (INT16)rgb; 354 } 355 }