mirror of
https://github.com/mozilla/pdf.js.git
synced 2025-04-26 10:08:06 +02:00
Improve performance with image masks (bug 857031)
- it aims to partially fix performance issue reported: https://bugzilla.mozilla.org/show_bug.cgi?id=857031; - the idea is too avoid to use byte arrays but use ImageBitmap which are a way faster to draw: * an ImageBitmap is Transferable which means that it can be built in the worker instead of in the main thread: - this is achieved in using an OffscreenCanvas when it's available, there is a bug to enable them for pdf.js: https://bugzilla.mozilla.org/show_bug.cgi?id=1763330; - or in using createImageBitmap: in Firefox a task is sent to the main thread to build the bitmap so it's slightly slower than using an OffscreenCanvas. * it's transfered from the worker to the main thread by "reference"; * the byte buffers used to create the image data have a very short lifetime and ergo the memory used is globally less than before. - Use the localImageCache for the mask; - Fix the pdf issue4436r.pdf: it was expected to have a binary stream for the image; - Move the singlePixel trick from operator_list to image: this way we can use this trick even if it isn't in a set as defined in operator_list.
This commit is contained in:
parent
2b673a6941
commit
040fcae5ab
11 changed files with 256 additions and 65 deletions
|
@ -13,7 +13,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { assert, FormatError, ImageKind, info, warn } from "../shared/util.js";
|
||||
import {
|
||||
assert,
|
||||
FeatureTest,
|
||||
FormatError,
|
||||
ImageKind,
|
||||
info,
|
||||
warn,
|
||||
} from "../shared/util.js";
|
||||
import { applyMaskImageData } from "../shared/image_utils.js";
|
||||
import { BaseStream } from "./base_stream.js";
|
||||
import { ColorSpace } from "./colorspace.js";
|
||||
import { DecodeStream } from "./decode_stream.js";
|
||||
|
@ -288,7 +296,7 @@ class PDFImage {
|
|||
});
|
||||
}
|
||||
|
||||
static createMask({
|
||||
static createRawMask({
|
||||
imgArray,
|
||||
width,
|
||||
height,
|
||||
|
@ -302,7 +310,7 @@ class PDFImage {
|
|||
) {
|
||||
assert(
|
||||
imgArray instanceof Uint8ClampedArray,
|
||||
'PDFImage.createMask: Unsupported "imgArray" type.'
|
||||
'PDFImage.createRawMask: Unsupported "imgArray" type.'
|
||||
);
|
||||
}
|
||||
// |imgArray| might not contain full data for every pixel of the mask, so
|
||||
|
@ -343,6 +351,69 @@ class PDFImage {
|
|||
return { data, width, height, interpolate };
|
||||
}
|
||||
|
||||
static createMask({
|
||||
imgArray,
|
||||
width,
|
||||
height,
|
||||
imageIsFromDecodeStream,
|
||||
inverseDecode,
|
||||
interpolate,
|
||||
}) {
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
imgArray instanceof Uint8ClampedArray,
|
||||
'PDFImage.createMask: Unsupported "imgArray" type.'
|
||||
);
|
||||
}
|
||||
|
||||
const isSingleOpaquePixel =
|
||||
width === 1 &&
|
||||
height === 1 &&
|
||||
inverseDecode === (imgArray.length === 0 || !!(imgArray[0] & 128));
|
||||
|
||||
if (isSingleOpaquePixel) {
|
||||
return { isSingleOpaquePixel };
|
||||
}
|
||||
|
||||
if (FeatureTest.isOffscreenCanvasSupported) {
|
||||
const canvas = new OffscreenCanvas(width, height);
|
||||
const ctx = canvas.getContext("2d");
|
||||
const imgData = ctx.createImageData(width, height);
|
||||
applyMaskImageData({
|
||||
src: imgArray,
|
||||
dest: imgData.data,
|
||||
width,
|
||||
height,
|
||||
inverseDecode,
|
||||
});
|
||||
|
||||
ctx.putImageData(imgData, 0, 0);
|
||||
const bitmap = canvas.transferToImageBitmap();
|
||||
|
||||
return {
|
||||
data: null,
|
||||
width,
|
||||
height,
|
||||
interpolate,
|
||||
bitmap,
|
||||
};
|
||||
}
|
||||
|
||||
// Get the data almost as they're and they'll be decoded
|
||||
// just before being drawn.
|
||||
return this.createRawMask({
|
||||
imgArray,
|
||||
width,
|
||||
height,
|
||||
inverseDecode,
|
||||
imageIsFromDecodeStream,
|
||||
interpolate,
|
||||
});
|
||||
}
|
||||
|
||||
get drawWidth() {
|
||||
return Math.max(
|
||||
this.width,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue