Merge pull request #19525 from calixteman/bug1935076_part2

Provide a js fallback when the wasm version of openjpeg is failing to load (bug 1935076)
This commit is contained in:
Jonas Jenwald
2025-02-22 09:34:40 +01:00
committed by GitHub
8 changed files with 107 additions and 18 deletions
+1
View File
@@ -39,6 +39,7 @@ export default [
"test/tmp/",
"test/pdfs/",
"web/locale/",
"web/wasm/",
"**/*~/",
],
},
+1 -1
View File
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.
File diff suppressed because one or more lines are too long
+11 -4
View File
@@ -651,10 +651,17 @@ function createStandardFontBundle() {
function createWasmBundle() {
return ordered([
gulp.src(["external/openjpeg/*.wasm", "external/openjpeg/LICENSE_*"], {
base: "external/openjpeg",
encoding: false,
}),
gulp.src(
[
"external/openjpeg/*.wasm",
"external/openjpeg/openjpeg_nowasm_fallback.js",
"external/openjpeg/LICENSE_*",
],
{
base: "external/openjpeg",
encoding: false,
}
),
]);
}
+56 -12
View File
@@ -31,18 +31,44 @@ class JpxImage {
static #modulePromise = null;
static #hasJSFallback = false;
static #wasmUrl = null;
static setOptions({ handler, wasmUrl }) {
if (!this.#buffer) {
this.#wasmUrl = wasmUrl || null;
if (wasmUrl === null) {
this.#handler = handler;
}
if (this.#buffer || this.#hasJSFallback || this.#modulePromise) {
return;
}
this.#wasmUrl = wasmUrl || null;
if (wasmUrl === null) {
this.#handler = handler;
}
}
static async #instantiateWasm(imports, successCallback) {
static async #getJsModule(fallbackCallback) {
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("TESTING")) {
this.#wasmUrl ??= "/build/generic/web/wasm/";
}
const path =
typeof PDFJSDev === "undefined"
? `../${this.#wasmUrl}openjpeg_nowasm_fallback.js`
: `${this.#wasmUrl}openjpeg_nowasm_fallback.js`;
let instance = null;
try {
const mod = await (typeof PDFJSDev === "undefined"
? import(path) // eslint-disable-line no-unsanitized/method
: __non_webpack_import__(path));
instance = mod.default();
} catch (e) {
warn(`JpxImage#getJsModule: ${e}`);
}
this.#hasJSFallback = true;
fallbackCallback(instance);
}
static async #instantiateWasm(fallbackCallback, imports, successCallback) {
const filename = "openjpeg.wasm";
try {
if (!this.#buffer) {
@@ -57,9 +83,13 @@ class JpxImage {
}
const results = await WebAssembly.instantiate(this.#buffer, imports);
return successCallback(results.instance);
} catch (reason) {
warn(`JpxImage#instantiateWasm: ${reason}`);
this.#getJsModule(fallbackCallback);
return null;
} finally {
this.#handler = null;
this.#wasmUrl = null;
}
}
@@ -67,12 +97,26 @@ class JpxImage {
bytes,
{ numComponents = 4, isIndexedColormap = false, smaskInData = false } = {}
) {
this.#modulePromise ||= OpenJPEG({
warn,
instantiateWasm: this.#instantiateWasm.bind(this),
});
if (!this.#modulePromise) {
const { promise, resolve } = Promise.withResolvers();
const promises = [promise];
if (this.#hasJSFallback) {
this.#getJsModule(resolve);
} else {
promises.push(
OpenJPEG({
warn,
instantiateWasm: this.#instantiateWasm.bind(this, resolve),
})
);
}
this.#modulePromise = Promise.race(promises);
}
const module = await this.#modulePromise;
if (!module) {
throw new JpxError("OpenJPEG failed to initialize");
}
let ptr;
try {
+1 -1
View File
@@ -638,7 +638,7 @@ class Driver {
password: task.password,
cMapUrl: CMAP_URL,
standardFontDataUrl: STANDARD_FONT_DATA_URL,
wasmUrl: WASM_URL,
wasmUrl: task.noWasm ? null : WASM_URL,
disableAutoFetch: !task.enableAutoFetch,
pdfBug: true,
useSystemFonts: task.useSystemFonts,
+8
View File
@@ -6418,6 +6418,14 @@
"rounds": 1,
"type": "eq"
},
{
"id": "issue19326_nowasm",
"file": "pdfs/issue19326.pdf",
"md5": "b4d937017daf439a6318501428e0c6ba",
"noWasm": true,
"rounds": 1,
"type": "eq"
},
{
"id": "issue19326_main_thread_fetch",
"file": "pdfs/issue19326.pdf",