ref: 4b88931b21f0795eb90f18a79284332c2b92e583
parent: 8a5ad7cc54f23fb99e231be3a123d6488829dc9e
author: Robin Watts <Robin.Watts@artifex.com>
date: Thu Jan 23 07:55:27 EST 2020
Further optimisations to jbig2_decode_generic_template0_TPGDON. Add a function to get a 'run' of pixels, and call that. This takes the time spent in this function from 29% to 22% for Jbig2_042_08.pdf.
--- a/jbig2_generic.c
+++ b/jbig2_generic.c
@@ -863,6 +863,10 @@
left = -gmin;
if (right < gmax)
right = gmax;
+ /* We need to guarantee 9 pixels in the right margin to be able
+ * to use jbig2_image_get_pixels_fast. */
+ if (right < 9)
+ right = 9;
right = GBW - right;
/* So 0 <= x < left or right <= x < GBW needs bounds checking. */
@@ -892,21 +896,12 @@
}
if (y >= top && x >= left && x < right)
{
- CONTEXT = jbig2_image_get_pixel_fast(image, x - 1, y);
- CONTEXT |= jbig2_image_get_pixel_fast(image, x - 2, y) << 1;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x - 3, y) << 2;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x - 4, y) << 3;
+ CONTEXT = jbig2_image_get_pixels_fast(image, x - 4, y, 4);
CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[0], y + params->gbat[1]) << 4;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + 2, y - 1) << 5;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + 1, y - 1) << 6;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x, y - 1) << 7;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x - 1, y - 1) << 8;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x - 2, y - 1) << 9;
+ CONTEXT |= jbig2_image_get_pixels_fast(image, x - 2, y - 1, 5) << 5;
CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[2], y + params->gbat[3]) << 10;
CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[4], y + params->gbat[5]) << 11;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x + 1, y - 2) << 12;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x, y - 2) << 13;
- CONTEXT |= jbig2_image_get_pixel_fast(image, x - 1, y - 2) << 14;
+ CONTEXT |= jbig2_image_get_pixels_fast(image, x - 1, y - 2, 3) << 12;
CONTEXT |= jbig2_image_get_pixel_fast(image, x + params->gbat[6], y + params->gbat[7]) << 15;
}
else
--- a/jbig2_image.h
+++ b/jbig2_image.h
@@ -39,6 +39,7 @@
int jbig2_image_get_pixel(Jbig2Image *image, int x, int y);
void jbig2_image_set_pixel(Jbig2Image *image, int x, int y, bool value);
+/* Get a bit. No bounds checking. */
static inline int
jbig2_image_get_pixel_fast(Jbig2Image *image, int x, int y)
{
@@ -48,7 +49,20 @@
return ((image->data[byte] >> bit) & 1);
}
-/* set an individual pixel value in an image */
+/* Get a run of up to 9 bits. This reads into the next byte, so the caller
+ * must ensure that we are always safe to read at least 9 pixels, even if
+ * it only wants less than that. */
+static inline int
+jbig2_image_get_pixels_fast(Jbig2Image *image, int x, int y, int bits)
+{
+ const int byte = (x >> 3) + y * image->stride;
+ const int bit = 7 - (x & 7);
+ int v = ((image->data[byte]<<8) | (image->data[byte+1]))>>(bit+9-bits);
+
+ return v & ((1<<bits)-1);
+}
+
+/* set an individual pixel value in an image - no bounds checking */
static inline void
jbig2_image_set_pixel_fast(Jbig2Image *image, int x, int y, bool value)
{