ref: 4cc11bea50d585804e93b985e7d7e8504990911b
parent: 1b6a01e666d0dbcd355c0b84fba43c1d02fb4b37
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Wed Jul 13 12:51:13 EDT 2005
Work-in-progress check in of huffman symbol dictionary support. git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@416 ded80894-8fb9-0310-811b-c03f3676ab4d
--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -84,6 +84,62 @@
return;
}
+/** Skip bits up to the next byte boundary
+ */
+void
+jbig2_huffman_skip(Jbig2HuffmanState *hs)
+{
+ int bits = hs->offset_bits & 7;
+
+ if (bits) hs->offset_bits += 8 - bits;
+
+ if (hs->offset_bits >= 32) {
+ Jbig2WordStream *ws = hs->ws;
+ hs->this_word = hs->next_word;
+ hs->offset += 4;
+ hs->next_word = ws->get_next_word (ws, hs->offset + 4);
+ hs->offset_bits -= 32;
+ }
+}
+
+/* skip ahead a specified number of bytes in the word stream
+ */
+void jbig2_huffman_advance(Jbig2HuffmanState *hs, int offset)
+{
+ Jbig2WordStream *ws = hs->ws;
+
+ hs->offset += offset;
+ hs->offset_bits = 0;
+ hs->this_word = ws->get_next_word (ws, hs->offset);
+ hs->next_word = ws->get_next_word (ws, hs->offset + 4);
+}
+
+/* return the offset of the huffman decode pointer (in bytes)
+ * from the beginning of the WordStream
+ */
+int
+jbig2_huffman_offset(Jbig2HuffmanState *hs)
+{
+ return hs->offset + (hs->offset_bits >> 4);
+}
+
+/* read a number of bits directly from the huffman state
+ * without decoding against a table
+ */
+int32_t
+jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits)
+{
+ uint32_t this_word = hs->this_word;
+ int32_t result;
+
+ result = this_word >> (32 - bits);
+ hs->this_word = (this_word << bits) |
+ (hs->next_word >> (32 - bits));
+ hs->offset_bits += bits;
+
+ return result;
+}
+
int32_t
jbig2_huffman_get (Jbig2HuffmanState *hs,
const Jbig2HuffmanTable *table, bool *oob)
--- a/jbig2_huffman.h
+++ b/jbig2_huffman.h
@@ -61,9 +61,20 @@
void
jbig2_huffman_free (Jbig2Ctx *ctx, Jbig2HuffmanState *hs);
+void
+jbig2_huffman_skip(Jbig2HuffmanState *hs);
+
+void jbig2_huffman_advance(Jbig2HuffmanState *hs, int offset);
+
+int
+jbig2_huffman_offset(Jbig2HuffmanState *hs);
+
int32_t
jbig2_huffman_get (Jbig2HuffmanState *hs,
const Jbig2HuffmanTable *table, bool *oob);
+
+int32_t
+jbig2_huffman_get_bits (Jbig2HuffmanState *hs, const int bits);
Jbig2HuffmanTable *
jbig2_build_huffman_table (Jbig2Ctx *ctx, const Jbig2HuffmanParams *params);
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -33,6 +33,7 @@
#include "jbig2_arith_iaid.h"
#include "jbig2_huffman.h"
#include "jbig2_generic.h"
+#include "jbig2_mmr.h"
#include "jbig2_symbol_dict.h"
#if defined(OUTPUT_PBM) || defined(DUMP_SYMDICT)
@@ -219,8 +220,10 @@
int32_t SYMWIDTH, TOTWIDTH;
uint32_t HCFIRSTSYM;
uint32_t *SDNEWSYMWIDTHS = NULL;
+ int SBSYMCODELEN = 0;
Jbig2WordStream *ws = NULL;
Jbig2HuffmanState *hs = NULL;
+ Jbig2HuffmanTable *SDHUFFRDX = NULL;
Jbig2ArithState *as = NULL;
Jbig2ArithIntCtx *IADH = NULL;
Jbig2ArithIntCtx *IADW = NULL;
@@ -245,7 +248,6 @@
IAAI = jbig2_arith_int_ctx_new(ctx);
if (params->SDREFAGG) {
int tmp = params->SDINSYMS->n_symbols + params->SDNUMNEWSYMS;
- int SBSYMCODELEN;
for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < tmp; SBSYMCODELEN++);
IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
IARDX = jbig2_arith_int_ctx_new(ctx);
@@ -255,6 +257,8 @@
jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
"huffman coded symbol dictionary");
hs = jbig2_huffman_new(ctx, ws);
+ SDHUFFRDX = jbig2_build_huffman_table(ctx,
+ &jbig2_huffman_params_O);
if (!params->SDREFAGG) {
SDNEWSYMWIDTHS = jbig2_alloc(ctx->allocator,
sizeof(*SDNEWSYMWIDTHS)*params->SDNUMNEWSYMS);
@@ -399,7 +403,9 @@
int ninsyms = params->SDINSYMS->n_symbols;
if (params->SDHUFF) {
- /* todo */
+ ID = jbig2_huffman_get_bits(hs, SBSYMCODELEN);
+ RDX = jbig2_huffman_get(hs, SDHUFFRDX, &code);
+ RDY = jbig2_huffman_get(hs, SDHUFFRDX, &code);
} else {
code = jbig2_arith_iaid_decode(IAID, as, (int32_t*)&ID);
code = jbig2_arith_int_decode(IARDX, as, &RDX);
@@ -406,7 +412,6 @@
code = jbig2_arith_int_decode(IARDY, as, &RDY);
}
-
if (ID >= ninsyms+NSYMSDECODED) {
code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
"refinement references unknown symbol %d", ID);
@@ -465,17 +470,46 @@
"%d of %d decoded", NSYMSDECODED, params->SDNUMNEWSYMS);
#endif
- /* 6.5.5 (4d) */
- if (params->SDHUFF && !params->SDREFAGG) {
- /* 6.5.9 */
- jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
- "unhandled collective bitmap");
- return NULL;
- }
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "at end of height class decode loop...");
+ } /* end height class decode loop */
+ jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+ "left height class decode loop");
+
+ /* 6.5.5 (4d) */
+ if (params->SDHUFF && !params->SDREFAGG) {
+ /* 6.5.9 */
+ Jbig2GenericRegionParams rparams;
+ Jbig2Image *image;
+ int BMSIZE = jbig2_huffman_get(hs, params->SDHUFFBMSIZE, &code);
+ if (code || (BMSIZE < 0)) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "error decoding size of collective bitmap!");
+ /* todo: memory cleanup */
+ return NULL;
}
- }
+ jbig2_huffman_skip(hs);
+ image = jbig2_image_new(ctx, TOTWIDTH, HCHEIGHT);
+ if (image == NULL) {
+ jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+ "could not allocate collective bitmap image!");
+ /* todo: memory cleanup */
+ return NULL;
+ }
+ /* todo: if BMSIZE == 0 bitmap is uncompressed */
+ 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);
+ 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_huffman_advance(hs, BMSIZE);
+ }
+ } /* end of symbol decode loop */
+
jbig2_free(ctx->allocator, GB_stats);
/* 6.5.10 */
@@ -524,6 +558,7 @@
if (params->SDREFAGG) {
jbig2_free(ctx->allocator, SDNEWSYMWIDTHS);
}
+ jbig2_release_huffman_table(ctx, SDHUFFRDX);
jbig2_free(ctx->allocator, hs);
}