jpeg_set_quality() public method

Constructs JPEG quantization tables appropriate for the indicated quality setting.
Note that the exact mapping from quality values to tables may change in future IJG releases as more is learned about DCT quantization.
public jpeg_set_quality ( int quality, bool force_baseline ) : void
quality int The quality value is expressed on the 0..100 scale recommended by IJG.
force_baseline bool If true, then the quantization table entries are constrained /// to the range 1..255 for full JPEG baseline compatibility. In the current implementation, /// this only makes a difference for quality settings below 25, and it effectively prevents /// very small/low quality files from being generated. The IJG decoder is capable of reading /// the non-baseline files generated at low quality settings when force_baseline is false, /// but other decoders may not be.
return void
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));
            }
        }
        private static bool applyOptions(jpeg_compress_struct compressor, CompressOptions options)
        {
            compressor.jpeg_set_quality(options.Quality, options.ForceBaseline);
            compressor.Dct_method = options.DCTMethod;

            if (options.Debug)
                compressor.Err.Trace_level = 1;

            if (options.Grayscale)
                compressor.jpeg_set_colorspace(J_COLOR_SPACE.JCS_GRAYSCALE);

            if (options.Optimize)
                compressor.Optimize_coding = true;

            compressor.Restart_interval = options.RestartInterval;
            compressor.Restart_in_rows = options.RestartInRows;

            compressor.Smoothing_factor = options.SmoothingFactor;

            int q_scale_factor = 100;
            if (options.Quality != 75)
                q_scale_factor = jpeg_compress_struct.jpeg_quality_scaling(options.Quality);

            /* Set quantization tables for selected quality. */
            /* Some or all may be overridden if -qtables is present. */
            if (options.Qtables != "") /* process -qtables if it was present */
            {
                if (!read_quant_tables(compressor, options.Qtables, q_scale_factor, options.ForceBaseline))
                    return false;
            }

            if (options.Qslots != "")  /* process -qslots if it was present */
            {
                if (!set_quant_slots(compressor, options.Qslots))
                    return false;
            }

            if (options.Sample != "")  /* process -sample if it was present */
            {
                if (!set_sample_factors(compressor, options.Sample))
                    return false;
            }

            if (options.Progressive) /* process -progressive; -scans can override */
                compressor.jpeg_simple_progression();

            return true;
        }
Example #3
0
        /// <summary>
        /// Parse optional switches.
        /// Returns true if switches were parsed successfully; false otherwise.
        /// fileIndex receives index of first file-name argument (== -1 if none).
        /// for_real is false on the first (dummy) pass; we may skip any expensive
        /// processing.
        /// </summary>
        static bool parse_switches(jpeg_compress_struct cinfo, string[] argv, bool for_real, out int fileIndex)
        {
            /* Set up default JPEG parameters. */
            /* Note that default -quality level need not, and does not,
             * match the default scaling for an explicit -qtables argument.
             */
            int quality = 75;           /* default -quality value */
            int q_scale_factor = 100;       /* default to no scaling for -qtables */
            bool force_baseline = false; /* by default, allow 16-bit quantizers */
            bool simple_progressive = false;

            string qtablefile = null;    /* saves -qtables filename if any */
            string qslotsarg = null; /* saves -qslots parm if any */
            string samplearg = null; /* saves -sample parm if any */

            outfilename = null;
            fileIndex = -1;
            cinfo.Err.Trace_level = 0;

            /* Scan command line options, adjust parameters */
            int argn = 0;
            for ( ; argn < argv.Length; argn++)
            {
                string arg = argv[argn];
                if (string.IsNullOrEmpty(arg) || arg[0] != '-')
                {
                    /* Not a switch, must be a file name argument */
                    fileIndex = argn;
                    break;
                }

                arg = arg.Substring(1);

                if (cdjpeg_utils.keymatch(arg, "baseline", 1))
                {
                    /* Force baseline-compatible output (8-bit quantizer values). */
                    force_baseline = true;
                }
                else if (cdjpeg_utils.keymatch(arg, "dct", 2))
                {
                    /* Select DCT algorithm. */
                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    if (cdjpeg_utils.keymatch(argv[argn], "int", 1))
                        cinfo.Dct_method = J_DCT_METHOD.JDCT_ISLOW;
                    else if (cdjpeg_utils.keymatch(argv[argn], "fast", 2))
                        cinfo.Dct_method = J_DCT_METHOD.JDCT_IFAST;
                    else if (cdjpeg_utils.keymatch(argv[argn], "float", 2))
                        cinfo.Dct_method = J_DCT_METHOD.JDCT_FLOAT;
                    else
                        return false;
                }
                else if (cdjpeg_utils.keymatch(arg, "debug", 1) || cdjpeg_utils.keymatch(arg, "verbose", 1))
                {
                    /* Enable debug printouts. */
                    /* On first -d, print version identification */
                    if (!printed_version)
                    {
                        Console.Write(string.Format("Bit Miracle's CJPEG, version {0}\n{1}\n", jpeg_common_struct.Version, jpeg_common_struct.Copyright));
                        printed_version = true;
                    }
                    cinfo.Err.Trace_level++;
                }
                else if (cdjpeg_utils.keymatch(arg, "grayscale", 2) || cdjpeg_utils.keymatch(arg, "greyscale", 2))
                {
                    /* Force a monochrome JPEG file to be generated. */
                    cinfo.jpeg_set_colorspace(J_COLOR_SPACE.JCS_GRAYSCALE);
                }
                else if (cdjpeg_utils.keymatch(arg, "optimize", 1) || cdjpeg_utils.keymatch(arg, "optimise", 1))
                {
                    /* Enable entropy parm optimization. */
                    cinfo.Optimize_coding = true;
                }
                else if (cdjpeg_utils.keymatch(arg, "outfile", 4))
                {
                    /* Set output file name. */
                    argn++;/* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    outfilename = argv[argn];   /* save it away for later use */
                }
                else if (cdjpeg_utils.keymatch(arg, "progressive", 1))
                {
                    /* Select simple progressive mode. */
                    simple_progressive = true;
                    /* We must postpone execution until num_components is known. */
                }
                else if (cdjpeg_utils.keymatch(arg, "quality", 1))
                {
                    /* Quality factor (quantization table scaling factor). */
                    argn++;/* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    try
                    {
                        quality = int.Parse(argv[argn]);
                        /* Change scale factor in case -qtables is present. */
                        q_scale_factor = jpeg_compress_struct.jpeg_quality_scaling(quality);
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        return false;
                    }
                }
                else if (cdjpeg_utils.keymatch(arg, "qslots", 2))
                {
                    /* Quantization table slot numbers. */
                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    qslotsarg = argv[argn];
                    /* Must delay setting qslots until after we have processed any
                     * colorspace-determining switches, since jpeg_set_colorspace sets
                     * default quant table numbers.
                     */
                }
                else if (cdjpeg_utils.keymatch(arg, "qtables", 2))
                {
                    /* Quantization tables fetched from file. */
                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    qtablefile = argv[argn];
                    /* We postpone actually reading the file in case -quality comes later. */
                }
                else if (cdjpeg_utils.keymatch(arg, "restart", 1))
                {
                    /* Restart interval in MCU rows (or in MCUs with 'b'). */
                    argn++; /* advance to next argument */

                    if (argn >= argv.Length)
                        return false;

                    bool inBlocks = false;
                    if (argv[argn].EndsWith("b") || argv[argn].EndsWith("B"))
                        inBlocks = true;

                    string parsee = argv[argn];
                    if (inBlocks)
                        parsee = parsee.Remove(parsee.Length - 1);

                    try
                    {
                        int val = int.Parse(parsee);
                        if (val < 0 || val > 65535)
                            return false;

                        if (inBlocks)
                        {
                            cinfo.Restart_interval = val;
                            cinfo.Restart_in_rows = 0; /* else prior '-restart n' overrides me */
                        }
                        else
                        {
                            cinfo.Restart_in_rows = val;
                            /* restart_interval will be computed during startup */
                        }
                    }
                    catch (Exception e)
                    {
                    	Console.WriteLine(e.Message);
                        return false;
                    }
                }
                else if (cdjpeg_utils.keymatch(arg, "sample", 2))
                {
                    /* Set sampling factors. */
                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    samplearg = argv[argn];
                    /* Must delay setting sample factors until after we have processed any
                     * colorspace-determining switches, since jpeg_set_colorspace sets
                     * default sampling factors.
                     */
                }
                else if (cdjpeg_utils.keymatch(arg, "smooth", 2))
                {
                    /* Set input smoothing factor. */

                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                        return false;

                    try
                    {
                        int val = int.Parse(argv[argn]);
                        if (val < 0 || val > 100)
                            return false;

                        cinfo.Smoothing_factor = val;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        return false;
                    }
                }
                else
                {
                    /* bogus switch */
                    return false;
                }
            }

            /* Post-switch-scanning cleanup */

            if (for_real)
            {
                /* Set quantization tables for selected quality. */
                /* Some or all may be overridden if -qtables is present. */
                cinfo.jpeg_set_quality(quality, force_baseline);

                if (qtablefile != null) /* process -qtables if it was present */
                {
                    if (!read_quant_tables(cinfo, qtablefile, q_scale_factor, force_baseline))
                        return false;
                }

                if (qslotsarg != null)  /* process -qslots if it was present */
                {
                    if (!set_quant_slots(cinfo, qslotsarg))
                        return false;
                }

                if (samplearg != null)  /* process -sample if it was present */
                {
                    if (!set_sample_factors(cinfo, samplearg))
                        return false;
                }

                if (simple_progressive) /* process -progressive; -scans can override */
                    cinfo.jpeg_simple_progression();
            }

            return true;
        }