Bug 690974 - .. more on typical prediction in jbig2dec
Summary: .. more on typical prediction in jbig2dec
Status: RESOLVED FIXED
Alias: None
Product: jbig2dec
Classification: Unclassified
Component: Rendering (show other bugs)
Version: unspecified
Hardware: PC Windows XP
: P4 normal
Assignee: Henry Stiles
URL:
Keywords: bountiable
: 691245 (view as bug list)
Depends on:
Blocks:
 
Reported: 2009-12-03 05:17 UTC by gorac
Modified: 2012-02-27 00:16 UTC (History)
3 users (show)

See Also:
Customer:
Word Size: ---


Attachments
Gorac's patch for Bug690974 (5.08 KB, patch)
2012-02-04 22:20 UTC, Shailesh Mistry
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description gorac 2009-12-03 05:17:45 UTC
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
Comment 1 Shailesh Mistry 2012-02-04 22:20:58 UTC
Created attachment 8334 [details]
Gorac's patch for Bug690974

This is Gorac's code in patch form, the cluster test shows that Jbig2_042_24.pdf now renders correctly and there are no new regressions.
Comment 2 Henry Stiles 2012-02-08 14:36:44 UTC
(In reply to comment #1)
> Created an attachment (id=8334) [details]
> Gorac's patch for Bug690974
> 
> This is Gorac's code in patch form, the cluster test shows that
> Jbig2_042_24.pdf now renders correctly and there are no new regressions.

Gorac and the staff had difficulty communicating and we don't expect to hear from him, let's take his post to be implicit approval to include his code under Artifex and GPL license.  If he objects we'll pull it out and do an original implementation.
Comment 3 Henry Stiles 2012-02-08 16:46:56 UTC
*** Bug 691245 has been marked as a duplicate of this bug. ***
Comment 4 Shailesh Mistry 2012-02-09 00:01:56 UTC
Patch committed in 082c31b99fd38ebb1a9bc678d06ac9791db2e222