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
commit 6d3bb47655
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 107 additions and 18 deletions

View File

@ -39,6 +39,7 @@ export default [
"test/tmp/", "test/tmp/",
"test/pdfs/", "test/pdfs/",
"web/locale/", "web/locale/",
"web/wasm/",
"**/*~/", "**/*~/",
], ],
}, },

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -651,10 +651,17 @@ function createStandardFontBundle() {
function createWasmBundle() { function createWasmBundle() {
return ordered([ return ordered([
gulp.src(["external/openjpeg/*.wasm", "external/openjpeg/LICENSE_*"], { gulp.src(
[
"external/openjpeg/*.wasm",
"external/openjpeg/openjpeg_nowasm_fallback.js",
"external/openjpeg/LICENSE_*",
],
{
base: "external/openjpeg", base: "external/openjpeg",
encoding: false, encoding: false,
}), }
),
]); ]);
} }

View File

@ -31,18 +31,44 @@ class JpxImage {
static #modulePromise = null; static #modulePromise = null;
static #hasJSFallback = false;
static #wasmUrl = null; static #wasmUrl = null;
static setOptions({ handler, wasmUrl }) { static setOptions({ handler, wasmUrl }) {
if (!this.#buffer) { if (this.#buffer || this.#hasJSFallback || this.#modulePromise) {
return;
}
this.#wasmUrl = wasmUrl || null; this.#wasmUrl = wasmUrl || null;
if (wasmUrl === null) { if (wasmUrl === null) {
this.#handler = handler; this.#handler = handler;
} }
} }
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}`);
} }
static async #instantiateWasm(imports, successCallback) { this.#hasJSFallback = true;
fallbackCallback(instance);
}
static async #instantiateWasm(fallbackCallback, imports, successCallback) {
const filename = "openjpeg.wasm"; const filename = "openjpeg.wasm";
try { try {
if (!this.#buffer) { if (!this.#buffer) {
@ -57,9 +83,13 @@ class JpxImage {
} }
const results = await WebAssembly.instantiate(this.#buffer, imports); const results = await WebAssembly.instantiate(this.#buffer, imports);
return successCallback(results.instance); return successCallback(results.instance);
} catch (reason) {
warn(`JpxImage#instantiateWasm: ${reason}`);
this.#getJsModule(fallbackCallback);
return null;
} finally { } finally {
this.#handler = null; this.#handler = null;
this.#wasmUrl = null;
} }
} }
@ -67,12 +97,26 @@ class JpxImage {
bytes, bytes,
{ numComponents = 4, isIndexedColormap = false, smaskInData = false } = {} { numComponents = 4, isIndexedColormap = false, smaskInData = false } = {}
) { ) {
this.#modulePromise ||= OpenJPEG({ if (!this.#modulePromise) {
const { promise, resolve } = Promise.withResolvers();
const promises = [promise];
if (this.#hasJSFallback) {
this.#getJsModule(resolve);
} else {
promises.push(
OpenJPEG({
warn, warn,
instantiateWasm: this.#instantiateWasm.bind(this), instantiateWasm: this.#instantiateWasm.bind(this, resolve),
}); })
);
}
this.#modulePromise = Promise.race(promises);
}
const module = await this.#modulePromise; const module = await this.#modulePromise;
if (!module) {
throw new JpxError("OpenJPEG failed to initialize");
}
let ptr; let ptr;
try { try {

View File

@ -638,7 +638,7 @@ class Driver {
password: task.password, password: task.password,
cMapUrl: CMAP_URL, cMapUrl: CMAP_URL,
standardFontDataUrl: STANDARD_FONT_DATA_URL, standardFontDataUrl: STANDARD_FONT_DATA_URL,
wasmUrl: WASM_URL, wasmUrl: task.noWasm ? null : WASM_URL,
disableAutoFetch: !task.enableAutoFetch, disableAutoFetch: !task.enableAutoFetch,
pdfBug: true, pdfBug: true,
useSystemFonts: task.useSystemFonts, useSystemFonts: task.useSystemFonts,

View File

@ -6418,6 +6418,14 @@
"rounds": 1, "rounds": 1,
"type": "eq" "type": "eq"
}, },
{
"id": "issue19326_nowasm",
"file": "pdfs/issue19326.pdf",
"md5": "b4d937017daf439a6318501428e0c6ba",
"noWasm": true,
"rounds": 1,
"type": "eq"
},
{ {
"id": "issue19326_main_thread_fetch", "id": "issue19326_main_thread_fetch",
"file": "pdfs/issue19326.pdf", "file": "pdfs/issue19326.pdf",