shithub: jbig2

Download patch

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);
   }