shithub: jbig2

Download patch

ref: a27094d1833bf10c9ab3b612182aa23f4eb3044f
parent: a43f448139d0a72688c9191adab0718b9ef43ec5
author: Shailesh Mistry <shailesh.mistry@hotmail.co.uk>
date: Wed Feb 8 19:00:31 EST 2012

Bug 690974: This patch from Gorac implements the generic refinement region decoding procedure for when TPGRON is TRUE.

--- a/jbig2_refinement.c
+++ b/jbig2_refinement.c
@@ -235,6 +235,116 @@
 }
 
 
+typedef uint32_t (*ContextBuilder)(const Jbig2RefinementRegionParams *,
+Jbig2Image *, int, int);
+
+static int implicit_value( const Jbig2RefinementRegionParams *params, Jbig2Image
+*image, int x, int y )
+{
+  Jbig2Image *ref = params->reference;
+  int i = x - params->DX;
+  int j = y - params->DY;
+  int m = jbig2_image_get_pixel(ref, i, j);
+  return (
+          (jbig2_image_get_pixel(ref, i - 1, j - 1) == m) &&
+          (jbig2_image_get_pixel(ref, i    , j - 1) == m) &&
+          (jbig2_image_get_pixel(ref, i + 1, j - 1) == m) &&
+          (jbig2_image_get_pixel(ref, i - 1, j    ) == m) &&
+          (jbig2_image_get_pixel(ref, i + 1, j    ) == m) &&
+          (jbig2_image_get_pixel(ref, i - 1, j + 1) == m) &&
+          (jbig2_image_get_pixel(ref, i    , j + 1) == m) &&
+          (jbig2_image_get_pixel(ref, i + 1, j + 1) == m)
+         )? m : -1;
+}
+
+static uint32_t mkctx0( const Jbig2RefinementRegionParams *params, Jbig2Image
+*image, int x, int y )
+{
+  const int dx = params->DX;
+  const int dy = params->DY;
+  Jbig2Image *ref = params->reference;
+  uint32_t CONTEXT;
+  CONTEXT  = jbig2_image_get_pixel(image, x - 1, y + 0);
+  CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 1;
+  CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 2;
+  CONTEXT |= jbig2_image_get_pixel(image, x + params->grat[0], y +
+params->grat[1]) << 3;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 1, y - dy + 1) << 4;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy + 1) << 5;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx - 1, y - dy + 1) << 6;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 1, y - dy + 0) << 7;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy + 0) << 8;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx - 1, y - dy + 0) << 9;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 1, y - dy - 1) << 10;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy - 1) << 11;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + params->grat[2], y - dy +
+params->grat[3]) << 12;
+  return CONTEXT;
+}
+
+static uint32_t mkctx1( const Jbig2RefinementRegionParams *params, Jbig2Image
+*image, int x, int y )
+{
+  const int dx = params->DX;
+  const int dy = params->DY;
+  Jbig2Image *ref = params->reference;
+  uint32_t CONTEXT;
+  CONTEXT  = jbig2_image_get_pixel(image, x - 1, y + 0);
+  CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 1;
+  CONTEXT |= jbig2_image_get_pixel(image, x + 0, y - 1) << 2;
+  CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 3;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 1, y - dy + 1) << 4;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy + 1) << 5;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 1, y - dy + 0) << 6;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy + 0) << 7;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx - 1, y - dy + 0) << 8;
+  CONTEXT |= jbig2_image_get_pixel(ref, x - dx + 0, y - dy - 1) << 9;
+  return CONTEXT;
+}
+
+static int jbig2_decode_refinement_TPGRON(const Jbig2RefinementRegionParams
+*params, Jbig2ArithState *as, Jbig2Image *image, Jbig2ArithCx *GR_stats)
+{
+  const int GRW = image->width;
+  const int GRH = image->height;
+  int x, y, iv, bit, LTP = 0;
+  uint32_t start_context = (params->GRTEMPLATE? 0x40   : 0x100);
+  ContextBuilder mkctx   = (params->GRTEMPLATE? mkctx1 : mkctx0);
+
+  for (y = 0; y < GRH; y++)
+  {
+    bit = jbig2_arith_decode(as, &GR_stats[start_context]);
+    if (bit < 0) return -1;
+    LTP = LTP ^ bit;
+    if (!LTP)
+    {
+      for (x = 0; x < GRW; x++)
+      {
+        bit = jbig2_arith_decode(as, &GR_stats[mkctx(params, image, x, y)]);
+        if (bit < 0) return -1;
+        jbig2_image_set_pixel(image, x, y, bit);
+      }
+    }
+    else
+    {
+      for (x = 0; x < GRW; x++)
+      {
+        iv = implicit_value(params, image, x, y);
+        if (iv < 0)
+        {
+          bit = jbig2_arith_decode(as, &GR_stats[mkctx(params, image, x, y)]);
+          if (bit < 0) return -1;
+          jbig2_image_set_pixel(image, x, y, bit);
+        }
+        else jbig2_image_set_pixel(image, x, y, iv);
+      }
+    }
+  }
+
+  return 0;
+}
+
+
 /**
  * jbig2_decode_refinement_region: Decode a generic refinement region.
  * @ctx: The context for allocation and error reporting.
@@ -267,9 +377,10 @@
       params->DX, params->DY, params->GRTEMPLATE, params->TPGRON,
       params->grat[0], params->grat[1], params->grat[2], params->grat[3]);
   }
+
   if (params->TPGRON)
-    return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
-        "decode_refinement_region: typical prediction coding NYI");
+    return jbig2_decode_refinement_TPGRON(params, as, image, GR_stats);
+
   if (params->GRTEMPLATE)
     return jbig2_decode_refinement_template1_unopt(ctx, segment, params,
                                              as, image, GR_stats);