Merge pull request #14825 from Snuffleupagus/issue-14824
Ensure that worker-thread image caching doesn't break optional content (issue 14824)
This commit is contained in:
commit
752dee5caa
@ -592,12 +592,8 @@ class PartialEvaluator {
|
|||||||
resources
|
resources
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (optionalContent !== undefined) {
|
|
||||||
operatorList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const imageMask = dict.get("IM", "ImageMask") || false;
|
const imageMask = dict.get("IM", "ImageMask") || false;
|
||||||
const interpolate = dict.get("I", "Interpolate");
|
|
||||||
let imgData, args;
|
let imgData, args;
|
||||||
if (imageMask) {
|
if (imageMask) {
|
||||||
// This depends on a tmpCanvas being filled with the
|
// This depends on a tmpCanvas being filled with the
|
||||||
@ -605,6 +601,7 @@ class PartialEvaluator {
|
|||||||
// data can't be done here. Instead of creating a
|
// data can't be done here. Instead of creating a
|
||||||
// complete PDFImage, only read the information needed
|
// complete PDFImage, only read the information needed
|
||||||
// for later.
|
// for later.
|
||||||
|
const interpolate = dict.get("I", "Interpolate");
|
||||||
const bitStrideLength = (w + 7) >> 3;
|
const bitStrideLength = (w + 7) >> 3;
|
||||||
const imgArray = image.getBytes(
|
const imgArray = image.getBytes(
|
||||||
bitStrideLength * h,
|
bitStrideLength * h,
|
||||||
@ -625,17 +622,19 @@ class PartialEvaluator {
|
|||||||
imgData.cached = !!cacheKey;
|
imgData.cached = !!cacheKey;
|
||||||
args = [imgData];
|
args = [imgData];
|
||||||
|
|
||||||
operatorList.addOp(OPS.paintImageMaskXObject, args);
|
operatorList.addImageOps(
|
||||||
|
OPS.paintImageMaskXObject,
|
||||||
|
args,
|
||||||
|
optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
localImageCache.set(cacheKey, imageRef, {
|
localImageCache.set(cacheKey, imageRef, {
|
||||||
fn: OPS.paintImageMaskXObject,
|
fn: OPS.paintImageMaskXObject,
|
||||||
args,
|
args,
|
||||||
|
optionalContent,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionalContent !== undefined) {
|
|
||||||
operatorList.addOp(OPS.endMarkedContent, []);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,17 +650,19 @@ class PartialEvaluator {
|
|||||||
if (imgData.isSingleOpaquePixel) {
|
if (imgData.isSingleOpaquePixel) {
|
||||||
// Handles special case of mainly LaTeX documents which use image
|
// Handles special case of mainly LaTeX documents which use image
|
||||||
// masks to draw lines with the current fill style.
|
// masks to draw lines with the current fill style.
|
||||||
operatorList.addOp(OPS.paintSolidColorImageMask, []);
|
operatorList.addImageOps(
|
||||||
|
OPS.paintSolidColorImageMask,
|
||||||
|
[],
|
||||||
|
optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
localImageCache.set(cacheKey, imageRef, {
|
localImageCache.set(cacheKey, imageRef, {
|
||||||
fn: OPS.paintSolidColorImageMask,
|
fn: OPS.paintSolidColorImageMask,
|
||||||
args: [],
|
args: [],
|
||||||
|
optionalContent,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionalContent !== undefined) {
|
|
||||||
operatorList.addOp(OPS.endMarkedContent, []);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,18 +679,19 @@ class PartialEvaluator {
|
|||||||
count: 1,
|
count: 1,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
operatorList.addImageOps(
|
||||||
|
OPS.paintImageMaskXObject,
|
||||||
|
args,
|
||||||
|
optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
operatorList.addOp(OPS.paintImageMaskXObject, args);
|
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
localImageCache.set(cacheKey, imageRef, {
|
localImageCache.set(cacheKey, imageRef, {
|
||||||
fn: OPS.paintImageMaskXObject,
|
fn: OPS.paintImageMaskXObject,
|
||||||
args,
|
args,
|
||||||
|
optionalContent,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionalContent !== undefined) {
|
|
||||||
operatorList.addOp(OPS.endMarkedContent, []);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,11 +712,11 @@ class PartialEvaluator {
|
|||||||
// We force the use of RGBA_32BPP images here, because we can't handle
|
// We force the use of RGBA_32BPP images here, because we can't handle
|
||||||
// any other kind.
|
// any other kind.
|
||||||
imgData = imageObj.createImageData(/* forceRGBA = */ true);
|
imgData = imageObj.createImageData(/* forceRGBA = */ true);
|
||||||
operatorList.addOp(OPS.paintInlineImageXObject, [imgData]);
|
operatorList.addImageOps(
|
||||||
|
OPS.paintInlineImageXObject,
|
||||||
if (optionalContent !== undefined) {
|
[imgData],
|
||||||
operatorList.addOp(OPS.endMarkedContent, []);
|
optionalContent
|
||||||
}
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,11 +764,13 @@ class PartialEvaluator {
|
|||||||
return this._sendImgData(objId, /* imgData = */ null, cacheGlobally);
|
return this._sendImgData(objId, /* imgData = */ null, cacheGlobally);
|
||||||
});
|
});
|
||||||
|
|
||||||
operatorList.addOp(OPS.paintImageXObject, args);
|
operatorList.addImageOps(OPS.paintImageXObject, args, optionalContent);
|
||||||
|
|
||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
localImageCache.set(cacheKey, imageRef, {
|
localImageCache.set(cacheKey, imageRef, {
|
||||||
fn: OPS.paintImageXObject,
|
fn: OPS.paintImageXObject,
|
||||||
args,
|
args,
|
||||||
|
optionalContent,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (imageRef) {
|
if (imageRef) {
|
||||||
@ -778,15 +782,12 @@ class PartialEvaluator {
|
|||||||
objId,
|
objId,
|
||||||
fn: OPS.paintImageXObject,
|
fn: OPS.paintImageXObject,
|
||||||
args,
|
args,
|
||||||
|
optionalContent,
|
||||||
byteSize: 0, // Temporary entry, note `addByteSize` above.
|
byteSize: 0, // Temporary entry, note `addByteSize` above.
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optionalContent !== undefined) {
|
|
||||||
operatorList.addOp(OPS.endMarkedContent, []);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSMask(
|
handleSMask(
|
||||||
@ -1700,7 +1701,12 @@ class PartialEvaluator {
|
|||||||
if (isValidName) {
|
if (isValidName) {
|
||||||
const localImage = localImageCache.getByName(name);
|
const localImage = localImageCache.getByName(name);
|
||||||
if (localImage) {
|
if (localImage) {
|
||||||
operatorList.addOp(localImage.fn, localImage.args);
|
operatorList.addImageOps(
|
||||||
|
localImage.fn,
|
||||||
|
localImage.args,
|
||||||
|
localImage.optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
localImage.fn === OPS.paintImageMaskXObject &&
|
localImage.fn === OPS.paintImageMaskXObject &&
|
||||||
localImage.args[0] &&
|
localImage.args[0] &&
|
||||||
@ -1723,7 +1729,12 @@ class PartialEvaluator {
|
|||||||
if (xobj instanceof Ref) {
|
if (xobj instanceof Ref) {
|
||||||
const localImage = localImageCache.getByRef(xobj);
|
const localImage = localImageCache.getByRef(xobj);
|
||||||
if (localImage) {
|
if (localImage) {
|
||||||
operatorList.addOp(localImage.fn, localImage.args);
|
operatorList.addImageOps(
|
||||||
|
localImage.fn,
|
||||||
|
localImage.args,
|
||||||
|
localImage.optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
localImage.fn === OPS.paintImageMaskXObject &&
|
localImage.fn === OPS.paintImageMaskXObject &&
|
||||||
localImage.args[0] &&
|
localImage.args[0] &&
|
||||||
@ -1741,7 +1752,11 @@ class PartialEvaluator {
|
|||||||
);
|
);
|
||||||
if (globalImage) {
|
if (globalImage) {
|
||||||
operatorList.addDependency(globalImage.objId);
|
operatorList.addDependency(globalImage.objId);
|
||||||
operatorList.addOp(globalImage.fn, globalImage.args);
|
operatorList.addImageOps(
|
||||||
|
globalImage.fn,
|
||||||
|
globalImage.args,
|
||||||
|
globalImage.optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
resolveXObject();
|
resolveXObject();
|
||||||
return;
|
return;
|
||||||
@ -1846,7 +1861,12 @@ class PartialEvaluator {
|
|||||||
if (cacheKey) {
|
if (cacheKey) {
|
||||||
const localImage = localImageCache.getByName(cacheKey);
|
const localImage = localImageCache.getByName(cacheKey);
|
||||||
if (localImage) {
|
if (localImage) {
|
||||||
operatorList.addOp(localImage.fn, localImage.args);
|
operatorList.addImageOps(
|
||||||
|
localImage.fn,
|
||||||
|
localImage.args,
|
||||||
|
localImage.optionalContent
|
||||||
|
);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
localImage.fn === OPS.paintImageMaskXObject &&
|
localImage.fn === OPS.paintImageMaskXObject &&
|
||||||
localImage.args[0] &&
|
localImage.args[0] &&
|
||||||
|
@ -622,6 +622,18 @@ class OperatorList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addImageOps(fn, args, optionalContent) {
|
||||||
|
if (optionalContent !== undefined) {
|
||||||
|
this.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.addOp(fn, args);
|
||||||
|
|
||||||
|
if (optionalContent !== undefined) {
|
||||||
|
this.addOp(OPS.endMarkedContent, []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addDependency(dependency) {
|
addDependency(dependency) {
|
||||||
if (this.dependencies.has(dependency)) {
|
if (this.dependencies.has(dependency)) {
|
||||||
return;
|
return;
|
||||||
|
1
test/pdfs/issue14824.pdf.link
Normal file
1
test/pdfs/issue14824.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/mozilla/pdf.js/files/8540275/PDF.pdf
|
@ -2965,6 +2965,18 @@
|
|||||||
"annotations": true,
|
"annotations": true,
|
||||||
"about": "LinkAnnotation with a relative link, and a /Catalog Base-URI."
|
"about": "LinkAnnotation with a relative link, and a /Catalog Base-URI."
|
||||||
},
|
},
|
||||||
|
{ "id": "issue14824",
|
||||||
|
"file": "pdfs/issue14824.pdf",
|
||||||
|
"md5": "7b8d061ab0a342e3606a3b3ba1925d5b",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": true,
|
||||||
|
"lastPage": 4,
|
||||||
|
"type": "eq",
|
||||||
|
"optionalContent": {
|
||||||
|
"7R": false
|
||||||
|
},
|
||||||
|
"about": "Need to test *at least* three pages, since the `GlobalImageCache` is involved."
|
||||||
|
},
|
||||||
{ "id": "issue1127-text",
|
{ "id": "issue1127-text",
|
||||||
"file": "pdfs/issue1127.pdf",
|
"file": "pdfs/issue1127.pdf",
|
||||||
"md5": "4fb2be5ffefeafda4ba977de2a1bb4d8",
|
"md5": "4fb2be5ffefeafda4ba977de2a1bb4d8",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user