shithub: jbig2

Download patch

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 */