rev 405 - trunk

[email protected] Wed, 11 May 2005 00:14:26 -0700 (PDT)
Newsgroups gmane.comp.printing.ghostscript.jbig2dec.cvs
Message-ID <[email protected]>
Author: giles
Date: 2005-05-11 00:14:25 -0700 (Wed, 11 May 2005)
New Revision: 405

Modified:
   trunk/jbig2_huffman.c
   trunk/jbig2_huffman.h
   trunk/jbig2_hufftab.h
   trunk/jbig2_symbol_dict.c
Log:
Export the pre-defined huffman tables for external use.

Read the huffman fields of the symbol dictionary header and allocate
appropriate tables and decoder context. This is a prerequisite for
handling huffman-coded symbol dicts.i

Part of the fix for bug 688009.


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-05-03 02:27:12 UTC (rev 404)
+++ trunk/jbig2_huffman.c	2005-05-11 07:14:25 UTC (rev 405)
@@ -17,7 +17,7 @@
 */
=20
 /* Huffman table decoding procedures=20
-    -- See Annex B of the JBIG2 draft spec */
+    -- See Annex B of the JBIG2 specification */
=20
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -164,6 +164,9 @@
=20
 #define LOG_TABLE_SIZE_MAX 8
=20
+/** Build an in-memory representation of a Huffman table from the
+ *  set of template params provided by the spec or a table segment
+ */=20
 Jbig2HuffmanTable *
 jbig2_build_huffman_table (Jbig2Ctx *ctx, const Jbig2HuffmanParams *para=
ms)
 {
@@ -265,6 +268,17 @@
   return result;
 }
=20
+/** Free the memory associated with the representation of table */
+void
+jbig2_release_huffman_table (Jbig2Ctx *ctx, Jbig2HuffmanTable *table)
+{
+  if (table !=3D NULL) {
+      jbig2_free(ctx->allocator, table->entries);
+      jbig2_free(ctx->allocator, table);
+  }
+  return;
+}
+
 #ifdef TEST
 #include <stdio.h>
=20

Modified: trunk/jbig2_huffman.h
=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.h	2005-05-03 02:27:12 UTC (rev 404)
+++ trunk/jbig2_huffman.h	2005-05-11 07:14:25 UTC (rev 405)
@@ -26,6 +26,35 @@
 typedef struct _Jbig2HuffmanTable Jbig2HuffmanTable;
 typedef struct _Jbig2HuffmanParams Jbig2HuffmanParams;
=20
+struct _Jbig2HuffmanEntry {
+  union {
+    int32_t RANGELOW;
+    Jbig2HuffmanTable *ext_table;
+  } u;
+  byte PREFLEN;
+  byte RANGELEN;
+  byte flags;
+};
+
+struct _Jbig2HuffmanTable {
+  int log_table_size;
+  Jbig2HuffmanEntry *entries;
+};
+
+typedef struct _Jbig2HuffmanLine Jbig2HuffmanLine;
+
+struct _Jbig2HuffmanLine {
+  int PREFLEN;
+  int RANGELEN;
+  int RANGELOW;
+};
+
+struct _Jbig2HuffmanParams {
+  bool HTOOB;
+  int n_lines;
+  const Jbig2HuffmanLine *lines;
+};
+
 Jbig2HuffmanState *
 jbig2_huffman_new (Jbig2Ctx *ctx, Jbig2WordStream *ws);
=20
@@ -37,7 +66,27 @@
 		   const Jbig2HuffmanTable *table, bool *oob);
=20
 Jbig2HuffmanTable *
-jbig2_build_huffman_table (Jbig2Ctx *ctx,
-			   const Jbig2HuffmanParams *params);
+jbig2_build_huffman_table (Jbig2Ctx *ctx, const Jbig2HuffmanParams *para=
ms);
=20
+void
+jbig2_release_huffman_table (Jbig2Ctx *ctx, Jbig2HuffmanTable *table);
+
+/* standard Huffman templates defined by the specification */
+extern const Jbig2HuffmanParams jbig2_huffman_params_A; /* Table B.1  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_B; /* Table B.2  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_C; /* Table B.3  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_D; /* Table B.4  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_E; /* Table B.5  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_F; /* Table B.6  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_G; /* Table B.7  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_H; /* Table B.8  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_I; /* Table B.9  */
+extern const Jbig2HuffmanParams jbig2_huffman_params_J; /* Table B.10 */
+extern const Jbig2HuffmanParams jbig2_huffman_params_K; /* Table B.11 */
+extern const Jbig2HuffmanParams jbig2_huffman_params_L; /* Table B.12 */
+extern const Jbig2HuffmanParams jbig2_huffman_params_M; /* Table B.13 */
+extern const Jbig2HuffmanParams jbig2_huffman_params_J; /* Table B.14 */
+extern const Jbig2HuffmanParams jbig2_huffman_params_O; /* Table B.15 */
+
+
 #endif /* JBIG2_HUFFMAN_H */

Modified: trunk/jbig2_hufftab.h
=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_hufftab.h	2005-05-03 02:27:12 UTC (rev 404)
+++ trunk/jbig2_hufftab.h	2005-05-11 07:14:25 UTC (rev 405)
@@ -17,45 +17,17 @@
 */
=20
 /* predefined Huffman table definitions=20
-    -- See Annex B of the JBIG2 draft spec */
+    -- See Annex B of the JBIG2 specification */
=20
 #ifndef JBIG2_HUFFTAB_H
 #define JBIG2_HUFFTAB_H
=20
 /* types are in jbig2_huffman.h, you must include that first */
=20
-struct _Jbig2HuffmanEntry {
-  union {
-    int32_t RANGELOW;
-    Jbig2HuffmanTable *ext_table;
-  } u;
-  byte PREFLEN;
-  byte RANGELEN;
-  byte flags;
-};
=20
-struct _Jbig2HuffmanTable {
-  int log_table_size;
-  Jbig2HuffmanEntry *entries;
-};
-
-typedef struct _Jbig2HuffmanLine Jbig2HuffmanLine;
-
-struct _Jbig2HuffmanLine {
-  int PREFLEN;
-  int RANGELEN;
-  int RANGELOW;
-};
-
-struct _Jbig2HuffmanParams {
-  bool HTOOB;
-  int n_lines;
-  const Jbig2HuffmanLine *lines;
-};
-
 /* Table B.1 */
 const Jbig2HuffmanLine
-jbig_huffman_lines_A[] =3D {
+jbig2_huffman_lines_A[] =3D {
   { 1, 4, 0 },
   { 2, 8, 16 },
   { 3, 16, 272 },
@@ -64,11 +36,11 @@
 };
=20
 const Jbig2HuffmanParams
-jbig_huffman_params_A =3D { FALSE, 5, jbig_huffman_lines_A };
+jbig2_huffman_params_A =3D { FALSE, 5, jbig2_huffman_lines_A };
=20
 /* Table B.2 */
 const Jbig2HuffmanLine
-jbig_huffman_lines_B[] =3D {
+jbig2_huffman_lines_B[] =3D {
   { 1, 0, 0 },
   { 2, 0, 1 },
   { 3, 0, 2 },
@@ -80,11 +52,11 @@
 };
=20
 const Jbig2HuffmanParams
-jbig_huffman_params_B =3D { TRUE, 8, jbig_huffman_lines_B };
+jbig2_huffman_params_B =3D { TRUE, 8, jbig2_huffman_lines_B };
=20
 /* Table B.3 */
 const Jbig2HuffmanLine
-jbig_huffman_lines_C[] =3D {
+jbig2_huffman_lines_C[] =3D {
   { 8, 8, -256 },
   { 1, 0, 0 },
   { 2, 0, 1 },
@@ -97,11 +69,11 @@
 };
=20
 const Jbig2HuffmanParams
-jbig_huffman_params_C =3D { TRUE, 9, jbig_huffman_lines_C };
+jbig2_huffman_params_C =3D { TRUE, 9, jbig2_huffman_lines_C };
=20
 /* Table B.4 */
 const Jbig2HuffmanLine
-jbig_huffman_lines_D[] =3D {
+jbig2_huffman_lines_D[] =3D {
   { 1, 0, 1 },
   { 2, 0, 2 },
   { 3, 0, 3 },
@@ -112,11 +84,11 @@
 };
=20
 const Jbig2HuffmanParams
-jbig_huffman_params_D =3D { FALSE, 7, jbig_huffman_lines_D };
+jbig2_huffman_params_D =3D { FALSE, 7, jbig2_huffman_lines_D };
=20
 /* Table B.5 */
 const Jbig2HuffmanLine
-jbig_huffman_lines_E[] =3D {
+jbig2_huffman_lines_E[] =3D {
 	{7, 8, -255},
 	{1, 0, 1},
 	{2, 0, 2},
@@ -128,11 +100,11 @@
 };
=20
 const Jbig2HuffmanParams
-jbig_huffman_params_E =3D { FALSE, 8, jbig_huffman_lines_E };
+jbig2_huffman_params_E =3D { FALSE, 8, jbig2_huffman_lines_E };
=20
 /* Table B.14 */
 const Jbig2HuffmanLine
-jbig_huffman_lines_N[] =3D {
+jbig2_huffman_lines_N[] =3D {
   { 3, 0, -2 },
   { 3, 0, -1 },
   { 1, 0, 0 },
@@ -143,7 +115,7 @@
 };
=20
 const Jbig2HuffmanParams
-jbig_huffman_params_N =3D { FALSE, 7, jbig_huffman_lines_N };
+jbig2_huffman_params_N =3D { FALSE, 7, jbig2_huffman_lines_N };
=20
=20
 #endif /* JBIG2_HUFFTAB_H */

Modified: trunk/jbig2_symbol_dict.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_symbol_dict.c	2005-05-03 02:27:12 UTC (rev 404)
+++ trunk/jbig2_symbol_dict.c	2005-05-11 07:14:25 UTC (rev 405)
@@ -48,10 +48,10 @@
   Jbig2SymbolDict *SDINSYMS;
   uint32_t SDNUMNEWSYMS;
   uint32_t SDNUMEXSYMS;
-  /* SDHUFFDH */
-  /* SDHUFFDW */
-  /* SDHUFFBMSIZE */
-  /* SDHUFFAGGINST */
+  Jbig2HuffmanTable *SDHUFFDH;
+  Jbig2HuffmanTable *SDHUFFDW;
+  Jbig2HuffmanTable *SDHUFFBMSIZE;
+  Jbig2HuffmanTable *SDHUFFAGGINST;
   int SDTEMPLATE;
   int8_t sdat[8];
   bool SDRTEMPLATE;
@@ -218,6 +218,7 @@
   uint32_t NSYMSDECODED;
   int32_t SYMWIDTH, TOTWIDTH;
   uint32_t HCFIRSTSYM;
+  uint32_t *SDNEWSYMWIDTHS =3D NULL;
   Jbig2WordStream *ws =3D NULL;
   Jbig2HuffmanState *hs =3D NULL;
   Jbig2ArithState *as =3D NULL;
@@ -254,6 +255,15 @@
       jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
 	"huffman coded symbol dictionary");
       hs =3D jbig2_huffman_new(ctx, ws);
+      if (params->SDREFAGG) {
+	  SDNEWSYMWIDTHS =3D jbig2_alloc(ctx->allocator,
+		sizeof(*SDNEWSYMWIDTHS)*params->SDNUMNEWSYMS);
+	  if (SDNEWSYMWIDTHS =3D=3D NULL) {
+	    jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+		"could not allocate storage for symbol widths");
+	    return NULL;
+	  }
+      }
   }
=20
   SDNEWSYMS =3D jbig2_sd_new(ctx, params->SDNUMNEWSYMS);
@@ -503,6 +513,9 @@
       }
       jbig2_free(ctx->allocator, as); =20
   } else {
+      if (params->SDREFAGG) {
+	jbig2_free(ctx->allocator, SDNEWSYMWIDTHS);
+      }
       jbig2_free(ctx->allocator, hs);
   }
=20
@@ -533,22 +546,84 @@
   params.SDTEMPLATE =3D (flags >> 10) & 3;
   params.SDRTEMPLATE =3D (flags >> 12) & 1;
=20
+  params.SDHUFFDH =3D NULL;
+  params.SDHUFFDW =3D NULL;
+  params.SDHUFFBMSIZE =3D NULL;
+  params.SDHUFFAGGINST =3D NULL;
+
   if (params.SDHUFF) {
     jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
         "symbol dictionary uses the Huffman encoding variant (NYI)");
-    return 0;
+    switch ((flags & 0x000c) >> 2) {
+      case 0: /* Table B.4 */
+	params.SDHUFFDH =3D jbig2_build_huffman_table(ctx,=20
+		                       &jbig2_huffman_params_D);
+	break;
+      case 1: /* Table B.5 */
+	params.SDHUFFDH =3D jbig2_build_huffman_table(ctx,=20
+		                       &jbig2_huffman_params_E);
+	break;
+      case 3: /* Custom table from referred segment */
+	/* We handle this case later by leaving the table as NULL */
+	return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+	    "symbol dictionary uses custom DH huffman table (NYI)");
+      case 2:
+      default:
+	return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+	    "symbol dictionary specified invalid huffman table");
+	break;
+    }
+    switch ((flags & 0x0030) >> 4) {
+      case 0: /* Table B.2 */
+	params.SDHUFFDW =3D jbig2_build_huffman_table(ctx,=20
+		                       &jbig2_huffman_params_B);
+	break;
+      case 1: /* Table B.3 */
+	params.SDHUFFDW =3D jbig2_build_huffman_table(ctx,=20
+		                       &jbig2_huffman_params_C);
+	break;
+      case 3: /* Custom table from referred segment */
+	/* We handle this case later by leaving the table as NULL */
+	return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+	    "symbol dictionary uses custom DW huffman table (NYI)");
+      case 2:
+      default:
+	return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+	    "symbol dictionary specified invalid huffman table");
+	break;
+    }
+    if (flags & 0x0040) {
+        /* Custom table from referred segment */
+	return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+	    "symbol dictionary uses custom BMSIZE huffman table (NYI)");
+    } else {
+	/* Table B.1 */
+	params.SDHUFFBMSIZE =3D jbig2_build_huffman_table(ctx,
+					&jbig2_huffman_params_A);
+    }
+    if (flags & 0x0080) {=20
+        /* Custom table from referred segment */
+	return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+	    "symbol dictionary uses custom REFAGG huffman table (NYI)");
+    } else {
+	/* Table B.1 */
+	params.SDHUFFAGGINST =3D jbig2_build_huffman_table(ctx,
+					&jbig2_huffman_params_A);
+    }
   }
=20
   /* FIXME: there are quite a few of these conditions to check */
   /* maybe #ifdef CONFORMANCE and a separate routine */
-  if(!params.SDHUFF && (flags & 0x000c)) {
+  if (!params.SDHUFF) {
+    if (flags & 0x000c) {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
 		  "SDHUFF is zero, but contrary to spec SDHUFFDH is not.");
-  }
-  if(!params.SDHUFF && (flags & 0x0030)) {
+    }
+    if (flags & 0x0030) {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
 		  "SDHUFF is zero, but contrary to spec SDHUFFDW is not.");
-  }
+    }
+  }=20
=20
   if (flags & 0x0080) {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
@@ -629,6 +704,13 @@
   if (segment->result) jbig2_dump_symbol_dict(ctx, segment);
 #endif
=20
+  if (params.SDHUFF) {
+      jbig2_release_huffman_table(ctx, params.SDHUFFDH);
+      jbig2_release_huffman_table(ctx, params.SDHUFFDW);
+      jbig2_release_huffman_table(ctx, params.SDHUFFBMSIZE);
+      jbig2_release_huffman_table(ctx, params.SDHUFFAGGINST);
+  }
+
   /* todo: retain or free GB_stats, GR_stats */
=20
   return (segment->result !=3D NULL) ? 0 : -1;