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++)