shithub: jbig2

Download patch

ref: 46555913d6ed4b5479b50f45564ed94c478af863
parent: e3092e1ff329e834e0e131ada149c692cff01688
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Fri May 9 09:41:01 EDT 2008

Support for aggregate symbol coding, patch from Ghostscript trunk.


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

--- a/jbig2_refinement.c
+++ b/jbig2_refinement.c
@@ -91,7 +91,7 @@
       jbig2_image_set_pixel(image, x, y, bit);
     }
   }
-#ifdef JBIG2_DEBUG_REFINEMENT
+#ifdef JBIG2_DEBUG
   {
     static count = 0;
     char name[32];
@@ -265,10 +265,6 @@
 			    Jbig2ArithCx *GR_stats)
 {
   {
-    jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
-      "decoding generic refinement region with offset %d,%x,\n"
-      "  GRTEMPLATE=%d, TPGRON=%d\n",
-      params->DX, params->DY, params->GRTEMPLATE, params->TPGRON);
     jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
       "decoding generic refinement region with offset %d,%x,\n"
       "  GRTEMPLATE=%d, TPGRON=%d, RA1=(%d,%d) RA2=(%d,%d)\n",
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -237,7 +237,11 @@
   Jbig2ArithIntCtx *IARDX = NULL;
   Jbig2ArithIntCtx *IARDY = NULL;
   int code = 0;
+  Jbig2SymbolDict **refagg_dicts;
+  int n_refagg_dicts = 1;
 
+  Jbig2TextRegionParams *tparams = NULL;
+
   /* 6.5.5 (3) */
   HCHEIGHT = 0;
   NSYMSDECODED = 0;
@@ -392,68 +396,100 @@
 		    "aggregate symbol coding (%d instances)", REFAGGNINST);
 
 		  if (REFAGGNINST > 1) {
-		      /* multiple symbols are embedded text regions */ 
-		      Jbig2TextRegionParams rparams;
-		      Jbig2SymbolDict *SBSYMS[2];
 		      Jbig2Image *image;
+		      int i;
 
-		      rparams.SBHUFF = params->SDHUFF;
-		      rparams.SBREFINE = 1;
-		      rparams.SBDEFPIXEL = 0;
-		      rparams.SBCOMBOP = JBIG2_COMPOSE_OR;
-		      rparams.TRANSPOSED = 0;
-		      rparams.REFCORNER = JBIG2_CORNER_TOPLEFT;
-		      rparams.SBDSOFFSET = 0;
-		      rparams.SBNUMINSTANCES = REFAGGNINST;
-		      rparams.LOGSBSTRIPS = 0;
-		      rparams.SBSTRIPS = 1;
-		      if (rparams.SBHUFF) {
-			rparams.SBHUFFFS = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_F);
-			rparams.SBHUFFDS = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_H);
-			rparams.SBHUFFDT = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_K);
-			rparams.SBHUFFRDW = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_O);
-			rparams.SBHUFFRDH = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_O);
-			rparams.SBHUFFRDX = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_O);
-			rparams.SBHUFFRDY = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_O);
-			rparams.SBHUFFRSIZE = jbig2_build_huffman_table(ctx,
-				&jbig2_huffman_params_A);
+		      if (tparams == NULL) 
+		      {
+			  /* First time through, we need to initialise the */
+			  /* various tables for Huffman or adaptive encoding */
+			  /* as well as the text region parameters structure */
+			  refagg_dicts = jbig2_alloc(ctx->allocator, sizeof(Jbig2SymbolDict *) * n_refagg_dicts);
+		          if (refagg_dicts == NULL) {
+			      code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+			       "Out of memory allocating dictionary array");
+		              return NULL;
+		          }
+		          refagg_dicts[0] = jbig2_sd_new(ctx, params->SDNUMINSYMS + params->SDNUMNEWSYMS);
+		          if (refagg_dicts[0] == NULL) {
+			      code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+			       "Out of memory allocating symbol dictionary");
+		              jbig2_free(ctx->allocator, refagg_dicts);
+		              return NULL;
+		          }
+		          refagg_dicts[0]->n_symbols = params->SDNUMINSYMS + params->SDNUMNEWSYMS;
+		          for (i=0;i < params->SDNUMINSYMS;i++)
+		          {
+			      refagg_dicts[0]->glyphs[i] = jbig2_image_clone(ctx, params->SDINSYMS->glyphs[i]);
+		          }
+
+			  tparams = jbig2_alloc(ctx->allocator, sizeof(Jbig2TextRegionParams));
+			  if (tparams == NULL) {
+			      code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+			      "Out of memory creating text region params");
+			      jbig2_sd_release(ctx, refagg_dicts[0]);
+			      jbig2_free(ctx->allocator, refagg_dicts);
+			      return NULL;
+			  }
+    		          if (!params->SDHUFF) {
+			      /* Values from Table 17, section 6.5.8.2 (2) */
+			      tparams->IADT = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IAFS = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IADS = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IAIT = jbig2_arith_int_ctx_new(ctx);
+			      /* Table 31 */
+			      for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < 
+				  (int)(params->SDNUMINSYMS + params->SDNUMNEWSYMS); SBSYMCODELEN++);
+			      tparams->IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
+			      tparams->IARI = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IARDW = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IARDH = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IARDX = jbig2_arith_int_ctx_new(ctx);
+			      tparams->IARDY = jbig2_arith_int_ctx_new(ctx);
+			  } else {
+			      tparams->SBHUFFFS = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_F);   /* Table B.6 */
+			      tparams->SBHUFFDS = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_H);  /* Table B.8 */
+			      tparams->SBHUFFDT = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_K);  /* Table B.11 */
+			      tparams->SBHUFFRDW = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_O); /* Table B.15 */
+			      tparams->SBHUFFRDH = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_O); /* Table B.15 */
+			      tparams->SBHUFFRDX = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_O); /* Table B.15 */
+			      tparams->SBHUFFRDY = jbig2_build_huffman_table(ctx,
+				&jbig2_huffman_params_O); /* Table B.15 */
+			  }
+			  tparams->SBHUFF = params->SDHUFF;
+			  tparams->SBREFINE = 1;
+			  tparams->SBSTRIPS = 1;
+			  tparams->SBDEFPIXEL = 0;
+			  tparams->SBCOMBOP = JBIG2_COMPOSE_OR;
+			  tparams->TRANSPOSED = 0;
+			  tparams->REFCORNER = JBIG2_CORNER_TOPLEFT;
+			  tparams->SBDSOFFSET = 0;
+			  tparams->SBRTEMPLATE = params->SDRTEMPLATE;
 		      }
-		      rparams.SBRTEMPLATE = params->SDRTEMPLATE;
-		      rparams.sbrat[0] = params->sdrat[0];
-		      rparams.sbrat[1] = params->sdrat[1];
-		      rparams.sbrat[2] = params->sdrat[2];
-		      rparams.sbrat[3] = params->sdrat[3];
+		      tparams->SBNUMINSTANCES = REFAGGNINST;
 
-		      SBSYMS[0] = params->SDINSYMS;
-		      SBSYMS[1] = SDNEWSYMS;
-		      image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
-		      code = jbig2_decode_text_region(ctx, segment, &rparams,
-			(const Jbig2SymbolDict * const *)SBSYMS, 2, 
-			image, data, size, NULL);
-		      jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
-			"text region decode returned %d", code);
-
-		      if (rparams.SBHUFF) {
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFFS);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFDS);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFDT);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFRDW);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFRDH);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFRDX);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFRDY);
-			jbig2_release_huffman_table(ctx, rparams.SBHUFFRSIZE);	
+      		      image = jbig2_image_new(ctx, SYMWIDTH, HCHEIGHT);
+		      if (image == NULL) {
+			  code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+			   "Out of memory creating symbol image");
+		          jbig2_free(ctx->allocator, tparams);
+			  jbig2_sd_release(ctx, refagg_dicts[0]);
+		          jbig2_free(ctx->allocator, refagg_dicts);
+		          return NULL;
 		      }
-		
-		      code = jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
-			"NYI aggregate coding with REFAGGNINST=%d", REFAGGNINST);
-		      return NULL;
+
+		      /* multiple symbols are handled as a text region */
+		      jbig2_decode_text_region(ctx, segment, tparams, (const Jbig2SymbolDict * const *)refagg_dicts, 
+			  n_refagg_dicts, image, data, size, GR_stats, as, (Jbig2WordStream *)NULL);
+
+		      SDNEWSYMS->glyphs[NSYMSDECODED] = image;
+		      refagg_dicts[0]->glyphs[params->SDNUMINSYMS + NSYMSDECODED] = jbig2_image_clone(ctx, SDNEWSYMS->glyphs[NSYMSDECODED]);
 		  } else {
 		      /* 6.5.8.2.2 */
 		      /* bool SBHUFF = params->SDHUFF; */
@@ -611,6 +647,37 @@
       }
 
   } /* end of symbol decode loop */
+
+  if (tparams != NULL) 
+  {
+      if (!params->SDHUFF)
+      {
+          jbig2_arith_int_ctx_free(ctx, tparams->IADT);
+          jbig2_arith_int_ctx_free(ctx, tparams->IAFS);
+          jbig2_arith_int_ctx_free(ctx, tparams->IADS);
+          jbig2_arith_int_ctx_free(ctx, tparams->IAIT);
+          jbig2_arith_iaid_ctx_free(ctx, tparams->IAID);
+          jbig2_arith_int_ctx_free(ctx, tparams->IARI);
+          jbig2_arith_int_ctx_free(ctx, tparams->IARDW);
+          jbig2_arith_int_ctx_free(ctx, tparams->IARDH);
+          jbig2_arith_int_ctx_free(ctx, tparams->IARDX);
+          jbig2_arith_int_ctx_free(ctx, tparams->IARDY);
+      }
+      else
+      {
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFFS);
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFDS);
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFDT);
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFRDX);
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFRDY);
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFRDW);
+          jbig2_release_huffman_table(ctx, tparams->SBHUFFRDH);
+      }
+      jbig2_free(ctx->allocator, tparams);
+      tparams = NULL;
+      jbig2_sd_release(ctx, refagg_dicts[0]);
+      jbig2_free(ctx->allocator, refagg_dicts);
+  }
 
   jbig2_free(ctx->allocator, GB_stats);
   
--- a/jbig2_text.c
+++ b/jbig2_text.c
@@ -1,7 +1,7 @@
 /*
     jbig2dec
     
-    Copyright (C) 2002-2006 Artifex Software, Inc.
+    Copyright (C) 2002-2008 Artifex Software, Inc.
     
     This software is distributed under license and may not
     be copied, modified or distributed except as expressly
@@ -34,6 +34,7 @@
 #include "jbig2_symbol_dict.h"
 #include "jbig2_text.h"
 
+
 /**
  * jbig2_decode_text_region: decode a text region segment
  *
@@ -57,7 +58,7 @@
                              const Jbig2SymbolDict * const *dicts, const int n_dicts,
                              Jbig2Image *image,
                              const byte *data, const size_t size,
-			     Jbig2ArithCx *GR_stats)
+			     Jbig2ArithCx *GR_stats, Jbig2ArithState *as, Jbig2WordStream *ws)
 {
     /* relevent bits of 6.4.4 */
     uint32_t NINSTANCES;
@@ -74,20 +75,8 @@
     bool first_symbol;
     uint32_t index, SBNUMSYMS;
     Jbig2Image *IB;
-    Jbig2WordStream *ws = NULL;
     Jbig2HuffmanState *hs = NULL;
     Jbig2HuffmanTable *SBSYMCODES = NULL;
-    Jbig2ArithState *as = NULL;
-    Jbig2ArithIntCtx *IADT = NULL;
-    Jbig2ArithIntCtx *IAFS = NULL;
-    Jbig2ArithIntCtx *IADS = NULL;
-    Jbig2ArithIntCtx *IAIT = NULL;
-    Jbig2ArithIaidCtx *IAID = NULL;
-    Jbig2ArithIntCtx *IARI = NULL;
-    Jbig2ArithIntCtx *IARDW = NULL;
-    Jbig2ArithIntCtx *IARDH = NULL;
-    Jbig2ArithIntCtx *IARDX = NULL;
-    Jbig2ArithIntCtx *IARDY = NULL;
     int code = 0;
     int RI;
     
@@ -98,24 +87,7 @@
     jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
         "symbol list contains %d glyphs in %d dictionaries", SBNUMSYMS, n_dicts);
     
-    ws = jbig2_word_stream_buf_new(ctx, data, size);
-    if (!params->SBHUFF) {
-	int SBSYMCODELEN;
-
-        as = jbig2_arith_new(ctx, ws);
-        IADT = jbig2_arith_int_ctx_new(ctx);
-        IAFS = jbig2_arith_int_ctx_new(ctx);
-        IADS = jbig2_arith_int_ctx_new(ctx);
-        IAIT = jbig2_arith_int_ctx_new(ctx);
-	/* Table 31 */
-	for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < SBNUMSYMS; SBSYMCODELEN++);
-        IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
-	IARI = jbig2_arith_int_ctx_new(ctx);
-	IARDW = jbig2_arith_int_ctx_new(ctx);
-	IARDH = jbig2_arith_int_ctx_new(ctx);
-	IARDX = jbig2_arith_int_ctx_new(ctx);
-	IARDY = jbig2_arith_int_ctx_new(ctx);
-    } else {
+    if (params->SBHUFF) {
 	Jbig2HuffmanTable *runcodes;
 	Jbig2HuffmanParams runcodeparams;
 	Jbig2HuffmanLine runcodelengths[35];
@@ -176,7 +148,7 @@
 	      return -1;
 	    }
 	    len = symcodelengths[index-1].PREFLEN;
-	    if (code == 32) range = jbig2_huffman_get_bits(hs, 2) + 2;
+	    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;
 	  }
@@ -227,7 +199,7 @@
     if (params->SBHUFF) {
         STRIPT = jbig2_huffman_get(hs, params->SBHUFFDT, &code);
     } else {
-        code = jbig2_arith_int_decode(IADT, as, &STRIPT);
+        code = jbig2_arith_int_decode(params->IADT, as, &STRIPT);
     }
 
     /* 6.4.5 (2) */
@@ -241,7 +213,7 @@
         if (params->SBHUFF) {
             DT = jbig2_huffman_get(hs, params->SBHUFFDT, &code);
         } else {
-            code = jbig2_arith_int_decode(IADT, as, &DT);
+            code = jbig2_arith_int_decode(params->IADT, as, &DT);
         }
         DT *= params->SBSTRIPS;
         STRIPT += DT;
@@ -255,7 +227,7 @@
 		if (params->SBHUFF) {
 		    DFS = jbig2_huffman_get(hs, params->SBHUFFFS, &code);
 		} else {
-		    code = jbig2_arith_int_decode(IAFS, as, &DFS);
+		    code = jbig2_arith_int_decode(params->IAFS, as, &DFS);
 		}
 		FIRSTS += DFS;
 		CURS = FIRSTS;
@@ -266,7 +238,7 @@
 		if (params->SBHUFF) {
 		    IDS = jbig2_huffman_get(hs, params->SBHUFFDS, &code);
 		} else {
-		    code = jbig2_arith_int_decode(IADS, as, &IDS);
+		    code = jbig2_arith_int_decode(params->IADS, as, &IDS);
 		}
 		if (code) {
 		    break;
@@ -280,7 +252,7 @@
 	    } else if (params->SBHUFF) {
 		CURT = jbig2_huffman_get_bits(hs, params->LOGSBSTRIPS);
 	    } else {
-		code = jbig2_arith_int_decode(IAIT, as, &CURT);
+		code = jbig2_arith_int_decode(params->IAIT, as, &CURT);
 	    }
 	    T = STRIPT + CURT;
 
@@ -288,7 +260,7 @@
 	    if (params->SBHUFF) {
 		ID = jbig2_huffman_get(hs, SBSYMCODES, &code);
 	    } else {
-		code = jbig2_arith_iaid_decode(IAID, as, (int *)&ID);
+		code = jbig2_arith_iaid_decode(params->IAID, as, (int *)&ID);
 	    }
 	    if (ID >= SBNUMSYMS) {
 		return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
@@ -308,7 +280,7 @@
 	      if (params->SBHUFF) {
 		RI = jbig2_huffman_get_bits(hs, 1);
 	      } else {
-		code = jbig2_arith_int_decode(IARI, as, &RI);
+		code = jbig2_arith_int_decode(params->IARI, as, &RI);
 	      }
 	    } else {
 		RI = 0;
@@ -322,10 +294,10 @@
 
 		/* 6.4.11 (1, 2, 3, 4) */
 		if (!params->SBHUFF) {
-		  code = jbig2_arith_int_decode(IARDW, as, &RDW);
-		  code = jbig2_arith_int_decode(IARDH, as, &RDH);
-		  code = jbig2_arith_int_decode(IARDX, as, &RDX);
-		  code = jbig2_arith_int_decode(IARDY, as, &RDY);
+		  code = jbig2_arith_int_decode(params->IARDW, as, &RDW);
+		  code = jbig2_arith_int_decode(params->IARDH, as, &RDH);
+		  code = jbig2_arith_int_decode(params->IARDX, as, &RDX);
+		  code = jbig2_arith_int_decode(params->IARDY, as, &RDY);
 		} else {
 		  RDW = jbig2_huffman_get(hs, params->SBHUFFRDW, &code);
 		  RDH = jbig2_huffman_get(hs, params->SBHUFFRDH, &code);
@@ -414,20 +386,7 @@
 
     if (params->SBHUFF) {
       jbig2_release_huffman_table(ctx, SBSYMCODES);
-    } else {
-	jbig2_arith_int_ctx_free(ctx, IADT);
-	jbig2_arith_int_ctx_free(ctx, IAFS);
-	jbig2_arith_int_ctx_free(ctx, IADS);
-	jbig2_arith_int_ctx_free(ctx, IAIT);
-	jbig2_arith_iaid_ctx_free(ctx, IAID);
-	jbig2_arith_int_ctx_free(ctx, IARI);
-	jbig2_arith_int_ctx_free(ctx, IARDW);
-	jbig2_arith_int_ctx_free(ctx, IARDH);
-	jbig2_arith_int_ctx_free(ctx, IARDX);
-	jbig2_arith_int_ctx_free(ctx, IARDY);
-	jbig2_free(ctx->allocator, as);
-	jbig2_word_stream_buf_free(ctx, ws);
-    }
+    } 
     
     return 0;
 }
@@ -448,6 +407,8 @@
     uint16_t huffman_flags = 0;
     Jbig2ArithCx *GR_stats = NULL;
     int code = 0;
+    Jbig2WordStream *ws = NULL; 
+    Jbig2ArithState *as = NULL; 
     
     /* 7.4.1 */
     if (segment->data_length < 17)
@@ -712,10 +673,35 @@
 
     image = jbig2_image_new(ctx, region_info.width, region_info.height);
 
+    ws = jbig2_word_stream_buf_new(ctx, segment_data + offset, segment->data_length - offset);
+    if (!params.SBHUFF) {
+	int SBSYMCODELEN, index;
+        int SBNUMSYMS = 0;
+	for (index = 0; index < n_dicts; index++) {
+	    SBNUMSYMS += dicts[index]->n_symbols;
+	}
+
+	as = jbig2_arith_new(ctx, ws);
+	ws = 0;
+
+        params.IADT = jbig2_arith_int_ctx_new(ctx);
+        params.IAFS = jbig2_arith_int_ctx_new(ctx);
+        params.IADS = jbig2_arith_int_ctx_new(ctx);
+        params.IAIT = jbig2_arith_int_ctx_new(ctx);
+	/* Table 31 */
+	for (SBSYMCODELEN = 0; (1 << SBSYMCODELEN) < SBNUMSYMS; SBSYMCODELEN++);
+        params.IAID = jbig2_arith_iaid_ctx_new(ctx, SBSYMCODELEN);
+	params.IARI = jbig2_arith_int_ctx_new(ctx);
+	params.IARDW = jbig2_arith_int_ctx_new(ctx);
+	params.IARDH = jbig2_arith_int_ctx_new(ctx);
+	params.IARDX = jbig2_arith_int_ctx_new(ctx);
+	params.IARDY = jbig2_arith_int_ctx_new(ctx);
+    }
+
     code = jbig2_decode_text_region(ctx, segment, &params,
                 (const Jbig2SymbolDict * const *)dicts, n_dicts, image,
                 segment_data + offset, segment->data_length - offset,
-		GR_stats);
+		GR_stats, as, ws);
 
     if (!params.SBHUFF && params.SBREFINE) {
 	jbig2_free(ctx->allocator, GR_stats);
@@ -730,6 +716,20 @@
       jbig2_release_huffman_table(ctx, params.SBHUFFRDW);
       jbig2_release_huffman_table(ctx, params.SBHUFFRDH);
       jbig2_release_huffman_table(ctx, params.SBHUFFRSIZE);
+    }
+    else {
+	jbig2_arith_int_ctx_free(ctx, params.IADT);
+	jbig2_arith_int_ctx_free(ctx, params.IAFS);
+	jbig2_arith_int_ctx_free(ctx, params.IADS);
+	jbig2_arith_int_ctx_free(ctx, params.IAIT);
+	jbig2_arith_iaid_ctx_free(ctx, params.IAID);
+	jbig2_arith_int_ctx_free(ctx, params.IARI);
+	jbig2_arith_int_ctx_free(ctx, params.IARDW);
+	jbig2_arith_int_ctx_free(ctx, params.IARDH);
+	jbig2_arith_int_ctx_free(ctx, params.IARDX);
+	jbig2_arith_int_ctx_free(ctx, params.IARDY);
+	jbig2_free(ctx->allocator, as);
+	jbig2_word_stream_buf_free(ctx, ws);
     }
 
     jbig2_free(ctx->allocator, dicts);
--- a/jbig2_text.h
+++ b/jbig2_text.h
@@ -1,7 +1,7 @@
 /*
     jbig2dec
     
-    Copyright (C) 2002-2006 Artifex Software, Inc.
+    Copyright (C) 2002-2004 Artifex Software, Inc.
     
     This software is distributed under license and may not
     be copied, modified or distributed except as expressly
@@ -13,12 +13,12 @@
     Artifex Software, Inc.,  101 Lucas Valley Road #110,
     San Rafael, CA  94903, U.S.A., +1(415)492-9861.
         
-    $Id: jbig2_priv.h 420 2005-07-27 23:55:54Z giles $
-    
-    text region header
+    $Id: jbig2_text.h 8022 2007-06-05 22:23:38Z giles $
 */
 
-/* jbig2_symbol_dict.h must be included first */
+/**
+ * Headers for Text region handling
+ **/
 
 typedef enum {
     JBIG2_CORNER_BOTTOMLEFT = 0,
@@ -35,12 +35,12 @@
     bool TRANSPOSED;
     Jbig2RefCorner REFCORNER;
     int SBDSOFFSET;
-    /* SBW */
-    /* SBH */
+    /* int SBW; */
+    /* int SBH; */
     uint32_t SBNUMINSTANCES;
     int LOGSBSTRIPS;
     int SBSTRIPS;
-    /* SBNUMSYMS */
+    /* int SBNUMSYMS; */
     /* SBSYMCODES */
     /* SBSYMCODELEN */
     /* SBSYMS */
@@ -52,6 +52,16 @@
     Jbig2HuffmanTable *SBHUFFRDX;
     Jbig2HuffmanTable *SBHUFFRDY;
     Jbig2HuffmanTable *SBHUFFRSIZE;
+    Jbig2ArithIntCtx *IADT;
+    Jbig2ArithIntCtx *IAFS;
+    Jbig2ArithIntCtx *IADS;
+    Jbig2ArithIntCtx *IAIT;
+    Jbig2ArithIaidCtx *IAID;
+    Jbig2ArithIntCtx *IARI;
+    Jbig2ArithIntCtx *IARDW;
+    Jbig2ArithIntCtx *IARDH;
+    Jbig2ArithIntCtx *IARDX;
+    Jbig2ArithIntCtx *IARDY;
     bool SBRTEMPLATE;
     int8_t sbrat[4];
 } Jbig2TextRegionParams;
@@ -58,8 +68,9 @@
 
 int
 jbig2_decode_text_region(Jbig2Ctx *ctx, Jbig2Segment *segment,
-			     const Jbig2TextRegionParams *params,
-			     const Jbig2SymbolDict * const *dicts, const int n_dicts,
-			     Jbig2Image *image,
-			     const byte *data, const size_t size,
-			     Jbig2ArithCx *GR_stats);
+                             const Jbig2TextRegionParams *params,
+                             const Jbig2SymbolDict * const *dicts, const int n_dicts,
+                             Jbig2Image *image,
+                             const byte *data, const size_t size,
+			     Jbig2ArithCx *GR_stats,
+			     Jbig2ArithState *as, Jbig2WordStream *ws);