shithub: jbig2

Download patch

ref: 508693c17eb8f052fbcc0ea4976cb326e746c2f0
parent: 19918285ec07521885d12a624507435a3da9f473
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Thu Aug 12 20:00:17 EDT 2004

Work in progress to implement generic refinement regions and aggregate symbol coding.
Commit to avoid losing work.


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

--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -1,7 +1,7 @@
 /*
     jbig2dec
     
-    Copyright (c) 2002 artofcode LLC.
+    Copyright (c) 2002-2004 artofcode LLC.
     
     This software is provided AS-IS with no warranty,
     either express or implied.
@@ -317,14 +317,14 @@
 /**
  * jbig2_decode_generic_region: Decode a generic region.
  * @ctx: The context for allocation and error reporting.
- * @params: Parameters, as specified in Table 2.
+ * @segment: A segment reference for error reporting.
+ * @params: Decoding parameter set.
  * @as: Arithmetic decoder state.
- * @gbreg: Where to store the decoded data.
+ * @image: Where to store the decoded data.
  * @GB_stats: Arithmetic stats.
  *
  * Decodes a generic region, according to section 6.2. The caller should
- * have allocated the memory for @gbreg, which is packed 8 pixels to a
- * byte, scanlines aligned to one byte boundaries.
+ * pass an already allocated Jbig2Image object for @image
  *
  * Because this API is based on an arithmetic decoding state, it is
  * not suitable for MMR decoding.
@@ -457,3 +457,33 @@
 
   return code;
 }
+
+
+/**
+ * jbig2_decode_refinement_region: Decode a generic refinement region.
+ * @ctx: The context for allocation and error reporting.
+ * @segment: A segment reference for error reporting.
+ * @params: Decoding parameter set.
+ * @as: Arithmetic decoder state.
+ * @image: Where to store the decoded data.
+ * @GB_stats: Arithmetic stats.
+ *
+ * Decodes a generic region, according to section 6.2. The caller should
+ * pass an already allocated Jbig2Image object for @image
+ *
+ * Because this API is based on an arithmetic decoding state, it is
+ * not suitable for MMR decoding.
+ *
+ * Return code: 0 on success.
+ **/
+int
+jbig2_decode_refinement_region(Jbig2Ctx *ctx,
+			    Jbig2Segment *segment,
+			    const Jbig2RefinementRegionParams *params,
+			    Jbig2ArithState *as,
+			    Jbig2Image *image,
+			    Jbig2ArithCx *GB_stats)
+{
+
+}
+
--- a/jbig2_generic.h
+++ b/jbig2_generic.h
@@ -1,7 +1,7 @@
 /*
     jbig2dec
     
-    Copyright (c) 2002 artofcode LLC.
+    Copyright (c) 2002-2004 artofcode LLC.
     
     This software is distributed under license and may not
     be copied, modified or distributed except as expressly
@@ -13,10 +13,10 @@
     Artifex Software, Inc.,  101 Lucas Valley Road #110,
     San Rafael, CA  94903, U.S.A., +1(415)492-9861.
         
-    $Id: jbig2_generic.h,v 1.7 2002/07/04 13:34:29 giles Exp $
+    $Id$
 */
 
-/* Table 2 */
+/* 6.4 Table 2 */
 typedef struct {
   bool MMR;
   /* GBW */
@@ -28,7 +28,6 @@
   byte gbat[8];
 } Jbig2GenericRegionParams;
 
-/* 6.2 */
 int
 jbig2_decode_generic_region(Jbig2Ctx *ctx,
 			    Jbig2Segment *segment,
@@ -38,3 +37,21 @@
 			    Jbig2ArithCx *GB_stats);
 
 
+/* 6.3 Table 6 */
+typedef struct {
+  /* GRW */
+  /* GRH */
+  bool GRTEMPLATE;
+  Jbig2Image *reference;
+  int32_t DX, DY;
+  bool TPGDON;
+  byte grat[4];
+} Jbig2RefinementRegionParams;
+
+int
+jbig2_decode_refinement_region(Jbig2Ctx *ctx,
+                            Jbig2Segment *segment,
+                            const Jbig2RefinementRegionParams *params,
+                            Jbig2ArithState *as,
+                            Jbig2Image *image,
+                            Jbig2ArithCx *GB_stats);
--- a/jbig2_symbol_dict.c
+++ b/jbig2_symbol_dict.c
@@ -93,12 +93,15 @@
      new->glyphs = (Jbig2Image **)jbig2_alloc(ctx->allocator,
      				n_symbols*sizeof(Jbig2Image*));
      new->n_symbols = n_symbols;
+   } else {
+     return NULL;
    }
+
    if (new->glyphs != NULL) {
      memset(new->glyphs, 0, n_symbols*sizeof(Jbig2Image*));
    } else {
      jbig2_free(ctx->allocator, new);
-     new = NULL;
+     return NULL;
    }
    
    return new;
@@ -215,6 +218,10 @@
   Jbig2ArithIntCtx *IADH = NULL;
   Jbig2ArithIntCtx *IADW = NULL;
   Jbig2ArithIntCtx *IAEX = NULL;
+  Jbig2ArithIntCtx *IAAI = NULL;
+  Jbig2ArithIntCtx *IAID = NULL;
+  Jbig2ArithIntCtx *IARDX = NULL;
+  Jbig2ArithIntCtx *IARDY = NULL;
   int code = 0;
 
   /* 6.5.5 (3) */
@@ -221,30 +228,40 @@
   HCHEIGHT = 0;
   NSYMSDECODED = 0;
 
-  if (!params->SDHUFF)
-    {
+  if (!params->SDHUFF) {
       Jbig2WordStream *ws = jbig2_word_stream_buf_new(ctx, data, size);
       as = jbig2_arith_new(ctx, ws);
       IADH = jbig2_arith_int_ctx_new(ctx);
       IADW = jbig2_arith_int_ctx_new(ctx);
       IAEX = jbig2_arith_int_ctx_new(ctx);
-    }
+      IAAI = jbig2_arith_int_ctx_new(ctx);
+      IAID = jbig2_arith_int_ctx_new(ctx);
+      IARDX = jbig2_arith_int_ctx_new(ctx);
+      IARDY = jbig2_arith_int_ctx_new(ctx);
+  } else {
+      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+	"NYI: huffman coded symbol dictionary");
+      return NULL;
+  }
 
   SDNEWSYMS = jbig2_sd_new(ctx, params->SDNUMNEWSYMS);
-  
+
   /* 6.5.5 (4a) */
-  while (NSYMSDECODED < params->SDNUMNEWSYMS)
-    {
+  while (NSYMSDECODED < params->SDNUMNEWSYMS) {
       int32_t HCDH, DW;
 
       /* 6.5.6 */
-      if (params->SDHUFF)
+      if (params->SDHUFF) {
 	; /* todo */
-      else
-	{
+      } else {
 	  code = jbig2_arith_int_decode(IADH, as, &HCDH);
-	}
+      }
 
+      if (code != 0) {
+	jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+	  "error or OOB decoding height class delta (%d)\n", code);
+      }
+
       /* 6.5.5 (4b) */
       HCHEIGHT = HCHEIGHT + HCDH;
       SYMWIDTH = 0;
@@ -251,49 +268,61 @@
       TOTWIDTH = 0;
       HCFIRSTSYM = NSYMSDECODED;
 
-      if (HCHEIGHT < 0)
-        {
+      if (HCHEIGHT < 0) {
 	  /* todo: mem cleanup */
 	  code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
 			   "Invalid HCHEIGHT value");
           return NULL;
-        }
+      }
 #ifdef JBIG2_DEBUG
       jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
         "HCHEIGHT = %d", HCHEIGHT);
 #endif        
-      for (;;)
-	{
+      jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+        "decoding height class %d with %d syms decoded", HCHEIGHT, NSYMSDECODED);
+
+      for (;;) {
+	  /* check for broken symbol table */
+ 	  if (NSYMSDECODED > params->SDNUMNEWSYMS)
+	    {
+	      /* todo: mem cleanup? */
+	      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+	        "No OOB signalling end of height class %d", HCHEIGHT);
+	      break;
+	    }
 	  /* 6.5.7 */
-	  if (params->SDHUFF)
+	  if (params->SDHUFF) {
 	    ; /* todo */
-	  else
-	    {
+	  } else {
 	      code = jbig2_arith_int_decode(IADW, as, &DW);
-	    }
+	  }
 
 	  /* 6.5.5 (4c.i) */
-	  if (code == 1)
+	  if (code == 1) {
+	    jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+	    " OOB signals end of height class %d", HCHEIGHT);
 	    break;
+	  }
 	  SYMWIDTH = SYMWIDTH + DW;
 	  TOTWIDTH = TOTWIDTH + SYMWIDTH;
-	  if (SYMWIDTH < 0)
-            {
+        jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+        "  decoded symbol %d width %d (total width now %d)", NSYMSDECODED, SYMWIDTH, TOTWIDTH); 
+	  if (SYMWIDTH < 0) {
 	      /* todo: mem cleanup */
               code = jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
                 "Invalid SYMWIDTH value (%d) at symbol %d", SYMWIDTH, NSYMSDECODED+1);
               return NULL;
-            }
+          }
 #ifdef JBIG2_DEBUG
 	  jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
             "SYMWIDTH = %d", SYMWIDTH);
 #endif
 	  /* 6.5.5 (4c.ii) */
-	  if (!params->SDHUFF || params->SDREFAGG)
-	    {
+	  if (!params->SDHUFF || params->SDREFAGG) {
+		jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+		  "SDHUFF = %d; SDREFAGG = %d", params->SDHUFF, params->SDREFAGG);
 	      /* 6.5.8 */
-	      if (!params->SDREFAGG)
-		{
+	      if (!params->SDREFAGG) {
 		  Jbig2GenericRegionParams region_params;
 		  int sdat_bytes;
 		  Jbig2Image *image;
@@ -314,20 +343,80 @@
                   
                   SDNEWSYMS->glyphs[NSYMSDECODED] = image;
 
+	      } else {
+                  /* 6.5.8.2 refinement/aggregate symbol */
+                  uint32_t REFAGGNINST;
+
+		  if (params->SDHUFF) {
+		      /* todo */
+		  } else {
+		      code = jbig2_arith_int_decode(IAAI, as, &REFAGGNINST);
+		  }
+		  if (code || REFAGGNINST <= 0)
+		      jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
+			"invalid number of symbols or OOB in aggregate glyph");
+
+		  jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+		    "aggregate symbol coding (%d instances)", REFAGGNINST);
+
+		  if (REFAGGNINST > 1) {
+		      /* multiple symbols are like a text region */
+		  } else {
+		      /* 6.5.8.2.2 */
+		      bool SBHUFF = params->SDHUFF;
+		      uint32_t ID;
+		      int32_t RDX, RDY;
+
+		      if (params->SDHUFF) {
+			  /* todo */
+		      } else {
+			  code = jbig2_arith_int_decode(IAID, as, &ID);
+		          code = jbig2_arith_int_decode(IARDY, as, &RDX);
+		          code = jbig2_arith_int_decode(IARDY, as, &RDY);
+		      }
+
+		      jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+			"symbol is a refinement of id %d with the refinement applied at (%d,%d)",
+			ID, RDX, RDY);
+
+		  }
+               }
+
 #ifdef OUTPUT_PBM
-                  jbig2_image_write_pbm(image, stdout);
+		  {
+		    char name[64];
+		    FILE *out;
+		    snprintf(name, 64, "sd.%04d.%04d.pbm", 
+		             segment->number, NSYMSDECODED);
+		    out = fopen(name, "wb");
+                    jbig2_image_write_pbm(SDNEWSYMS->glyphs[NSYMSDECODED], out);
+		    jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
+			"writing out glyph as '%s' ...", name);
+		    fclose(out);
+		  }
 #endif
-		}
-	    }
 
+	  } else {
+	      jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+                "unhandled bitmap case!!!");
+          }
+
+	  /* 6.5.5 (4c.iii) */
+	  if (params->SDHUFF && !params->SDREFAGG) {
+	    jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
+              "NYI: parsing collective bitmaps!!!");
+	  }
+	
 	  /* 6.5.5 (4c.iv) */
 	  NSYMSDECODED = NSYMSDECODED + 1;
+
 #ifdef JBIG2_DEBUG
 	  jbig2_error(ctx, JBIG2_SEVERITY_DEBUG, segment->number,
             "%d of %d decoded", NSYMSDECODED, params->SDNUMNEWSYMS);
 #endif
+
 	}
-    }
+     }
 
   jbig2_free(ctx->allocator, GB_stats);
   
@@ -393,22 +482,19 @@
 
   /* 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 && (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(!params.SDHUFF && (flags & 0x0030)) {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
 		  "SDHUFF is zero, but contrary to spec SDHUFFDW is not.");
-    }
+  }
 
-  if (flags & 0x0080)
-    {
+  if (flags & 0x0080) {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
         "bitmap coding context is used (NYI) symbol data likely to be garbage!");
-    }
+  }
 
   /* 7.4.2.1.2 */
   sdat_bytes = params.SDHUFF ? 0 : params.SDTEMPLATE == 0 ? 8 : 2;
@@ -416,13 +502,12 @@
   offset = 2 + sdat_bytes;
 
   /* 7.4.2.1.3 */
-  if (params.SDREFAGG && !params.SDRTEMPLATE)
-    {
+  if (params.SDREFAGG && !params.SDRTEMPLATE) {
       if (offset + 4 > segment->data_length)
 	goto too_short;
       memcpy(params.sdrat, segment_data + offset, 4);
       offset += 4;
-    }
+  }
 
   if (offset + 8 > segment->data_length)
     goto too_short;
@@ -455,19 +540,17 @@
   }
   
   /* 7.4.2.2 (4) */
-  if (!params.SDHUFF)
-    {
+  if (!params.SDHUFF) {
       int stats_size = params.SDTEMPLATE == 0 ? 65536 :
 	params.SDTEMPLATE == 1 ? 8192 : 1024;
       GB_stats = jbig2_alloc(ctx->allocator, stats_size);
       memset(GB_stats, 0, stats_size);
-    }
+  }
 
-  if (flags & 0x0100)
-    {
+  if (flags & 0x0100) {
       jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
         "segment marks bitmap coding context as retained (NYI)");
-    }
+  }
 
   segment->result = (void *)jbig2_decode_symbol_dict(ctx, segment,
 				  &params,