From 04bc131f680c2640ac1ac06b8ad36a6f22f0e183 Mon Sep 17 00:00:00 2001 From: Oliver Schinagl Date: Wed, 18 May 2005 23:05:24 +0000 Subject: fixed compiler errors. ToDo: Fix warning. --- src/c_huffman.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 119 insertions(+), 1 deletion(-) diff --git a/src/c_huffman.c b/src/c_huffman.c index 22dda6e..fceed82 100644 --- a/src/c_huffman.c +++ b/src/c_huffman.c @@ -20,6 +20,7 @@ typedef struct { int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ } savable_state; +#define ASSIGN_STATE(dest,src) ((dest) = (src)) typedef struct { struct jpeg_entropy_encoder pub; /* public fields */ @@ -55,6 +56,10 @@ typedef struct { } working_state; +/* Forward declarations */ +static boolean encode_mcu_huff JPP((j_compress_ptr cinfo, JBLOCKROW *MCU_data)); +static void finish_pass_huff JPP((j_compress_ptr cinfo)); + /* Outputting bytes to the file */ /* Emit a byte, taking 'action' if must suspend. */ @@ -128,7 +133,7 @@ inline static boolean emit_bits(working_state * state, unsigned int code, int si * Initialize for a Huffman-compressed scan. */ -void start_pass_huff (j_compress_ptr cinfo) { +static void start_pass_huff (j_compress_ptr cinfo) { huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; entropy->pub.encode_mcu = encode_mcu_huff; @@ -143,6 +148,14 @@ void start_pass_huff (j_compress_ptr cinfo) { entropy->next_restart_num = 0; } +static boolean flush_bits (working_state * state) { + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_derived_tbl *dctbl, c_derived_tbl *actbl) { register int temp, temp2; @@ -249,6 +262,111 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de } /* + * Emit a restart marker & resynchronize predictions. + */ + +static boolean emit_restart (working_state * state, int restart_num) { + int ci; + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) + state->cur.last_dc_val[ci] = 0; + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one MCU's worth of Huffman-compressed coefficients. + */ + +static boolean encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + int blkn, ci; + jpeg_component_info * compptr; + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return FALSE; + } + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + if (! encode_one_block(&state, + MCU_data[blkn][0], 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][0]; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + 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; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +static void finish_pass_huff (j_compress_ptr cinfo) { + huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + perror("Suspension not allowed here"); + exit(0); + /* ERREXIT(cinfo, JERR_CANT_SUSPEND); */ + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* * Module initialization routine for Huffman entropy encoding. */ -- cgit v0.12