From a4440a1c6bf96707caa2bcc5e45a1b49c40d794d Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 1 Feb 2020 11:42:22 +0100 Subject: [PATCH] Avoid re-calculating the `xScaleBlockOffset` when not necessary in `JpegImage._getLinearizedBlockData` As can be seen in the code, the `xScaleBlockOffset` typed array doesn't depend on the actual image data but only on the width and x-scale. The width is obviously consistent for an image, and it turns out that in practice the `componentScaleX` is quite often identical between two (or more) adjacent image components. All-in-all it's thus not necessary to *unconditionally* re-compute the `xScaleBlockOffset` when getting the JPEG image data. While avoiding, in many cases, one or more loops can never be a bad thing these changes are unfortunately completely dominated by the rest of the JpegImage code and consequently doesn't really show up in benchmark results. *Hence I'd understand if this patch is ultimately deemed not necessary.* --- src/core/jpg.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/jpg.js b/src/core/jpg.js index 5f973ba6e..9abc8de80 100644 --- a/src/core/jpg.js +++ b/src/core/jpg.js @@ -1105,6 +1105,7 @@ var JpegImage = (function JpegImageClosure() { var data = new Uint8ClampedArray(dataLength); var xScaleBlockOffset = new Uint32Array(width); var mask3LSB = 0xfffffff8; // used to clear the 3 LSBs + let lastComponentScaleX; for (i = 0; i < numComponents; i++) { component = this.components[i]; @@ -1113,10 +1114,14 @@ var JpegImage = (function JpegImageClosure() { offset = i; output = component.output; blocksPerScanline = (component.blocksPerLine + 1) << 3; - // precalculate the xScaleBlockOffset - for (x = 0; x < width; x++) { - j = 0 | (x * componentScaleX); - xScaleBlockOffset[x] = ((j & mask3LSB) << 3) | (j & 7); + // Precalculate the `xScaleBlockOffset`. Since it doesn't depend on the + // component data, that's only necessary when `componentScaleX` changes. + if (componentScaleX !== lastComponentScaleX) { + for (x = 0; x < width; x++) { + j = 0 | (x * componentScaleX); + xScaleBlockOffset[x] = ((j & mask3LSB) << 3) | (j & 7); + } + lastComponentScaleX = componentScaleX; } // linearize the blocks of the component for (y = 0; y < height; y++) {