示例#1
0
        // Module initialization routine for Huffman entropy encoding.
        static void jinit_shuff_encoder(jpeg_compress cinfo)
        {
            jpeg_lossy_c_codec    lossyc  = (jpeg_lossy_c_codec)cinfo.coef;
            shuff_entropy_encoder entropy = null;

            try
            {
                entropy = new shuff_entropy_encoder();
                entropy.saved.last_dc_val = new int[MAX_COMPS_IN_SCAN];
            }
            catch
            {
                ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
            }
            lossyc.entropy_private        = entropy;
            lossyc.entropy_start_pass     = start_pass_huff;
            lossyc.need_optimization_pass = need_optimization_pass_sq;

            // Mark tables unallocated
            for (int i = 0; i < NUM_HUFF_TBLS; i++)
            {
                entropy.dc_derived_tbls[i] = entropy.ac_derived_tbls[i] = null;
#if ENTROPY_OPT_SUPPORTED
                entropy.dc_count_ptrs[i] = entropy.ac_count_ptrs[i] = null;
#endif
            }
        }
示例#2
0
        // Trial-encode one MCU's worth of Huffman-compressed coefficients.
        // No data is actually output, so no suspension return is possible.
        static bool encode_mcu_gather_sq(jpeg_compress cinfo, short[][] MCU_data)
        {
            jpeg_lossy_c_codec    lossyc  = (jpeg_lossy_c_codec)cinfo.coef;
            shuff_entropy_encoder entropy = (shuff_entropy_encoder)lossyc.entropy_private;

            // Take care of restart intervals if needed
            if (cinfo.restart_interval != 0)
            {
                if (entropy.restarts_to_go == 0)
                {
                    // Re-initialize DC predictions to 0
                    for (int ci = 0; ci < cinfo.comps_in_scan; ci++)
                    {
                        entropy.saved.last_dc_val[ci] = 0;
                    }
                    // Update restart state
                    entropy.restarts_to_go = cinfo.restart_interval;
                }
                entropy.restarts_to_go--;
            }

            for (int blkn = 0; blkn < cinfo.block_in_MCU; blkn++)
            {
                int ci = cinfo.MCU_membership[blkn];
                jpeg_component_info compptr = cinfo.cur_comp_info[ci];
                htest_one_block_sq(cinfo, MCU_data[blkn], entropy.saved.last_dc_val[ci], entropy.dc_count_ptrs[compptr.dc_tbl_no], entropy.ac_count_ptrs[compptr.ac_tbl_no]);
                entropy.saved.last_dc_val[ci] = MCU_data[blkn][0];
            }

            return(true);
        }
示例#3
0
        // Finish up at the end of a Huffman-compressed scan.
        static void finish_pass_huff_sq(jpeg_compress cinfo)
        {
            jpeg_lossy_c_codec    lossyc  = (jpeg_lossy_c_codec)cinfo.coef;
            shuff_entropy_encoder entropy = (shuff_entropy_encoder)lossyc.entropy_private;
            working_state_sq      state;

            state.cur.last_dc_val = new int[MAX_COMPS_IN_SCAN];

            // Load up working state ... flush_bits needs it
            state.output_bytes     = cinfo.dest.output_bytes;
            state.next_output_byte = cinfo.dest.next_output_byte;
            state.free_in_buffer   = cinfo.dest.free_in_buffer;
            state.cur = entropy.saved;
            entropy.saved.last_dc_val.CopyTo(state.cur.last_dc_val, 0);
            state.cinfo = cinfo;

            // Flush out the last data
            if (!flush_bits(ref state))
            {
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_CANT_SUSPEND);
            }

            // Update state
            cinfo.dest.output_bytes     = state.output_bytes;
            cinfo.dest.next_output_byte = state.next_output_byte;
            cinfo.dest.free_in_buffer   = state.free_in_buffer;
            entropy.saved = state.cur;
            state.cur.last_dc_val.CopyTo(entropy.saved.last_dc_val, 0);
        }
示例#4
0
        // Finish up a statistics-gathering pass and create the new Huffman tables.
        static void finish_pass_gather_sq(jpeg_compress cinfo)
        {
            jpeg_lossy_c_codec    lossyc  = (jpeg_lossy_c_codec)cinfo.coef;
            shuff_entropy_encoder entropy = (shuff_entropy_encoder)lossyc.entropy_private;

            // It's important not to apply jpeg_gen_optimal_table more than once
            // per table, because it clobbers the input frequency counts!
            bool[] did_dc = new bool[NUM_HUFF_TBLS];
            bool[] did_ac = new bool[NUM_HUFF_TBLS];

            for (int ci = 0; ci < cinfo.comps_in_scan; ci++)
            {
                jpeg_component_info compptr = cinfo.cur_comp_info[ci];
                int dctbl = compptr.dc_tbl_no;
                int actbl = compptr.ac_tbl_no;

                if (!did_dc[dctbl])
                {
                    if (cinfo.dc_huff_tbl_ptrs[dctbl] == null)
                    {
                        cinfo.dc_huff_tbl_ptrs[dctbl] = jpeg_alloc_huff_table(cinfo);
                    }
                    jpeg_gen_optimal_table(cinfo, cinfo.dc_huff_tbl_ptrs[dctbl], entropy.dc_count_ptrs[dctbl]);
                    did_dc[dctbl] = true;
                }
                if (!did_ac[actbl])
                {
                    if (cinfo.ac_huff_tbl_ptrs[actbl] == null)
                    {
                        cinfo.ac_huff_tbl_ptrs[actbl] = jpeg_alloc_huff_table(cinfo);
                    }
                    jpeg_gen_optimal_table(cinfo, cinfo.ac_huff_tbl_ptrs[actbl], entropy.ac_count_ptrs[actbl]);
                    did_ac[actbl] = true;
                }
            }
        }
示例#5
0
		// Module initialization routine for Huffman entropy encoding.
		static void jinit_shuff_encoder(jpeg_compress cinfo)
		{
			jpeg_lossy_c_codec lossyc=(jpeg_lossy_c_codec)cinfo.coef;
			shuff_entropy_encoder entropy=null;

			try
			{
				entropy=new shuff_entropy_encoder();
				entropy.saved.last_dc_val=new int[MAX_COMPS_IN_SCAN];
			}
			catch
			{
				ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
			}
			lossyc.entropy_private=entropy;
			lossyc.entropy_start_pass=start_pass_huff;
			lossyc.need_optimization_pass=need_optimization_pass_sq;

			// Mark tables unallocated
			for(int i=0; i<NUM_HUFF_TBLS; i++)
			{
				entropy.dc_derived_tbls[i]=entropy.ac_derived_tbls[i]=null;
#if ENTROPY_OPT_SUPPORTED
				entropy.dc_count_ptrs[i]=entropy.ac_count_ptrs[i]=null;
#endif
			}
		}
示例#6
0
        // Initialize for a Huffman-compressed scan.
        // If gather_statistics is true, we do not output anything during the scan,
        // just count the Huffman symbols used and generate Huffman code tables.
        static void start_pass_huff(jpeg_compress cinfo, bool gather_statistics)
        {
            jpeg_lossy_c_codec    lossyc  = (jpeg_lossy_c_codec)cinfo.coef;
            shuff_entropy_encoder entropy = (shuff_entropy_encoder)lossyc.entropy_private;

            if (gather_statistics)
            {
#if ENTROPY_OPT_SUPPORTED
                lossyc.entropy_encode_mcu  = encode_mcu_gather_sq;
                lossyc.entropy_finish_pass = finish_pass_gather_sq;
#else
                ERREXIT(cinfo, J_MESSAGE_CODE.JERR_NOT_COMPILED);
#endif
            }
            else
            {
                lossyc.entropy_encode_mcu  = encode_mcu_huff_sq;
                lossyc.entropy_finish_pass = finish_pass_huff_sq;
            }

            for (int ci = 0; ci < cinfo.comps_in_scan; ci++)
            {
                jpeg_component_info compptr = cinfo.cur_comp_info[ci];
                int dctbl = compptr.dc_tbl_no;
                int actbl = compptr.ac_tbl_no;
                if (gather_statistics)
                {
#if ENTROPY_OPT_SUPPORTED
                    // Check for invalid table indexes
                    // (make_c_derived_tbl does this in the other path)
                    if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
                    {
                        ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, dctbl);
                    }
                    if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
                    {
                        ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_NO_HUFF_TABLE, actbl);
                    }

                    // Allocate and zero the statistics tables
                    // Note that jpeg_gen_optimal_table expects 257 entries in each table!
                    if (entropy.dc_count_ptrs[dctbl] == null)
                    {
                        try
                        {
                            entropy.dc_count_ptrs[dctbl] = new int[257];
                        }
                        catch
                        {
                            ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < 257; i++)
                        {
                            entropy.dc_count_ptrs[dctbl][i] = 0;
                        }
                    }

                    if (entropy.ac_count_ptrs[actbl] == null)
                    {
                        try
                        {
                            entropy.ac_count_ptrs[actbl] = new int[257];
                        }
                        catch
                        {
                            ERREXIT1(cinfo, J_MESSAGE_CODE.JERR_OUT_OF_MEMORY, 4);
                        }
                    }
                    else
                    {
                        for (int i = 0; i < 257; i++)
                        {
                            entropy.ac_count_ptrs[actbl][i] = 0;
                        }
                    }
#endif
                }
                else
                {
                    // Compute derived values for Huffman tables
                    // We may do this more than once for a table, but it's not expensive
                    jpeg_make_c_derived_tbl(cinfo, true, dctbl, ref entropy.dc_derived_tbls[dctbl]);
                    jpeg_make_c_derived_tbl(cinfo, false, actbl, ref entropy.ac_derived_tbls[actbl]);
                }
                // Initialize DC predictions to 0
                entropy.saved.last_dc_val[ci] = 0;
            }

            // Initialize bit buffer to empty
            entropy.saved.put_buffer = 0;
            entropy.saved.put_bits   = 0;

            // Initialize restart stuff
            entropy.restarts_to_go   = cinfo.restart_interval;
            entropy.next_restart_num = 0;
        }
示例#7
0
        // Encode and output one MCU's worth of Huffman-compressed coefficients.
        static bool encode_mcu_huff_sq(jpeg_compress cinfo, short[][] MCU_data)
        {
            jpeg_lossy_c_codec    lossyc  = (jpeg_lossy_c_codec)cinfo.coef;
            shuff_entropy_encoder entropy = (shuff_entropy_encoder)lossyc.entropy_private;

            // Load up working state
            working_state_sq state;

            state.cur.last_dc_val  = new int[MAX_COMPS_IN_SCAN];
            state.output_bytes     = cinfo.dest.output_bytes;
            state.next_output_byte = cinfo.dest.next_output_byte;
            state.free_in_buffer   = cinfo.dest.free_in_buffer;

            //was state.cur=entropy.saved;
            state.cur.put_bits   = entropy.saved.put_bits;
            state.cur.put_buffer = entropy.saved.put_buffer;
            entropy.saved.last_dc_val.CopyTo(state.cur.last_dc_val, 0);

            state.cinfo = cinfo;

            // Emit restart marker if needed
            if (cinfo.restart_interval != 0)
            {
                if (entropy.restarts_to_go == 0)
                {
                    if (!emit_restart(ref state, entropy.next_restart_num))
                    {
                        return(false);
                    }
                }
            }

            // Encode the MCU data blocks
            for (int blkn = 0; blkn < cinfo.block_in_MCU; blkn++)
            {
                int ci = cinfo.MCU_membership[blkn];
                jpeg_component_info compptr = cinfo.cur_comp_info[ci];
                if (!encode_one_block(ref state, MCU_data[blkn], state.cur.last_dc_val[ci], entropy.dc_derived_tbls[compptr.dc_tbl_no], entropy.ac_derived_tbls[compptr.ac_tbl_no]))
                {
                    return(false);
                }

                // Update last_dc_val
                state.cur.last_dc_val[ci] = MCU_data[blkn][0];
            }

            // Completed MCU, so update state
            cinfo.dest.output_bytes     = state.output_bytes;
            cinfo.dest.next_output_byte = state.next_output_byte;
            cinfo.dest.free_in_buffer   = state.free_in_buffer;

            //was entropy.saved=state.cur;
            entropy.saved.put_bits   = state.cur.put_bits;
            entropy.saved.put_buffer = state.cur.put_buffer;
            state.cur.last_dc_val.CopyTo(entropy.saved.last_dc_val, 0);

            // Update restart-interval state too
            if (cinfo.restart_interval != 0)
            {
                if (entropy.restarts_to_go == 0)
                {
                    entropy.restarts_to_go = cinfo.restart_interval;
                    entropy.next_restart_num++;
                    entropy.next_restart_num &= 7;
                }
                entropy.restarts_to_go--;
            }

            return(true);
        }