コード例 #1
0
        // Convert a stream into a destination manager.
        public static void StreamToDestinationManager
            (ref jpeg_compress_struct cinfo, Stream stream)
        {
            // Allocate a state structure and store it in "cinfo".
            IntPtr      buf   = Marshal.AllocHGlobal(4096);
            StreamState state = new StreamState();

            state.buf         = buf;
            state.buffer      = new byte [4096];
            state.stream      = stream;
            cinfo.client_data = (IntPtr)(GCHandle.Alloc(state));

            // Create the managed version of "jpeg_destination_mgr".
            jpeg_destination_mgr mgr = new jpeg_destination_mgr();

            mgr.next_output_byte = buf;
            mgr.free_in_buffer   = (size_t)4096;
            mgr.init_destination =
                new init_destination_type(init_destination);
            mgr.empty_output_buffer =
                new empty_output_buffer_type(empty_output_buffer);
            mgr.term_destination =
                new term_destination_type(term_destination);

            // Convert it into the unmanaged version and store it.
#if __CSCC__
            IntPtr umgr = Marshal.AllocHGlobal
                              (sizeof(jpeg_destination_mgr));
            Marshal.StructureToPtr(mgr, umgr, false);
            cinfo.dest = (jpeg_destination_mgr *)umgr;
#endif
        }
コード例 #2
0
        /* Process a quality-ratings parameter string, of the form
         *     N[,N,...]
         * If there are more q-table slots than parameters, the last value is replicated.
         */
        static bool set_quality_ratings(jpeg_compress_struct cinfo, string arg, bool force_baseline)
        {
            int val = 75;           /* default value */

            string[] factors = arg.Split(new char[','], StringSplitOptions.RemoveEmptyEntries);

            for (int tblno = 0; tblno < JpegConstants.NUM_QUANT_TBLS; tblno++)
            {
                if (factors.Length > tblno)
                {
                    bool parsed = int.TryParse(factors[tblno], out val);
                    if (!parsed)
                    {
                        return(false);
                    }

                    /* Convert user 0-100 rating to percentage scaling */
                    cinfo.q_scale_factor[tblno] = jpeg_compress_struct.jpeg_quality_scaling(val);
                }
                else
                {
                    /* reached end of parameter, set remaining factors to last value */
                    cinfo.q_scale_factor[tblno] = jpeg_compress_struct.jpeg_quality_scaling(val);
                }
            }

            cinfo.jpeg_default_qtables(force_baseline);
            return(true);
        }
コード例 #3
0
ファイル: JpegHelper.cs プロジェクト: aleph0mc/StegImageUI
        /// <summary>
        /// Get the Huffman tables using reflection for a specific component (AC, DC)
        /// </summary>
        /// <returns></returns>
        public static HuffmanTable[] GetHuffmanTables(string JpegFilePath)
        {
            FileStream             objFileStreamMegaMap = File.Create(JpegFilePath);
            jpeg_decompress_struct jpds = new jpeg_decompress_struct();
            jpeg_compress_struct   jpcs = new jpeg_compress_struct();

            jpcs.jpeg_stdio_dest(objFileStreamMegaMap);
            jpds.jpeg_copy_critical_parameters(jpcs);
            jpds.jpeg_finish_decompress();
            objFileStreamMegaMap.Close();

            // DC Huffman tables
            JHUFF_TBL[] jpeg_dc_huffman_tables = jpcs.Dc_huff_tbl_ptrs;
            var         comp = HuffmanTable.EnumComponent.DC;
            var         htdc = getHTables(jpeg_dc_huffman_tables, comp);

            // AC Huffman tables
            JHUFF_TBL[] jpeg_ac_huffman_tables = jpcs.Ac_huff_tbl_ptrs;
            comp = HuffmanTable.EnumComponent.AC;
            var htac = getHTables(jpeg_ac_huffman_tables, comp);

            HuffmanTable[] hts = new HuffmanTable[htdc.Length + htac.Length];
            Array.Copy(htdc, hts, htdc.Length);
            Array.Copy(htac, 0, hts, htdc.Length, htac.Length);

            return(hts);
        }
コード例 #4
0
        private void Enc(string inputPath, string outputPath, byte[] data)
        {
            var input = new jpeg_decompress_struct();

            using (var fileStream = new FileStream(inputPath, FileMode.Open))
            {
                input.jpeg_stdio_src(fileStream);
                input.jpeg_read_header(false);
                var coefficients = input.jpeg_read_coefficients();

                var channels = coefficients.Take(3).Select(JpegHelper.GetBuffer).ToArray();
                Encrypt(channels, data);

                var output = new jpeg_compress_struct();
                using (var outfile = new FileStream(outputPath, FileMode.Create))
                {
                    output.jpeg_stdio_dest(outfile);

                    input.jpeg_copy_critical_parameters(output);

                    output.jpeg_write_coefficients(coefficients);
                    output.jpeg_finish_compress();
                }
            }
        }
コード例 #5
0
        private int m_next_buf_stop;      /* downsample when we reach this index */

        public jpeg_c_prep_controller(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Allocate the color conversion buffer.
            * We make the buffer wide enough to allow the downsampler to edge-expand
            * horizontally within the buffer, if it so chooses.
            */
            if (cinfo.m_downsample.NeedContextRows())
            {
                /* Set up to provide context rows */
                create_context_buffer();
            }
            else
            {
                /* No context, just make it tall enough for one row group */
                for (int ci = 0; ci < cinfo.m_num_components; ci++)
                {
                    m_colorBufRowsOffset = 0;
                    m_color_buf[ci] = jpeg_compress_struct.AllocJpegSamples(
                        (cinfo.Component_info[ci].Width_in_blocks * JpegConstants.DCTSIZE * cinfo.m_max_h_samp_factor) / cinfo.Component_info[ci].H_samp_factor,
                        cinfo.m_max_v_samp_factor);
                }
            }
        }
コード例 #6
0
ファイル: jpeg_comp_master.cs プロジェクト: saik0/libtiff.net
        private int m_scan_number;        /* current index in scan_info[] */

        public jpeg_comp_master(jpeg_compress_struct cinfo, bool transcode_only)
        {
            m_cinfo = cinfo;

            if (transcode_only)
            {
                /* no main pass in transcoding */
                if (cinfo.m_optimize_coding)
                {
                    m_pass_type = c_pass_type.huff_opt_pass;
                }
                else
                {
                    m_pass_type = c_pass_type.output_pass;
                }
            }
            else
            {
                /* for normal compression, first pass is always this type: */
                m_pass_type = c_pass_type.main_pass;
            }

            if (cinfo.m_optimize_coding)
            {
                m_total_passes = cinfo.m_num_scans * 2;
            }
            else
            {
                m_total_passes = cinfo.m_num_scans;
            }
        }
コード例 #7
0
        public my_c_coef_controller(jpeg_compress_struct cinfo, bool need_full_buffer)
        {
            m_cinfo = cinfo;

            /* Create the coefficient buffer. */
            if (need_full_buffer)
            {
                /* Allocate a full-image virtual array for each component, */
                /* padded to a multiple of samp_factor DCT blocks in each direction. */
                for (int ci = 0; ci < cinfo.m_num_components; ci++)
                {
                    m_whole_image[ci] = jpeg_common_struct.CreateBlocksArray(
                        JpegUtils.jround_up(cinfo.Component_info[ci].Width_in_blocks, cinfo.Component_info[ci].H_samp_factor),
                        JpegUtils.jround_up(cinfo.Component_info[ci].height_in_blocks, cinfo.Component_info[ci].V_samp_factor));
                    m_whole_image[ci].ErrorProcessor = cinfo;
                }
            }
            else
            {
                /* We only need a single-MCU buffer. */
                JBLOCK[] buffer = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU];
                for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
                    buffer[i] = new JBLOCK();

                for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
                {
                    m_MCU_buffer[i] = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU - i];
                    for (int j = i; j < JpegConstants.C_MAX_BLOCKS_IN_MCU; j++)
                        m_MCU_buffer[i][j - i] = buffer[j];
                }

                /* flag for no virtual arrays */
                m_whole_image[0] = null;
            }
        }
コード例 #8
0
        public jpeg_forward_dct(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            switch (cinfo.m_dct_method)
            {
            case J_DCT_METHOD.JDCT_ISLOW:
                m_useFloatMethod = false;
                m_useSlowMethod  = true;
                break;

            case J_DCT_METHOD.JDCT_IFAST:
                m_useFloatMethod = false;
                m_useSlowMethod  = false;
                break;

            case J_DCT_METHOD.JDCT_FLOAT:
                m_useFloatMethod = true;
                break;

            default:
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NOT_COMPILED);
                break;
            }

            /* Mark divisor tables unallocated */
            for (int i = 0; i < JpegConstants.NUM_QUANT_TBLS; i++)
            {
                m_divisors[i]       = null;
                m_float_divisors[i] = null;
            }
        }
コード例 #9
0
ファイル: JpegHelper.cs プロジェクト: aleph0mc/StegImageUI
        /// <summary>
        /// Get the Quantization tables using reflection per component
        /// </summary>
        /// <returns></returns>
        public static short[][] GetQuantizationTables(string JpegFilePath)
        {
            FileStream             objFileStreamMegaMap = File.Create(JpegFilePath);
            jpeg_decompress_struct jpds = new jpeg_decompress_struct();
            jpeg_compress_struct   jpcs = new jpeg_compress_struct();

            jpcs.jpeg_stdio_dest(objFileStreamMegaMap);
            jpds.jpeg_copy_critical_parameters(jpcs);
            jpds.jpeg_finish_decompress();
            objFileStreamMegaMap.Close();
            JQUANT_TBL[] jpeg_quant_tables = jpcs.Quant_tbl_ptrs;
            int          qCount            = jpeg_quant_tables.Length;

            short[][]    qt        = new short[qCount][];
            BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static;
            int          idx       = 0;

            while (null != jpeg_quant_tables[idx])
            {
                Type      type     = jpeg_quant_tables[idx].GetType();
                object    instance = jpeg_quant_tables[idx];
                FieldInfo field    = type.GetField("quantval", bindFlags);
                qt[idx] = field.GetValue(instance) as short[];
                ++idx;
            }
            var qTables = qt.Where(tab => null != tab).ToArray();

            return(qTables);
        }
コード例 #10
0
        private int m_next_buf_stop;  /* downsample when we reach this index */

        public jpeg_c_prep_controller(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Allocate the color conversion buffer.
             * We make the buffer wide enough to allow the downsampler to edge-expand
             * horizontally within the buffer, if it so chooses.
             */
            if (cinfo.m_downsample.NeedContextRows())
            {
                /* Set up to provide context rows */
                create_context_buffer();
            }
            else
            {
                /* No context, just make it tall enough for one row group */
                for (int ci = 0; ci < cinfo.m_num_components; ci++)
                {
                    m_colorBufRowsOffset = 0;
                    m_color_buf[ci]      = jpeg_compress_struct.AllocJpegSamples(
                        (cinfo.Component_info[ci].Width_in_blocks * JpegConstants.DCTSIZE * cinfo.m_max_h_samp_factor) / cinfo.Component_info[ci].H_samp_factor,
                        cinfo.m_max_v_samp_factor);
                }
            }
        }
コード例 #11
0
        private bool m_need_context_rows; /* true if need rows above & below */

        public jpeg_downsampler(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;
            m_need_context_rows = false;

            if (cinfo.m_CCIR601_sampling)
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CCIR601_NOTIMPL);

            /* Verify we can handle the sampling factors, and set up method pointers */
            bool smoothok = true;
            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                jpeg_component_info componentInfo = cinfo.Component_info[ci];

                if (componentInfo.H_samp_factor == cinfo.m_max_h_samp_factor &&
                    componentInfo.V_samp_factor == cinfo.m_max_v_samp_factor)
                {
                    if (cinfo.m_smoothing_factor != 0)
                    {
                        m_downSamplers[ci] = downSampleMethod.fullsize_smooth_downsampler;
                        m_need_context_rows = true;
                    }
                    else
                    {
                        m_downSamplers[ci] = downSampleMethod.fullsize_downsampler;
                    }
                }
                else if (componentInfo.H_samp_factor * 2 == cinfo.m_max_h_samp_factor &&
                         componentInfo.V_samp_factor == cinfo.m_max_v_samp_factor)
                {
                    smoothok = false;
                    m_downSamplers[ci] = downSampleMethod.h2v1_downsampler;
                }
                else if (componentInfo.H_samp_factor * 2 == cinfo.m_max_h_samp_factor &&
                         componentInfo.V_samp_factor * 2 == cinfo.m_max_v_samp_factor)
                {
                    if (cinfo.m_smoothing_factor != 0)
                    {
                        m_downSamplers[ci] = downSampleMethod.h2v2_smooth_downsampler;
                        m_need_context_rows = true;
                    }
                    else
                    {
                        m_downSamplers[ci] = downSampleMethod.h2v2_downsampler;
                    }
                }
                else if ((cinfo.m_max_h_samp_factor % componentInfo.H_samp_factor) == 0 &&
                         (cinfo.m_max_v_samp_factor % componentInfo.V_samp_factor) == 0)
                {
                    smoothok = false;
                    m_downSamplers[ci] = downSampleMethod.int_downsampler;
                }
                else
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_FRACT_SAMPLE_NOTIMPL);
            }

            if (cinfo.m_smoothing_factor != 0 && !smoothok)
                cinfo.TRACEMS(0, J_MESSAGE_CODE.JTRC_SMOOTH_NOTIMPL);
        }
コード例 #12
0
        private static void compress(Stream input, CompressOptions options, Stream output)
        {
            Debug.Assert(input != null);
            Debug.Assert(options != null);
            Debug.Assert(output != null);

            jpeg_compress_struct cinfo = new jpeg_compress_struct(new cd_jpeg_error_mgr());

            /* Initialize JPEG parameters.
             * Much of this may be overridden later.
             * In particular, we don't yet know the input file's color space,
             * but we need to provide some value for jpeg_set_defaults() to work.
             */
            cinfo.In_color_space = J_COLOR_SPACE.JCS_RGB; /* arbitrary guess */
            cinfo.jpeg_set_defaults();

            /* Figure out the input file format, and set up to read it. */
            cjpeg_source_struct src_mgr = new bmp_source_struct(cinfo);

            src_mgr.input_file = input;

            /* Read the input file header to obtain file size & colorspace. */
            src_mgr.start_input();

            /* Now that we know input colorspace, fix colorspace-dependent defaults */
            cinfo.jpeg_default_colorspace();

            /* Adjust default compression parameters */
            if (!applyOptions(cinfo, options))
            {
                return;
            }

            /* Specify data destination for compression */
            cinfo.jpeg_stdio_dest(output);

            /* Start compressor */
            cinfo.jpeg_start_compress(true);

            /* Process data */
            while (cinfo.Next_scanline < cinfo.Image_height)
            {
                int num_scanlines = src_mgr.get_pixel_rows();
                cinfo.jpeg_write_scanlines(src_mgr.buffer, num_scanlines);
            }

            /* Finish compression and release memory */
            src_mgr.finish_input();
            cinfo.jpeg_finish_compress();

            /* All done. */
            if (cinfo.Err.Num_warnings != 0)
            {
                Console.WriteLine("Corrupt-data warning count is not zero");
            }
        }
コード例 #13
0
        private int m_restarts_to_go; /* MCUs left in this restart interval */

        #endregion Fields

        #region Constructors

        public phuff_entropy_encoder(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Mark tables unallocated */
            for (int i = 0; i < JpegConstants.NUM_HUFF_TBLS; i++)
            {
                m_derived_tbls[i] = null;
                m_count_ptrs[i] = null;
            }
        }
コード例 #14
0
        public phuff_entropy_encoder(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Mark tables unallocated */
            for (int i = 0; i < JpegConstants.NUM_HUFF_TBLS; i++)
            {
                m_derived_tbls[i] = null;
                m_count_ptrs[i]   = null;
            }
        }
コード例 #15
0
        // Free a destination manager.
        public static void FreeDestinationManager(ref jpeg_compress_struct cinfo)
        {
            GCHandle    handle = (GCHandle)(cinfo.client_data);
            StreamState state  = (StreamState)(handle.Target);

            Marshal.FreeHGlobal(state.buf);
            handle.Free();
            Marshal.FreeHGlobal((IntPtr)(cinfo.dest));
            cinfo.client_data = IntPtr.Zero;
            cinfo.dest        = null;
        }
コード例 #16
0
        public jpeg_c_main_controller(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Allocate a strip buffer for each component */
            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                m_buffer[ci] = jpeg_common_struct.AllocJpegSamples(
                    cinfo.Component_info[ci].Width_in_blocks * JpegConstants.DCTSIZE,
                    cinfo.Component_info[ci].V_samp_factor * JpegConstants.DCTSIZE);
            }
        }
コード例 #17
0
        // Empty an output buffer to a stream.
        private static Int empty_output_buffer(ref jpeg_compress_struct cinfo)
        {
            int         len;
            StreamState state = GetStreamState(ref cinfo);

            len = state.buffer.Length;
            Marshal.Copy(state.buf, state.buffer, 0, len);
            state.stream.Write(state.buffer, 0, len);
            cinfo.dest->next_output_byte = state.buf;
            cinfo.dest->free_in_buffer   = (size_t)len;
            return((Int)1);
        }
コード例 #18
0
        public jpeg_c_main_controller(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Allocate a strip buffer for each component */
            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                m_buffer[ci] = jpeg_common_struct.AllocJpegSamples(
                    cinfo.Component_info[ci].Width_in_blocks * JpegConstants.DCTSIZE,
                    cinfo.Component_info[ci].V_samp_factor * JpegConstants.DCTSIZE);
            }
        }
コード例 #19
0
        public jpeg_c_main_controller(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Allocate a strip buffer for each component */
            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                jpeg_component_info compptr = cinfo.Component_info[ci];
                m_buffer[ci] = jpeg_common_struct.AllocJpegSamples(
                    compptr.Width_in_blocks * compptr.DCT_h_scaled_size,
                    compptr.V_samp_factor * compptr.DCT_v_scaled_size);
            }
        }
コード例 #20
0
        public jpeg_c_main_controller(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* Allocate a strip buffer for each component */
            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                jpeg_component_info compptr = cinfo.Component_info[ci];
                m_buffer[ci] = jpeg_common_struct.AllocJpegSamples(
                    compptr.Width_in_blocks * compptr.DCT_h_scaled_size,
                    compptr.V_samp_factor * compptr.DCT_v_scaled_size);
            }
        }
コード例 #21
0
ファイル: JpegHelper.cs プロジェクト: aleph0mc/StegImageUI
        public static void ApplyQuantizationTable(string JpegFilePath, EnumStegoChannel Component = EnumStegoChannel.Y, int ScaleFactor = 50, int[] QuantizationTable = null)
        {
            var        jpds          = new jpeg_decompress_struct();
            FileStream fileStreamImg = new FileStream(JpegFilePath, FileMode.Open, FileAccess.Read);

            jpds.jpeg_stdio_src(fileStreamImg);
            jpds.jpeg_read_header(true);
            // DCT coefficients
            var jBlock = jpds.jpeg_read_coefficients();

            jpds.jpeg_finish_decompress();
            fileStreamImg.Close();

            if (null == QuantizationTable)
            {
                switch (Component)
                {
                case EnumStegoChannel.Y:
                    QuantizationTable = _qLuminance;
                    break;

                case EnumStegoChannel.Cb:
                case EnumStegoChannel.Cr:
                    QuantizationTable = _qChromiance;
                    break;
                }
            }

            // Get fle info
            FileInfo fInfo            = new FileInfo(JpegFilePath);
            string   dir              = fInfo.DirectoryName;
            string   fNane            = fInfo.Name;
            string   stegFName        = $"steg_{DateTime.Now.ToString("yyyyMMddHHmm")}_{fNane}";
            string   stegJpegFilePath = Path.Combine(dir, stegFName);
            // Compress process
            FileStream           fileStream = File.Create(stegJpegFilePath);
            jpeg_compress_struct jpcs       = new jpeg_compress_struct();

            jpcs.jpeg_stdio_dest(fileStream);
            jpds.jpeg_copy_critical_parameters(jpcs);
            jpcs.jpeg_write_coefficients(jBlock);
            jpcs.jpeg_finish_compress();
            fileStream.Close();
            jpds.jpeg_abort_decompress();
        }
コード例 #22
0
        /// <summary>
        /// Initialize coefficient buffer controller.
        /// 
        /// Each passed coefficient array must be the right size for that
        /// coefficient: width_in_blocks wide and height_in_blocks high,
        /// with unit height at least v_samp_factor.
        /// </summary>
        public my_trans_c_coef_controller(jpeg_compress_struct cinfo, jvirt_array<JBLOCK>[] coef_arrays)
        {
            m_cinfo = cinfo;

            /* Save pointer to virtual arrays */
            m_whole_image = coef_arrays;

            /* Allocate and pre-zero space for dummy DCT blocks. */
            JBLOCK[] buffer = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU];
            for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
                buffer[i] = new JBLOCK();

            for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
            {
                m_dummy_buffer[i] = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU - i];
                for (int j = i; j < JpegConstants.C_MAX_BLOCKS_IN_MCU; j++)
                    m_dummy_buffer[i][j - i] = buffer[j];
            }
        }
コード例 #23
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));
            }
        }
コード例 #24
0
        public my_c_coef_controller(jpeg_compress_struct cinfo, bool need_full_buffer)
        {
            m_cinfo = cinfo;

            /* Create the coefficient buffer. */
            if (need_full_buffer)
            {
                /* Allocate a full-image virtual array for each component, */
                /* padded to a multiple of samp_factor DCT blocks in each direction. */
                for (int ci = 0; ci < cinfo.m_num_components; ci++)
                {
                    m_whole_image[ci] = jpeg_common_struct.CreateBlocksArray(
                        JpegUtils.jround_up(cinfo.Component_info[ci].Width_in_blocks, cinfo.Component_info[ci].H_samp_factor),
                        JpegUtils.jround_up(cinfo.Component_info[ci].height_in_blocks, cinfo.Component_info[ci].V_samp_factor));
                    m_whole_image[ci].ErrorProcessor = cinfo;
                }
            }
            else
            {
                /* We only need a single-MCU buffer. */
                JBLOCK[] buffer = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU];
                for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
                {
                    buffer[i] = new JBLOCK();
                }

                for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
                {
                    m_MCU_buffer[i] = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU - i];
                    for (int j = i; j < JpegConstants.C_MAX_BLOCKS_IN_MCU; j++)
                    {
                        m_MCU_buffer[i][j - i] = buffer[j];
                    }
                }

                /* flag for no virtual arrays */
                m_whole_image[0] = null;
            }
        }
コード例 #25
0
        /// <summary>
        /// Initialize coefficient buffer controller.
        ///
        /// Each passed coefficient array must be the right size for that
        /// coefficient: width_in_blocks wide and height_in_blocks high,
        /// with unit height at least v_samp_factor.
        /// </summary>
        public my_trans_c_coef_controller(jpeg_compress_struct cinfo, jvirt_array <JBLOCK>[] coef_arrays)
        {
            m_cinfo = cinfo;

            /* Save pointer to virtual arrays */
            m_whole_image = coef_arrays;

            /* Allocate and pre-zero space for dummy DCT blocks. */
            JBLOCK[] buffer = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU];
            for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
            {
                buffer[i] = new JBLOCK();
            }

            for (int i = 0; i < JpegConstants.C_MAX_BLOCKS_IN_MCU; i++)
            {
                m_dummy_buffer[i] = new JBLOCK[JpegConstants.C_MAX_BLOCKS_IN_MCU - i];
                for (int j = i; j < JpegConstants.C_MAX_BLOCKS_IN_MCU; j++)
                {
                    m_dummy_buffer[i][j - i] = buffer[j];
                }
            }
        }
コード例 #26
0
        private int m_scan_number;        /* current index in scan_info[] */

        public jpeg_comp_master(jpeg_compress_struct cinfo, bool transcode_only)
        {
            m_cinfo = cinfo;

            if (transcode_only)
            {
                /* no main pass in transcoding */
                if (cinfo.m_optimize_coding)
                    m_pass_type = c_pass_type.huff_opt_pass;
                else
                    m_pass_type = c_pass_type.output_pass;
            }
            else
            {
                /* for normal compression, first pass is always this type: */
                m_pass_type = c_pass_type.main_pass;
            }

            if (cinfo.m_optimize_coding)
                m_total_passes = cinfo.m_num_scans * 2;
            else
                m_total_passes = cinfo.m_num_scans;
        }
コード例 #27
0
        public static byte[] CompressJPEG(byte[] uncompressedFileData, int vWidth, int vHeight)
        {
            using (MemoryStream stream = new MemoryStream()) {
                jpeg_compress_struct compressor = new jpeg_compress_struct(new jpeg_error_mgr());
                compressor.Image_height     = vHeight;
                compressor.Image_width      = vWidth;
                compressor.In_color_space   = J_COLOR_SPACE.JCS_RGB;
                compressor.Input_components = 3;
                compressor.jpeg_set_defaults();

                compressor.Dct_method       = J_DCT_METHOD.JDCT_IFAST;
                compressor.Smoothing_factor = 0;
                compressor.jpeg_set_quality(80, true);
                compressor.jpeg_simple_progression();

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

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

                byte[][] rowForDecompressor = new byte[1][];
                int      bytesPerPixel      = 3;
                byte[]   row = new byte[vWidth * bytesPerPixel]; // wasteful, but gets you 0 bytes every time - content is immaterial.
                while (compressor.Next_scanline < compressor.Image_height)
                {
                    Buffer.BlockCopy(uncompressedFileData, compressor.Next_scanline * vWidth * bytesPerPixel, row, 0, vWidth * bytesPerPixel);

                    rowForDecompressor[0] = row;
                    compressor.jpeg_write_scanlines(rowForDecompressor, 1);
                }
                compressor.jpeg_finish_compress();

                return(stream.ToArray());
            }
        }
コード例 #28
0
        private byte[] m_buffer;     /* start of buffer */

        public my_destination_mgr(jpeg_compress_struct cinfo, Stream alreadyOpenFile)
        {
            m_cinfo = cinfo;
            m_outfile = alreadyOpenFile;
        }
コード例 #29
0
ファイル: jpeg_downsampler.cs プロジェクト: room-end/catalog
        private bool m_need_context_rows; /* true if need rows above & below */

        public jpeg_downsampler(jpeg_compress_struct cinfo)
        {
            m_cinfo             = cinfo;
            m_need_context_rows = false;

            if (cinfo.m_CCIR601_sampling)
            {
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CCIR601_NOTIMPL);
            }

            /* Verify we can handle the sampling factors, and set up method pointers */
            bool smoothok = true;

            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                jpeg_component_info componentInfo = cinfo.Component_info[ci];

                if (componentInfo.H_samp_factor == cinfo.m_max_h_samp_factor &&
                    componentInfo.V_samp_factor == cinfo.m_max_v_samp_factor)
                {
                    if (cinfo.m_smoothing_factor != 0)
                    {
                        m_downSamplers[ci]  = downSampleMethod.fullsize_smooth_downsampler;
                        m_need_context_rows = true;
                    }
                    else
                    {
                        m_downSamplers[ci] = downSampleMethod.fullsize_downsampler;
                    }
                }
                else if (componentInfo.H_samp_factor * 2 == cinfo.m_max_h_samp_factor &&
                         componentInfo.V_samp_factor == cinfo.m_max_v_samp_factor)
                {
                    smoothok           = false;
                    m_downSamplers[ci] = downSampleMethod.h2v1_downsampler;
                }
                else if (componentInfo.H_samp_factor * 2 == cinfo.m_max_h_samp_factor &&
                         componentInfo.V_samp_factor * 2 == cinfo.m_max_v_samp_factor)
                {
                    if (cinfo.m_smoothing_factor != 0)
                    {
                        m_downSamplers[ci]  = downSampleMethod.h2v2_smooth_downsampler;
                        m_need_context_rows = true;
                    }
                    else
                    {
                        m_downSamplers[ci] = downSampleMethod.h2v2_downsampler;
                    }
                }
                else if ((cinfo.m_max_h_samp_factor % componentInfo.H_samp_factor) == 0 &&
                         (cinfo.m_max_v_samp_factor % componentInfo.V_samp_factor) == 0)
                {
                    smoothok           = false;
                    m_downSamplers[ci] = downSampleMethod.int_downsampler;
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_FRACT_SAMPLE_NOTIMPL);
                }
            }

            if (cinfo.m_smoothing_factor != 0 && !smoothok)
            {
                cinfo.TRACEMS(0, J_MESSAGE_CODE.JTRC_SMOOTH_NOTIMPL);
            }
        }
コード例 #30
0
 static bool set_quant_slots(jpeg_compress_struct cinfo, string arg)
 {
     // not implemented yet
     return(false);
 }
コード例 #31
0
 static bool read_quant_tables(jpeg_compress_struct cinfo, string filename, bool force_baseline)
 {
     // not implemented yet
     return(false);
 }
コード例 #32
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. */
            bool force_baseline     = false; /* by default, allow 16-bit quantizers */
            bool simple_progressive = false;

            string qualityarg = null; /* saves -quality parm if any */
            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", 2))
                {
                    /* Force baseline-compatible output (8-bit quantizer values). */
                    force_baseline = true;
                }
                else if (cdjpeg_utils.keymatch(arg, "block", 2))
                {
                    /* Set DCT block size. */
                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                    {
                        return(false);
                    }

                    int val;
                    if (!int.TryParse(argv[argn], out val))
                    {
                        return(false);
                    }

                    if (val < 1 || val > 16)
                    {
                        return(false);
                    }

                    cinfo.block_size = val;
                }
                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, "rgb", 3) || cdjpeg_utils.keymatch(arg, "rgb1", 4))
                {
                    /* Force an RGB JPEG file to be generated. */

                    /* Note: Entropy table assignment in Jpeg_color_space depends
                     * on color_transform.
                     */
                    cinfo.color_transform  = (arg == "rgb") ? J_COLOR_TRANSFORM.JCT_SUBTRACT_GREEN : J_COLOR_TRANSFORM.JCT_NONE;
                    cinfo.Jpeg_color_space = J_COLOR_SPACE.JCS_RGB;
                }
                else if (cdjpeg_utils.keymatch(arg, "bgycc", 5))
                {
                    /* Force a big gamut YCC JPEG file to be generated. */
                    cinfo.Jpeg_color_space = J_COLOR_SPACE.JCS_BG_YCC;
                }
                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, "nosmooth", 3))
                {
                    /* Suppress fancy downsampling. */
                    cinfo.do_fancy_downsampling = false;
                }
                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 ratings (quantization table scaling factors). */
                    argn++;/* advance to next argument */
                    if (argn >= argv.Length)
                    {
                        return(false);
                    }

                    qualityarg = argv[argn];
                }
                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, "scale", 4))
                {
                    /* Scale the image by a fraction M/N. */
                    argn++; /* advance to next argument */
                    if (argn >= argv.Length)
                    {
                        return(false);
                    }

                    string[] parts = argv[argn].Split(',');
                    if (parts.Length != 2)
                    {
                        return(false);
                    }

                    if (!int.TryParse(parts[0], out cinfo.scale_num))
                    {
                        return(false);
                    }

                    if (!int.TryParse(parts[1], out cinfo.scale_denom))
                    {
                        return(false);
                    }
                }
                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. */
                if (qualityarg != null)
                {
                    if (!set_quality_ratings(cinfo, qualityarg, force_baseline))
                    {
                        return(false);
                    }
                }

                if (qtablefile != null) /* process -qtables if it was present */
                {
                    if (!read_quant_tables(cinfo, qtablefile, 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);
        }
コード例 #33
0
ファイル: jpeg_forward_dct.cs プロジェクト: Daramkun/Misty
        public jpeg_forward_dct(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            switch (cinfo.m_dct_method)
            {
                case J_DCT_METHOD.JDCT_ISLOW:
                    m_useFloatMethod = false;
                    m_useSlowMethod = true;
                    break;
                case J_DCT_METHOD.JDCT_IFAST:
                    m_useFloatMethod = false;
                    m_useSlowMethod = false;
                    break;
                case J_DCT_METHOD.JDCT_FLOAT:
                    m_useFloatMethod = true;
                    break;
                default:
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_NOT_COMPILED);
                    break;
            }

            /* Mark divisor tables unallocated */
            for (int i = 0; i < JpegConstants.NUM_QUANT_TBLS; i++)
            {
                m_divisors[i] = null;
                m_float_divisors[i] = null;
            }
        }
コード例 #34
0
	extern public static void jpeg_simple_progression
				(ref jpeg_compress_struct cinfo);
コード例 #35
0
	// Empty an output buffer to a stream.
	private static Int empty_output_buffer(ref jpeg_compress_struct cinfo)
			{
				int len;
				StreamState state = GetStreamState(ref cinfo);
				len = state.buffer.Length;
				Marshal.Copy(state.buf, state.buffer, 0, len);
				state.stream.Write(state.buffer, 0, len);
				cinfo.dest->next_output_byte = state.buf;
				cinfo.dest->free_in_buffer = (size_t)len;
				return (Int)1;
			}
コード例 #36
0
	// Terminate an output destination.
	private static void term_destination(ref jpeg_compress_struct cinfo)
			{
				// Nothing to do here.
			}
コード例 #37
0
        private byte[] m_buffer;     /* start of buffer */

        public my_destination_mgr(jpeg_compress_struct cinfo, Stream alreadyOpenFile)
        {
            m_cinfo   = cinfo;
            m_outfile = alreadyOpenFile;
        }
コード例 #38
0
        public jpeg_color_converter(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* set start_pass to null method until we find out differently */
            m_useNullStart = true;

            /* Make sure input_components agrees with in_color_space */
            switch (cinfo.m_in_color_space)
            {
            case J_COLOR_SPACE.JCS_GRAYSCALE:
                if (cinfo.m_input_components != 1)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            case J_COLOR_SPACE.JCS_RGB:
            case J_COLOR_SPACE.JCS_BG_RGB:
                if (cinfo.m_input_components != JpegConstants.RGB_PIXELSIZE)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            case J_COLOR_SPACE.JCS_YCbCr:
            case J_COLOR_SPACE.JCS_BG_YCC:
                if (cinfo.m_input_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            case J_COLOR_SPACE.JCS_CMYK:
            case J_COLOR_SPACE.JCS_YCCK:
                if (cinfo.m_input_components != 4)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            default:
                /* JCS_UNKNOWN can be anything */
                if (cinfo.m_input_components < 1)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;
            }

            /* Support color transform only for RGB colorspaces */
            if (cinfo.color_transform != J_COLOR_TRANSFORM.JCT_NONE &&
                cinfo.Jpeg_color_space != J_COLOR_SPACE.JCS_RGB &&
                cinfo.Jpeg_color_space != J_COLOR_SPACE.JCS_BG_RGB)
            {
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
            }

            /* Check num_components, set conversion method based on requested space */
            switch (cinfo.m_jpeg_color_space)
            {
            case J_COLOR_SPACE.JCS_GRAYSCALE:
                if (cinfo.m_num_components != 1)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                switch (cinfo.m_in_color_space)
                {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                case J_COLOR_SPACE.JCS_YCbCr:
                case J_COLOR_SPACE.JCS_BG_YCC:
                    color_convert = grayscale_convert;
                    break;

                case J_COLOR_SPACE.JCS_RGB:
                    m_useNullStart = false;         // use rgb_ycc_start
                    color_convert  = rgb_gray_convert;
                    break;

                default:
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;
                }
                break;

            case J_COLOR_SPACE.JCS_RGB:
            case J_COLOR_SPACE.JCS_BG_RGB:
                if (cinfo.m_num_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                if (cinfo.m_in_color_space == cinfo.Jpeg_color_space)
                {
                    switch (cinfo.color_transform)
                    {
                    case J_COLOR_TRANSFORM.JCT_NONE:
                        color_convert = rgb_convert;
                        break;

                    case J_COLOR_TRANSFORM.JCT_SUBTRACT_GREEN:
                        color_convert = rgb_rgb1_convert;
                        break;

                    default:
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                        break;
                    }
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }
                break;

            case J_COLOR_SPACE.JCS_YCbCr:
                if (cinfo.m_num_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                switch (cinfo.m_in_color_space)
                {
                case J_COLOR_SPACE.JCS_RGB:
                    m_useNullStart = false;         // use rgb_ycc_start
                    color_convert  = rgb_ycc_convert;
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                    color_convert = null_convert;
                    break;

                default:
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;
                }
                break;

            case J_COLOR_SPACE.JCS_BG_YCC:
                if (cinfo.m_num_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                switch (cinfo.m_in_color_space)
                {
                case J_COLOR_SPACE.JCS_RGB:
                    /* For conversion from normal RGB input to BG_YCC representation,
                     * the Cb/Cr values are first computed as usual, and then
                     * quantized further after DCT processing by a factor of
                     * 2 in reference to the nominal quantization factor.
                     */
                    /* need quantization scale by factor of 2 after DCT */
                    cinfo.Component_info[1].component_needed = true;
                    cinfo.Component_info[2].component_needed = true;
                    /* compute normal YCC first */
                    m_useNullStart = false;         // use rgb_ycc_start
                    color_convert  = rgb_ycc_convert;
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                    /* need quantization scale by factor of 2 after DCT */
                    cinfo.Component_info[1].component_needed = true;
                    cinfo.Component_info[2].component_needed = true;
                    color_convert = null_convert;
                    break;

                case J_COLOR_SPACE.JCS_BG_YCC:
                    /* Pass through for BG_YCC input */
                    color_convert = null_convert;
                    break;

                default:
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                    break;
                }
                break;

            case J_COLOR_SPACE.JCS_CMYK:
                if (cinfo.m_num_components != 4)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_CMYK)
                {
                    color_convert = null_convert;
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }
                break;

            case J_COLOR_SPACE.JCS_YCCK:
                if (cinfo.m_num_components != 4)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                switch (cinfo.m_in_color_space)
                {
                case J_COLOR_SPACE.JCS_CMYK:
                    m_useNullStart = false;         // use rgb_ycc_start
                    color_convert  = cmyk_ycck_convert;
                    break;

                case J_COLOR_SPACE.JCS_YCCK:
                    color_convert = null_convert;
                    break;

                default:
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;
                }
                break;

            default:
                /* allow null conversion of JCS_UNKNOWN */
                if (cinfo.m_jpeg_color_space != cinfo.m_in_color_space || cinfo.m_num_components != cinfo.m_input_components)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }

                color_convert = null_convert;
                break;
            }
        }
コード例 #39
0
	// Convert a stream into a destination manager.
	public static void StreamToDestinationManager
				(ref jpeg_compress_struct cinfo, Stream stream)
			{
				// Allocate a state structure and store it in "cinfo".
				IntPtr buf = Marshal.AllocHGlobal(4096);
				StreamState state = new StreamState();
				state.buf = buf;
				state.buffer = new byte [4096];
				state.stream = stream;
				cinfo.client_data = (IntPtr)(GCHandle.Alloc(state));

				// Create the managed version of "jpeg_destination_mgr".
				jpeg_destination_mgr mgr = new jpeg_destination_mgr();
				mgr.next_output_byte = buf;
				mgr.free_in_buffer = (size_t)4096;
				mgr.init_destination =
					new init_destination_type(init_destination);
				mgr.empty_output_buffer =
					new empty_output_buffer_type(empty_output_buffer);
				mgr.term_destination =
					new term_destination_type(term_destination);

				// Convert it into the unmanaged version and store it.
#if __CSCC__
				IntPtr umgr = Marshal.AllocHGlobal
					(sizeof(jpeg_destination_mgr));
				Marshal.StructureToPtr(mgr, umgr, false);
				cinfo.dest = (jpeg_destination_mgr *)umgr;
#endif
			}
コード例 #40
0
        private bool m_need_context_rows; /* true if need rows above & below */

        public jpeg_downsampler(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;
            m_need_context_rows = false;

            if (cinfo.m_CCIR601_sampling)
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CCIR601_NOTIMPL);

            /* Verify we can handle the sampling factors, and set up method pointers */
            bool smoothok = true;
            for (int ci = 0; ci < cinfo.m_num_components; ci++)
            {
                jpeg_component_info componentInfo = cinfo.Component_info[ci];

                /* Compute size of an "output group" for DCT scaling.  This many samples
                 * are to be converted from max_h_samp_factor * max_v_samp_factor pixels.
                 */
                int h_out_group = (componentInfo.H_samp_factor * componentInfo.DCT_h_scaled_size) /
                      m_cinfo.min_DCT_h_scaled_size;
                int v_out_group = (componentInfo.V_samp_factor * componentInfo.DCT_v_scaled_size) /
                      m_cinfo.min_DCT_v_scaled_size;
                int h_in_group = m_cinfo.m_max_h_samp_factor;
                int v_in_group = m_cinfo.m_max_v_samp_factor;
                rowgroup_height[ci] = v_out_group; /* save for use later */
                if (h_in_group == h_out_group && v_in_group == v_out_group)
                {
                    if (cinfo.m_smoothing_factor != 0)
                    {
                        m_downSamplers[ci] = downSampleMethod.fullsize_smooth_downsampler;
                        m_need_context_rows = true;
                    }
                    else
                    {
                        m_downSamplers[ci] = downSampleMethod.fullsize_downsampler;
                    }
                }
                else if (h_in_group == h_out_group * 2 && v_in_group == v_out_group)
                {
                    smoothok = false;
                    m_downSamplers[ci] = downSampleMethod.h2v1_downsampler;
                }
                else if (h_in_group == h_out_group * 2 && v_in_group == v_out_group * 2)
                {
                    if (cinfo.m_smoothing_factor != 0)
                    {
                        m_downSamplers[ci] = downSampleMethod.h2v2_smooth_downsampler;
                        m_need_context_rows = true;
                    }
                    else
                    {
                        m_downSamplers[ci] = downSampleMethod.h2v2_downsampler;
                    }
                }
                else if ((h_in_group % h_out_group) == 0 && (v_in_group % v_out_group) == 0)
                {
                    smoothok = false;
                    m_downSamplers[ci] = downSampleMethod.int_downsampler;
                    h_expand[ci] = (byte)(h_in_group / h_out_group);
                    v_expand[ci] = (byte)(v_in_group / v_out_group);
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_FRACT_SAMPLE_NOTIMPL);
                }
            }

            if (cinfo.m_smoothing_factor != 0 && !smoothok)
                cinfo.TRACEMS(0, J_MESSAGE_CODE.JTRC_SMOOTH_NOTIMPL);
        }
コード例 #41
0
        static string outfilename; /* for -outfile switch */

        public static void Main(string[] args)
        {
            progname = Path.GetFileName(Environment.GetCommandLineArgs()[0]);

            cd_jpeg_error_mgr    err   = new cd_jpeg_error_mgr();
            jpeg_compress_struct cinfo = new jpeg_compress_struct(err);

            /* Initialize JPEG parameters.
             * Much of this may be overridden later.
             * In particular, we don't yet know the input file's color space,
             * but we need to provide some value for jpeg_set_defaults() to work.
             */

            cinfo.In_color_space = J_COLOR_SPACE.JCS_RGB; /* arbitrary guess */
            cinfo.jpeg_set_defaults();

            /* Scan command line to find file names.
             * It is convenient to use just one switch-parsing routine, but the switch
             * values read here are ignored; we will rescan the switches after opening
             * the input file.
             */
            int file_index;

            if (!parse_switches(cinfo, args, false, out file_index))
            {
                usage();
                return;
            }

            /* Must have either -outfile switch or explicit output file name */
            if (outfilename == null)
            {
                // file_index should point to input file
                if (file_index != args.Length - 2)
                {
                    Console.WriteLine(string.Format("{0}: must name one input and one output file.", progname));
                    usage();
                    return;
                }

                // output file comes right after input one
                outfilename = args[file_index + 1];
            }
            else
            {
                // file_index should point to input file
                if (file_index != args.Length - 1)
                {
                    Console.WriteLine(string.Format("{0}: must name one input and one output file.", progname));
                    usage();
                    return;
                }
            }

            /* Open the input file. */
            FileStream input_file = null;

            if (file_index < args.Length)
            {
                try
                {
                    input_file = new FileStream(args[file_index], FileMode.Open);
                }
                catch (Exception e)
                {
                    Console.WriteLine(string.Format("{0}: can't open {1}", progname, args[file_index]));
                    Console.WriteLine(e.Message);
                    return;
                }
            }
            else
            {
                Console.WriteLine(string.Format("{0}: sorry, can't read file from console"));
                return;
            }

            /* Open the output file. */
            FileStream output_file = null;

            if (outfilename != null)
            {
                try
                {
                    output_file = new FileStream(outfilename, FileMode.Create);
                }
                catch (Exception e)
                {
                    Console.WriteLine(string.Format("{0}: can't open {1}", progname, args[file_index]));
                    Console.WriteLine(e.Message);
                    return;
                }
            }
            else
            {
                Console.WriteLine(string.Format("{0}: sorry, can't write file to console"));
                return;
            }

            /* Figure out the input file format, and set up to read it. */
            cjpeg_source_struct src_mgr = new bmp_source_struct(cinfo);

            src_mgr.input_file = input_file;

            /* Read the input file header to obtain file size & colorspace. */
            src_mgr.start_input();

            /* Now that we know input colorspace, fix colorspace-dependent defaults */
            cinfo.jpeg_default_colorspace();

            /* Adjust default compression parameters by re-parsing the options */
            parse_switches(cinfo, args, true, out file_index);

            /* Specify data destination for compression */
            cinfo.jpeg_stdio_dest(output_file);

            /* Start compressor */
            cinfo.jpeg_start_compress(true);

            /* Process data */
            while (cinfo.Next_scanline < cinfo.Image_height)
            {
                int num_scanlines = src_mgr.get_pixel_rows();
                cinfo.jpeg_write_scanlines(src_mgr.buffer, num_scanlines);
            }

            /* Finish compression and release memory */
            src_mgr.finish_input();
            cinfo.jpeg_finish_compress();

            /* Close files, if we opened them */
            input_file.Close();
            input_file.Dispose();

            output_file.Close();
            output_file.Dispose();

            /* All done. */
            if (cinfo.Err.Num_warnings != 0)
            {
                Console.WriteLine("Corrupt-data warning count is not zero");
            }
        }
コード例 #42
0
	// Initialize a stream data destination.
	private static void init_destination(ref jpeg_compress_struct cinfo)
			{
				// Nothing to do here: already initialized.
			}
コード例 #43
0
	extern public static UInt jpeg_write_scanlines
				(ref jpeg_compress_struct cinfo,
				 ref IntPtr scanline, UInt num_lines);
コード例 #44
0
        public jpeg_forward_dct(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;
            m_dctTables = new divisor_table[m_cinfo.m_num_components];

            for (int ci = 0; ci < m_cinfo.m_num_components; ci++)
            {
                /* Allocate a divisor table for each component */
                m_dctTables[ci] = new divisor_table();
            }
        }
コード例 #45
0
 static bool set_sample_factors(jpeg_compress_struct cinfo, string arg)
 {
     // not implemented yet
     return(false);
 }
コード例 #46
0
	// Get the stream state for a compress structure.
	private static StreamState GetStreamState(ref jpeg_compress_struct cinfo)
			{
				GCHandle handle = (GCHandle)(cinfo.client_data);
				return (StreamState)(handle.Target);
			}
コード例 #47
0
	extern public static void jpeg_start_compress
				(ref jpeg_compress_struct cinfo, Int write_all_tables);
コード例 #48
0
	extern public static void jpeg_abort_compress
				(ref jpeg_compress_struct cinfo);
コード例 #49
0
ファイル: jpeg_marker_writer.cs プロジェクト: Daramkun/Misty
        private int m_last_restart_interval; /* last DRI value emitted; 0 after SOI */

        #endregion Fields

        #region Constructors

        public jpeg_marker_writer(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;
        }
コード例 #50
0
        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);
        }
コード例 #51
0
	extern public static void *jpeg_alloc_huff_table
				(ref jpeg_compress_struct cinfo);
コード例 #52
0
	extern public static void jpeg_write_tables
				(ref jpeg_compress_struct cinfo);
コード例 #53
0
	extern public static void jpeg_suppress_tables
				(ref jpeg_compress_struct cinfo, Int suppress);
コード例 #54
0
        private int[] m_rgb_ycc_tab;     /* => table for RGB to YCbCr conversion */

        public jpeg_color_converter(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* set start_pass to null method until we find out differently */
            m_useNullStart = true;

            /* Make sure input_components agrees with in_color_space */
            switch (cinfo.m_in_color_space)
            {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                    if (cinfo.m_input_components != 1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                case J_COLOR_SPACE.JCS_RGB:
                case J_COLOR_SPACE.JCS_YCbCr:
                    if (cinfo.m_input_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                case J_COLOR_SPACE.JCS_CMYK:
                case J_COLOR_SPACE.JCS_YCCK:
                    if (cinfo.m_input_components != 4)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                default:
                    /* JCS_UNKNOWN can be anything */
                    if (cinfo.m_input_components < 1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;
            }

            /* Check num_components, set conversion method based on requested space */
            clearConvertFlags();
            switch (cinfo.m_jpeg_color_space)
            {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                    if (cinfo.m_num_components != 1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                    switch (cinfo.m_in_color_space)
                    {
                        case J_COLOR_SPACE.JCS_GRAYSCALE:
                            m_useGrayscaleConvert = true;
                            break;
                        case J_COLOR_SPACE.JCS_RGB:
                            m_useNullStart = false; // use rgb_ycc_start
                            m_useRgbGrayConvert = true;
                            break;
                        case J_COLOR_SPACE.JCS_YCbCr:
                            m_useGrayscaleConvert = true;
                            break;
                        default:
                            cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                            break;
                    }

                    break;

                case J_COLOR_SPACE.JCS_RGB:
                    if (cinfo.m_num_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                    
                    if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_RGB)
                        m_useNullConvert = true;
                    else
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                    if (cinfo.m_num_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                    
                    if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_RGB)
                    {
                        m_useNullStart = false; // use rgb_ycc_start
                        m_useRgbYccConvert = true;
                    }
                    else if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_YCbCr)
                        m_useNullConvert = true;
                    else
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;

                case J_COLOR_SPACE.JCS_CMYK:
                    if (cinfo.m_num_components != 4)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                    
                    if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_CMYK)
                        m_useNullConvert = true;
                    else
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;

                case J_COLOR_SPACE.JCS_YCCK:
                    if (cinfo.m_num_components != 4)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                    
                    if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_CMYK)
                    {
                        m_useNullStart = false; // use rgb_ycc_start
                        m_useCmykYcckConvert = true;
                    }
                    else if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_YCCK)
                        m_useNullConvert = true;
                    else
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;

                default:
                    /* allow null conversion of JCS_UNKNOWN */
                    if (cinfo.m_jpeg_color_space != cinfo.m_in_color_space || cinfo.m_num_components != cinfo.m_input_components)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);

                    m_useNullConvert = true;
                    break;
            }
        }
コード例 #55
0
	extern public static void jpeg_add_quant_table
				(ref jpeg_compress_struct cinfo, Int which_tbl,
				 void *basic_table, Int scale_factor, Int force_baseline);
コード例 #56
0
        public jpeg_color_converter(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* set start_pass to null method until we find out differently */
            m_useNullStart = true;

            /* Make sure input_components agrees with in_color_space */
            switch (cinfo.m_in_color_space)
            {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                    if (cinfo.m_input_components != 1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                case J_COLOR_SPACE.JCS_RGB:
                case J_COLOR_SPACE.JCS_BG_RGB:
                    if (cinfo.m_input_components != JpegConstants.RGB_PIXELSIZE)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                case J_COLOR_SPACE.JCS_BG_YCC:
                    if (cinfo.m_input_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                case J_COLOR_SPACE.JCS_CMYK:
                case J_COLOR_SPACE.JCS_YCCK:
                    if (cinfo.m_input_components != 4)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;

                default:
                    /* JCS_UNKNOWN can be anything */
                    if (cinfo.m_input_components < 1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                    break;
            }

            /* Support color transform only for RGB colorspaces */
            if (cinfo.color_transform != J_COLOR_TRANSFORM.JCT_NONE &&
                cinfo.Jpeg_color_space != J_COLOR_SPACE.JCS_RGB &&
                cinfo.Jpeg_color_space != J_COLOR_SPACE.JCS_BG_RGB)
            {
                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
            }

            /* Check num_components, set conversion method based on requested space */
            switch (cinfo.m_jpeg_color_space)
            {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                    if (cinfo.m_num_components != 1)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);

                    switch (cinfo.m_in_color_space)
                    {
                        case J_COLOR_SPACE.JCS_GRAYSCALE:
                        case J_COLOR_SPACE.JCS_YCbCr:
                        case J_COLOR_SPACE.JCS_BG_YCC:
                            color_convert = grayscale_convert;
                            break;

                        case J_COLOR_SPACE.JCS_RGB:
                            m_useNullStart = false; // use rgb_ycc_start
                            color_convert = rgb_gray_convert;
                            break;

                        default:
                            cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                            break;
                    }
                    break;

                case J_COLOR_SPACE.JCS_RGB:
                case J_COLOR_SPACE.JCS_BG_RGB:
                    if (cinfo.m_num_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);

                    if (cinfo.m_in_color_space == cinfo.Jpeg_color_space)
                    {
                        switch (cinfo.color_transform)
                        {
                            case J_COLOR_TRANSFORM.JCT_NONE:
                                color_convert = rgb_convert;
                                break;
                            case J_COLOR_TRANSFORM.JCT_SUBTRACT_GREEN:
                                color_convert = rgb_rgb1_convert;
                                break;
                            default:
                                cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                                break;
                        }
                    }
                    else
                    {
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    }
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                    if (cinfo.m_num_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);

                    switch (cinfo.m_in_color_space)
                    {
                        case J_COLOR_SPACE.JCS_RGB:
                            m_useNullStart = false; // use rgb_ycc_start
                            color_convert = rgb_ycc_convert;
                            break;

                        case J_COLOR_SPACE.JCS_YCbCr:
                            color_convert = null_convert;
                            break;

                        default:
                            cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                            break;
                    }
                    break;

                case J_COLOR_SPACE.JCS_BG_YCC:
                    if (cinfo.m_num_components != 3)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);

                    switch (cinfo.m_in_color_space)
                    {
                        case J_COLOR_SPACE.JCS_RGB:
                            /* For conversion from normal RGB input to BG_YCC representation,
                             * the Cb/Cr values are first computed as usual, and then
                             * quantized further after DCT processing by a factor of
                             * 2 in reference to the nominal quantization factor.
                             */
                            /* need quantization scale by factor of 2 after DCT */
                            cinfo.Component_info[1].component_needed = true;
                            cinfo.Component_info[2].component_needed = true;
                            /* compute normal YCC first */
                            m_useNullStart = false; // use rgb_ycc_start
                            color_convert = rgb_ycc_convert;
                            break;
                        case J_COLOR_SPACE.JCS_YCbCr:
                            /* need quantization scale by factor of 2 after DCT */
                            cinfo.Component_info[1].component_needed = true;
                            cinfo.Component_info[2].component_needed = true;
                            color_convert = null_convert;
                            break;
                        case J_COLOR_SPACE.JCS_BG_YCC:
                            /* Pass through for BG_YCC input */
                            color_convert = null_convert;
                            break;
                        default:
                            cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                            break;
                    }
                    break;

                case J_COLOR_SPACE.JCS_CMYK:
                    if (cinfo.m_num_components != 4)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);

                    if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_CMYK)
                        color_convert = null_convert;
                    else
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;

                case J_COLOR_SPACE.JCS_YCCK:
                    if (cinfo.m_num_components != 4)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);

                    switch (cinfo.m_in_color_space)
                    {
                        case J_COLOR_SPACE.JCS_CMYK:
                            m_useNullStart = false; // use rgb_ycc_start
                            color_convert = cmyk_ycck_convert;
                            break;

                        case J_COLOR_SPACE.JCS_YCCK:
                            color_convert = null_convert;
                            break;

                        default:
                            cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                            break;
                    }
                    break;

                default:
                    /* allow null conversion of JCS_UNKNOWN */
                    if (cinfo.m_jpeg_color_space != cinfo.m_in_color_space || cinfo.m_num_components != cinfo.m_input_components)
                        cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);

                    color_convert = null_convert;
                    break;
            }
        }
コード例 #57
0
        private int[] m_rgb_ycc_tab;     /* => table for RGB to YCbCr conversion */

        public jpeg_color_converter(jpeg_compress_struct cinfo)
        {
            m_cinfo = cinfo;

            /* set start_pass to null method until we find out differently */
            m_useNullStart = true;

            /* Make sure input_components agrees with in_color_space */
            switch (cinfo.m_in_color_space)
            {
            case J_COLOR_SPACE.JCS_GRAYSCALE:
                if (cinfo.m_input_components != 1)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            case J_COLOR_SPACE.JCS_RGB:
            case J_COLOR_SPACE.JCS_YCbCr:
                if (cinfo.m_input_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            case J_COLOR_SPACE.JCS_CMYK:
            case J_COLOR_SPACE.JCS_YCCK:
                if (cinfo.m_input_components != 4)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;

            default:
                /* JCS_UNKNOWN can be anything */
                if (cinfo.m_input_components < 1)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_IN_COLORSPACE);
                }
                break;
            }

            /* Check num_components, set conversion method based on requested space */
            clearConvertFlags();
            switch (cinfo.m_jpeg_color_space)
            {
            case J_COLOR_SPACE.JCS_GRAYSCALE:
                if (cinfo.m_num_components != 1)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }
                switch (cinfo.m_in_color_space)
                {
                case J_COLOR_SPACE.JCS_GRAYSCALE:
                    m_useGrayscaleConvert = true;
                    break;

                case J_COLOR_SPACE.JCS_RGB:
                    m_useNullStart      = false;    // use rgb_ycc_start
                    m_useRgbGrayConvert = true;
                    break;

                case J_COLOR_SPACE.JCS_YCbCr:
                    m_useGrayscaleConvert = true;
                    break;

                default:
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                    break;
                }

                break;

            case J_COLOR_SPACE.JCS_RGB:
                if (cinfo.m_num_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_RGB)
                {
                    m_useNullConvert = true;
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }
                break;

            case J_COLOR_SPACE.JCS_YCbCr:
                if (cinfo.m_num_components != 3)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_RGB)
                {
                    m_useNullStart     = false; // use rgb_ycc_start
                    m_useRgbYccConvert = true;
                }
                else if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_YCbCr)
                {
                    m_useNullConvert = true;
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }
                break;

            case J_COLOR_SPACE.JCS_CMYK:
                if (cinfo.m_num_components != 4)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_CMYK)
                {
                    m_useNullConvert = true;
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }
                break;

            case J_COLOR_SPACE.JCS_YCCK:
                if (cinfo.m_num_components != 4)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_BAD_J_COLORSPACE);
                }

                if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_CMYK)
                {
                    m_useNullStart       = false; // use rgb_ycc_start
                    m_useCmykYcckConvert = true;
                }
                else if (cinfo.m_in_color_space == J_COLOR_SPACE.JCS_YCCK)
                {
                    m_useNullConvert = true;
                }
                else
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }
                break;

            default:
                /* allow null conversion of JCS_UNKNOWN */
                if (cinfo.m_jpeg_color_space != cinfo.m_in_color_space || cinfo.m_num_components != cinfo.m_input_components)
                {
                    cinfo.ERREXIT(J_MESSAGE_CODE.JERR_CONVERSION_NOTIMPL);
                }

                m_useNullConvert = true;
                break;
            }
        }
コード例 #58
0
        // the algorithm flow is based on:
        // https://bitmiracle.github.io/libjpeg.net/help/articles/KB/compression-details.html
        private static byte[] CompressRawToJpeg(byte[] input, int width, int height, int scale, int quality, Tuple <int, int> crop)
        {
            jpeg_error_mgr       errorManager = new jpeg_error_mgr();
            jpeg_compress_struct cinfo        = new jpeg_compress_struct(errorManager);

            var memoryStream = new MemoryStream();

            cinfo.jpeg_stdio_dest(memoryStream);

            var widthToSkip      = 0;
            var widthToSkipFront = 0;
            var widthToSkipBack  = 0;

            if (crop != null && width > crop.Item1)
            {
                widthToSkip      = (width - crop.Item1);
                widthToSkipFront = widthToSkip / 2;
                widthToSkipBack  = widthToSkip - widthToSkipFront; // to handle odd 'widthToSkip' values
            }

            var heightToSkip    = 0;
            var heightToSkipTop = 0;

            if (crop != null && height > crop.Item2)
            {
                heightToSkip    = (height - crop.Item2);
                heightToSkipTop = heightToSkip / 2;
            }

            cinfo.Image_width      = (width - widthToSkip) / scale;
            cinfo.Image_height     = (height - heightToSkip) / scale;
            cinfo.Input_components = 3;
            cinfo.In_color_space   = J_COLOR_SPACE.JCS_RGB;
            cinfo.jpeg_set_defaults();

            if (quality != -1)
            {
                cinfo.jpeg_set_quality(quality, true);
            }

            cinfo.jpeg_start_compress(true);

            int row_stride = cinfo.Image_width * 3; // physical row width in buffer

            byte[][] rowData = new byte[1][];       // single row
            rowData[0] = new byte[row_stride];

            int inputOffset = heightToSkipTop * width;

            while (cinfo.Next_scanline < cinfo.Image_height)
            {
                // crop pixels at the beginning of the line
                inputOffset += 3 * widthToSkipFront;

                for (int i = 0; i < rowData[0].Length - 2; i += 3)
                {
                    rowData[0][i]     = input[inputOffset];
                    rowData[0][i + 1] = input[inputOffset + 1];
                    rowData[0][i + 2] = input[inputOffset + 2];

                    inputOffset += 3 * scale;
                }

                // crop pixels at the end of the line
                inputOffset += 3 * widthToSkipBack;

                // drop some lines due to scaling
                inputOffset += 3 * (scale - 1) * width;

                cinfo.jpeg_write_scanlines(rowData, 1);
            }

            cinfo.jpeg_finish_compress();

            var result = memoryStream.ToArray();

            memoryStream.Close();
            return(result);
        }
コード例 #59
0
	extern public static void jpeg_finish_compress
				(ref jpeg_compress_struct cinfo);
コード例 #60
0
	// Free a destination manager.
	public static void FreeDestinationManager(ref jpeg_compress_struct cinfo)
			{
				GCHandle handle = (GCHandle)(cinfo.client_data);
				StreamState state = (StreamState)(handle.Target);
				Marshal.FreeHGlobal(state.buf);
				handle.Free();
				Marshal.FreeHGlobal((IntPtr)(cinfo.dest));
				cinfo.client_data = IntPtr.Zero;
				cinfo.dest = null;
			}