1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-24 09:08:07 +02:00

Add a GlobalColorSpaceCache to reduce unnecessary re-parsing

This complements the existing `LocalColorSpaceCache`, which is unique to each `getOperatorList`-invocation since it also caches by `Name`, which should help reduce unnecessary re-parsing especially for e.g. `ICCBased` ColorSpaces once we properly support those.
This commit is contained in:
Jonas Jenwald 2025-02-28 19:11:42 +01:00
parent 6e1cfa20d1
commit 4be79748c9
11 changed files with 311 additions and 77 deletions

View file

@ -14,9 +14,12 @@
*/
import { Dict, Name, Ref } from "../../src/core/primitives.js";
import {
GlobalColorSpaceCache,
LocalColorSpaceCache,
} from "../../src/core/image_utils.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";
@ -50,13 +53,15 @@ describe("colorspace", function () {
});
describe("ColorSpace caching", function () {
let localColorSpaceCache = null;
let globalColorSpaceCache, localColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
localColorSpaceCache = new LocalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
localColorSpaceCache = null;
});
@ -71,6 +76,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache,
});
expect(colorSpace1.name).toEqual("Pattern");
@ -80,6 +86,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache,
});
expect(colorSpace2.name).toEqual("Pattern");
@ -89,6 +96,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache: new GlobalColorSpaceCache(),
localColorSpaceCache: new LocalColorSpaceCache(),
});
expect(colorSpaceNonCached.name).toEqual("Pattern");
@ -98,6 +106,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache,
});
expect(colorSpaceOther.name).toEqual("DeviceRGB");
@ -140,6 +149,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache,
});
expect(colorSpace1.name).toEqual("CalGray");
@ -149,6 +159,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache,
});
expect(colorSpace2.name).toEqual("CalGray");
@ -158,6 +169,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache: new GlobalColorSpaceCache(),
localColorSpaceCache: new LocalColorSpaceCache(),
});
expect(colorSpaceNonCached.name).toEqual("CalGray");
@ -167,6 +179,7 @@ describe("colorspace", function () {
xref,
resources: null,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache,
});
expect(colorSpaceOther.name).toEqual("CalRGB");
@ -180,6 +193,16 @@ describe("colorspace", function () {
});
describe("DeviceGrayCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is a Name object", function () {
const cs = Name.get("DeviceGray");
const xref = new XRefMock([
@ -198,6 +221,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -249,6 +273,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -278,6 +303,16 @@ describe("colorspace", function () {
});
describe("DeviceRgbCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is a Name object", function () {
const cs = Name.get("DeviceRGB");
const xref = new XRefMock([
@ -296,6 +331,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -353,6 +389,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -388,6 +425,16 @@ describe("colorspace", function () {
});
describe("DeviceCmykCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is a Name object", function () {
const cs = Name.get("DeviceCMYK");
const xref = new XRefMock([
@ -406,6 +453,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -463,6 +511,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -498,6 +547,16 @@ describe("colorspace", function () {
});
describe("CalGrayCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is an array", function () {
const params = new Dict();
params.set("WhitePoint", [1, 1, 1]);
@ -521,6 +580,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -557,6 +617,16 @@ describe("colorspace", function () {
});
describe("CalRGBCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is an array", function () {
const params = new Dict();
params.set("WhitePoint", [1, 1, 1]);
@ -581,6 +651,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -616,6 +687,16 @@ describe("colorspace", function () {
});
describe("LabCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is an array", function () {
const params = new Dict();
params.set("WhitePoint", [1, 1, 1]);
@ -639,6 +720,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -675,6 +757,16 @@ describe("colorspace", function () {
});
describe("IndexedCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is an array", function () {
// prettier-ignore
const lookup = new Stream(
@ -701,6 +793,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});
@ -730,6 +823,16 @@ describe("colorspace", function () {
});
describe("AlternateCS", function () {
let globalColorSpaceCache;
beforeAll(function () {
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
globalColorSpaceCache = null;
});
it("should handle the case when cs is an array", function () {
const fnDict = new Dict();
fnDict.set("FunctionType", 4);
@ -769,6 +872,7 @@ describe("colorspace", function () {
xref,
resources,
pdfFunctionFactory,
globalColorSpaceCache,
localColorSpaceCache: new LocalColorSpaceCache(),
});

View file

@ -20,6 +20,7 @@ import {
} from "../../src/core/default_appearance.js";
import { Dict, Name } from "../../src/core/primitives.js";
import { NullStream, StringStream } from "../../src/core/stream.js";
import { GlobalColorSpaceCache } from "../../src/core/image_utils.js";
import { XRefMock } from "./test_utils.js";
describe("Default appearance", function () {
@ -56,7 +57,7 @@ describe("Default appearance", function () {
});
describe("parseAppearanceStream", () => {
let evaluatorOptions, xref;
let evaluatorOptions, xref, globalColorSpaceCache;
beforeAll(function () {
evaluatorOptions = {
@ -64,11 +65,13 @@ describe("Default appearance", function () {
isOffscreenCanvasSupported: false,
};
xref = new XRefMock();
globalColorSpaceCache = new GlobalColorSpaceCache();
});
afterAll(function () {
evaluatorOptions = null;
xref = null;
globalColorSpaceCache = null;
});
it("should parse a FreeText (from Acrobat) appearance", () => {
@ -101,9 +104,14 @@ describe("Default appearance", function () {
fontName: "Helv",
fontColor: new Uint8ClampedArray([107, 217, 41]),
};
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
result
);
expect(
parseAppearanceStream(
appearance,
evaluatorOptions,
xref,
globalColorSpaceCache
)
).toEqual(result);
expect(appearance.pos).toEqual(0);
});
@ -122,9 +130,14 @@ describe("Default appearance", function () {
fontName: "Helv",
fontColor: new Uint8ClampedArray([237, 43, 112]),
};
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
result
);
expect(
parseAppearanceStream(
appearance,
evaluatorOptions,
xref,
globalColorSpaceCache
)
).toEqual(result);
expect(appearance.pos).toEqual(0);
});
@ -159,9 +172,14 @@ describe("Default appearance", function () {
fontName: "TT1",
fontColor: new Uint8ClampedArray([135, 78, 254]),
};
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
result
);
expect(
parseAppearanceStream(
appearance,
evaluatorOptions,
xref,
globalColorSpaceCache
)
).toEqual(result);
expect(appearance.pos).toEqual(0);
});
@ -182,9 +200,14 @@ describe("Default appearance", function () {
fontName: "Helv",
fontColor: new Uint8ClampedArray([16, 124, 16]),
};
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
result
);
expect(
parseAppearanceStream(
appearance,
evaluatorOptions,
xref,
globalColorSpaceCache
)
).toEqual(result);
expect(appearance.pos).toEqual(0);
});
@ -208,9 +231,14 @@ describe("Default appearance", function () {
fontName: "FXF0",
fontColor: new Uint8ClampedArray([149, 63, 60]),
};
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
result
);
expect(
parseAppearanceStream(
appearance,
evaluatorOptions,
xref,
globalColorSpaceCache
)
).toEqual(result);
expect(appearance.pos).toEqual(0);
});
@ -232,9 +260,14 @@ describe("Default appearance", function () {
fontName: "Invalid_font",
fontColor: new Uint8ClampedArray([0, 85, 127]),
};
expect(parseAppearanceStream(appearance, evaluatorOptions, xref)).toEqual(
result
);
expect(
parseAppearanceStream(
appearance,
evaluatorOptions,
xref,
globalColorSpaceCache
)
).toEqual(result);
expect(appearance.pos).toEqual(0);
});
});