1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-21 23:58:07 +02:00

Improve (local) caching of parsed ColorSpaces (PR 12001 follow-up)

This patch contains the following *notable* improvements:
 - Changes the `ColorSpace.parse` call-sites to, where possible, pass in a reference rather than actual ColorSpace data (necessary for the next point).
 - Adds (local) caching of `ColorSpace`s by `Ref`, when applicable, in addition the caching by name. This (generally) improves `ColorSpace` caching for e.g. the SMask code-paths.
 - Extends the (local) `ColorSpace` caching to also apply when handling Images and Patterns, thus further reducing unneeded re-parsing.
 - Adds a new `ColorSpace.parseAsync` method, almost identical to the existing `ColorSpace.parse` one, but returning a Promise instead (this simplifies some code in the `PartialEvaluator`).
This commit is contained in:
Jonas Jenwald 2020-06-17 18:45:11 +02:00
parent 51e87b9248
commit 19d7976483
5 changed files with 335 additions and 45 deletions

View file

@ -16,18 +16,21 @@
import { Dict, Name, Ref } from "../../src/core/primitives.js";
import { Stream, StringStream } from "../../src/core/stream.js";
import { ColorSpace } from "../../src/core/colorspace.js";
import { LocalColorSpaceCache } from "../../src/core/image_utils.js";
import { PDFFunctionFactory } from "../../src/core/function.js";
import { XRefMock } from "./test_utils.js";
describe("colorspace", function () {
describe("ColorSpace", function () {
describe("ColorSpace.isDefaultDecode", function () {
it("should be true if decode is not an array", function () {
expect(ColorSpace.isDefaultDecode("string", 0)).toBeTruthy();
});
it("should be true if length of decode array is not correct", function () {
expect(ColorSpace.isDefaultDecode([0], 1)).toBeTruthy();
expect(ColorSpace.isDefaultDecode([0, 1, 0], 1)).toBeTruthy();
});
it("should be true if decode map matches the default decode map", function () {
expect(ColorSpace.isDefaultDecode([], 0)).toBeTruthy();
@ -46,6 +49,138 @@ describe("colorspace", function () {
});
});
describe("ColorSpace caching", function () {
let localColorSpaceCache = null;
beforeAll(function (done) {
localColorSpaceCache = new LocalColorSpaceCache();
done();
});
afterAll(function (done) {
localColorSpaceCache = null;
done();
});
it("caching by Name", function () {
const xref = new XRefMock();
const pdfFunctionFactory = new PDFFunctionFactory({
xref,
});
const colorSpace1 = ColorSpace.parse({
cs: Name.get("Pattern"),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache,
});
expect(colorSpace1.name).toEqual("Pattern");
const colorSpace2 = ColorSpace.parse({
cs: Name.get("Pattern"),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache,
});
expect(colorSpace2.name).toEqual("Pattern");
const colorSpaceNonCached = ColorSpace.parse({
cs: Name.get("Pattern"),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
expect(colorSpaceNonCached.name).toEqual("Pattern");
const colorSpaceOther = ColorSpace.parse({
cs: Name.get("RGB"),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache,
});
expect(colorSpaceOther.name).toEqual("DeviceRGB");
// These two must be *identical* if caching worked as intended.
expect(colorSpace1).toBe(colorSpace2);
expect(colorSpace1).not.toBe(colorSpaceNonCached);
expect(colorSpace1).not.toBe(colorSpaceOther);
});
it("caching by Ref", function () {
const paramsCalGray = new Dict();
paramsCalGray.set("WhitePoint", [1, 1, 1]);
paramsCalGray.set("BlackPoint", [0, 0, 0]);
paramsCalGray.set("Gamma", 2.0);
const paramsCalRGB = new Dict();
paramsCalRGB.set("WhitePoint", [1, 1, 1]);
paramsCalRGB.set("BlackPoint", [0, 0, 0]);
paramsCalRGB.set("Gamma", [1, 1, 1]);
paramsCalRGB.set("Matrix", [1, 0, 0, 0, 1, 0, 0, 0, 1]);
const xref = new XRefMock([
{
ref: Ref.get(50, 0),
data: [Name.get("CalGray"), paramsCalGray],
},
{
ref: Ref.get(100, 0),
data: [Name.get("CalRGB"), paramsCalRGB],
},
]);
const pdfFunctionFactory = new PDFFunctionFactory({
xref,
});
const colorSpace1 = ColorSpace.parse({
cs: Ref.get(50, 0),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache,
});
expect(colorSpace1.name).toEqual("CalGray");
const colorSpace2 = ColorSpace.parse({
cs: Ref.get(50, 0),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache,
});
expect(colorSpace2.name).toEqual("CalGray");
const colorSpaceNonCached = ColorSpace.parse({
cs: Ref.get(50, 0),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
expect(colorSpaceNonCached.name).toEqual("CalGray");
const colorSpaceOther = ColorSpace.parse({
cs: Ref.get(100, 0),
xref,
resources: null,
pdfFunctionFactory,
localColorSpaceCache,
});
expect(colorSpaceOther.name).toEqual("CalRGB");
// These two must be *identical* if caching worked as intended.
expect(colorSpace1).toBe(colorSpace2);
expect(colorSpace1).not.toBe(colorSpaceNonCached);
expect(colorSpace1).not.toBe(colorSpaceOther);
});
});
describe("DeviceGrayCS", function () {
it("should handle the case when cs is a Name object", function () {
const cs = Name.get("DeviceGray");
@ -65,6 +200,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
const testSrc = new Uint8Array([27, 125, 250, 131]);
@ -115,6 +251,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
const testSrc = new Uint8Array([27, 125, 250, 131]);
@ -161,6 +298,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
// prettier-ignore
@ -217,6 +355,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
// prettier-ignore
@ -269,6 +408,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
// prettier-ignore
@ -325,6 +465,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
// prettier-ignore
@ -382,6 +523,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
const testSrc = new Uint8Array([27, 125, 250, 131]);
@ -441,6 +583,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
// prettier-ignore
@ -498,6 +641,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
// prettier-ignore
@ -557,6 +701,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
const testSrc = new Uint8Array([2, 2, 0, 1]);
@ -624,6 +769,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
localColorSpaceCache: new LocalColorSpaceCache(),
});
const testSrc = new Uint8Array([27, 25, 50, 31]);