BitMiracle.LibJpeg.Classic.Internal.my_2pass_cquantizer.pass2_fs_dither C# (CSharp) Метод

pass2_fs_dither() приватный Метод

Map some rows of pixels to the output colormapped representation. This version performs Floyd-Steinberg dithering
private pass2_fs_dither ( byte input_buf, int in_row, byte output_buf, int out_row, int num_rows ) : void
input_buf byte
in_row int
output_buf byte
out_row int
num_rows int
Результат void
        private void pass2_fs_dither(byte[][] input_buf, int in_row, byte[][] output_buf, int out_row, int num_rows)
        {
            byte[] limit = m_cinfo.m_sample_range_limit;
            int limitOffset = m_cinfo.m_sampleRangeLimitOffset;

            for (int row = 0; row < num_rows; row++)
            {
                int inputPixelIndex = 0;
                int outputPixelIndex = 0;
                int errorIndex = 0;
                int dir;            /* +1 or -1 depending on direction */
                int dir3;           /* 3*dir, for advancing inputIndex & errorIndex */
                if (m_on_odd_row)
                {
                    /* work right to left in this row */
                    inputPixelIndex += (m_cinfo.m_output_width - 1) * 3;   /* so point to rightmost pixel */
                    outputPixelIndex += m_cinfo.m_output_width - 1;
                    dir = -1;
                    dir3 = -3;
                    errorIndex = (m_cinfo.m_output_width + 1) * 3; /* => entry after last column */
                    m_on_odd_row = false; /* flip for next time */
                }
                else
                {
                    /* work left to right in this row */
                    dir = 1;
                    dir3 = 3;
                    errorIndex = 0; /* => entry before first real column */
                    m_on_odd_row = true; /* flip for next time */
                }

                /* Preset error values: no error propagated to first pixel from left */
                /* current error or pixel value */
                int cur0 = 0;
                int cur1 = 0;
                int cur2 = 0;
                /* and no error propagated to row below yet */
                /* error for pixel below cur */
                int belowerr0 = 0;
                int belowerr1 = 0;
                int belowerr2 = 0;
                /* error for below/prev col */
                int bpreverr0 = 0;
                int bpreverr1 = 0;
                int bpreverr2 = 0;

                for (int col = m_cinfo.m_output_width; col > 0; col--)
                {
                    /* curN 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.
                     */
                    cur0 = JpegUtils.RIGHT_SHIFT(cur0 + m_fserrors[errorIndex + dir3] + 8, 4);
                    cur1 = JpegUtils.RIGHT_SHIFT(cur1 + m_fserrors[errorIndex + dir3 + 1] + 8, 4);
                    cur2 = JpegUtils.RIGHT_SHIFT(cur2 + m_fserrors[errorIndex + dir3 + 2] + 8, 4);

                    /* Limit the error using transfer function set by init_error_limit.
                     * See comments with init_error_limit for rationale.
                     */
                    cur0 = m_error_limiter[JpegConstants.MAXJSAMPLE + cur0];
                    cur1 = m_error_limiter[JpegConstants.MAXJSAMPLE + cur1];
                    cur2 = m_error_limiter[JpegConstants.MAXJSAMPLE + cur2];
                    
                    /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
                     * The maximum error is +- MAXJSAMPLE (or less with error limiting);
                     * this sets the required size of the range_limit array.
                     */
                    cur0 += input_buf[in_row + row][inputPixelIndex];
                    cur1 += input_buf[in_row + row][inputPixelIndex + 1];
                    cur2 += input_buf[in_row + row][inputPixelIndex + 2];
                    cur0 = limit[limitOffset + cur0];
                    cur1 = limit[limitOffset + cur1];
                    cur2 = limit[limitOffset + cur2];

                    /* Index into the cache with adjusted pixel value */
                    int hRow = cur0 >> C0_SHIFT;
                    int hColumn = (cur1 >> C1_SHIFT) * HIST_C2_ELEMS + (cur2 >> C2_SHIFT);

                    /* If we have not seen this color before, find nearest colormap */
                    /* entry and update the cache */
                    if (m_histogram[hRow][hColumn] == 0)
                        fill_inverse_cmap(cur0 >> C0_SHIFT, cur1 >> C1_SHIFT, cur2 >> C2_SHIFT);

                    /* Now emit the colormap index for this cell */
                    int pixcode = m_histogram[hRow][hColumn] - 1;
                    output_buf[out_row + row][outputPixelIndex] = (byte) pixcode;

                    /* Compute representation error for this pixel */
                    cur0 -= m_cinfo.m_colormap[0][pixcode];
                    cur1 -= m_cinfo.m_colormap[1][pixcode];
                    cur2 -= m_cinfo.m_colormap[2][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 = cur0;    /* Process component 0 */
                    int delta = cur0 * 2;
                    cur0 += delta;      /* form error * 3 */
                    m_fserrors[errorIndex] = (short) (bpreverr0 + cur0);
                    cur0 += delta;      /* form error * 5 */
                    bpreverr0 = belowerr0 + cur0;
                    belowerr0 = bnexterr;
                    cur0 += delta;      /* form error * 7 */
                    bnexterr = cur1;    /* Process component 1 */
                    delta = cur1 * 2;
                    cur1 += delta;      /* form error * 3 */
                    m_fserrors[errorIndex + 1] = (short) (bpreverr1 + cur1);
                    cur1 += delta;      /* form error * 5 */
                    bpreverr1 = belowerr1 + cur1;
                    belowerr1 = bnexterr;
                    cur1 += delta;      /* form error * 7 */
                    bnexterr = cur2;    /* Process component 2 */
                    delta = cur2 * 2;
                    cur2 += delta;      /* form error * 3 */
                    m_fserrors[errorIndex + 2] = (short) (bpreverr2 + cur2);
                    cur2 += delta;      /* form error * 5 */
                    bpreverr2 = belowerr2 + cur2;
                    belowerr2 = bnexterr;
                    cur2 += delta;      /* form error * 7 */

                    /* At this point curN 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.
                     */
                    inputPixelIndex += dir3;      /* Advance pixel pointers to next column */
                    outputPixelIndex += dir;
                    errorIndex += dir3;       /* advance errorIndex to current column */
                }

                /* Post-loop cleanup: we must unload the final error values into the
                 * final fserrors[] entry.  Note we need not unload belowerrN because
                 * it is for the dummy column before or after the actual array.
                 */
                m_fserrors[errorIndex] = (short) bpreverr0; /* unload prev errs into array */
                m_fserrors[errorIndex + 1] = (short) bpreverr1;
                m_fserrors[errorIndex + 2] = (short) bpreverr2;
            }
        }