shithub: jbig2

Download patch

ref: 2b6179196091f01a58c17a79024d7ee5243ab8a2
parent: b8fc23e4731a172600282a65e9602ff1963bfead
author: giles <giles@ded80894-8fb9-0310-811b-c03f3676ab4d>
date: Sat Dec 4 22:48:36 EST 2004

Add a generic but unoptimized handler for generic region arithmetic 
template 3, and an optimized but untested handler for the default AT 
pixel position. We now properly decode 042_6.jb2 from the UBC test 
suite.


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

--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,8 @@
  * properly initialize page buffers
  * refinement region handling
  * successfully decodes ubc test streams 042_21, 042_22 and 042_23
+ * generic region template 3 handling with arbitrary AT locations
+ * seccussfully decodes ubc test stream 042_6
  
 Version 0.6 (2003 December 31)
 
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -314,6 +314,105 @@
   return 0;
 }
 
+static int
+jbig2_decode_generic_template3(Jbig2Ctx *ctx,
+			       Jbig2Segment *segment,
+			       const Jbig2GenericRegionParams *params,
+			       Jbig2ArithState *as,
+			       Jbig2Image *image,
+			       Jbig2ArithCx *GB_stats)
+{
+  const int GBW = image->width;
+  const int GBH = image->height;
+  const int rowstride = image->stride;
+  byte *gbreg_line = (byte *)image->data;
+  int x, y;
+
+  /* this routine only handles the nominal AT location */
+
+#ifdef OUTPUT_PBM
+  printf("P4\n%d %d\n", GBW, GBH);
+#endif
+
+  for (y = 0; y < GBH; y++)
+    {
+      uint32_t CONTEXT;
+      uint32_t line_m1;
+      int padded_width = (GBW + 7) & -8;
+
+      line_m1 = (y >= 1) ? gbreg_line[-rowstride] : 0;
+      CONTEXT = (line_m1 >> 1) & 0x3f0;
+
+      /* 6.2.5.7 3d */
+      for (x = 0; x < padded_width; x += 8)
+	{
+	  byte result = 0;
+	  int x_minor;
+	  int minor_width = GBW - x > 8 ? 8 : GBW - x;
+
+	  if (y >= 1)
+	    line_m1 = (line_m1 << 8) |
+	      (x + 8 < GBW ? gbreg_line[-rowstride + (x >> 3) + 1] : 0);
+
+	  /* This is the speed-critical inner loop. */
+	  for (x_minor = 0; x_minor < minor_width; x_minor++)
+	    {
+	      bool bit;
+
+	      bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+	      result |= bit << (7 - x_minor);
+	      CONTEXT = ((CONTEXT & 0x1f7) << 1) | bit |
+		((line_m1 >> (10 - x_minor)) & 0x010);
+	    }
+	  gbreg_line[x >> 3] = result;
+	}
+#ifdef OUTPUT_PBM
+      fwrite(gbreg_line, 1, rowstride, stdout);
+#endif
+      gbreg_line += rowstride;
+    }
+
+  return 0;
+}
+
+static int
+jbig2_decode_generic_template3_unopt(Jbig2Ctx *ctx,
+                               Jbig2Segment *segment,
+                               const Jbig2GenericRegionParams *params,
+                               Jbig2ArithState *as,
+                               Jbig2Image *image,
+                               Jbig2ArithCx *GB_stats)
+{
+  const int GBW = image->width;
+  const int GBH = image->height;
+  uint32_t CONTEXT;
+  int x,y;
+  bool bit;
+
+  /* this version is generic and easy to understand, but very slow */
+
+  for (y = 0; y < GBH; y++) {
+    for (x = 0; x < GBW; x++) {
+      CONTEXT = 0;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 1, y) << 0;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 2, y) << 1;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 3, y) << 2;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 4, y) << 3;
+      CONTEXT |= jbig2_image_get_pixel(image, x + params->gbat[0],
+	y + params->gbat[1]) << 4;
+      CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 5;
+      CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 6;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 7;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 8;
+      CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 9;
+      bit = jbig2_arith_decode(as, &GB_stats[CONTEXT]);
+      jbig2_image_set_pixel(image, x, y, bit);
+    }
+  }
+  return 0;
+}
+
+
 /**
  * jbig2_decode_generic_region: Decode a generic region.
  * @ctx: The context for allocation and error reporting.
@@ -354,6 +453,15 @@
 	return jbig2_decode_generic_template2(ctx, segment, params,
                                               as, image, GB_stats);
     }
+  else if (!params->MMR && params->GBTEMPLATE == 3) {
+   if (params->gbat[0] == 2 && params->gbat[1] == -1)
+     return jbig2_decode_generic_template3_unopt(ctx, segment, params,
+                                         as, image, GB_stats);
+   else
+     return jbig2_decode_generic_template3_unopt(ctx, segment, params,
+                                         as, image, GB_stats);
+  }
+
   {
     int i;
     for (i = 0; i < 8; i++)