summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Schinagl <oliver@schinagl.nl>2005-06-05 16:10:43 (GMT)
committerOliver Schinagl <oliver@schinagl.nl>2005-06-05 16:10:43 (GMT)
commit5e03cffd5f9e981a57ae55e1a85d85ecbfdb63c0 (patch)
tree267d964b651bdf4e74bcc88425b5a1aafa2dd4d5
parentb0e9256777b20e03ded05824c38b7c3c1343e00a (diff)
download5kk53-5e03cffd5f9e981a57ae55e1a85d85ecbfdb63c0.zip
5kk53-5e03cffd5f9e981a57ae55e1a85d85ecbfdb63c0.tar.gz
5kk53-5e03cffd5f9e981a57ae55e1a85d85ecbfdb63c0.tar.bz2
-rw-r--r--src/c_huffman.c707
1 files changed, 542 insertions, 165 deletions
diff --git a/src/c_huffman.c b/src/c_huffman.c
index fceed82..ec2943c 100644
--- a/src/c_huffman.c
+++ b/src/c_huffman.c
@@ -1,86 +1,301 @@
#include <stdlib.h>
#include <stdio.h>
-#include "config.h"
#include "morecfg.h"
-
#include "jpeglib.h"
-#include "jpegint.h"
#include "c_huffman.h"
+#include <string.h>
+#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
+#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
+
+
+/*
+ * In ANSI C, and indeed any rational implementation, size_t is also the
+ * type returned by sizeof(). However, it seems there are some irrational
+ * implementations out there, in which sizeof() returns an int even though
+ * size_t is defined as long or unsigned long. To ensure consistent results
+ * we always use this SIZEOF() macro in place of using sizeof() directly.
+ */
+
+#define SIZEOF(object) ((size_t) sizeof(object))
+
+void ERRORREPORT(void)
+{
+ printf("Error");
+}
+
/* Expanded entropy encoder object for Huffman encoding.
*
* The savable_state subrecord contains fields that change within an MCU,
* but must not be updated permanently until we complete the MCU.
*/
typedef struct {
- INT32 put_buffer; /* current bit-accumulation buffer */
- int put_bits; /* # of bits now in it */
- int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+ INT32 put_buffer; /* current bit-accumulation buffer */
+ int put_bits; /* # of bits now in it */
+ 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 */
+ //struct jpeg_entropy_encoder pub; // public fields
- savable_state saved; /* Bit buffer & DC state at start of MCU */
+ savable_state saved; // Bit buffer & DC state at start of MCU
- /* These fields are NOT loaded into local working state. */
- unsigned int restarts_to_go; /* MCUs left in this restart interval */
- int next_restart_num; /* next restart number to write (0-7) */
+ // These fields are NOT loaded into local working state.
+ unsigned int restarts_to_go; // MCUs left in this restart interval
+ int next_restart_num; // next restart number to write (0-7)
- /* Pointers to derived tables (these workspaces have image lifespan) */
- c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
- c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+ // Pointers to derived tables (these workspaces have image lifespan)
+ c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+ c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
-#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
- long * dc_count_ptrs[NUM_HUFF_TBLS];
- long * ac_count_ptrs[NUM_HUFF_TBLS];
-#endif
} huff_entropy_encoder;
typedef huff_entropy_encoder * huff_entropy_ptr;
-
+*/
/* Working state while writing an MCU.
* This struct contains all the fields that are needed by subroutines.
*/
typedef struct {
- JOCTET * next_output_byte; /* => next byte to write in buffer */
- size_t free_in_buffer; /* # of byte spaces remaining in buffer */
- savable_state cur; /* Current bit buffer & DC state */
- j_compress_ptr cinfo; /* dump_buffer needs access to this */
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+ savable_state cur; /* Current bit buffer & DC state */
+ // j_compress_ptr cinfo; /* dump_buffer needs access to this */
} 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));
+// ///////////////////////////////////////////
+// Huffman Tables allocated here
+//
+// //////////////////////////////////////////
+
+JHUFF_TBL dc_Huffman_Table[2];
+JHUFF_TBL ac_Huffman_Table[2];
+
+c_derived_tbl dc_derived_table;
+c_derived_tbl ac_derived_table;
+
+/*
+ * Huffman table setup routines
+ */
+
+ LOCAL(void)
+add_huff_table (JHUFF_TBL *htblptr, const UINT8 *bits, const UINT8 *val)
+ /* Define a Huffman table */
+{
+ int nsymbols, len;
+
+ /* Copy the number-of-symbols-of-each-code-length counts */
+ MEMCOPY((htblptr)->bits, bits, SIZEOF((htblptr)->bits));
+
+ /* Validate the counts. We do this here mainly so we can copy the right
+ * number of symbols from the val[] array, without risking marching off
+ * the end of memory. jchuff.c will do a more thorough test later.
+ */
+ nsymbols = 0;
+ for (len = 1; len <= 16; len++)
+ nsymbols += bits[len];
+ if (nsymbols < 1 || nsymbols > 256)
+ {
+ perror("Bad Huffman code table entry");
+ exit(0);
+ }
+ //ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+ MEMCOPY((htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
+
+ /* Initialize sent_table FALSE so table will be written to JPEG file. */
+ (htblptr)->sent_table = FALSE;
+}
+
+
+ LOCAL(void)
+std_huff_tables ()
+ /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
+ /* IMPORTANT: these are only valid for 8-bit data precision! */
+{
+ static const UINT8 bits_dc_luminance[17] =
+ { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+ static const UINT8 val_dc_luminance[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ static const UINT8 bits_dc_chrominance[17] =
+ { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+ static const UINT8 val_dc_chrominance[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ static const UINT8 bits_ac_luminance[17] =
+ { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+ static const UINT8 val_ac_luminance[] =
+ { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa };
+
+ static const UINT8 bits_ac_chrominance[17] =
+ { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+ static const UINT8 val_ac_chrominance[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa };
+
+ add_huff_table(&dc_Huffman_Table[0], bits_dc_luminance, val_dc_luminance);
+ add_huff_table(&ac_Huffman_Table[0], bits_ac_luminance, val_ac_luminance);
+ add_huff_table(&dc_Huffman_Table[1], bits_dc_chrominance, val_dc_chrominance);
+ add_huff_table(&dc_Huffman_Table[1], bits_ac_chrominance, val_ac_chrominance);
+}
+
+
+ GLOBAL(void)
+jpeg_make_c_derived_tbl (JHUFF_TBL *htbl, boolean isDC,
+ c_derived_tbl * pdtbl)
+{
+ c_derived_tbl *dtbl;
+ int p, i, l, lastp, si, maxsymbol;
+ char huffsize[257];
+ unsigned int huffcode[257];
+ unsigned int code;
+
+ /* Note that huffsize[] and huffcode[] are filled in code-length order,
+ * paralleling the order of the symbols themselves in htbl->huffval[].
+ */
+
+ if (htbl == NULL)
+ ERRORREPORT();
+
+
+ dtbl = pdtbl;
+
+ // Figure C.1: make table of Huffman code length for each symbol
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ i = (int) htbl->bits[l];
+ if (i < 0 || p + i > 256) /* protect against table overrun */
+ ERRORREPORT();
+ while (i--)
+ huffsize[p++] = (char) l;
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ // Figure C.2: generate the codes themselves
+ // We also validate that the counts represent a legal Huffman code tree.
+ //
+ //
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int) huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ /* code is now 1 more than the last code used for codelength si; but
+ * it must still fit in si bits, since no code is allowed to be all ones.
+ */
+ if (((INT32) code) >= (((INT32) 1) << si))
+ ERRORREPORT();
+ code <<= 1;
+ si++;
+ }
+
+ /* Figure C.3: generate encoding tables */
+ /* These are code and size indexed by symbol value */
+
+ /* Set all codeless symbols to have code length 0;
+ * this lets us detect duplicate VAL entries here, and later
+ * allows emit_bits to detect any attempt to emit such symbols.
+ */
+ MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
+
+ /* This is also a convenient place to check for out-of-range
+ * and duplicated VAL entries. We allow 0..255 for AC symbols
+ * but only 0..15 for DC. (We could constrain them further
+ * based on data depth and mode, but this seems enough.)
+ */
+ maxsymbol = isDC ? 15 : 255;
+
+ for (p = 0; p < lastp; p++) {
+ i = htbl->huffval[p];
+ if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
+ ERRORREPORT();
+ dtbl->ehufco[i] = huffcode[p];
+ dtbl->ehufsi[i] = huffsize[p];
+ }
+}
+
+
+
/* Outputting bytes to the file */
/* Emit a byte, taking 'action' if must suspend. */
#define emit_byte(state,val,action) \
- { *(state)->next_output_byte++ = (JOCTET) (val); \
- if (--(state)->free_in_buffer == 0) \
- if (! dump_buffer(state)) \
- { action; } }
+{ *(state)->next_output_byte++ = (JOCTET) (val); \
+ if (--(state)->free_in_buffer == 0) \
+ if (! dump_buffer(state)) \
+ { action; } }
/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
static boolean dump_buffer(working_state * state) {
- struct jpeg_destination_mgr * dest = state->cinfo->dest;
-
- if (! (*dest->empty_output_buffer) (state->cinfo)) {
- return FALSE;
- }
- /* After a successful buffer dump, must reset buffer pointers */
+ // TODO
+ //
+ /*
+ struct jpeg_destination_mgr * dest = state->cinfo->dest;
+
+ if (! (*dest->empty_output_buffer) (state->cinfo)) {
+ return FALSE;
+ }
+ // After a successful buffer dump, must reset buffer pointers
state->next_output_byte = dest->next_output_byte;
state->free_in_buffer = dest->free_in_buffer;
return TRUE;
+
+*/
+ return TRUE;
}
@@ -106,16 +321,16 @@ inline static boolean emit_bits(working_state * state, unsigned int code, int si
}
put_buffer &= (((INT32) 1)<<size) - 1; /* mask off any extra bits in code */
-
+
put_bits += size; /* new number of bits in buffer */
-
+
put_buffer <<= 24 - put_bits; /* align incoming bits */
put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
-
+
while (put_bits >= 8) {
int c = (int) ((put_buffer >> 16) & 0xFF);
- emit_byte(state, c, return FALSE);
+ emit_byte(state, c, return FALSE);
if (c == 0xFF) { /* need to stuff a zero byte? */
emit_byte(state, 0, return FALSE);
}
@@ -132,29 +347,60 @@ inline static boolean emit_bits(working_state * state, unsigned int code, int si
/*
* Initialize for a Huffman-compressed scan.
*/
+/*
+ static void start_pass_huff (j_compress_ptr cinfo) {
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
-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;
- entropy->pub.finish_pass = finish_pass_huff;
+//entropy->pub.encode_mcu = encode_mcu_huff;
+//entropy->pub.finish_pass = finish_pass_huff;
- /* Initialize bit buffer to empty */
- entropy->saved.put_buffer = 0;
- entropy->saved.put_bits = 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;
+// Initialize restart stuff
+entropy->restarts_to_go = cinfo->restart_interval;
+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;
-}
+ 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;
+ }
+
+
+/*
+ * jpeg_natural_order[i] is the natural-order position of the i'th element
+ * of zigzag order.
+ *
+ * When reading corrupted data, the Huffman decoders could attempt
+ * to reference an entry beyond the end of this array (if the decoded
+ * zero run length reaches past the end of the block). To prevent
+ * wild stores without adding an inner-loop test, we put some extra
+ * "63"s after the real entries. This will cause the extra coefficient
+ * to be stored in location 63 of the block, not somewhere random.
+ * The worst case would be a run-length of 15, which means we need 16
+ * fake entries.
+ */
+
+const int jpeg_natural_order[DCTSIZE2+16] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
+ 63, 63, 63, 63, 63, 63, 63, 63
+};
+
+int bitCounter;
int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_derived_tbl *dctbl, c_derived_tbl *actbl) {
@@ -162,17 +408,18 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de
register int nbits;
register int k, r, i;
+ bitCounter = 0; // TODEBUG
/* Encode the DC coefficient difference per section F.1.2.1 */
temp = temp2 = block[0] - last_dc_val;
- if (temp < 0) {
+ if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* For a negative input, want temp2 = bitwise complement of abs(input) */
/* This code assumes we are on a two's complement machine */
temp2--;
}
-
+
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 0;
while (temp) {
@@ -187,11 +434,12 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de
exit(0);
/* ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); */
}
-
+
/* Emit the Huffman-coded symbol for the number of bits */
if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) {
return FALSE;
}
+ bitCounter += dctbl->ehufsi[nbits]; // TODEBUG
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
@@ -199,12 +447,13 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de
if (! emit_bits(state, (unsigned int) temp2, nbits)) {
return FALSE;
}
+ bitCounter += nbits; // TODEBUG
}
/* Encode the AC coefficients per section F.1.2.2 */
-
+
r = 0; /* r = run length of zeros */
-
+
for (k = 1; k < DCTSIZE2; k++) {
if ((temp = block[jpeg_natural_order[k]]) == 0) {
r++;
@@ -215,15 +464,16 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de
return FALSE;
}
r -= 16;
+ bitCounter += actbl->ehufsi[0xF0]; // TODEBUG
}
-
+
temp2 = temp;
if (temp < 0) {
temp = -temp; /* temp is abs value of input */
/* This code assumes we are on a two's complement machine */
temp2--;
}
-
+
/* Find the number of bits needed for the magnitude of the coefficient */
nbits = 1; /* there must be at least one 1 bit */
while ((temp >>= 1)) {
@@ -235,19 +485,20 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de
exit(0);
/* ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); */
}
-
+
/* Emit Huffman symbol for run length / number of bits */
i = (r << 4) + nbits;
if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) {
return FALSE;
}
+ bitCounter += actbl->ehufsi[i]; // TODEBUG
/* Emit that number of bits of the value, if positive, */
/* or the complement of its magnitude, if negative. */
if (! emit_bits(state, (unsigned int) temp2, nbits)) {
return FALSE;
}
-
+ bitCounter += nbits; // TODEBUG
r = 0;
}
}
@@ -255,135 +506,261 @@ int encode_one_block(working_state *state, JCOEFPTR block, int last_dc_val, c_de
/* If the last coef(s) were zero, emit an end-of-block code */
if (r > 0) {
if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) {
- return FALSE;
+ return FALSE;
}
+ printf("END");
}
+ printf("\n Bitcounter = %d (%d)",bitCounter,bitCounter/8);
return TRUE;
}
/*
* Emit a restart marker & resynchronize predictions.
*/
+/*
+ static boolean emit_restart (working_state * state, int restart_num) {
+ int ci;
-static boolean emit_restart (working_state * state, int restart_num) {
- int ci;
-
- if (! flush_bits(state))
- return FALSE;
+ if (! flush_bits(state))
+ return FALSE;
- emit_byte(state, 0xFF, return FALSE);
- emit_byte(state, JPEG_RST0 + restart_num, 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;
+// 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. */
+// The restart counter is not updated until we successfully write the MCU.
- return TRUE;
+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;
+}
-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;
+// 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);
+}
+*/
+
+
-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);
+//int dataToCode[64];
+
+static int lastDCValue;
+static working_state savedHuffstate;
+unsigned char outputBufferHuffman[500];
+
+void encode_huffBlock64_init(void)
+{
+ std_huff_tables();
+ /* 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(dc_Huffman_Table, TRUE,
+ &dc_derived_table);
+ jpeg_make_c_derived_tbl(ac_Huffman_Table, FALSE,
+ &ac_derived_table);
+}
+
+
+void encode_huffBlock64_start(void)
+{
+ lastDCValue = 0;
+ // Initialise buffer
+ savedHuffstate.next_output_byte = outputBufferHuffman;
+ savedHuffstate.free_in_buffer = 500; // TODO:
+ // savedHuffstate.cinfo = NULL;
}
+void encode_huffBlock64(short * data)
+{
+ working_state state;
+
+ // Load up working state ... flush_bits needs it
+ state.next_output_byte = savedHuffstate.next_output_byte;
+ state.free_in_buffer = savedHuffstate.free_in_buffer;
+ ASSIGN_STATE(state.cur, savedHuffstate.cur);
+
+ encode_one_block(&state, data, savedHuffstate.cur.last_dc_val[0], &dc_derived_table, &ac_derived_table);
+
+ // Update last_dc_val
+ savedHuffstate.cur.last_dc_val[0] = data[0]; // Different for YUV TODO if all colours used
+
+ // Completed MCU, so update state
+ savedHuffstate.next_output_byte = state.next_output_byte;
+ savedHuffstate.free_in_buffer = state.free_in_buffer;
+ ASSIGN_STATE(savedHuffstate.cur, state.cur);
+
+
+
+}
+void encode_huffBlock64_end(void )
+{
+ working_state state;
+
+ // Load up working state ... flush_bits needs it
+ savedHuffstate.next_output_byte = state.next_output_byte;
+ savedHuffstate.free_in_buffer = state.free_in_buffer ;
+ ASSIGN_STATE(savedHuffstate.cur, state.cur);
+
+ if (! flush_bits(&state))
+ {
+ perror("Suspension not allowed here");
+ exit(0);
+ }
+}
/*
- * Module initialization routine for Huffman entropy encoding.
- */
+ typedef struct {
+ unsigned int ehufco[256]; // code for each symbol
+ char ehufsi[256]; // length of code for each symbol
+// If no code has been allocated for a symbol S, ehufsi[S] contains 0
+} c_derived_tbl;
+*/
+void dump_Table(void)
+{
+ int i,j;
+ printf("\n DC Derived Table Code\n\n ");
+ for (i=0; i < 32; i++)
+ {
+ for(j=0;j < 8; j++)
+ {
+ printf("%4x\t",dc_derived_table.ehufco[ ((i * 8) + j)]);
+ }
+ printf("\n");
+ }
+ printf("\n DC Derived Table Symbol\n\n ");
+ for (i=0; i < 32; i++)
+ {
+ for(j=0;j < 8; j++)
+ {
+ printf("%d\t",dc_derived_table.ehufsi[ ((i * 8) + j)]);
+ }
+ printf("\n");
+ }
+ printf("\n AC Derived Table Code\n\n");
+ for (i=0; i < 32; i++)
+ {
+ for(j=0;j < 8; j++)
+ {
+ printf("%4x\t",ac_derived_table.ehufco[ ((i * 8) + j)]);
+ }
+ printf("\n");
+ }
+ printf("\n AC Derived Table Symbol\n\n ");
+ for (i=0; i < 32; i++)
+ {
+ for(j=0;j < 8; j++)
+ {
+ printf("%d\t",ac_derived_table.ehufsi[ ((i * 8) + j)]);
+ }
+ printf("\n");
+ }
-void jinit_huff_encoder(j_compress_ptr cinfo) {
- huff_entropy_ptr entropy;
- int i;
+}
- entropy = (huff_entropy_ptr) malloc((size_t) sizeof(huff_entropy_encoder));
+void dump_Encoded(void)
+{
+ int i,j;
+ printf("\n Huffman coded\n\n ");
+ for (i=0; i < 50; i++)
+ {
+ for(j=0;j < 10; j++)
+ {
+ printf("%4x\t",outputBufferHuffman[ ((i * 10) + j)]);
+ }
+ printf("\n");
+ }
+}
+
+void Test_dhuffman(short * data)
+{
- cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
- entropy->pub.start_pass = start_pass_huff;
+ // dump_Encoded();
+
+ encode_huffBlock64_init();
+
+ dump_Table();
+ encode_huffBlock64_start();
+ encode_huffBlock64(data);
+ encode_huffBlock64_end();
+ dump_Encoded();
- /* Mark tables unallocated */
- for (i = 0; i < NUM_HUFF_TBLS; i++) {
- entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
-#ifdef ENTROPY_OPT_SUPPORTED
- entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
-#endif
- }
}
+