BitMiracle.LibTiff.Classic.Internal.JpegCodec.JPEGDecodeRaw C# (CSharp) Method

JPEGDecodeRaw() private method

Decode a chunk of pixels. Returned data is downsampled per sampling factors.
private JPEGDecodeRaw ( byte buffer, int offset, int count, short plane ) : bool
buffer byte
offset int
count int
plane short
return bool
        private bool JPEGDecodeRaw(byte[] buffer, int offset, int count, short plane)
        {
            // data is expected to be read in multiples of a scanline
            int nrows = m_decompression.Image_height;
            if (nrows != 0)
            {
                // Cb,Cr both have sampling factors 1, so this is correct
                int clumps_per_line = m_decompression.Comp_info[1].Downsampled_width;

                do
                {
                    // Reload downsampled-data buffer if needed
                    if (m_scancount >= JpegConstants.DCTSIZE)
                    {
                        int n = m_decompression.Max_v_samp_factor * JpegConstants.DCTSIZE;
                        if (TIFFjpeg_read_raw_data(m_ds_buffer, n) != n)
                            return false;

                        m_scancount = 0;
                    }

                    // Fastest way to unseparate data is to make one pass over the scanline for
                    // each row of each component.
                    int clumpoffset = 0; // first sample in clump
                    for (int ci = 0; ci < m_decompression.Num_components; ci++)
                    {
                        int hsamp = m_decompression.Comp_info[ci].H_samp_factor;
                        int vsamp = m_decompression.Comp_info[ci].V_samp_factor;

                        for (int ypos = 0; ypos < vsamp; ypos++)
                        {
                            byte[] inBuf = m_ds_buffer[ci][m_scancount * vsamp + ypos];
                            int inptr = 0;

                            int outptr = offset + clumpoffset;
                            if (outptr >= buffer.Length)
                                break;

                            if (hsamp == 1)
                            {
                                // fast path for at least Cb and Cr
                                for (int nclump = clumps_per_line; nclump-- > 0; )
                                {
                                    buffer[outptr] = inBuf[inptr];
                                    inptr++;
                                    outptr += m_samplesperclump;
                                }
                            }
                            else
                            {
                                // general case
                                for (int nclump = clumps_per_line; nclump-- > 0; )
                                {
                                    for (int xpos = 0; xpos < hsamp; xpos++)
                                    {
                                        buffer[outptr + xpos] = inBuf[inptr];
                                        inptr++;
                                    }

                                    outptr += m_samplesperclump;
                                }
                            }

                            clumpoffset += hsamp;
                        }
                    }

                    ++m_scancount;
                    m_tif.m_row += m_v_sampling;

                    // increment/decrement of buffer and count is still incorrect, but should not matter
                    // TODO: resolve this
                    offset += m_bytesperline;
                    count -= m_bytesperline;
                    nrows -= m_v_sampling;
                }
                while (nrows > 0);
            }

            // Close down the decompressor if done.
            return m_decompression.Output_scanline < m_decompression.Output_height || TIFFjpeg_finish_decompress();
        }