ref: 0d128dbed01e775befd59050c415b5aa7f21562d
parent: 4cc11bea50d585804e93b985e7d7e8504990911b
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Wed Jul 27 04:29:56 EDT 2005
Work in progress commit of huffman support. This version is still buggy and includes some serious debug spew. git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@417 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -25,6 +25,7 @@
#include "os_types.h"
#include <stdlib.h>
+#include <stdio.h>
#include "jbig2.h"
#include "jbig2_priv.h"
@@ -84,6 +85,25 @@
return;
}
+/** debug routine */
+void jbig2_dump_huffman_state(Jbig2HuffmanState *hs)
+{
+ fprintf(stderr, "huffman state %08x %08x offset %d.%d\n",
+ hs->this_word, hs->next_word, hs->offset, hs->offset_bits);
+}
+
+/** debug routine */
+void jbig2_dump_huffman_binary(Jbig2HuffmanState *hs)
+{
+ const uint32_t word = hs->this_word;
+ int i;
+
+ fprintf(stderr, "huffman binary ");
+ for (i = 31; i >= 0; i--)
+ fprintf(stderr, ((word >> i) & 1) ? "1" : "0");
+ fprintf(stderr, "\n");
+}
+
/** Skip bits up to the next byte boundary
*/
void
@@ -91,7 +111,14 @@
{
int bits = hs->offset_bits & 7;
- if (bits) hs->offset_bits += 8 - bits;
+ if (bits) {
+ bits = 8 - bits;
+ hs->offset_bits += bits;
+ hs->this_word = (hs->this_word << bits) |
+ (hs->next_word >> (32 - hs->offset_bits));
+ printf("jbig2_huffman_skip() advancing %d bits (offset now %d)\n",
+ bits, hs->offset_bits);
+ }
if (hs->offset_bits >= 32) {
Jbig2WordStream *ws = hs->ws;
@@ -99,6 +126,10 @@
hs->offset += 4;
hs->next_word = ws->get_next_word (ws, hs->offset + 4);
hs->offset_bits -= 32;
+ if (hs->offset_bits) {
+ hs->this_word = (hs->this_word << hs->offset_bits) |
+ (hs->next_word >> (32 - hs->offset_bits));
+ }
}
}
@@ -108,10 +139,17 @@
{
Jbig2WordStream *ws = hs->ws;
- hs->offset += offset;
- hs->offset_bits = 0;
+ printf("jbig2_huffman_advance() advancing %d bytes\n", offset);
+ hs->offset += offset & ~3;
+ hs->offset_bits += (offset & 3) << 3;
+ if (hs->offset_bits >= 32) {
+ hs->offset += 4;
+ hs->offset_bits -= 32;
+ }
hs->this_word = ws->get_next_word (ws, hs->offset);
hs->next_word = ws->get_next_word (ws, hs->offset + 4);
+ hs->this_word = (hs->this_word << hs->offset_bits) |
+ (hs->next_word >> (32 - hs->offset_bits));
}
/* return the offset of the huffman decode pointer (in bytes)
@@ -120,7 +158,7 @@
int
jbig2_huffman_offset(Jbig2HuffmanState *hs)
{
- return hs->offset + (hs->offset_bits >> 4);
+ return hs->offset + (hs->offset_bits >> 3);
}
/* read a number of bits directly from the huffman state
@@ -161,6 +199,13 @@
flags = entry->flags;
PREFLEN = entry->PREFLEN;
+fprintf(stderr, "huffman reading prefix %x (entry %d len %d) flags %d\n",
+ (this_word >> (32 - PREFLEN)),
+ (this_word >> (32 - log_table_size)), PREFLEN, flags);
+
+fprintf(stderr, "huffman state %08x %08x before prefix read\n",
+ this_word, hs->next_word);
+
next_word = hs->next_word;
offset_bits += PREFLEN;
if (offset_bits >= 32)
@@ -173,8 +218,13 @@
hs->next_word = next_word;
PREFLEN = offset_bits;
}
+fprintf(stderr, "huffman state %08x %08x after prefix read\n",
+ this_word, next_word);
+if (PREFLEN)
this_word = (this_word << PREFLEN) |
(next_word >> (32 - offset_bits));
+fprintf(stderr, "huffman state %08x %08x after prefix update\n",
+ this_word, next_word);
if (flags & JBIG2_HUFFMAN_FLAGS_ISEXT)
{
table = entry->u.ext_table;
@@ -194,6 +244,9 @@
else
result += HTOFFSET;
+fprintf(stderr, "huffman reading range %x (%d bits)\n",
+ HTOFFSET, RANGELEN);
+
offset_bits += RANGELEN;
if (offset_bits >= 32)
{
@@ -205,6 +258,7 @@
hs->next_word = next_word;
RANGELEN = offset_bits;
}
+if (RANGELEN)
this_word = (this_word << RANGELEN) |
(next_word >> (32 - offset_bits));
}
@@ -214,6 +268,9 @@
if (oob != NULL)
*oob = (flags & JBIG2_HUFFMAN_FLAGS_ISOOB);
+
+fprintf(stderr, "huffman value is %d%s\n", result,
+ (flags & JBIG2_HUFFMAN_FLAGS_ISOOB) ? " (oob)" : "");
return result;
}
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -278,7 +278,9 @@
/* 6.5.6 */
if (params->SDHUFF) {
+ jbig2_dump_huffman_state(hs);
HCDH = jbig2_huffman_get(hs, params->SDHUFFDH, &code);
+ jbig2_dump_huffman_state(hs);
} else {
code = jbig2_arith_int_decode(IADH, as, &HCDH);
}
@@ -318,7 +320,11 @@
}
/* 6.5.7 */
if (params->SDHUFF) {
+ jbig2_dump_huffman_state(hs);
+ jbig2_dump_huffman_binary(hs);
DW = jbig2_huffman_get(hs, params->SDHUFFDW, &code);
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "decoded symbol delta width %d", DW);
} else {
code = jbig2_arith_int_decode(IADW, as, &DW);
}
@@ -403,9 +409,13 @@
int ninsyms = params->SDINSYMS->n_symbols;
if (params->SDHUFF) {
+ jbig2_dump_huffman_state(hs);
ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN);
+ jbig2_dump_huffman_state(hs);
RDX = jbig2_huffman_get(hs, SDHUFFRDX, &code);
+ jbig2_dump_huffman_state(hs);
RDY = jbig2_huffman_get(hs, SDHUFFRDX, &code);
+ jbig2_dump_huffman_state(hs);
} else {
code = jbig2_arith_iaid_decode(IAID, as, (int32_t*)&ID);
code = jbig2_arith_int_decode(IARDX, as, &RDX);
@@ -489,7 +499,9 @@
/* todo: memory cleanup */
return NULL;
}
+ jbig2_dump_huffman_state(hs);
jbig2_huffman_skip(hs);
+ jbig2_dump_huffman_state(hs);
image = jbig2_image_new(ctx, TOTWIDTH, HCHEIGHT);
if (image == NULL) {
jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
@@ -498,14 +510,23 @@
return NULL;
}
/* todo: if BMSIZE == 0 bitmap is uncompressed */
+ if (BMSIZE == 0) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "uncompressed collective bitmap NYI!");
+ return NULL;
+ }
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
- "reading %dx%d collective bitmap for %d symbols (%d bytes)",
- image->width, image->height, NSYMSDECODED - HCFIRSTSYM, BMSIZE);
+ "reading %dx%d collective bitmap for %d symbols"
+ " (%d bytes at data offset %d)",
+ image->width, image->height, NSYMSDECODED - HCFIRSTSYM,
+ BMSIZE, jbig2_huffman_offset(hs));
rparams.MMR = 1;
code = jbig2_decode_generic_mmr(ctx, segment, &rparams,
data + jbig2_huffman_offset(hs), BMSIZE, image);
jbig2_image_write_pbm_file(image, "collective.pbm");
+ jbig2_dump_huffman_state(hs);
jbig2_huffman_advance(hs, BMSIZE);
+ jbig2_dump_huffman_state(hs);
}
} /* end of symbol decode loop */