shithub: jbig2

Download patch

ref: d23b5e5b4d8fabdf51d202094ac4259d59dcc974
parent: d2d97abc0be98770dc506620f5f8921900e55e5e
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Thu Aug 25 04:14:21 EDT 2005

Work-in-progress commit of huffman text region support. Fix a number
of bugs in jbig2_huffman_get_bits() and implement symbol id huffman
table decode (a custom table is always included inline in the text
region segment header.)

However, the constructed table gives an out-of-bounds symbol id on
the first read with the UBC test file.


git-svn-id: http://svn.ghostscript.com/jbig2dec/trunk@432 ded80894-8fb9-0310-811b-c03f3676ab4d

--- a/jbig2_huffman.c
+++ b/jbig2_huffman.c
@@ -90,6 +90,7 @@
 
 /** debug routines **/
 #ifdef JBIG2_DEBUG
+#include <stdio.h>
 /** print current huffman state */
 void jbig2_dump_huffman_state(Jbig2HuffmanState *hs)
 {
@@ -175,9 +176,18 @@
   int32_t result;
 	
   result = this_word >> (32 - bits);
-  hs->this_word = (this_word << bits) |
-	(hs->next_word >> (32 - bits));
   hs->offset_bits += bits;
+  if (hs->offset_bits >= 32) {
+    hs->offset += 4;
+    hs->offset_bits -= 32;
+    hs->this_word = hs->next_word;
+    hs->next_word = hs->ws->get_next_word(hs->ws, hs->offset + 4);
+    hs->this_word = (hs->this_word << hs->offset_bits) |
+	(hs->next_word >> (32 - hs->offset_bits));
+  } else {
+    hs->this_word = (this_word << bits) |
+	(hs->next_word >> (32 - hs->offset_bits));
+  }
 
   return result;
 }
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -157,7 +157,7 @@
 	Jbig2HuffmanLine runcodelengths[35];
 	Jbig2HuffmanLine *symcodelengths;
 	Jbig2HuffmanParams symcodeparams;
-	int code, err, range, r;
+	int code, err, len, range, r;
 
 	jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
 	  "huffman coded text region");
@@ -173,7 +173,7 @@
 	  runcodelengths[index].RANGELEN = 0;
 	  runcodelengths[index].RANGELOW = index;
 	  jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
-	    "  read runcode%d length %d", index, runcodelengths[index]);
+	    "  read runcode%d length %d", index, runcodelengths[index].PREFLEN);
 	}
 	runcodeparams.HTOOB = 0;
 	runcodeparams.lines = runcodelengths;
@@ -193,20 +193,34 @@
 	    "memory allocation failure reading symbol ID huffman table!");
 	  return -1;
 	}
-	for (index = 0; index < SBNUMSYMS; index++) {
+	index = 0;
+	while (index < SBNUMSYMS) {
 	  code = jbig2_huffman_get(hs, runcodes, &err);
 	  if (err != 0 || code < 0 || code >= 35) {
 	    jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
 	      "error reading symbol ID huffman table!");
-	    return err;
+	    return err ? err : -1;
 	  }
 
-	  if (code < 32) range = 0;
-	  else if (code == 32) range = jbig2_huffman_get_bits(hs, 2);
-	  else if (code == 34) range = jbig2_huffman_get_bits(hs, 3);
-	  else if (code == 35) range = jbig2_huffman_get_bits(hs, 7);
-	  for (r = 0; r < range + 1; r++) {
-	    symcodelengths[index+r].PREFLEN = code; 
+	  if (code < 32) {
+	    len = code;
+	    range = 1;
+	  } else {
+	    if (index < 1) {
+	      jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+		"error decoding symbol id table: run length with no antecedent!");
+	      /* todo: memory cleanup */
+	      return -1;
+	    }
+	    len = symcodelengths[index-1].PREFLEN;
+	    if (code == 32) range = jbig2_huffman_get_bits(hs, 2) + 3;
+	    else if (code == 33) range = jbig2_huffman_get_bits(hs, 3) + 3;
+	    else if (code == 34) range = jbig2_huffman_get_bits(hs, 7) + 11;
+	  }
+	  jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+	    "  read runcode%d at index %d (length %d range %d)", code, index, len, range);
+	  for (r = 0; r < range; r++) {
+	    symcodelengths[index+r].PREFLEN = len; 
 	    symcodelengths[index+r].RANGELEN = 0; 
 	    symcodelengths[index+r].RANGELOW = index;
 	  }