1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-22 16:18:08 +02:00

[api-minor] Add a new transferPdfData option to allow transferring more data to the worker-thread (bug 1809164)

Also, removes the `initialData`-parameter JSDocs for the `getDocument`-function given that this parameter has been completely unused since PR 8982 (over five years ago). Note that the `initialData`-parameter is, and always was, intended to be provided when initializing a `PDFDataRangeTransport`-instance.
This commit is contained in:
Jonas Jenwald 2023-01-09 17:24:52 +01:00
parent d6f63b5fb7
commit bbe629018d
4 changed files with 130 additions and 23 deletions

View file

@ -146,9 +146,6 @@ if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {
* cross-site Access-Control requests should be made using credentials such
* as cookies or authorization headers. The default is `false`.
* @property {string} [password] - For decrypting password-protected PDFs.
* @property {TypedArray} [initialData] - A typed array with the first portion
* or all of the pdf data. Used by the extension since some data is already
* loaded before the switch to range requests.
* @property {number} [length] - The PDF file length. It's used for progress
* reports and range requests operations.
* @property {PDFDataRangeTransport} [range] - Allows for using a custom range
@ -192,6 +189,14 @@ if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")) {
* @property {number} [maxImageSize] - The maximum allowed image size in total
* pixels, i.e. width * height. Images above this value will not be rendered.
* Use -1 for no limit, which is also the default value.
* @property {boolean} [transferPdfData] - Determines if we can transfer
* TypedArrays used for loading the PDF file, utilized together with:
* - The `data`-option, for the `getDocument` function.
* - The `initialData`-option, for the `PDFDataRangeTransport` constructor.
* - The `chunk`-option, for the `PDFDataTransportStream._onReceiveData`
* method.
* This will help reduce main-thread memory usage, however it will take
* ownership of the TypedArrays. The default value is `false`.
* @property {boolean} [isEvalSupported] - Determines if we can evaluate strings
* as JavaScript. Primarily used to improve performance of font rendering, and
* when parsing PDF functions. The default value is `true`.
@ -342,6 +347,7 @@ function getDocument(src) {
params.StandardFontDataFactory =
params.StandardFontDataFactory || DefaultStandardFontDataFactory;
params.ignoreErrors = params.stopAtErrors !== true;
params.transferPdfData = params.transferPdfData === true;
params.fontExtraProperties = params.fontExtraProperties === true;
params.pdfBug = params.pdfBug === true;
params.enableXfa = params.enableXfa === true;
@ -439,6 +445,7 @@ function getDocument(src) {
{
length: params.length,
initialData: params.initialData,
transferPdfData: params.transferPdfData,
progressiveDone: params.progressiveDone,
contentDispositionFilename: params.contentDispositionFilename,
disableRange: params.disableRange,
@ -513,6 +520,9 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
source.contentDispositionFilename =
pdfDataRangeTransport.contentDispositionFilename;
}
const transfers =
source.transferPdfData && source.data ? [source.data.buffer] : null;
const workerId = await worker.messageHandler.sendWithPromise(
"GetDocRequest",
// Only send the required properties, and *not* the entire `source` object.
@ -542,15 +552,10 @@ async function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
? source.standardFontDataUrl
: null,
},
}
},
transfers
);
// Release the TypedArray data, when it exists, since it's no longer needed
// on the main-thread *after* it's been sent to the worker-thread.
if (source.data) {
source.data = null;
}
if (worker.destroyed) {
throw new Error("Worker was destroyed");
}

View file

@ -18,27 +18,41 @@ import { isPdfFile } from "./display_utils.js";
/** @implements {IPDFStream} */
class PDFDataTransportStream {
constructor(params, pdfDataRangeTransport) {
#transferPdfData = false;
constructor(
{
length,
initialData,
transferPdfData = false,
progressiveDone = false,
contentDispositionFilename = null,
disableRange = false,
disableStream = false,
},
pdfDataRangeTransport
) {
assert(
pdfDataRangeTransport,
'PDFDataTransportStream - missing required "pdfDataRangeTransport" argument.'
);
this._queuedChunks = [];
this._progressiveDone = params.progressiveDone || false;
this._contentDispositionFilename =
params.contentDispositionFilename || null;
this.#transferPdfData = transferPdfData;
this._progressiveDone = progressiveDone;
this._contentDispositionFilename = contentDispositionFilename;
const initialData = params.initialData;
if (initialData?.length > 0) {
const buffer = new Uint8Array(initialData).buffer;
const buffer = this.#transferPdfData
? initialData.buffer
: new Uint8Array(initialData).buffer;
this._queuedChunks.push(buffer);
}
this._pdfDataRangeTransport = pdfDataRangeTransport;
this._isStreamingSupported = !params.disableStream;
this._isRangeSupported = !params.disableRange;
this._contentLength = params.length;
this._isStreamingSupported = !disableStream;
this._isRangeSupported = !disableRange;
this._contentLength = length;
this._fullRequestReader = null;
this._rangeReaders = [];
@ -62,9 +76,12 @@ class PDFDataTransportStream {
this._pdfDataRangeTransport.transportReady();
}
_onReceiveData(args) {
const buffer = new Uint8Array(args.chunk).buffer;
if (args.begin === undefined) {
_onReceiveData({ begin, chunk }) {
const buffer = this.#transferPdfData
? chunk.buffer
: new Uint8Array(chunk).buffer;
if (begin === undefined) {
if (this._fullRequestReader) {
this._fullRequestReader._enqueue(buffer);
} else {
@ -72,7 +89,7 @@ class PDFDataTransportStream {
}
} else {
const found = this._rangeReaders.some(function (rangeReader) {
if (rangeReader._begin !== args.begin) {
if (rangeReader._begin !== begin) {
return false;
}
rangeReader._enqueue(buffer);