Exemplo n.º 1
0
        /// <summary>
        /// Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
        /// It's still a box filter.
        /// </summary>
        private void h2v2_upsample(ComponentBuffer input_data)
        {
            ComponentBuffer output_data = m_color_buf[m_currentComponent];

            int inrow  = 0;
            int outrow = 0;

            while (outrow < m_cinfo.m_max_v_samp_factor)
            {
                int row      = m_upsampleRowOffset + inrow;
                int outIndex = 0;

                var inputBuffer  = input_data[row];
                var outputBuffer = output_data[outrow];
                for (int col = 0; outIndex < m_cinfo.m_output_width; col++)
                {
                    byte invalue = inputBuffer[col]; /* don't need GETJSAMPLE() here */
                    outputBuffer[outIndex++] = invalue;
                    outputBuffer[outIndex++] = invalue;
                }

                JpegUtils.jcopy_sample_rows(output_data, outrow, output_data, outrow + 1, 1, m_cinfo.m_output_width);
                inrow++;
                outrow += 2;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// This version handles any integral sampling ratios.
        /// This is not used for typical JPEG files, so it need not be fast.
        /// Nor, for that matter, is it particularly accurate: the algorithm is
        /// simple replication of the input pixel onto the corresponding output
        /// pixels.  The hi-falutin sampling literature refers to this as a
        /// "box filter".  A box filter tends to introduce visible artifacts,
        /// so if you are actually going to use 3:1 or 4:1 sampling ratios
        /// you would be well advised to improve this code.
        /// </summary>
        private void int_upsample(ref ComponentBuffer input_data)
        {
            ComponentBuffer output_data = m_color_buf[m_currentComponent];
            int             h_expand    = m_h_expand[m_currentComponent];
            int             v_expand    = m_v_expand[m_currentComponent];

            int inrow  = 0;
            int outrow = 0;

            while (outrow < m_cinfo.m_max_v_samp_factor)
            {
                /* Generate one output row with proper horizontal expansion */
                int row = m_upsampleRowOffset + inrow;
                for (int col = 0; col < m_cinfo.m_output_width; col++)
                {
                    byte invalue  = input_data[row][col]; /* don't need GETJSAMPLE() here */
                    int  outIndex = 0;
                    for (int h = h_expand; h > 0; h--)
                    {
                        output_data[outrow][outIndex] = invalue;
                        outIndex++;
                    }
                }

                /* Generate any additional output rows by duplicating the first one */
                if (v_expand > 1)
                {
                    JpegUtils.jcopy_sample_rows(output_data, outrow, output_data,
                                                outrow + 1, v_expand - 1, m_cinfo.m_output_width);
                }

                inrow++;
                outrow += v_expand;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
        /// It's still a box filter.
        /// </summary>
        private void H2V2UpSample(ref ComponentBuffer input_data)
        {
            var output_data = m_color_buf[m_currentComponent];

            var inrow  = 0;
            var outrow = 0;

            while (outrow < m_cinfo.m_maxVSampleFactor)
            {
                var row      = m_upsampleRowOffset + inrow;
                var outIndex = 0;

                for (var col = 0; outIndex < m_cinfo.outputWidth; col++)
                {
                    var invalue = input_data[row][col]; /* don't need GETJSAMPLE() here */
                    output_data[outrow][outIndex] = invalue;
                    outIndex++;
                    output_data[outrow][outIndex] = invalue;
                    outIndex++;
                }

                JpegUtils.jcopy_sample_rows(output_data, outrow, output_data, outrow + 1, 1, m_cinfo.outputWidth);
                inrow++;
                outrow += 2;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Control routine to do upsampling (and color conversion).
        /// The control routine just handles the row buffering considerations.
        /// 2:1 vertical sampling case: may need a spare row.
        /// </summary>
        private void merged_2v_upsample(ComponentBuffer[] input_buf, ref int in_row_group_ctr, byte[][] output_buf, ref int out_row_ctr, int out_rows_avail)
        {
            int num_rows;        /* number of rows returned to caller */

            if (m_spare_full)
            {
                /* If we have a spare row saved from a previous cycle, just return it. */
                byte[][] temp = new byte[1][];
                temp[0] = m_spare_row;
                JpegUtils.jcopy_sample_rows(temp, 0, output_buf, out_row_ctr, 1, m_out_row_width);
                num_rows     = 1;
                m_spare_full = false;
            }
            else
            {
                /* Figure number of rows to return to caller. */
                num_rows = 2;

                /* Not more than the distance to the end of the image. */
                if (num_rows > m_rows_to_go)
                {
                    num_rows = m_rows_to_go;
                }

                /* And not more than what the client can accept: */
                out_rows_avail -= out_row_ctr;
                if (num_rows > out_rows_avail)
                {
                    num_rows = out_rows_avail;
                }

                /* Create output pointer array for upsampler. */
                byte[][] work_ptrs = new byte[2][];
                work_ptrs[0] = output_buf[out_row_ctr];
                if (num_rows > 1)
                {
                    work_ptrs[1] = output_buf[out_row_ctr + 1];
                }
                else
                {
                    work_ptrs[1] = m_spare_row;
                    m_spare_full = true;
                }

                /* Now do the upsampling. */
                h2v2_merged_upsample(input_buf, in_row_group_ctr, work_ptrs);
            }

            /* Adjust counts */
            out_row_ctr  += num_rows;
            m_rows_to_go -= num_rows;

            /* When the buffer is emptied, declare this input row group consumed */
            if (!m_spare_full)
            {
                in_row_group_ctr++;
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Downsample pixel values of a single component.
        /// This version handles the special case of a full-size component,
        /// without smoothing.
        /// </summary>
        private void FullsizeDownsample(int componentIndex, byte[][] input_data, int startInputRow, byte[][] output_data, int startOutRow)
        {
            /* Copy the data */
            JpegUtils.jcopy_sample_rows(input_data, startInputRow, output_data, startOutRow, m_cinfo.m_max_v_samp_factor, m_cinfo.m_image_width);

            /* Edge-expand */
            var compptr = m_cinfo.Component_info[componentIndex];

            ExpandRightEdge(output_data, startOutRow, m_cinfo.m_max_v_samp_factor,
                            m_cinfo.m_image_width, compptr.Width_in_blocks * compptr.DCT_h_scaled_size);
        }
Exemplo n.º 6
0
 /// <summary>
 /// Color conversion for grayscale: just copy the data.
 /// This also works for YCC -> grayscale conversion, in which
 /// we just copy the Y (luminance) component and ignore chrominance.
 /// </summary>
 private void GrayscaleConvert(ComponentBuffer[] input_buf, int input_row, byte[][] output_buf, int output_row, int num_rows)
 {
     JpegUtils.jcopy_sample_rows(input_buf[0], input_row + m_perComponentOffsets[0], output_buf, output_row, num_rows, m_cinfo.outputWidth);
 }