michael@0: /* michael@0: * jdmrgext.c michael@0: * michael@0: * This file was part of the Independent JPEG Group's software: michael@0: * Copyright (C) 1994-1996, Thomas G. Lane. michael@0: * libjpeg-turbo Modifications: michael@0: * Copyright (C) 2011, D. R. Commander. michael@0: * For conditions of distribution and use, see the accompanying README file. michael@0: * michael@0: * This file contains code for merged upsampling/color conversion. michael@0: */ michael@0: michael@0: michael@0: /* This file is included by jdmerge.c */ michael@0: michael@0: michael@0: /* michael@0: * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. michael@0: */ michael@0: michael@0: INLINE michael@0: LOCAL(void) michael@0: h2v1_merged_upsample_internal (j_decompress_ptr cinfo, michael@0: JSAMPIMAGE input_buf, michael@0: JDIMENSION in_row_group_ctr, michael@0: JSAMPARRAY output_buf) michael@0: { michael@0: my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; michael@0: register int y, cred, cgreen, cblue; michael@0: int cb, cr; michael@0: register JSAMPROW outptr; michael@0: JSAMPROW inptr0, inptr1, inptr2; michael@0: JDIMENSION col; michael@0: /* copy these pointers into registers if possible */ michael@0: register JSAMPLE * range_limit = cinfo->sample_range_limit; michael@0: int * Crrtab = upsample->Cr_r_tab; michael@0: int * Cbbtab = upsample->Cb_b_tab; michael@0: INT32 * Crgtab = upsample->Cr_g_tab; michael@0: INT32 * Cbgtab = upsample->Cb_g_tab; michael@0: SHIFT_TEMPS michael@0: michael@0: inptr0 = input_buf[0][in_row_group_ctr]; michael@0: inptr1 = input_buf[1][in_row_group_ctr]; michael@0: inptr2 = input_buf[2][in_row_group_ctr]; michael@0: outptr = output_buf[0]; michael@0: /* Loop for each pair of output pixels */ michael@0: for (col = cinfo->output_width >> 1; col > 0; col--) { michael@0: /* Do the chroma part of the calculation */ michael@0: cb = GETJSAMPLE(*inptr1++); michael@0: cr = GETJSAMPLE(*inptr2++); michael@0: cred = Crrtab[cr]; michael@0: cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); michael@0: cblue = Cbbtab[cb]; michael@0: /* Fetch 2 Y values and emit 2 pixels */ michael@0: y = GETJSAMPLE(*inptr0++); michael@0: outptr[RGB_RED] = range_limit[y + cred]; michael@0: outptr[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: outptr += RGB_PIXELSIZE; michael@0: y = GETJSAMPLE(*inptr0++); michael@0: outptr[RGB_RED] = range_limit[y + cred]; michael@0: outptr[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: outptr += RGB_PIXELSIZE; michael@0: } michael@0: /* If image width is odd, do the last output column separately */ michael@0: if (cinfo->output_width & 1) { michael@0: cb = GETJSAMPLE(*inptr1); michael@0: cr = GETJSAMPLE(*inptr2); michael@0: cred = Crrtab[cr]; michael@0: cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); michael@0: cblue = Cbbtab[cb]; michael@0: y = GETJSAMPLE(*inptr0); michael@0: outptr[RGB_RED] = range_limit[y + cred]; michael@0: outptr[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: } michael@0: } michael@0: michael@0: michael@0: /* michael@0: * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. michael@0: */ michael@0: michael@0: INLINE michael@0: LOCAL(void) michael@0: h2v2_merged_upsample_internal (j_decompress_ptr cinfo, michael@0: JSAMPIMAGE input_buf, michael@0: JDIMENSION in_row_group_ctr, michael@0: JSAMPARRAY output_buf) michael@0: { michael@0: my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; michael@0: register int y, cred, cgreen, cblue; michael@0: int cb, cr; michael@0: register JSAMPROW outptr0, outptr1; michael@0: JSAMPROW inptr00, inptr01, inptr1, inptr2; michael@0: JDIMENSION col; michael@0: /* copy these pointers into registers if possible */ michael@0: register JSAMPLE * range_limit = cinfo->sample_range_limit; michael@0: int * Crrtab = upsample->Cr_r_tab; michael@0: int * Cbbtab = upsample->Cb_b_tab; michael@0: INT32 * Crgtab = upsample->Cr_g_tab; michael@0: INT32 * Cbgtab = upsample->Cb_g_tab; michael@0: SHIFT_TEMPS michael@0: michael@0: inptr00 = input_buf[0][in_row_group_ctr*2]; michael@0: inptr01 = input_buf[0][in_row_group_ctr*2 + 1]; michael@0: inptr1 = input_buf[1][in_row_group_ctr]; michael@0: inptr2 = input_buf[2][in_row_group_ctr]; michael@0: outptr0 = output_buf[0]; michael@0: outptr1 = output_buf[1]; michael@0: /* Loop for each group of output pixels */ michael@0: for (col = cinfo->output_width >> 1; col > 0; col--) { michael@0: /* Do the chroma part of the calculation */ michael@0: cb = GETJSAMPLE(*inptr1++); michael@0: cr = GETJSAMPLE(*inptr2++); michael@0: cred = Crrtab[cr]; michael@0: cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); michael@0: cblue = Cbbtab[cb]; michael@0: /* Fetch 4 Y values and emit 4 pixels */ michael@0: y = GETJSAMPLE(*inptr00++); michael@0: outptr0[RGB_RED] = range_limit[y + cred]; michael@0: outptr0[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr0[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr0[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: outptr0 += RGB_PIXELSIZE; michael@0: y = GETJSAMPLE(*inptr00++); michael@0: outptr0[RGB_RED] = range_limit[y + cred]; michael@0: outptr0[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr0[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr0[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: outptr0 += RGB_PIXELSIZE; michael@0: y = GETJSAMPLE(*inptr01++); michael@0: outptr1[RGB_RED] = range_limit[y + cred]; michael@0: outptr1[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr1[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr1[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: outptr1 += RGB_PIXELSIZE; michael@0: y = GETJSAMPLE(*inptr01++); michael@0: outptr1[RGB_RED] = range_limit[y + cred]; michael@0: outptr1[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr1[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr1[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: outptr1 += RGB_PIXELSIZE; michael@0: } michael@0: /* If image width is odd, do the last output column separately */ michael@0: if (cinfo->output_width & 1) { michael@0: cb = GETJSAMPLE(*inptr1); michael@0: cr = GETJSAMPLE(*inptr2); michael@0: cred = Crrtab[cr]; michael@0: cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS); michael@0: cblue = Cbbtab[cb]; michael@0: y = GETJSAMPLE(*inptr00); michael@0: outptr0[RGB_RED] = range_limit[y + cred]; michael@0: outptr0[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr0[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr0[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: y = GETJSAMPLE(*inptr01); michael@0: outptr1[RGB_RED] = range_limit[y + cred]; michael@0: outptr1[RGB_GREEN] = range_limit[y + cgreen]; michael@0: outptr1[RGB_BLUE] = range_limit[y + cblue]; michael@0: #ifdef RGB_ALPHA michael@0: outptr1[RGB_ALPHA] = 0xFF; michael@0: #endif michael@0: } michael@0: }