summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Schinagl <oliver@schinagl.nl>2005-05-18 23:05:24 (GMT)
committerOliver Schinagl <oliver@schinagl.nl>2005-05-18 23:05:24 (GMT)
commit04bc131f680c2640ac1ac06b8ad36a6f22f0e183 (patch)
treebb8cccd7ec8efe17274f6325e05d5d57216506f0
parentd9acf5e1a02108d6231be74ef42fc2071688cb70 (diff)
download5kk53-04bc131f680c2640ac1ac06b8ad36a6f22f0e183.zip
5kk53-04bc131f680c2640ac1ac06b8ad36a6f22f0e183.tar.gz
5kk53-04bc131f680c2640ac1ac06b8ad36a6f22f0e183.tar.bz2
fixed compiler errors. ToDo: Fix warning.
-rw-r--r--src/c_huffman.c120
1 files changed, 119 insertions, 1 deletions
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.
*/