rev 434 - trunk

[email protected] Mon, 5 Dec 2005 16:02:26 -0800 (PST)
Newsgroups gmane.comp.printing.ghostscript.jbig2dec.cvs
Message-ID <[email protected]>
Author: giles
Date: 2005-08-29 19:05:05 -0700 (Mon, 29 Aug 2005)
New Revision: 434

Modified:
   trunk/jbig2_huffman.c
   trunk/jbig2_text.c
Log:
Fix some small bugs and add additional error checking to the
huffman decoding support.


Modified: trunk/jbig2_huffman.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/jbig2_huffman.c	2005-08-28 00:10:20 UTC (rev 433)
+++ trunk/jbig2_huffman.c	2005-08-30 02:05:05 UTC (rev 434)
@@ -90,10 +90,9 @@
=20
 /** debug routines **/
 #ifdef JBIG2_DEBUG
-#include <stdio.h>
+
 /** print current huffman state */
-void jbig2_dump_huffman_state(Jbig2HuffmanState *hs)
-{
+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);=20
 }
@@ -109,6 +108,7 @@
     fprintf(stderr, ((word >> i) & 1) ? "1" : "0");
   fprintf(stderr, "\n");
 }
+
 #endif /* JBIG2_DEBUG */
=20
 /** Skip bits up to the next byte boundary
@@ -174,7 +174,7 @@
 {
   uint32_t this_word =3D hs->this_word;
   int32_t result;
-=09
+
   result =3D this_word >> (32 - bits);
   hs->offset_bits +=3D bits;
   if (hs->offset_bits >=3D 32) {
@@ -182,8 +182,12 @@
     hs->offset_bits -=3D 32;
     hs->this_word =3D hs->next_word;
     hs->next_word =3D hs->ws->get_next_word(hs->ws, hs->offset + 4);
-    hs->this_word =3D (hs->this_word << hs->offset_bits) |
+    if (hs->offset_bits) {
+      hs->this_word =3D (hs->this_word << hs->offset_bits) |
 	(hs->next_word >> (32 - hs->offset_bits));
+    } else {
+      hs->this_word =3D (hs->this_word << hs->offset_bits);
+    }
   } else {
     hs->this_word =3D (this_word << bits) |
 	(hs->next_word >> (32 - hs->offset_bits));
@@ -225,9 +229,9 @@
 	  hs->next_word =3D next_word;
 	  PREFLEN =3D offset_bits;
 	}
-if (PREFLEN)
-      this_word =3D (this_word << PREFLEN) |
-	(next_word >> (32 - offset_bits));
+      if (PREFLEN)
+	this_word =3D (this_word << PREFLEN) |
+	  (next_word >> (32 - offset_bits));
       if (flags & JBIG2_HUFFMAN_FLAGS_ISEXT)
 	{
 	  table =3D entry->u.ext_table;
@@ -272,10 +276,10 @@
   return result;
 }
=20
-/* TODO: 10 bits here is wasteful of memory. We have support for=20
-   sub-trees in jbig2_huffman_get() above, but don't use it here.
+/* TODO: more than 8 bits here is wasteful of memory. We have support=20
+   for sub-trees in jbig2_huffman_get() above, but don't use it here.
    We should, and then revert to 8 bits */
-#define LOG_TABLE_SIZE_MAX 10
+#define LOG_TABLE_SIZE_MAX 16
=20
 /** Build an in-memory representation of a Huffman table from the
  *  set of template params provided by the spec or a table segment
@@ -288,6 +292,7 @@
   const Jbig2HuffmanLine *lines =3D params->lines;
   int n_lines =3D params->n_lines;
   int i, j;
+  int max_j;
   int log_table_size =3D 0;
   Jbig2HuffmanTable *result;
   Jbig2HuffmanEntry *entries;
@@ -316,9 +321,13 @@
       if (lts <=3D LOG_TABLE_SIZE_MAX && log_table_size < lts)
 		log_table_size =3D lts;
     }
+  jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, -1,
+	"constructing huffman table log size %d", log_table_size);
+  max_j =3D 1 << log_table_size;
+
   result =3D (Jbig2HuffmanTable *)jbig2_alloc(ctx->allocator, sizeof(Jbi=
g2HuffmanTable));
   result->log_table_size =3D log_table_size;
-  entries =3D (Jbig2HuffmanEntry *)jbig2_alloc(ctx->allocator, sizeof(Jb=
ig2HuffmanEntry) << log_table_size);
+  entries =3D (Jbig2HuffmanEntry *)jbig2_alloc(ctx->allocator, max_j * s=
izeof(Jbig2HuffmanEntry));
   result->entries =3D entries;
=20
   LENCOUNT[0] =3D 0;
@@ -341,25 +350,28 @@
 	      int end_j =3D (CURCODE + 1) << shift;
 	      byte eflags =3D 0;
=20
+	      if (end_j > max_j) {
+		jbig2_error(ctx, JBIG2_SEVERITY_FATAL, -1,
+		  "ran off the end of the entries table! (%d >=3D %d)",
+		  end_j, max_j);
+		jbig2_free(ctx->allocator, result->entries);
+		jbig2_free(ctx->allocator, result);
+		return NULL;
+	      }
 	      /* todo: build extension tables */
 	      if (params->HTOOB && CURTEMP =3D=3D n_lines - 1)
 		eflags |=3D JBIG2_HUFFMAN_FLAGS_ISOOB;
 	      if (CURTEMP =3D=3D n_lines - (params->HTOOB ? 3 : 2))
 		eflags |=3D JBIG2_HUFFMAN_FLAGS_ISLOW;
-	      if (PREFLEN + RANGELEN > LOG_TABLE_SIZE_MAX)
-		{
-		  for (j =3D start_j; j < end_j; j++)
-		    {
+	      if (PREFLEN + RANGELEN > LOG_TABLE_SIZE_MAX) {
+		  for (j =3D start_j; j < end_j; j++) {
 		      entries[j].u.RANGELOW =3D lines[CURTEMP].RANGELOW;
 		      entries[j].PREFLEN =3D PREFLEN;
 		      entries[j].RANGELEN =3D RANGELEN;
 		      entries[j].flags =3D eflags;
 		    }
-		}
-	      else
-		{
-		  for (j =3D start_j; j < end_j; j++)
-		    {
+	      } else {
+		  for (j =3D start_j; j < end_j; j++) {
 		      int32_t HTOFFSET =3D (j >> (shift - RANGELEN)) &
 			((1 << RANGELEN) - 1);
 		      if (eflags & JBIG2_HUFFMAN_FLAGS_ISLOW)

Modified: trunk/jbig2_text.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/jbig2_text.c	2005-08-28 00:10:20 UTC (rev 433)
+++ trunk/jbig2_text.c	2005-08-30 02:05:05 UTC (rev 434)
@@ -187,7 +187,6 @@
=20
 	/* decode the symbol id codelengths using the runlength table */
 	symcodelengths =3D jbig2_alloc(ctx->allocator, SBNUMSYMS*sizeof(Jbig2Hu=
ffmanLine));
-	/* todo: could save considerable space by growing the lines array as ne=
eded */
 	if (symcodelengths =3D=3D NULL) {
 	  jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
 	    "memory allocation failure reading symbol ID huffman table!");
@@ -213,23 +212,30 @@
 	      return -1;
 	    }
 	    len =3D symcodelengths[index-1].PREFLEN;
-	    if (code =3D=3D 32) range =3D jbig2_huffman_get_bits(hs, 2) + 3;
+	    if (code =3D=3D 32) range =3D jbig2_huffman_get_bits(hs, 2) + 2;
 	    else if (code =3D=3D 33) range =3D jbig2_huffman_get_bits(hs, 3) + =
3;
 	    else if (code =3D=3D 34) range =3D 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, l=
en, range);
+	  if (index+range > SBNUMSYMS) {
+	    jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+	      "runlength extends %d entries beyond the end of symbol id table!"=
,
+		index+range - SBNUMSYMS);
+	    range =3D SBNUMSYMS - index;
+	  }
 	  for (r =3D 0; r < range; r++) {
 	    symcodelengths[index+r].PREFLEN =3D len;=20
 	    symcodelengths[index+r].RANGELEN =3D 0;=20
-	    symcodelengths[index+r].RANGELOW =3D index;
+	    symcodelengths[index+r].RANGELOW =3D index + r;
 	  }
 	  index +=3D r;
-	  if (index > SBNUMSYMS) {
-	    jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
-	      "runlength extends beyond the end of symbol id table");
-	  }
 	}
+
+	if (index < SBNUMSYMS) {
+	  jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+	    "runlength codes do not cover the available symbol set");
+	}
 	symcodeparams.HTOOB =3D 0;
 	symcodeparams.lines =3D symcodelengths;
 	symcodeparams.n_lines =3D SBNUMSYMS;
@@ -242,6 +248,12 @@
=20
 	jbig2_free(ctx->allocator, symcodelengths);
 	jbig2_release_huffman_table(ctx, runcodes);
+
+	if (SBSYMCODES =3D=3D NULL) {
+	    jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+		"could not construct Symbol ID huffman table!");
+	    return NULL;
+	}
     }
=20
     /* 6.4.5 (1) */