mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-05-23 19:30:59 +02:00
Merge pull request #19329 from calixteman/bug1935076_1
[api-major] Add openjpeg.wasm to pdf.js (bug 1935076)
This commit is contained in:
commit
7a57af12e1
5
external/openjpeg/openjpeg.js
vendored
5
external/openjpeg/openjpeg.js
vendored
File diff suppressed because one or more lines are too long
BIN
external/openjpeg/openjpeg.wasm
vendored
Normal file
BIN
external/openjpeg/openjpeg.wasm
vendored
Normal file
Binary file not shown.
16
gulpfile.mjs
16
gulpfile.mjs
@ -192,6 +192,7 @@ function createWebpackAlias(defines) {
|
|||||||
const libraryAlias = {
|
const libraryAlias = {
|
||||||
"display-cmap_reader_factory": "src/display/stubs.js",
|
"display-cmap_reader_factory": "src/display/stubs.js",
|
||||||
"display-standard_fontdata_factory": "src/display/stubs.js",
|
"display-standard_fontdata_factory": "src/display/stubs.js",
|
||||||
|
"display-wasm_factory": "src/display/stubs.js",
|
||||||
"display-fetch_stream": "src/display/stubs.js",
|
"display-fetch_stream": "src/display/stubs.js",
|
||||||
"display-network": "src/display/stubs.js",
|
"display-network": "src/display/stubs.js",
|
||||||
"display-node_stream": "src/display/stubs.js",
|
"display-node_stream": "src/display/stubs.js",
|
||||||
@ -224,6 +225,7 @@ function createWebpackAlias(defines) {
|
|||||||
"src/display/cmap_reader_factory.js";
|
"src/display/cmap_reader_factory.js";
|
||||||
libraryAlias["display-standard_fontdata_factory"] =
|
libraryAlias["display-standard_fontdata_factory"] =
|
||||||
"src/display/standard_fontdata_factory.js";
|
"src/display/standard_fontdata_factory.js";
|
||||||
|
libraryAlias["display-wasm_factory"] = "src/display/wasm_factory.js";
|
||||||
libraryAlias["display-fetch_stream"] = "src/display/fetch_stream.js";
|
libraryAlias["display-fetch_stream"] = "src/display/fetch_stream.js";
|
||||||
libraryAlias["display-network"] = "src/display/network.js";
|
libraryAlias["display-network"] = "src/display/network.js";
|
||||||
|
|
||||||
@ -240,6 +242,7 @@ function createWebpackAlias(defines) {
|
|||||||
"src/display/cmap_reader_factory.js";
|
"src/display/cmap_reader_factory.js";
|
||||||
libraryAlias["display-standard_fontdata_factory"] =
|
libraryAlias["display-standard_fontdata_factory"] =
|
||||||
"src/display/standard_fontdata_factory.js";
|
"src/display/standard_fontdata_factory.js";
|
||||||
|
libraryAlias["display-wasm_factory"] = "src/display/wasm_factory.js";
|
||||||
libraryAlias["display-fetch_stream"] = "src/display/fetch_stream.js";
|
libraryAlias["display-fetch_stream"] = "src/display/fetch_stream.js";
|
||||||
libraryAlias["display-network"] = "src/display/network.js";
|
libraryAlias["display-network"] = "src/display/network.js";
|
||||||
libraryAlias["display-node_stream"] = "src/display/node_stream.js";
|
libraryAlias["display-node_stream"] = "src/display/node_stream.js";
|
||||||
@ -646,6 +649,13 @@ function createStandardFontBundle() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createWasmBundle() {
|
||||||
|
return gulp.src(["external/openjpeg/openjpeg.wasm"], {
|
||||||
|
base: "external/openjpeg",
|
||||||
|
encoding: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function checkFile(filePath) {
|
function checkFile(filePath) {
|
||||||
try {
|
try {
|
||||||
const stat = fs.lstatSync(filePath);
|
const stat = fs.lstatSync(filePath);
|
||||||
@ -1068,6 +1078,7 @@ function buildGeneric(defines, dir) {
|
|||||||
.pipe(gulp.dest(dir + "web")),
|
.pipe(gulp.dest(dir + "web")),
|
||||||
createCMapBundle().pipe(gulp.dest(dir + "web/cmaps")),
|
createCMapBundle().pipe(gulp.dest(dir + "web/cmaps")),
|
||||||
createStandardFontBundle().pipe(gulp.dest(dir + "web/standard_fonts")),
|
createStandardFontBundle().pipe(gulp.dest(dir + "web/standard_fonts")),
|
||||||
|
createWasmBundle().pipe(gulp.dest(dir + "web/wasm")),
|
||||||
|
|
||||||
preprocessHTML("web/viewer.html", defines).pipe(gulp.dest(dir + "web")),
|
preprocessHTML("web/viewer.html", defines).pipe(gulp.dest(dir + "web")),
|
||||||
preprocessCSS("web/viewer.css", defines)
|
preprocessCSS("web/viewer.css", defines)
|
||||||
@ -1398,6 +1409,7 @@ gulp.task(
|
|||||||
createStandardFontBundle().pipe(
|
createStandardFontBundle().pipe(
|
||||||
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/standard_fonts")
|
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/standard_fonts")
|
||||||
),
|
),
|
||||||
|
createWasmBundle().pipe(gulp.dest(MOZCENTRAL_CONTENT_DIR + "web/wasm")),
|
||||||
|
|
||||||
preprocessHTML("web/viewer.html", defines).pipe(
|
preprocessHTML("web/viewer.html", defines).pipe(
|
||||||
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web")
|
gulp.dest(MOZCENTRAL_CONTENT_DIR + "web")
|
||||||
@ -1500,6 +1512,9 @@ gulp.task(
|
|||||||
createStandardFontBundle().pipe(
|
createStandardFontBundle().pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/standard_fonts")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/standard_fonts")
|
||||||
),
|
),
|
||||||
|
createWasmBundle().pipe(
|
||||||
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web/wasm")
|
||||||
|
),
|
||||||
|
|
||||||
preprocessHTML("web/viewer.html", defines).pipe(
|
preprocessHTML("web/viewer.html", defines).pipe(
|
||||||
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
|
gulp.dest(CHROME_BUILD_CONTENT_DIR + "web")
|
||||||
@ -1586,6 +1601,7 @@ function buildLibHelper(bundleDefines, inputStream, outputDir) {
|
|||||||
"pdfjs-lib": "../pdf.js",
|
"pdfjs-lib": "../pdf.js",
|
||||||
"display-cmap_reader_factory": "./cmap_reader_factory.js",
|
"display-cmap_reader_factory": "./cmap_reader_factory.js",
|
||||||
"display-standard_fontdata_factory": "./standard_fontdata_factory.js",
|
"display-standard_fontdata_factory": "./standard_fontdata_factory.js",
|
||||||
|
"display-wasm_factory": "./wasm_factory.js",
|
||||||
"display-fetch_stream": "./fetch_stream.js",
|
"display-fetch_stream": "./fetch_stream.js",
|
||||||
"display-network": "./network.js",
|
"display-network": "./network.js",
|
||||||
"display-node_stream": "./node_stream.js",
|
"display-node_stream": "./node_stream.js",
|
||||||
|
|||||||
@ -64,6 +64,10 @@ class BaseStream {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isAsyncDecoder() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
get canAsyncDecodeImageFromBuffer() {
|
get canAsyncDecodeImageFromBuffer() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -99,8 +99,11 @@ class DecodeStream extends BaseStream {
|
|||||||
return this.buffer.subarray(pos, end);
|
return this.buffer.subarray(pos, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getImageData(length, decoderOptions = null) {
|
async getImageData(length, decoderOptions) {
|
||||||
if (!this.canAsyncDecodeImageFromBuffer) {
|
if (!this.canAsyncDecodeImageFromBuffer) {
|
||||||
|
if (this.isAsyncDecoder) {
|
||||||
|
return this.decodeImage(null, decoderOptions);
|
||||||
|
}
|
||||||
return this.getBytes(length, decoderOptions);
|
return this.getBytes(length, decoderOptions);
|
||||||
}
|
}
|
||||||
const data = await this.stream.asyncGetBytes();
|
const data = await this.stream.asyncGetBytes();
|
||||||
|
|||||||
@ -72,6 +72,7 @@ import { getMetrics } from "./metrics.js";
|
|||||||
import { getUnicodeForGlyph } from "./unicode.js";
|
import { getUnicodeForGlyph } from "./unicode.js";
|
||||||
import { ImageResizer } from "./image_resizer.js";
|
import { ImageResizer } from "./image_resizer.js";
|
||||||
import { JpegStream } from "./jpeg_stream.js";
|
import { JpegStream } from "./jpeg_stream.js";
|
||||||
|
import { JpxImage } from "./jpx.js";
|
||||||
import { MurmurHash3_64 } from "../shared/murmurhash3.js";
|
import { MurmurHash3_64 } from "../shared/murmurhash3.js";
|
||||||
import { OperatorList } from "./operator_list.js";
|
import { OperatorList } from "./operator_list.js";
|
||||||
import { PDFImage } from "./image.js";
|
import { PDFImage } from "./image.js";
|
||||||
@ -89,6 +90,7 @@ const DefaultPartialEvaluatorOptions = Object.freeze({
|
|||||||
useSystemFonts: true,
|
useSystemFonts: true,
|
||||||
cMapUrl: null,
|
cMapUrl: null,
|
||||||
standardFontDataUrl: null,
|
standardFontDataUrl: null,
|
||||||
|
wasmUrl: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const PatternType = {
|
const PatternType = {
|
||||||
@ -236,6 +238,10 @@ class PartialEvaluator {
|
|||||||
|
|
||||||
ImageResizer.setOptions(this.options);
|
ImageResizer.setOptions(this.options);
|
||||||
JpegStream.setOptions(this.options);
|
JpegStream.setOptions(this.options);
|
||||||
|
JpxImage.setOptions({
|
||||||
|
wasmUrl: this.options.wasmUrl,
|
||||||
|
handler,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -24,20 +24,97 @@ class JpxError extends BaseException {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class JpxImage {
|
class JpxImage {
|
||||||
static #module = null;
|
static #buffer = null;
|
||||||
|
|
||||||
static decode(data, decoderOptions) {
|
static #handler = null;
|
||||||
decoderOptions ||= {};
|
|
||||||
this.#module ||= OpenJPEG({ warn });
|
static #instantiationFailed = false;
|
||||||
const imageData = this.#module.decode(data, decoderOptions);
|
|
||||||
if (typeof imageData === "string") {
|
static #modulePromise = null;
|
||||||
throw new JpxError(imageData);
|
|
||||||
|
static #wasmUrl = null;
|
||||||
|
|
||||||
|
static setOptions({ handler, wasmUrl }) {
|
||||||
|
if (!this.#buffer) {
|
||||||
|
this.#wasmUrl = wasmUrl || null;
|
||||||
|
if (wasmUrl === null) {
|
||||||
|
this.#handler = handler;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #instantiateWasm(imports, successCallback) {
|
||||||
|
try {
|
||||||
|
if (!this.#buffer) {
|
||||||
|
if (this.#wasmUrl !== null) {
|
||||||
|
const response = await fetch(`${this.#wasmUrl}openjpeg.wasm`);
|
||||||
|
this.#buffer = await response.arrayBuffer();
|
||||||
|
} else {
|
||||||
|
this.#buffer = await this.#handler.sendWithPromise("FetchWasm", {
|
||||||
|
filename: "openjpeg.wasm",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const results = await WebAssembly.instantiate(this.#buffer, imports);
|
||||||
|
return successCallback(results.instance);
|
||||||
|
} catch (e) {
|
||||||
|
this.#instantiationFailed = true;
|
||||||
|
warn(`Cannot load openjpeg.wasm: "${e}".`);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
this.#handler = null;
|
||||||
|
this.#wasmUrl = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async decode(
|
||||||
|
bytes,
|
||||||
|
{ numComponents = 4, isIndexedColormap = false, smaskInData = false } = {}
|
||||||
|
) {
|
||||||
|
if (this.#instantiationFailed) {
|
||||||
|
throw new JpxError("OpenJPEG failed to instantiate.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#modulePromise ||= OpenJPEG({
|
||||||
|
warn,
|
||||||
|
instantiateWasm: this.#instantiateWasm.bind(this),
|
||||||
|
});
|
||||||
|
|
||||||
|
const module = await this.#modulePromise;
|
||||||
|
let ptr;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const size = bytes.length;
|
||||||
|
ptr = module._malloc(size);
|
||||||
|
module.HEAPU8.set(bytes, ptr);
|
||||||
|
const ret = module._jp2_decode(
|
||||||
|
ptr,
|
||||||
|
size,
|
||||||
|
numComponents > 0 ? numComponents : 0,
|
||||||
|
!!isIndexedColormap,
|
||||||
|
!!smaskInData
|
||||||
|
);
|
||||||
|
if (ret) {
|
||||||
|
const { errorMessages } = module;
|
||||||
|
if (errorMessages) {
|
||||||
|
delete module.errorMessages;
|
||||||
|
throw new JpxError(errorMessages);
|
||||||
|
}
|
||||||
|
throw new JpxError("Unknown error");
|
||||||
|
}
|
||||||
|
const { imageData } = module;
|
||||||
|
module.imageData = null;
|
||||||
|
|
||||||
return imageData;
|
return imageData;
|
||||||
|
} finally {
|
||||||
|
if (ptr) {
|
||||||
|
module._free(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static cleanup() {
|
static cleanup() {
|
||||||
this.#module = null;
|
this.#modulePromise = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseImageProperties(stream) {
|
static parseImageProperties(stream) {
|
||||||
|
|||||||
@ -13,9 +13,9 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { shadow, unreachable } from "../shared/util.js";
|
||||||
import { DecodeStream } from "./decode_stream.js";
|
import { DecodeStream } from "./decode_stream.js";
|
||||||
import { JpxImage } from "./jpx.js";
|
import { JpxImage } from "./jpx.js";
|
||||||
import { shadow } from "../shared/util.js";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For JPEG 2000's we use a library to decode these images and
|
* For JPEG 2000's we use a library to decode these images and
|
||||||
@ -42,15 +42,19 @@ class JpxStream extends DecodeStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readBlock(decoderOptions) {
|
readBlock(decoderOptions) {
|
||||||
this.decodeImage(null, decoderOptions);
|
unreachable("JpxStream.readBlock");
|
||||||
}
|
}
|
||||||
|
|
||||||
decodeImage(bytes, decoderOptions) {
|
get isAsyncDecoder() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async decodeImage(bytes, decoderOptions) {
|
||||||
if (this.eof) {
|
if (this.eof) {
|
||||||
return this.buffer;
|
return this.buffer;
|
||||||
}
|
}
|
||||||
bytes ||= this.bytes;
|
bytes ||= this.bytes;
|
||||||
this.buffer = JpxImage.decode(bytes, decoderOptions);
|
this.buffer = await JpxImage.decode(bytes, decoderOptions);
|
||||||
this.bufferLength = this.buffer.length;
|
this.bufferLength = this.buffer.length;
|
||||||
this.eof = true;
|
this.eof = true;
|
||||||
|
|
||||||
|
|||||||
@ -52,12 +52,14 @@ import {
|
|||||||
NodeCMapReaderFactory,
|
NodeCMapReaderFactory,
|
||||||
NodeFilterFactory,
|
NodeFilterFactory,
|
||||||
NodeStandardFontDataFactory,
|
NodeStandardFontDataFactory,
|
||||||
|
NodeWasmFactory,
|
||||||
} from "display-node_utils";
|
} from "display-node_utils";
|
||||||
import { CanvasGraphics } from "./canvas.js";
|
import { CanvasGraphics } from "./canvas.js";
|
||||||
import { DOMCanvasFactory } from "./canvas_factory.js";
|
import { DOMCanvasFactory } from "./canvas_factory.js";
|
||||||
import { DOMCMapReaderFactory } from "display-cmap_reader_factory";
|
import { DOMCMapReaderFactory } from "display-cmap_reader_factory";
|
||||||
import { DOMFilterFactory } from "./filter_factory.js";
|
import { DOMFilterFactory } from "./filter_factory.js";
|
||||||
import { DOMStandardFontDataFactory } from "display-standard_fontdata_factory";
|
import { DOMStandardFontDataFactory } from "display-standard_fontdata_factory";
|
||||||
|
import { DOMWasmFactory } from "display-wasm_factory";
|
||||||
import { GlobalWorkerOptions } from "./worker_options.js";
|
import { GlobalWorkerOptions } from "./worker_options.js";
|
||||||
import { Metadata } from "./metadata.js";
|
import { Metadata } from "./metadata.js";
|
||||||
import { OptionalContentConfig } from "./optional_content_config.js";
|
import { OptionalContentConfig } from "./optional_content_config.js";
|
||||||
@ -88,6 +90,10 @@ const DefaultStandardFontDataFactory =
|
|||||||
typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC") && isNodeJS
|
typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC") && isNodeJS
|
||||||
? NodeStandardFontDataFactory
|
? NodeStandardFontDataFactory
|
||||||
: DOMStandardFontDataFactory;
|
: DOMStandardFontDataFactory;
|
||||||
|
const DefaultWasmFactory =
|
||||||
|
typeof PDFJSDev !== "undefined" && PDFJSDev.test("GENERIC") && isNodeJS
|
||||||
|
? NodeWasmFactory
|
||||||
|
: DOMWasmFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef { Int8Array | Uint8Array | Uint8ClampedArray |
|
* @typedef { Int8Array | Uint8Array | Uint8ClampedArray |
|
||||||
@ -153,6 +159,12 @@ const DefaultStandardFontDataFactory =
|
|||||||
* when reading the standard font files. Providing a custom factory is useful
|
* when reading the standard font files. Providing a custom factory is useful
|
||||||
* for environments without Fetch API or `XMLHttpRequest` support, such as
|
* for environments without Fetch API or `XMLHttpRequest` support, such as
|
||||||
* Node.js. The default value is {DOMStandardFontDataFactory}.
|
* Node.js. The default value is {DOMStandardFontDataFactory}.
|
||||||
|
* @property {string} [wasmUrl] - The URL where the wasm files are located.
|
||||||
|
* Include the trailing slash.
|
||||||
|
* @property {Object} [WasmFactory] - The factory that will be used
|
||||||
|
* when reading the wasm files. Providing a custom factory is useful
|
||||||
|
* for environments without Fetch API or `XMLHttpRequest` support, such as
|
||||||
|
* Node.js. The default value is {DOMWasmFactory}.
|
||||||
* @property {boolean} [useWorkerFetch] - Enable using the Fetch API in the
|
* @property {boolean} [useWorkerFetch] - Enable using the Fetch API in the
|
||||||
* worker-thread when reading CMap and standard font files. When `true`,
|
* worker-thread when reading CMap and standard font files. When `true`,
|
||||||
* the `CMapReaderFactory` and `StandardFontDataFactory` options are ignored.
|
* the `CMapReaderFactory` and `StandardFontDataFactory` options are ignored.
|
||||||
@ -280,6 +292,8 @@ function getDocument(src = {}) {
|
|||||||
: null;
|
: null;
|
||||||
const StandardFontDataFactory =
|
const StandardFontDataFactory =
|
||||||
src.StandardFontDataFactory || DefaultStandardFontDataFactory;
|
src.StandardFontDataFactory || DefaultStandardFontDataFactory;
|
||||||
|
const wasmUrl = typeof src.wasmUrl === "string" ? src.wasmUrl : null;
|
||||||
|
const WasmFactory = src.WasmFactory || DefaultWasmFactory;
|
||||||
const ignoreErrors = src.stopAtErrors !== true;
|
const ignoreErrors = src.stopAtErrors !== true;
|
||||||
const maxImageSize =
|
const maxImageSize =
|
||||||
Number.isInteger(src.maxImageSize) && src.maxImageSize > -1
|
Number.isInteger(src.maxImageSize) && src.maxImageSize > -1
|
||||||
@ -328,10 +342,13 @@ function getDocument(src = {}) {
|
|||||||
: (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
: (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
||||||
(CMapReaderFactory === DOMCMapReaderFactory &&
|
(CMapReaderFactory === DOMCMapReaderFactory &&
|
||||||
StandardFontDataFactory === DOMStandardFontDataFactory &&
|
StandardFontDataFactory === DOMStandardFontDataFactory &&
|
||||||
|
WasmFactory === DOMWasmFactory &&
|
||||||
cMapUrl &&
|
cMapUrl &&
|
||||||
standardFontDataUrl &&
|
standardFontDataUrl &&
|
||||||
|
wasmUrl &&
|
||||||
isValidFetchUrl(cMapUrl, document.baseURI) &&
|
isValidFetchUrl(cMapUrl, document.baseURI) &&
|
||||||
isValidFetchUrl(standardFontDataUrl, document.baseURI));
|
isValidFetchUrl(standardFontDataUrl, document.baseURI) &&
|
||||||
|
isValidFetchUrl(wasmUrl, document.baseURI));
|
||||||
|
|
||||||
// Parameters only intended for development/testing purposes.
|
// Parameters only intended for development/testing purposes.
|
||||||
const styleElement =
|
const styleElement =
|
||||||
@ -357,6 +374,11 @@ function getDocument(src = {}) {
|
|||||||
useWorkerFetch
|
useWorkerFetch
|
||||||
? null
|
? null
|
||||||
: new StandardFontDataFactory({ baseUrl: standardFontDataUrl }),
|
: new StandardFontDataFactory({ baseUrl: standardFontDataUrl }),
|
||||||
|
wasmFactory:
|
||||||
|
(typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) ||
|
||||||
|
useWorkerFetch
|
||||||
|
? null
|
||||||
|
: new WasmFactory({ baseUrl: wasmUrl }),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!worker) {
|
if (!worker) {
|
||||||
@ -397,6 +419,7 @@ function getDocument(src = {}) {
|
|||||||
useSystemFonts,
|
useSystemFonts,
|
||||||
cMapUrl: useWorkerFetch ? cMapUrl : null,
|
cMapUrl: useWorkerFetch ? cMapUrl : null,
|
||||||
standardFontDataUrl: useWorkerFetch ? standardFontDataUrl : null,
|
standardFontDataUrl: useWorkerFetch ? standardFontDataUrl : null,
|
||||||
|
wasmUrl: useWorkerFetch ? wasmUrl : null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const transportParams = {
|
const transportParams = {
|
||||||
@ -2423,6 +2446,7 @@ class WorkerTransport {
|
|||||||
this.filterFactory = factory.filterFactory;
|
this.filterFactory = factory.filterFactory;
|
||||||
this.cMapReaderFactory = factory.cMapReaderFactory;
|
this.cMapReaderFactory = factory.cMapReaderFactory;
|
||||||
this.standardFontDataFactory = factory.standardFontDataFactory;
|
this.standardFontDataFactory = factory.standardFontDataFactory;
|
||||||
|
this.wasmFactory = factory.wasmFactory;
|
||||||
|
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
this.destroyCapability = null;
|
this.destroyCapability = null;
|
||||||
@ -2918,6 +2942,21 @@ class WorkerTransport {
|
|||||||
}
|
}
|
||||||
return this.standardFontDataFactory.fetch(data);
|
return this.standardFontDataFactory.fetch(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
messageHandler.on("FetchWasm", async data => {
|
||||||
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
||||||
|
throw new Error("Not implemented: FetchWasm");
|
||||||
|
}
|
||||||
|
if (this.destroyed) {
|
||||||
|
throw new Error("Worker was destroyed.");
|
||||||
|
}
|
||||||
|
if (!this.wasmFactory) {
|
||||||
|
throw new Error(
|
||||||
|
"WasmFactory not initialized, see the `useWorkerFetch` parameter."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return this.wasmFactory.fetch(data);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
@ -3501,6 +3540,7 @@ export {
|
|||||||
DefaultCMapReaderFactory,
|
DefaultCMapReaderFactory,
|
||||||
DefaultFilterFactory,
|
DefaultFilterFactory,
|
||||||
DefaultStandardFontDataFactory,
|
DefaultStandardFontDataFactory,
|
||||||
|
DefaultWasmFactory,
|
||||||
getDocument,
|
getDocument,
|
||||||
LoopbackPort,
|
LoopbackPort,
|
||||||
PDFDataRangeTransport,
|
PDFDataRangeTransport,
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import { BaseCanvasFactory } from "./canvas_factory.js";
|
|||||||
import { BaseCMapReaderFactory } from "./cmap_reader_factory.js";
|
import { BaseCMapReaderFactory } from "./cmap_reader_factory.js";
|
||||||
import { BaseFilterFactory } from "./filter_factory.js";
|
import { BaseFilterFactory } from "./filter_factory.js";
|
||||||
import { BaseStandardFontDataFactory } from "./standard_fontdata_factory.js";
|
import { BaseStandardFontDataFactory } from "./standard_fontdata_factory.js";
|
||||||
|
import { BaseWasmFactory } from "./wasm_factory.js";
|
||||||
|
|
||||||
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -108,10 +109,20 @@ class NodeStandardFontDataFactory extends BaseStandardFontDataFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NodeWasmFactory extends BaseWasmFactory {
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
async _fetch(url) {
|
||||||
|
return fetchData(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
fetchData,
|
fetchData,
|
||||||
NodeCanvasFactory,
|
NodeCanvasFactory,
|
||||||
NodeCMapReaderFactory,
|
NodeCMapReaderFactory,
|
||||||
NodeFilterFactory,
|
NodeFilterFactory,
|
||||||
NodeStandardFontDataFactory,
|
NodeStandardFontDataFactory,
|
||||||
|
NodeWasmFactory,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -14,10 +14,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const DOMCMapReaderFactory = null;
|
const DOMCMapReaderFactory = null;
|
||||||
|
const DOMWasmFactory = null;
|
||||||
const DOMStandardFontDataFactory = null;
|
const DOMStandardFontDataFactory = null;
|
||||||
const NodeCanvasFactory = null;
|
const NodeCanvasFactory = null;
|
||||||
const NodeCMapReaderFactory = null;
|
const NodeCMapReaderFactory = null;
|
||||||
const NodeFilterFactory = null;
|
const NodeFilterFactory = null;
|
||||||
|
const NodeWasmFactory = null;
|
||||||
const NodeStandardFontDataFactory = null;
|
const NodeStandardFontDataFactory = null;
|
||||||
const PDFFetchStream = null;
|
const PDFFetchStream = null;
|
||||||
const PDFNetworkStream = null;
|
const PDFNetworkStream = null;
|
||||||
@ -26,10 +28,12 @@ const PDFNodeStream = null;
|
|||||||
export {
|
export {
|
||||||
DOMCMapReaderFactory,
|
DOMCMapReaderFactory,
|
||||||
DOMStandardFontDataFactory,
|
DOMStandardFontDataFactory,
|
||||||
|
DOMWasmFactory,
|
||||||
NodeCanvasFactory,
|
NodeCanvasFactory,
|
||||||
NodeCMapReaderFactory,
|
NodeCMapReaderFactory,
|
||||||
NodeFilterFactory,
|
NodeFilterFactory,
|
||||||
NodeStandardFontDataFactory,
|
NodeStandardFontDataFactory,
|
||||||
|
NodeWasmFactory,
|
||||||
PDFFetchStream,
|
PDFFetchStream,
|
||||||
PDFNetworkStream,
|
PDFNetworkStream,
|
||||||
PDFNodeStream,
|
PDFNodeStream,
|
||||||
|
|||||||
63
src/display/wasm_factory.js
Normal file
63
src/display/wasm_factory.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright 2015 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { fetchData } from "./display_utils.js";
|
||||||
|
import { unreachable } from "../shared/util.js";
|
||||||
|
|
||||||
|
class BaseWasmFactory {
|
||||||
|
constructor({ baseUrl = null }) {
|
||||||
|
if (
|
||||||
|
(typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) &&
|
||||||
|
this.constructor === BaseWasmFactory
|
||||||
|
) {
|
||||||
|
unreachable("Cannot initialize BaseWasmFactory.");
|
||||||
|
}
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetch({ filename }) {
|
||||||
|
if (!this.baseUrl) {
|
||||||
|
throw new Error("Ensure that the `wasmUrl` API parameter is provided.");
|
||||||
|
}
|
||||||
|
if (!filename) {
|
||||||
|
throw new Error("Wasm filename must be specified.");
|
||||||
|
}
|
||||||
|
const url = `${this.baseUrl}${filename}`;
|
||||||
|
|
||||||
|
return this._fetch(url).catch(reason => {
|
||||||
|
throw new Error(`Unable to load wasm data at: ${url}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
* @returns {Promise<Uint8Array>}
|
||||||
|
*/
|
||||||
|
async _fetch(url) {
|
||||||
|
unreachable("Abstract method `_fetch` called.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DOMWasmFactory extends BaseWasmFactory {
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
|
async _fetch(url) {
|
||||||
|
const data = await fetchData(url, /* type = */ "arraybuffer");
|
||||||
|
return new Uint8Array(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { BaseWasmFactory, DOMWasmFactory };
|
||||||
@ -31,6 +31,7 @@ const { GenericL10n, parseQueryString, SimpleLinkService } = pdfjsViewer;
|
|||||||
const WAITING_TIME = 100; // ms
|
const WAITING_TIME = 100; // ms
|
||||||
const CMAP_URL = "/build/generic/web/cmaps/";
|
const CMAP_URL = "/build/generic/web/cmaps/";
|
||||||
const STANDARD_FONT_DATA_URL = "/build/generic/web/standard_fonts/";
|
const STANDARD_FONT_DATA_URL = "/build/generic/web/standard_fonts/";
|
||||||
|
const WASM_URL = "/build/generic/web/wasm/";
|
||||||
const IMAGE_RESOURCES_PATH = "/web/images/";
|
const IMAGE_RESOURCES_PATH = "/web/images/";
|
||||||
const VIEWER_CSS = "../build/components/pdf_viewer.css";
|
const VIEWER_CSS = "../build/components/pdf_viewer.css";
|
||||||
const VIEWER_LOCALE = "en-US";
|
const VIEWER_LOCALE = "en-US";
|
||||||
@ -631,6 +632,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,
|
||||||
disableAutoFetch: !task.enableAutoFetch,
|
disableAutoFetch: !task.enableAutoFetch,
|
||||||
pdfBug: true,
|
pdfBug: true,
|
||||||
useSystemFonts: task.useSystemFonts,
|
useSystemFonts: task.useSystemFonts,
|
||||||
|
|||||||
@ -6371,6 +6371,14 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "issue19326_main_thread_fetch",
|
||||||
|
"file": "pdfs/issue19326.pdf",
|
||||||
|
"md5": "b4d937017daf439a6318501428e0c6ba",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq",
|
||||||
|
"useWorkerFetch": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "bug1140761",
|
"id": "bug1140761",
|
||||||
"file": "pdfs/bug1140761.pdf",
|
"file": "pdfs/bug1140761.pdf",
|
||||||
|
|||||||
@ -28,6 +28,8 @@ const STANDARD_FONT_DATA_URL = isNodeJS
|
|||||||
? "./external/standard_fonts/"
|
? "./external/standard_fonts/"
|
||||||
: "../../external/standard_fonts/";
|
: "../../external/standard_fonts/";
|
||||||
|
|
||||||
|
const WASM_URL = isNodeJS ? "./external/openjpeg/" : "../../external/openjpeg/";
|
||||||
|
|
||||||
class DefaultFileReaderFactory {
|
class DefaultFileReaderFactory {
|
||||||
static async fetch(params) {
|
static async fetch(params) {
|
||||||
if (isNodeJS) {
|
if (isNodeJS) {
|
||||||
@ -44,6 +46,7 @@ function buildGetDocumentParams(filename, options) {
|
|||||||
? TEST_PDFS_PATH + filename
|
? TEST_PDFS_PATH + filename
|
||||||
: new URL(TEST_PDFS_PATH + filename, window.location).href;
|
: new URL(TEST_PDFS_PATH + filename, window.location).href;
|
||||||
params.standardFontDataUrl = STANDARD_FONT_DATA_URL;
|
params.standardFontDataUrl = STANDARD_FONT_DATA_URL;
|
||||||
|
params.wasmUrl = WASM_URL;
|
||||||
|
|
||||||
for (const option in options) {
|
for (const option in options) {
|
||||||
params[option] = options[option];
|
params[option] = options[option];
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
"display-cmap_reader_factory": "../../src/display/cmap_reader_factory.js",
|
"display-cmap_reader_factory": "../../src/display/cmap_reader_factory.js",
|
||||||
"display-standard_fontdata_factory": "../../src/display/standard_fontdata_factory.js",
|
"display-standard_fontdata_factory": "../../src/display/standard_fontdata_factory.js",
|
||||||
|
"display-wasm_factory": "../../src/display/wasm_factory.js",
|
||||||
"display-fetch_stream": "../../src/display/fetch_stream.js",
|
"display-fetch_stream": "../../src/display/fetch_stream.js",
|
||||||
"display-network": "../../src/display/network.js",
|
"display-network": "../../src/display/network.js",
|
||||||
"display-node_stream": "../../src/display/stubs.js",
|
"display-node_stream": "../../src/display/stubs.js",
|
||||||
|
|||||||
@ -38,6 +38,7 @@ const MIME_TYPES = {
|
|||||||
".log": "text/plain",
|
".log": "text/plain",
|
||||||
".bcmap": "application/octet-stream",
|
".bcmap": "application/octet-stream",
|
||||||
".ftl": "text/plain",
|
".ftl": "text/plain",
|
||||||
|
".wasm": "application/wasm",
|
||||||
};
|
};
|
||||||
const DEFAULT_MIME_TYPE = "application/octet-stream";
|
const DEFAULT_MIME_TYPE = "application/octet-stream";
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
"display-standard_fontdata_factory": [
|
"display-standard_fontdata_factory": [
|
||||||
"./src/display/standard_fontdata_factory"
|
"./src/display/standard_fontdata_factory"
|
||||||
],
|
],
|
||||||
|
"display-wasm_factory": ["./src/display/wasm_factory"],
|
||||||
"display-fetch_stream": ["./src/display/fetch_stream"],
|
"display-fetch_stream": ["./src/display/fetch_stream"],
|
||||||
"display-network": ["./src/display/network"],
|
"display-network": ["./src/display/network"],
|
||||||
"display-node_stream": ["./src/display/node_stream"],
|
"display-node_stream": ["./src/display/node_stream"],
|
||||||
|
|||||||
@ -431,7 +431,17 @@ const defaultOptions = {
|
|||||||
value: 1,
|
value: 1,
|
||||||
kind: OptionKind.API,
|
kind: OptionKind.API,
|
||||||
},
|
},
|
||||||
|
wasmUrl: {
|
||||||
|
/** @type {string} */
|
||||||
|
value:
|
||||||
|
// eslint-disable-next-line no-nested-ternary
|
||||||
|
typeof PDFJSDev === "undefined"
|
||||||
|
? "../external/openjpeg/"
|
||||||
|
: PDFJSDev.test("MOZCENTRAL")
|
||||||
|
? "resource://pdf.js/web/wasm/"
|
||||||
|
: "../web/wasm/",
|
||||||
|
kind: OptionKind.API,
|
||||||
|
},
|
||||||
workerPort: {
|
workerPort: {
|
||||||
/** @type {Object} */
|
/** @type {Object} */
|
||||||
value: null,
|
value: null,
|
||||||
|
|||||||
@ -61,6 +61,7 @@ See https://github.com/adobe-type-tools/cmap-resources
|
|||||||
|
|
||||||
"display-cmap_reader_factory": "../src/display/cmap_reader_factory.js",
|
"display-cmap_reader_factory": "../src/display/cmap_reader_factory.js",
|
||||||
"display-standard_fontdata_factory": "../src/display/standard_fontdata_factory.js",
|
"display-standard_fontdata_factory": "../src/display/standard_fontdata_factory.js",
|
||||||
|
"display-wasm_factory": "../src/display/wasm_factory.js",
|
||||||
"display-fetch_stream": "../src/display/fetch_stream.js",
|
"display-fetch_stream": "../src/display/fetch_stream.js",
|
||||||
"display-network": "../src/display/network.js",
|
"display-network": "../src/display/network.js",
|
||||||
"display-node_stream": "../src/display/stubs.js",
|
"display-node_stream": "../src/display/stubs.js",
|
||||||
|
|||||||
@ -64,6 +64,7 @@ See https://github.com/adobe-type-tools/cmap-resources
|
|||||||
|
|
||||||
"display-cmap_reader_factory": "../src/display/cmap_reader_factory.js",
|
"display-cmap_reader_factory": "../src/display/cmap_reader_factory.js",
|
||||||
"display-standard_fontdata_factory": "../src/display/standard_fontdata_factory.js",
|
"display-standard_fontdata_factory": "../src/display/standard_fontdata_factory.js",
|
||||||
|
"display-wasm_factory": "../src/display/wasm_factory.js",
|
||||||
"display-fetch_stream": "../src/display/fetch_stream.js",
|
"display-fetch_stream": "../src/display/fetch_stream.js",
|
||||||
"display-network": "../src/display/network.js",
|
"display-network": "../src/display/network.js",
|
||||||
"display-node_stream": "../src/display/stubs.js",
|
"display-node_stream": "../src/display/stubs.js",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user