Improve (local) caching of parsed ColorSpace
s (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:
parent
51e87b9248
commit
19d7976483
@ -22,7 +22,8 @@ import {
|
||||
unreachable,
|
||||
warn,
|
||||
} from "../shared/util.js";
|
||||
import { isDict, isName, isStream } from "./primitives.js";
|
||||
import { isDict, isName, isStream, Name, Ref } from "./primitives.js";
|
||||
import { MissingDataException } from "./core_utils.js";
|
||||
|
||||
/**
|
||||
* Resizes an RGB image with 3 components.
|
||||
@ -259,9 +260,109 @@ class ColorSpace {
|
||||
return shadow(this, "usesZeroToOneRange", true);
|
||||
}
|
||||
|
||||
static parse({ cs, xref, resources = null, pdfFunctionFactory }) {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static _cache(cacheKey, xref, localColorSpaceCache, parsedColorSpace) {
|
||||
if (!localColorSpaceCache) {
|
||||
throw new Error(
|
||||
'ColorSpace._cache - expected "localColorSpaceCache" argument.'
|
||||
);
|
||||
}
|
||||
if (!parsedColorSpace) {
|
||||
throw new Error(
|
||||
'ColorSpace._cache - expected "parsedColorSpace" argument.'
|
||||
);
|
||||
}
|
||||
let csName, csRef;
|
||||
if (cacheKey instanceof Ref) {
|
||||
csRef = cacheKey;
|
||||
|
||||
// If parsing succeeded, we know that this call cannot throw.
|
||||
cacheKey = xref.fetch(cacheKey);
|
||||
}
|
||||
if (cacheKey instanceof Name) {
|
||||
csName = cacheKey.name;
|
||||
}
|
||||
if (csName || csRef) {
|
||||
localColorSpaceCache.set(csName, csRef, parsedColorSpace);
|
||||
}
|
||||
}
|
||||
|
||||
static getCached(cacheKey, xref, localColorSpaceCache) {
|
||||
if (!localColorSpaceCache) {
|
||||
throw new Error(
|
||||
'ColorSpace.getCached - expected "localColorSpaceCache" argument.'
|
||||
);
|
||||
}
|
||||
if (cacheKey instanceof Ref) {
|
||||
const localColorSpace = localColorSpaceCache.getByRef(cacheKey);
|
||||
if (localColorSpace) {
|
||||
return localColorSpace;
|
||||
}
|
||||
|
||||
try {
|
||||
cacheKey = xref.fetch(cacheKey);
|
||||
} catch (ex) {
|
||||
if (ex instanceof MissingDataException) {
|
||||
throw ex;
|
||||
}
|
||||
// Any errors should be handled during parsing, rather than here.
|
||||
}
|
||||
}
|
||||
if (cacheKey instanceof Name) {
|
||||
const localColorSpace = localColorSpaceCache.getByName(cacheKey.name);
|
||||
if (localColorSpace) {
|
||||
return localColorSpace;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async parseAsync({
|
||||
cs,
|
||||
xref,
|
||||
resources = null,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
}) {
|
||||
if (
|
||||
typeof PDFJSDev === "undefined" ||
|
||||
PDFJSDev.test("!PRODUCTION || TESTING")
|
||||
) {
|
||||
assert(
|
||||
!this.getCached(cs, xref, localColorSpaceCache),
|
||||
"Expected `ColorSpace.getCached` to have been manually checked " +
|
||||
"before calling `ColorSpace.parseAsync`."
|
||||
);
|
||||
}
|
||||
const IR = this.parseToIR(cs, xref, resources, pdfFunctionFactory);
|
||||
return this.fromIR(IR);
|
||||
const parsedColorSpace = this.fromIR(IR);
|
||||
|
||||
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
||||
this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);
|
||||
|
||||
return parsedColorSpace;
|
||||
}
|
||||
|
||||
static parse({
|
||||
cs,
|
||||
xref,
|
||||
resources = null,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
}) {
|
||||
const cachedColorSpace = this.getCached(cs, xref, localColorSpaceCache);
|
||||
if (cachedColorSpace) {
|
||||
return cachedColorSpace;
|
||||
}
|
||||
const IR = this.parseToIR(cs, xref, resources, pdfFunctionFactory);
|
||||
const parsedColorSpace = this.fromIR(IR);
|
||||
|
||||
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
||||
this._cache(cs, xref, localColorSpaceCache, parsedColorSpace);
|
||||
|
||||
return parsedColorSpace;
|
||||
}
|
||||
|
||||
static fromIR(IR) {
|
||||
|
@ -411,12 +411,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
groupOptions.isolated = group.get("I") || false;
|
||||
groupOptions.knockout = group.get("K") || false;
|
||||
if (group.has("CS")) {
|
||||
const cs = group.get("CS");
|
||||
const cs = group.getRaw("CS");
|
||||
|
||||
const localColorSpace =
|
||||
cs instanceof Name && localColorSpaceCache.getByName(cs.name);
|
||||
if (localColorSpace) {
|
||||
colorSpace = localColorSpace;
|
||||
const cachedColorSpace = ColorSpace.getCached(
|
||||
cs,
|
||||
this.xref,
|
||||
localColorSpaceCache
|
||||
);
|
||||
if (cachedColorSpace) {
|
||||
colorSpace = cachedColorSpace;
|
||||
} else {
|
||||
colorSpace = await this.parseColorSpace({
|
||||
cs,
|
||||
@ -483,6 +486,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
operatorList,
|
||||
cacheKey,
|
||||
localImageCache,
|
||||
localColorSpaceCache,
|
||||
}) {
|
||||
var dict = image.dict;
|
||||
const imageRef = dict.objId;
|
||||
@ -549,6 +553,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
image,
|
||||
isInline,
|
||||
pdfFunctionFactory: this.pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
// We force the use of RGBA_32BPP images here, because we can't handle
|
||||
// any other kind.
|
||||
@ -585,6 +590,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
image,
|
||||
isInline,
|
||||
pdfFunctionFactory: this.pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
})
|
||||
.then(imageObj => {
|
||||
imgData = imageObj.createImageData(/* forceRGBA = */ false);
|
||||
@ -1135,19 +1141,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
},
|
||||
|
||||
parseColorSpace({ cs, resources, localColorSpaceCache }) {
|
||||
return new Promise(resolve => {
|
||||
const parsedColorSpace = ColorSpace.parse({
|
||||
cs,
|
||||
xref: this.xref,
|
||||
resources,
|
||||
pdfFunctionFactory: this.pdfFunctionFactory,
|
||||
});
|
||||
|
||||
const csName = cs instanceof Name ? cs.name : null;
|
||||
if (csName) {
|
||||
localColorSpaceCache.set(csName, /* ref = */ null, parsedColorSpace);
|
||||
}
|
||||
resolve(parsedColorSpace);
|
||||
return ColorSpace.parseAsync({
|
||||
cs,
|
||||
xref: this.xref,
|
||||
resources,
|
||||
pdfFunctionFactory: this.pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
}).catch(reason => {
|
||||
if (reason instanceof AbortException) {
|
||||
return null;
|
||||
@ -1165,7 +1164,16 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
});
|
||||
},
|
||||
|
||||
async handleColorN(operatorList, fn, args, cs, patterns, resources, task) {
|
||||
async handleColorN(
|
||||
operatorList,
|
||||
fn,
|
||||
args,
|
||||
cs,
|
||||
patterns,
|
||||
resources,
|
||||
task,
|
||||
localColorSpaceCache
|
||||
) {
|
||||
// compile tiling patterns
|
||||
var patternName = args[args.length - 1];
|
||||
// SCN/scn applies patterns along with normal colors
|
||||
@ -1194,7 +1202,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
this.xref,
|
||||
resources,
|
||||
this.handler,
|
||||
this.pdfFunctionFactory
|
||||
this.pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
);
|
||||
operatorList.addOp(fn, pattern.getIR());
|
||||
return undefined;
|
||||
@ -1352,6 +1361,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
operatorList,
|
||||
cacheKey: name,
|
||||
localImageCache,
|
||||
localColorSpaceCache,
|
||||
})
|
||||
.then(resolveXObject, rejectXObject);
|
||||
return;
|
||||
@ -1425,6 +1435,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
operatorList,
|
||||
cacheKey,
|
||||
localImageCache,
|
||||
localColorSpaceCache,
|
||||
})
|
||||
);
|
||||
return;
|
||||
@ -1483,11 +1494,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
break;
|
||||
|
||||
case OPS.setFillColorSpace: {
|
||||
const localColorSpace =
|
||||
args[0] instanceof Name &&
|
||||
localColorSpaceCache.getByName(args[0].name);
|
||||
if (localColorSpace) {
|
||||
stateManager.state.fillColorSpace = localColorSpace;
|
||||
const cachedColorSpace = ColorSpace.getCached(
|
||||
args[0],
|
||||
xref,
|
||||
localColorSpaceCache
|
||||
);
|
||||
if (cachedColorSpace) {
|
||||
stateManager.state.fillColorSpace = cachedColorSpace;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1507,11 +1520,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
return;
|
||||
}
|
||||
case OPS.setStrokeColorSpace: {
|
||||
const localColorSpace =
|
||||
args[0] instanceof Name &&
|
||||
localColorSpaceCache.getByName(args[0].name);
|
||||
if (localColorSpace) {
|
||||
stateManager.state.strokeColorSpace = localColorSpace;
|
||||
const cachedColorSpace = ColorSpace.getCached(
|
||||
args[0],
|
||||
xref,
|
||||
localColorSpaceCache
|
||||
);
|
||||
if (cachedColorSpace) {
|
||||
stateManager.state.strokeColorSpace = cachedColorSpace;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1579,7 +1594,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
cs,
|
||||
patterns,
|
||||
resources,
|
||||
task
|
||||
task,
|
||||
localColorSpaceCache
|
||||
)
|
||||
);
|
||||
return;
|
||||
@ -1598,7 +1614,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
cs,
|
||||
patterns,
|
||||
resources,
|
||||
task
|
||||
task,
|
||||
localColorSpaceCache
|
||||
)
|
||||
);
|
||||
return;
|
||||
@ -1624,7 +1641,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
xref,
|
||||
resources,
|
||||
self.handler,
|
||||
self.pdfFunctionFactory
|
||||
self.pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
);
|
||||
var patternIR = shadingFill.getIR();
|
||||
args = [patternIR];
|
||||
|
@ -89,6 +89,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
mask = null,
|
||||
isMask = false,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
}) {
|
||||
this.image = image;
|
||||
var dict = image.dict;
|
||||
@ -159,7 +160,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
this.bpc = bitsPerComponent;
|
||||
|
||||
if (!this.imageMask) {
|
||||
var colorSpace = dict.get("ColorSpace", "CS");
|
||||
let colorSpace = dict.getRaw("ColorSpace") || dict.getRaw("CS");
|
||||
if (!colorSpace) {
|
||||
info("JPX images (which do not require color spaces)");
|
||||
switch (image.numComps) {
|
||||
@ -184,6 +185,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
xref,
|
||||
resources: isInline ? res : null,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
this.numComps = this.colorSpace.numComps;
|
||||
}
|
||||
@ -220,6 +222,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
image: smask,
|
||||
isInline,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
} else if (mask) {
|
||||
if (isStream(mask)) {
|
||||
@ -235,6 +238,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
isInline,
|
||||
isMask: true,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
@ -253,6 +257,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
image,
|
||||
isInline = false,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
}) {
|
||||
const imageData = image;
|
||||
let smaskData = null;
|
||||
@ -279,6 +284,7 @@ var PDFImage = (function PDFImageClosure() {
|
||||
smask: smaskData,
|
||||
mask: maskData,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,8 @@ var Pattern = (function PatternClosure() {
|
||||
xref,
|
||||
res,
|
||||
handler,
|
||||
pdfFunctionFactory
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
) {
|
||||
var dict = isStream(shading) ? shading.dict : shading;
|
||||
var type = dict.get("ShadingType");
|
||||
@ -72,7 +73,8 @@ var Pattern = (function PatternClosure() {
|
||||
matrix,
|
||||
xref,
|
||||
res,
|
||||
pdfFunctionFactory
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
);
|
||||
case ShadingType.FREE_FORM_MESH:
|
||||
case ShadingType.LATTICE_FORM_MESH:
|
||||
@ -83,7 +85,8 @@ var Pattern = (function PatternClosure() {
|
||||
matrix,
|
||||
xref,
|
||||
res,
|
||||
pdfFunctionFactory
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
);
|
||||
default:
|
||||
throw new FormatError("Unsupported ShadingType: " + type);
|
||||
@ -111,16 +114,24 @@ Shadings.SMALL_NUMBER = 1e-6;
|
||||
// Radial and axial shading have very similar implementations
|
||||
// If needed, the implementations can be broken into two classes
|
||||
Shadings.RadialAxial = (function RadialAxialClosure() {
|
||||
function RadialAxial(dict, matrix, xref, resources, pdfFunctionFactory) {
|
||||
function RadialAxial(
|
||||
dict,
|
||||
matrix,
|
||||
xref,
|
||||
resources,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
) {
|
||||
this.matrix = matrix;
|
||||
this.coordsArr = dict.getArray("Coords");
|
||||
this.shadingType = dict.get("ShadingType");
|
||||
this.type = "Pattern";
|
||||
const cs = ColorSpace.parse({
|
||||
cs: dict.get("ColorSpace", "CS"),
|
||||
cs: dict.getRaw("ColorSpace") || dict.getRaw("CS"),
|
||||
xref,
|
||||
resources,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
this.cs = cs;
|
||||
const bbox = dict.getArray("BBox");
|
||||
@ -834,7 +845,14 @@ Shadings.Mesh = (function MeshClosure() {
|
||||
}
|
||||
}
|
||||
|
||||
function Mesh(stream, matrix, xref, resources, pdfFunctionFactory) {
|
||||
function Mesh(
|
||||
stream,
|
||||
matrix,
|
||||
xref,
|
||||
resources,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache
|
||||
) {
|
||||
if (!isStream(stream)) {
|
||||
throw new FormatError("Mesh data is not a stream");
|
||||
}
|
||||
@ -849,10 +867,11 @@ Shadings.Mesh = (function MeshClosure() {
|
||||
this.bbox = null;
|
||||
}
|
||||
const cs = ColorSpace.parse({
|
||||
cs: dict.get("ColorSpace", "CS"),
|
||||
cs: dict.getRaw("ColorSpace") || dict.getRaw("CS"),
|
||||
xref,
|
||||
resources,
|
||||
pdfFunctionFactory,
|
||||
localColorSpaceCache,
|
||||
});
|
||||
this.cs = cs;
|
||||
this.background = dict.has("Background")
|
||||
|
@ -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]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user