Merge pull request #16558 from Snuffleupagus/writeStream-filter-fixes

Improve handling of /Filter-entries in `writeStream`
This commit is contained in:
Jonas Jenwald 2023-06-16 13:07:41 +02:00 committed by GitHub
commit 04c31a55d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 25 deletions

View File

@ -14,7 +14,7 @@
*/
import { bytesToString, info, stringToBytes, warn } from "../shared/util.js";
import { Dict, Name, Ref } from "./primitives.js";
import { Dict, isName, Name, Ref } from "./primitives.js";
import {
escapePDFName,
escapeString,
@ -49,28 +49,29 @@ async function writeStream(stream, buffer, transform) {
if (transform !== null) {
string = transform.encryptString(string);
}
const { dict } = stream;
// eslint-disable-next-line no-undef
if (typeof CompressionStream === "undefined") {
stream.dict.set("Length", string.length);
await writeDict(stream.dict, buffer, transform);
dict.set("Length", string.length);
await writeDict(dict, buffer, transform);
buffer.push(" stream\n", string, "\nendstream");
return;
}
const filter = await stream.dict.getAsync("Filter");
const flateDecode = Name.get("FlateDecode");
const filter = await dict.getAsync("Filter");
const params = await dict.getAsync("DecodeParms");
// If the string is too small there is no real benefit
// in compressing it.
const filterZero = Array.isArray(filter)
? await dict.xref.fetchIfRefAsync(filter[0])
: filter;
const isFilterZeroFlateDecode = isName(filterZero, "FlateDecode");
// If the string is too small there is no real benefit in compressing it.
// The number 256 is arbitrary, but it should be reasonable.
const MIN_LENGTH_FOR_COMPRESSING = 256;
if (
string.length >= MIN_LENGTH_FOR_COMPRESSING ||
(Array.isArray(filter) && filter.includes(flateDecode)) ||
(filter instanceof Name && filter.name === flateDecode.name)
) {
if (string.length >= MIN_LENGTH_FOR_COMPRESSING || isFilterZeroFlateDecode) {
try {
const byteArray = stringToBytes(string);
// eslint-disable-next-line no-undef
@ -83,25 +84,32 @@ async function writeStream(stream, buffer, transform) {
const buf = await new Response(cs.readable).arrayBuffer();
string = bytesToString(new Uint8Array(buf));
if (Array.isArray(filter)) {
if (!filter.includes(flateDecode)) {
filter.push(flateDecode);
let newFilter, newParams;
if (!filter) {
newFilter = Name.get("FlateDecode");
} else if (!isFilterZeroFlateDecode) {
newFilter = Array.isArray(filter)
? [Name.get("FlateDecode"), ...filter]
: [Name.get("FlateDecode"), filter];
if (params) {
newParams = Array.isArray(params)
? [null, ...params]
: [null, params];
}
} else if (!filter) {
stream.dict.set("Filter", flateDecode);
} else if (
!(filter instanceof Name) ||
filter.name !== flateDecode.name
) {
stream.dict.set("Filter", [filter, flateDecode]);
}
if (newFilter) {
dict.set("Filter", newFilter);
}
if (newParams) {
dict.set("DecodeParms", newParams);
}
} catch (ex) {
info(`writeStream - cannot compress data: "${ex}".`);
}
}
stream.dict.set("Length", string.length);
await writeDict(stream.dict, buffer, transform);
dict.set("Length", string.length);
await writeDict(dict, buffer, transform);
buffer.push(" stream\n", string, "\nendstream");
}

View File

@ -1979,7 +1979,7 @@ describe("api", function () {
await loadingTask.destroy();
});
it("write a a new annotation, save the pdf and check that the prev entry in xref stream is correct", async function () {
it("write a new annotation, save the pdf and check that the prev entry in xref stream is correct", async function () {
if (isNodeJS) {
pending("Linked test-cases are not supported in Node.js.");
}