Merge pull request #19598 from Snuffleupagus/ColorSpace#subParse
Also cache "sub" ColorSpaces globally (PR 19583 follow-up)
This commit is contained in:
commit
5e6cfbe163
@ -308,10 +308,8 @@ class ColorSpace {
|
|||||||
|
|
||||||
static #cache(
|
static #cache(
|
||||||
cacheKey,
|
cacheKey,
|
||||||
xref,
|
parsedCS,
|
||||||
globalColorSpaceCache,
|
{ xref, globalColorSpaceCache, localColorSpaceCache }
|
||||||
localColorSpaceCache,
|
|
||||||
parsedCS
|
|
||||||
) {
|
) {
|
||||||
if (!globalColorSpaceCache || !localColorSpaceCache) {
|
if (!globalColorSpaceCache || !localColorSpaceCache) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
@ -389,16 +387,18 @@ class ColorSpace {
|
|||||||
"before calling `ColorSpace.parseAsync`."
|
"before calling `ColorSpace.parseAsync`."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const parsedCS = this.#parse(cs, xref, resources, pdfFunctionFactory);
|
|
||||||
|
|
||||||
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
const options = {
|
||||||
this.#cache(
|
|
||||||
cs,
|
|
||||||
xref,
|
xref,
|
||||||
|
resources,
|
||||||
|
pdfFunctionFactory,
|
||||||
globalColorSpaceCache,
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
parsedCS
|
};
|
||||||
);
|
const parsedCS = this.#parse(cs, options);
|
||||||
|
|
||||||
|
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
||||||
|
this.#cache(cs, parsedCS, options);
|
||||||
|
|
||||||
return parsedCS;
|
return parsedCS;
|
||||||
}
|
}
|
||||||
@ -420,21 +420,49 @@ class ColorSpace {
|
|||||||
if (cachedCS) {
|
if (cachedCS) {
|
||||||
return cachedCS;
|
return cachedCS;
|
||||||
}
|
}
|
||||||
const parsedCS = this.#parse(cs, xref, resources, pdfFunctionFactory);
|
|
||||||
|
|
||||||
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
const options = {
|
||||||
this.#cache(
|
|
||||||
cs,
|
|
||||||
xref,
|
xref,
|
||||||
|
resources,
|
||||||
|
pdfFunctionFactory,
|
||||||
globalColorSpaceCache,
|
globalColorSpaceCache,
|
||||||
localColorSpaceCache,
|
localColorSpaceCache,
|
||||||
parsedCS
|
};
|
||||||
);
|
const parsedCS = this.#parse(cs, options);
|
||||||
|
|
||||||
|
// Attempt to cache the parsed ColorSpace, by name and/or reference.
|
||||||
|
this.#cache(cs, parsedCS, options);
|
||||||
|
|
||||||
return parsedCS;
|
return parsedCS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static #parse(cs, xref, resources = null, pdfFunctionFactory) {
|
/**
|
||||||
|
* NOTE: This method should *only* be invoked from `this.#parse`,
|
||||||
|
* when parsing "sub" ColorSpaces.
|
||||||
|
*/
|
||||||
|
static #subParse(cs, options) {
|
||||||
|
const { globalColorSpaceCache } = options;
|
||||||
|
|
||||||
|
let csRef;
|
||||||
|
if (cs instanceof Ref) {
|
||||||
|
const cachedCS = globalColorSpaceCache.getByRef(cs);
|
||||||
|
if (cachedCS) {
|
||||||
|
return cachedCS;
|
||||||
|
}
|
||||||
|
csRef = cs;
|
||||||
|
}
|
||||||
|
const parsedCS = this.#parse(cs, options);
|
||||||
|
|
||||||
|
// Only cache the parsed ColorSpace globally, by reference.
|
||||||
|
if (csRef) {
|
||||||
|
globalColorSpaceCache.set(/* name = */ null, csRef, parsedCS);
|
||||||
|
}
|
||||||
|
return parsedCS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static #parse(cs, options) {
|
||||||
|
const { xref, resources, pdfFunctionFactory } = options;
|
||||||
|
|
||||||
cs = xref.fetchIfRef(cs);
|
cs = xref.fetchIfRef(cs);
|
||||||
if (cs instanceof Name) {
|
if (cs instanceof Name) {
|
||||||
switch (cs.name) {
|
switch (cs.name) {
|
||||||
@ -458,12 +486,7 @@ class ColorSpace {
|
|||||||
const resourcesCS = colorSpaces.get(cs.name);
|
const resourcesCS = colorSpaces.get(cs.name);
|
||||||
if (resourcesCS) {
|
if (resourcesCS) {
|
||||||
if (resourcesCS instanceof Name) {
|
if (resourcesCS instanceof Name) {
|
||||||
return this.#parse(
|
return this.#parse(resourcesCS, options);
|
||||||
resourcesCS,
|
|
||||||
xref,
|
|
||||||
resources,
|
|
||||||
pdfFunctionFactory
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
cs = resourcesCS;
|
cs = resourcesCS;
|
||||||
break;
|
break;
|
||||||
@ -506,9 +529,9 @@ class ColorSpace {
|
|||||||
const stream = xref.fetchIfRef(cs[1]);
|
const stream = xref.fetchIfRef(cs[1]);
|
||||||
const dict = stream.dict;
|
const dict = stream.dict;
|
||||||
numComps = dict.get("N");
|
numComps = dict.get("N");
|
||||||
const alt = dict.get("Alternate");
|
const altRaw = dict.getRaw("Alternate");
|
||||||
if (alt) {
|
if (altRaw) {
|
||||||
const altCS = this.#parse(alt, xref, resources, pdfFunctionFactory);
|
const altCS = this.#subParse(altRaw, options);
|
||||||
// Ensure that the number of components are correct,
|
// Ensure that the number of components are correct,
|
||||||
// and also (indirectly) that it is not a PatternCS.
|
// and also (indirectly) that it is not a PatternCS.
|
||||||
if (altCS.numComps === numComps) {
|
if (altCS.numComps === numComps) {
|
||||||
@ -527,12 +550,12 @@ class ColorSpace {
|
|||||||
case "Pattern":
|
case "Pattern":
|
||||||
baseCS = cs[1] || null;
|
baseCS = cs[1] || null;
|
||||||
if (baseCS) {
|
if (baseCS) {
|
||||||
baseCS = this.#parse(baseCS, xref, resources, pdfFunctionFactory);
|
baseCS = this.#subParse(baseCS, options);
|
||||||
}
|
}
|
||||||
return new PatternCS(baseCS);
|
return new PatternCS(baseCS);
|
||||||
case "I":
|
case "I":
|
||||||
case "Indexed":
|
case "Indexed":
|
||||||
baseCS = this.#parse(cs[1], xref, resources, pdfFunctionFactory);
|
baseCS = this.#subParse(cs[1], options);
|
||||||
const hiVal = Math.max(0, Math.min(xref.fetchIfRef(cs[2]), 255));
|
const hiVal = Math.max(0, Math.min(xref.fetchIfRef(cs[2]), 255));
|
||||||
const lookup = xref.fetchIfRef(cs[3]);
|
const lookup = xref.fetchIfRef(cs[3]);
|
||||||
return new IndexedCS(baseCS, hiVal, lookup);
|
return new IndexedCS(baseCS, hiVal, lookup);
|
||||||
@ -540,7 +563,7 @@ class ColorSpace {
|
|||||||
case "DeviceN":
|
case "DeviceN":
|
||||||
const name = xref.fetchIfRef(cs[1]);
|
const name = xref.fetchIfRef(cs[1]);
|
||||||
numComps = Array.isArray(name) ? name.length : 1;
|
numComps = Array.isArray(name) ? name.length : 1;
|
||||||
baseCS = this.#parse(cs[2], xref, resources, pdfFunctionFactory);
|
baseCS = this.#subParse(cs[2], options);
|
||||||
const tintFn = pdfFunctionFactory.create(cs[3]);
|
const tintFn = pdfFunctionFactory.create(cs[3]);
|
||||||
return new AlternateCS(numComps, baseCS, tintFn);
|
return new AlternateCS(numComps, baseCS, tintFn);
|
||||||
case "Lab":
|
case "Lab":
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user