[gs-bugs] [Bug 690974] New: .. more on typical prediction in jbig2dec

bugs.ghostscript.com-bugzilla-daemon at ghostscript.com bugs.ghostscript.com-bugzilla-daemon at ghostscript.com
Thu Dec 3 05:17:46 PST 2009


http://bugs.ghostscript.com/show_bug.cgi?id=690974

           Summary: .. more on typical prediction in jbig2dec
           Product: jbig2dec
           Version: unspecified
          Platform: PC
        OS/Version: Windows XP
            Status: UNCONFIRMED
          Severity: normal
          Priority: P4
         Component: Rendering
        AssignedTo: ralph.giles at artifex.com
        ReportedBy: drugo.pedrouvene at gmail.com
         QAContact: gs-bugs at ghostscript.com


Actually typical prediction in generic refinement region decoding procedure is
not yet implemented in jbig2dec (case TPGRON == TRUE, reference: 042_24.jb2 test
stream). The following simple code, added to jbig2_refinement.c, implements this
case.

1) in routine jbig2_decode_refinement_region() change the statement at second line:

    if (params->TPGRON)
       return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number,
       "decode_refinement_region: typical prediction coding NYI");
   
   with this one:
   
    if (params->TPGRON) 
       return jbig2_decode_refinement_TPGRON(params, as, image, GR_stats);

2) add to the same source file the following code:


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;
  const int dx  = params->DX;
  const int dy  = params->DY;
  Jbig2Image *ref = params->reference;
  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;
}


That's all. In my test this implementation works fine and correctly decode the
test stream cited.

Gorac



------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.


More information about the gs-bugs mailing list