BitMiracle.LibJpeg.Classic.jpeg_compress_struct.jpeg_simple_progression C# (CSharp) Method

jpeg_simple_progression() public method

Generates a default scan script for writing a progressive-JPEG file.
This is the recommended method of creating a progressive file, unless you want to make a custom scan sequence. You must ensure that the JPEG color space is set correctly before calling this routine.
public jpeg_simple_progression ( ) : void
return void
        public void jpeg_simple_progression()
        {
            /* Safety check to ensure start_compress not called yet. */
            if (m_global_state != JpegState.CSTATE_START)
                ERREXIT(J_MESSAGE_CODE.JERR_BAD_STATE, (int)m_global_state);

            /* Figure space needed for script.  Calculation must match code below! */
            int nscans;
            if (m_num_components == 3 &&
                (m_jpeg_color_space == J_COLOR_SPACE.JCS_YCbCr ||
                m_jpeg_color_space == J_COLOR_SPACE.JCS_BG_YCC))
            {
                /* Custom script for YCC color images. */
                nscans = 10;
            }
            else
            {
                /* All-purpose script for other color spaces. */
                if (m_num_components > JpegConstants.MAX_COMPS_IN_SCAN)
                {
                    /* 2 DC + 4 AC scans per component */
                    nscans = 6 * m_num_components;
                }
                else
                {
                    /* 2 DC scans; 4 AC scans per component */
                    nscans = 2 + 4 * m_num_components;
                }
            }

            /* Allocate space for script.
            * We need to put it in the permanent pool in case the application performs
            * multiple compressions without changing the settings.  To avoid a memory
            * leak if jpeg_simple_progression is called repeatedly for the same JPEG
            * object, we try to re-use previously allocated space, and we allocate
            * enough space to handle YCC even if initially asked for grayscale.
            */
            if (m_script_space == null || m_script_space_size < nscans)
            {
                m_script_space_size = Math.Max(nscans, 10);
                m_script_space = new jpeg_scan_info[m_script_space_size];
                for (int i = 0; i < m_script_space_size; i++)
                    m_script_space[i] = new jpeg_scan_info();
            }

            m_scan_info = m_script_space;
            m_num_scans = nscans;

            int scanIndex = 0;
            if (m_num_components == 3 &&
                (m_jpeg_color_space == J_COLOR_SPACE.JCS_YCbCr ||
                m_jpeg_color_space == J_COLOR_SPACE.JCS_BG_YCC))
            {
                /* Custom script for YCC color images. */
                /* Initial DC scan */
                fill_dc_scans(ref scanIndex, m_num_components, 0, 1);

                /* Initial AC scan: get some luma data out in a hurry */
                fill_a_scan(ref scanIndex, 0, 1, 5, 0, 2);

                /* Chroma data is too small to be worth expending many scans on */
                fill_a_scan(ref scanIndex, 2, 1, 63, 0, 1);
                fill_a_scan(ref scanIndex, 1, 1, 63, 0, 1);

                /* Complete spectral selection for luma AC */
                fill_a_scan(ref scanIndex, 0, 6, 63, 0, 2);

                /* Refine next bit of luma AC */
                fill_a_scan(ref scanIndex, 0, 1, 63, 2, 1);

                /* Finish DC successive approximation */
                fill_dc_scans(ref scanIndex, m_num_components, 1, 0);

                /* Finish AC successive approximation */
                fill_a_scan(ref scanIndex, 2, 1, 63, 1, 0);
                fill_a_scan(ref scanIndex, 1, 1, 63, 1, 0);

                /* Luma bottom bit comes last since it's usually largest scan */
                fill_a_scan(ref scanIndex, 0, 1, 63, 1, 0);
            }
            else
            {
                /* All-purpose script for other color spaces. */
                /* Successive approximation first pass */
                fill_dc_scans(ref scanIndex, m_num_components, 0, 1);
                fill_scans(ref scanIndex, m_num_components, 1, 5, 0, 2);
                fill_scans(ref scanIndex, m_num_components, 6, 63, 0, 2);

                /* Successive approximation second pass */
                fill_scans(ref scanIndex, m_num_components, 1, 63, 2, 1);

                /* Successive approximation final pass */
                fill_dc_scans(ref scanIndex, m_num_components, 1, 0);
                fill_scans(ref scanIndex, m_num_components, 1, 63, 1, 0);
            }
        }

Usage Example

Example #1
0
        public void TestCompressorWithContextRows()
        {
            using (MemoryStream stream = new MemoryStream())
            {
                jpeg_compress_struct compressor = new jpeg_compress_struct(new jpeg_error_mgr());
                compressor.Image_height = 100;
                compressor.Image_width = 100;
                compressor.In_color_space = J_COLOR_SPACE.JCS_GRAYSCALE;
                compressor.Input_components = 1;
                compressor.jpeg_set_defaults();

                compressor.Dct_method = J_DCT_METHOD.JDCT_IFAST;
                compressor.Smoothing_factor = 94;
                compressor.jpeg_set_quality(75, true);
                compressor.jpeg_simple_progression();

                compressor.Density_unit = DensityUnit.Unknown;
                compressor.X_density = (short)96;
                compressor.Y_density = (short)96;

                compressor.jpeg_stdio_dest(stream);
                compressor.jpeg_start_compress(true);

                byte[][] rowForDecompressor = new byte[1][];
                int bytesPerPixel = 1;
                while (compressor.Next_scanline < compressor.Image_height)
                {
                    byte[] row = new byte[100 * bytesPerPixel]; // wasteful, but gets you 0 bytes every time - content is immaterial.
                    rowForDecompressor[0] = row;
                    compressor.jpeg_write_scanlines(rowForDecompressor, 1);
                }
                compressor.jpeg_finish_compress();

                byte[] bytes = stream.ToArray();

                string filename = "TestCompressorWithContextRows.jpg";
                File.WriteAllBytes(Tester.MapOutputPath(filename), bytes);
                FileAssert.AreEqual(Tester.MapExpectedPath(filename), Tester.MapOutputPath(filename));
            }
        }
All Usage Examples Of BitMiracle.LibJpeg.Classic.jpeg_compress_struct::jpeg_simple_progression