diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 9aadc4649..64e41f76b 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -592,12 +592,8 @@ class PartialEvaluator { resources ); } - if (optionalContent !== undefined) { - operatorList.addOp(OPS.beginMarkedContentProps, ["OC", optionalContent]); - } const imageMask = dict.get("IM", "ImageMask") || false; - const interpolate = dict.get("I", "Interpolate"); let imgData, args; if (imageMask) { // 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 // complete PDFImage, only read the information needed // for later. + const interpolate = dict.get("I", "Interpolate"); const bitStrideLength = (w + 7) >> 3; const imgArray = image.getBytes( bitStrideLength * h, @@ -625,17 +622,19 @@ class PartialEvaluator { imgData.cached = !!cacheKey; args = [imgData]; - operatorList.addOp(OPS.paintImageMaskXObject, args); + operatorList.addImageOps( + OPS.paintImageMaskXObject, + args, + optionalContent + ); + if (cacheKey) { localImageCache.set(cacheKey, imageRef, { fn: OPS.paintImageMaskXObject, args, + optionalContent, }); } - - if (optionalContent !== undefined) { - operatorList.addOp(OPS.endMarkedContent, []); - } return; } @@ -651,17 +650,19 @@ class PartialEvaluator { if (imgData.isSingleOpaquePixel) { // Handles special case of mainly LaTeX documents which use image // masks to draw lines with the current fill style. - operatorList.addOp(OPS.paintSolidColorImageMask, []); + operatorList.addImageOps( + OPS.paintSolidColorImageMask, + [], + optionalContent + ); + if (cacheKey) { localImageCache.set(cacheKey, imageRef, { fn: OPS.paintSolidColorImageMask, args: [], + optionalContent, }); } - - if (optionalContent !== undefined) { - operatorList.addOp(OPS.endMarkedContent, []); - } return; } @@ -678,18 +679,19 @@ class PartialEvaluator { count: 1, }, ]; + operatorList.addImageOps( + OPS.paintImageMaskXObject, + args, + optionalContent + ); - operatorList.addOp(OPS.paintImageMaskXObject, args); if (cacheKey) { localImageCache.set(cacheKey, imageRef, { fn: OPS.paintImageMaskXObject, args, + optionalContent, }); } - - if (optionalContent !== undefined) { - operatorList.addOp(OPS.endMarkedContent, []); - } return; } @@ -710,11 +712,11 @@ class PartialEvaluator { // We force the use of RGBA_32BPP images here, because we can't handle // any other kind. imgData = imageObj.createImageData(/* forceRGBA = */ true); - operatorList.addOp(OPS.paintInlineImageXObject, [imgData]); - - if (optionalContent !== undefined) { - operatorList.addOp(OPS.endMarkedContent, []); - } + operatorList.addImageOps( + OPS.paintInlineImageXObject, + [imgData], + optionalContent + ); return; } @@ -762,11 +764,13 @@ class PartialEvaluator { return this._sendImgData(objId, /* imgData = */ null, cacheGlobally); }); - operatorList.addOp(OPS.paintImageXObject, args); + operatorList.addImageOps(OPS.paintImageXObject, args, optionalContent); + if (cacheKey) { localImageCache.set(cacheKey, imageRef, { fn: OPS.paintImageXObject, args, + optionalContent, }); if (imageRef) { @@ -778,15 +782,12 @@ class PartialEvaluator { objId, fn: OPS.paintImageXObject, args, + optionalContent, byteSize: 0, // Temporary entry, note `addByteSize` above. }); } } } - - if (optionalContent !== undefined) { - operatorList.addOp(OPS.endMarkedContent, []); - } } handleSMask( @@ -1700,7 +1701,12 @@ class PartialEvaluator { if (isValidName) { const localImage = localImageCache.getByName(name); if (localImage) { - operatorList.addOp(localImage.fn, localImage.args); + operatorList.addImageOps( + localImage.fn, + localImage.args, + localImage.optionalContent + ); + if ( localImage.fn === OPS.paintImageMaskXObject && localImage.args[0] && @@ -1723,7 +1729,12 @@ class PartialEvaluator { if (xobj instanceof Ref) { const localImage = localImageCache.getByRef(xobj); if (localImage) { - operatorList.addOp(localImage.fn, localImage.args); + operatorList.addImageOps( + localImage.fn, + localImage.args, + localImage.optionalContent + ); + if ( localImage.fn === OPS.paintImageMaskXObject && localImage.args[0] && @@ -1741,7 +1752,11 @@ class PartialEvaluator { ); if (globalImage) { operatorList.addDependency(globalImage.objId); - operatorList.addOp(globalImage.fn, globalImage.args); + operatorList.addImageOps( + globalImage.fn, + globalImage.args, + globalImage.optionalContent + ); resolveXObject(); return; @@ -1846,7 +1861,12 @@ class PartialEvaluator { if (cacheKey) { const localImage = localImageCache.getByName(cacheKey); if (localImage) { - operatorList.addOp(localImage.fn, localImage.args); + operatorList.addImageOps( + localImage.fn, + localImage.args, + localImage.optionalContent + ); + if ( localImage.fn === OPS.paintImageMaskXObject && localImage.args[0] && diff --git a/src/core/operator_list.js b/src/core/operator_list.js index 767b2669a..cfd4be69c 100644 --- a/src/core/operator_list.js +++ b/src/core/operator_list.js @@ -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) { if (this.dependencies.has(dependency)) { return; diff --git a/test/pdfs/issue14824.pdf.link b/test/pdfs/issue14824.pdf.link new file mode 100644 index 000000000..b1b900d69 --- /dev/null +++ b/test/pdfs/issue14824.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/8540275/PDF.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index c69bff3f8..6082ee0f1 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -2965,6 +2965,18 @@ "annotations": true, "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", "file": "pdfs/issue1127.pdf", "md5": "4fb2be5ffefeafda4ba977de2a1bb4d8",