shithub: jbig2

Download patch

ref: b2686b34d8bcd890424b2670d5884b44001e07a2
parent: 4b88931b21f0795eb90f18a79284332c2b92e583
author: Robin Watts <Robin.Watts@artifex.com>
date: Thu Jan 23 09:45:15 EST 2020

Further optimisation to jbig2_decode_generic_template0_TPGDON.

When the "standard" values for gbat are used, the pixel lookups
simplify nicely. Optimise for this case.

This brings the time spent in this function down to 17% (from 22%)
for JBig2_042_08.pdf.

--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -841,6 +841,69 @@
         return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number,
                            "adaptive template pixel is out of field");
 
+    /* JBig2 has 'standard' values for gbat (see 6.2.5.4 of the spec).
+     * Have an optimised version for those locations. This greatly
+     * simplifies some of the fetches. It's almost like they thought
+     * it through. */
+    if (params->gbat[0] ==  3 && params->gbat[1] == -1 &&
+        params->gbat[2] == -3 && params->gbat[3] == -1 &&
+        params->gbat[4] ==  2 && params->gbat[5] == -2 &&
+        params->gbat[6] == -2 && params->gbat[7] == -2)
+    {
+        right = GBW-9; /* To allow us to use get_pixels */
+        for (y = 0; y < GBH; y++) {
+            LTP ^= jbig2_arith_decode(as, &GB_stats[0x9B25], &code);
+            if (code)
+                return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON1");
+            if (!LTP) {
+                for (x = 0; x < GBW; x++) {
+                    if (params->USESKIP && jbig2_image_get_pixel(params->SKIP, x, y)) {
+                        jbig2_image_set_pixel_fast(image, x, y, 0);
+                        continue;
+                    }
+                    if (y >= 2 && x >= 4 && x < right)
+                    {
+                        CONTEXT  = jbig2_image_get_pixels_fast(image, x - 4, y,     4);
+                        CONTEXT |= jbig2_image_get_pixels_fast(image, x - 3, y - 1, 7) << 4;
+                        CONTEXT |= jbig2_image_get_pixels_fast(image, x - 2, y - 2, 5) << 11;
+                    }
+                    else
+                    {
+                        CONTEXT  = jbig2_image_get_pixel(image, x - 1, y);
+                        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;
+                        if (y >= 1)
+                        {
+                            CONTEXT |= jbig2_image_get_pixel(image, x + 3, y - 1) << 4;
+                            CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 1) << 5;
+                            CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 1) << 6;
+                            CONTEXT |= jbig2_image_get_pixel(image, x,     y - 1) << 7;
+                            CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 1) << 8;
+                            CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 1) << 9;
+                            CONTEXT |= jbig2_image_get_pixel(image, x - 3, y - 1) << 10;
+                        }
+                        if (y >= 2)
+                        {
+                            CONTEXT |= jbig2_image_get_pixel(image, x + 2, y - 2) << 11;
+                            CONTEXT |= jbig2_image_get_pixel(image, x + 1, y - 2) << 12;
+                            CONTEXT |= jbig2_image_get_pixel(image, x,     y - 2) << 13;
+                            CONTEXT |= jbig2_image_get_pixel(image, x - 1, y - 2) << 14;
+                            CONTEXT |= jbig2_image_get_pixel(image, x - 2, y - 2) << 15;
+                        }
+                    }
+                    bit = jbig2_arith_decode(as, &GB_stats[CONTEXT], &code);
+                    if (code)
+                        return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, segment->number, "failed to decode arithmetic code when handling generic template0 TPGDON2");
+                    jbig2_image_set_pixel_fast(image, x, y, bit);
+                }
+            } else {
+                copy_prev_row(image, y);
+            }
+        }
+        return 0;
+    }
+
     /* We divide the width into 3 regions 0..left...right...GBW,
      * between left and right, we know that our accesses will never
      * step outside the image, enabling us to use faster accessors. */