RIGHT_SHIFT() public static method

public static RIGHT_SHIFT ( int x, int shft ) : int
x int
shft int
return int
        /*
         * These are the routines invoked by the control routines to do
         * the actual upsampling/conversion.  One row group is processed per call.
         *
         * Note: since we may be writing directly into application-supplied buffers,
         * we have to be honest about the output width; we can't assume the buffer
         * has been rounded up to an even width.
         */

        /// <summary>
        /// Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
        /// </summary>
        private void h2v1_merged_upsample(ComponentBuffer[] input_buf, int in_row_group_ctr, byte[][] output_buf, int outRow)
        {
            int inputIndex0 = 0;
            int inputIndex1 = 0;
            int inputIndex2 = 0;
            int outputIndex = 0;

            byte[] limit       = m_cinfo.m_sample_range_limit;
            int    limitOffset = m_cinfo.m_sampleRangeLimitOffset;

            /* Loop for each pair of output pixels */
            for (int col = m_cinfo.m_output_width >> 1; col > 0; col--)
            {
                /* Do the chroma part of the calculation */
                int cb = input_buf[1][in_row_group_ctr][inputIndex1];
                inputIndex1++;

                int cr = input_buf[2][in_row_group_ctr][inputIndex2];
                inputIndex2++;

                int cred   = m_Cr_r_tab[cr];
                int cgreen = JpegUtils.RIGHT_SHIFT(m_Cb_g_tab[cb] + m_Cr_g_tab[cr], SCALEBITS);
                int cblue  = m_Cb_b_tab[cb];

                /* Fetch 2 Y values and emit 2 pixels */
                int y = input_buf[0][in_row_group_ctr][inputIndex0];
                inputIndex0++;

                output_buf[outRow][outputIndex + JpegConstants.RGB_RED]   = limit[limitOffset + y + cred];
                output_buf[outRow][outputIndex + JpegConstants.RGB_GREEN] = limit[limitOffset + y + cgreen];
                output_buf[outRow][outputIndex + JpegConstants.RGB_BLUE]  = limit[limitOffset + y + cblue];
                outputIndex += JpegConstants.RGB_PIXELSIZE;

                y = input_buf[0][in_row_group_ctr][inputIndex0];
                inputIndex0++;

                output_buf[outRow][outputIndex + JpegConstants.RGB_RED]   = limit[limitOffset + y + cred];
                output_buf[outRow][outputIndex + JpegConstants.RGB_GREEN] = limit[limitOffset + y + cgreen];
                output_buf[outRow][outputIndex + JpegConstants.RGB_BLUE]  = limit[limitOffset + y + cblue];
                outputIndex += JpegConstants.RGB_PIXELSIZE;
            }

            /* If image width is odd, do the last output column separately */
            if ((m_cinfo.m_output_width & 1) != 0)
            {
                int cb     = input_buf[1][in_row_group_ctr][inputIndex1];
                int cr     = input_buf[2][in_row_group_ctr][inputIndex2];
                int cred   = m_Cr_r_tab[cr];
                int cgreen = JpegUtils.RIGHT_SHIFT(m_Cb_g_tab[cb] + m_Cr_g_tab[cr], SCALEBITS);
                int cblue  = m_Cb_b_tab[cb];

                int y = input_buf[0][in_row_group_ctr][inputIndex0];
                output_buf[outRow][outputIndex + JpegConstants.RGB_RED]   = limit[limitOffset + y + cred];
                output_buf[outRow][outputIndex + JpegConstants.RGB_GREEN] = limit[limitOffset + y + cgreen];
                output_buf[outRow][outputIndex + JpegConstants.RGB_BLUE]  = limit[limitOffset + y + cblue];
            }
        }
Esempio n. 2
0
        /**************** Cases other than YCbCr -> RGB **************/

        /// <summary>
        /// Adobe-style YCCK->CMYK conversion.
        /// We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
        /// conversion as above, while passing K (black) unchanged.
        /// We assume build_ycc_rgb_table has been called.
        /// </summary>
        private void ycck_cmyk_convert(ComponentBuffer[] input_buf, int input_row, byte[][] output_buf, int output_row, int num_rows)
        {
            int component0RowOffset = m_perComponentOffsets[0];
            int component1RowOffset = m_perComponentOffsets[1];
            int component2RowOffset = m_perComponentOffsets[2];
            int component3RowOffset = m_perComponentOffsets[3];

            byte[] limit       = m_cinfo.m_sample_range_limit;
            int    limitOffset = m_cinfo.m_sampleRangeLimitOffset;

            int num_cols = m_cinfo.m_output_width;

            for (int row = 0; row < num_rows; row++)
            {
                int columnOffset = 0;
                for (int col = 0; col < num_cols; col++)
                {
                    int y  = input_buf[0][input_row + component0RowOffset][col];
                    int cb = input_buf[1][input_row + component1RowOffset][col];
                    int cr = input_buf[2][input_row + component2RowOffset][col];

                    /* Range-limiting is essential due to noise introduced by DCT losses. */
                    output_buf[output_row + row][columnOffset]     = limit[limitOffset + JpegConstants.MAXJSAMPLE - (y + m_Cr_r_tab[cr])];                                                    /* red */
                    output_buf[output_row + row][columnOffset + 1] = limit[limitOffset + JpegConstants.MAXJSAMPLE - (y + JpegUtils.RIGHT_SHIFT(m_Cb_g_tab[cb] + m_Cr_g_tab[cr], SCALEBITS))]; /* green */
                    output_buf[output_row + row][columnOffset + 2] = limit[limitOffset + JpegConstants.MAXJSAMPLE - (y + m_Cb_b_tab[cb])];                                                    /* blue */

                    /* K passes through unchanged */
                    /* don't need GETJSAMPLE here */
                    output_buf[output_row + row][columnOffset + 3] = input_buf[3][input_row + component3RowOffset][col];
                    columnOffset += 4;
                }

                input_row++;
            }
        }
Esempio n. 3
0
        private void ycc_rgb_convert(ComponentBuffer[] input_buf, int input_row, byte[][] output_buf, int output_row, int num_rows)
        {
            int component0RowOffset = m_perComponentOffsets[0];
            int component1RowOffset = m_perComponentOffsets[1];
            int component2RowOffset = m_perComponentOffsets[2];

            byte[] limit       = m_cinfo.m_sample_range_limit;
            int    limitOffset = m_cinfo.m_sampleRangeLimitOffset;

            for (int row = 0; row < num_rows; row++)
            {
                int columnOffset = 0;
                for (int col = 0; col < m_cinfo.m_output_width; col++)
                {
                    int y  = input_buf[0][input_row + component0RowOffset][col];
                    int cb = input_buf[1][input_row + component1RowOffset][col];
                    int cr = input_buf[2][input_row + component2RowOffset][col];

                    /* Range-limiting is essential due to noise introduced by DCT losses. */
                    output_buf[output_row + row][columnOffset + JpegConstants.RGB_RED]   = limit[limitOffset + y + m_Cr_r_tab[cr]];
                    output_buf[output_row + row][columnOffset + JpegConstants.RGB_GREEN] = limit[limitOffset + y + JpegUtils.RIGHT_SHIFT(m_Cb_g_tab[cb] + m_Cr_g_tab[cr], SCALEBITS)];
                    output_buf[output_row + row][columnOffset + JpegConstants.RGB_BLUE]  = limit[limitOffset + y + m_Cb_b_tab[cb]];
                    columnOffset += JpegConstants.RGB_PIXELSIZE;
                }

                input_row++;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Map some rows of pixels to the output colormapped representation.
        /// General case, with Floyd-Steinberg dithering
        /// </summary>
        private void quantize_fs_dither(byte[][] input_buf, int in_row, byte[][] output_buf, int out_row, int num_rows)
        {
            int nc    = m_cinfo.m_out_color_components;
            int width = m_cinfo.m_output_width;

            byte[] limit       = m_cinfo.m_sample_range_limit;
            int    limitOffset = m_cinfo.m_sampleRangeLimitOffset;

            for (int row = 0; row < num_rows; row++)
            {
                /* Initialize output values to 0 so can process components separately */
                Array.Clear(output_buf[out_row + row], 0, width);

                for (int ci = 0; ci < nc; ci++)
                {
                    int inRow   = in_row + row;
                    int inIndex = ci;

                    int outIndex = 0;
                    int outRow   = out_row + row;

                    int errorIndex = 0;
                    int dir;            /* 1 for left-to-right, -1 for right-to-left */
                    if (m_on_odd_row)
                    {
                        /* work right to left in this row */
                        inIndex   += (width - 1) * nc; /* so point to rightmost pixel */
                        outIndex  += width - 1;
                        dir        = -1;
                        errorIndex = width + 1; /* => entry after last column */
                    }
                    else
                    {
                        /* work left to right in this row */
                        dir        = 1;
                        errorIndex = 0; /* => entry before first column */
                    }
                    int dirnc = dir * nc;

                    /* Preset error values: no error propagated to first pixel from left */
                    int cur = 0;
                    /* and no error propagated to row below yet */
                    int belowerr = 0;
                    int bpreverr = 0;

                    for (int col = width; col > 0; col--)
                    {
                        /* cur holds the error propagated from the previous pixel on the
                         * current line.  Add the error propagated from the previous line
                         * to form the complete error correction term for this pixel, and
                         * round the error term (which is expressed * 16) to an integer.
                         * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
                         * for either sign of the error value.
                         * Note: errorIndex is for *previous* column's array entry.
                         */
                        cur = JpegUtils.RIGHT_SHIFT(cur + m_fserrors[ci][errorIndex + dir] + 8, 4);

                        /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
                         * The maximum error is +- MAXJSAMPLE; this sets the required size
                         * of the range_limit array.
                         */
                        cur += input_buf[inRow][inIndex];
                        cur  = limit[limitOffset + cur];

                        /* Select output value, accumulate into output code for this pixel */
                        int pixcode = m_colorindex[ci][m_colorindexOffset[ci] + cur];
                        output_buf[outRow][outIndex] += (byte)pixcode;

                        /* Compute actual representation error at this pixel */
                        /* Note: we can do this even though we don't have the final */
                        /* pixel code, because the colormap is orthogonal. */
                        cur -= m_sv_colormap[ci][pixcode];

                        /* Compute error fractions to be propagated to adjacent pixels.
                         * Add these into the running sums, and simultaneously shift the
                         * next-line error sums left by 1 column.
                         */
                        int bnexterr = cur;
                        int delta    = cur * 2;
                        cur += delta;       /* form error * 3 */
                        m_fserrors[ci][errorIndex + 0] = (short)(bpreverr + cur);
                        cur     += delta;   /* form error * 5 */
                        bpreverr = belowerr + cur;
                        belowerr = bnexterr;
                        cur     += delta;   /* form error * 7 */

                        /* At this point cur contains the 7/16 error value to be propagated
                         * to the next pixel on the current line, and all the errors for the
                         * next line have been shifted over. We are therefore ready to move on.
                         */
                        inIndex    += dirnc; /* advance input to next column */
                        outIndex   += dir;   /* advance output to next column */
                        errorIndex += dir;   /* advance errorIndex to current column */
                    }

                    /* Post-loop cleanup: we must unload the final error value into the
                     * final fserrors[] entry.  Note we need not unload belowerr because
                     * it is for the dummy column before or after the actual array.
                     */
                    m_fserrors[ci][errorIndex + 0] = (short)bpreverr;  /* unload prev err into array */
                }

                m_on_odd_row = (m_on_odd_row ? false : true);
            }
        }