Skip to content

Use ImageDecoder to decode cmyk jpeg images (bug 1965870) #19918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion src/core/jpeg_stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ class JpegStream extends DecodeStream {
);
}

static get canUseImageDecoderCMYK() {
return shadow(
this,
"canUseImageDecoderCMYK",
this.#isImageDecoderSupported
? ImageDecoder.isTypeSupported("image/x-jpeg-pdf")
: Promise.resolve(false)
);
}

static setOptions({ isImageDecoderSupported = false }) {
this.#isImageDecoderSupported = isImageDecoderSupported;
}
Expand Down Expand Up @@ -171,6 +181,14 @@ class JpegStream extends DecodeStream {
if (!useImageDecoder) {
return null;
}
let type = "image/jpeg";
if (useImageDecoder.cmyk) {
if (await JpegStream.canUseImageDecoderCMYK) {
type = "image/x-jpeg-pdf";
} else {
return null;
}
}
if (useImageDecoder.exifStart) {
// Replace the entire EXIF-block with dummy data, to ensure that a
// non-default EXIF orientation won't cause the image to be rotated
Expand All @@ -182,7 +200,7 @@ class JpegStream extends DecodeStream {
}
decoder = new ImageDecoder({
data,
type: "image/jpeg",
type,
preferAnimation: false,
});

Expand Down
15 changes: 8 additions & 7 deletions src/core/jpg.js
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ class JpegImage {
}

static canUseImageDecoder(data, colorTransform = -1) {
let exifOffsets = null;
const jpegInfo = Object.create(null);
let offset = 0;
let numComponents = null;
let fileMarker = readUint16(data, offset);
Expand Down Expand Up @@ -838,12 +838,13 @@ class JpegImage {
appData[4] === 0 &&
appData[5] === 0
) {
if (exifOffsets) {
if (jpegInfo.exifStart) {
throw new JpegError("Duplicate EXIF-blocks found.");
}
// Don't do the EXIF-block replacement here, see `JpegStream`,
// since that can modify the original PDF document.
exifOffsets = { exifStart: oldOffset + 6, exifEnd: newOffset };
jpegInfo.exifStart = oldOffset + 6;
jpegInfo.exifEnd = newOffset;
}
fileMarker = readUint16(data, offset);
offset += 2;
Expand All @@ -868,13 +869,13 @@ class JpegImage {
fileMarker = readUint16(data, offset);
offset += 2;
}
if (numComponents === 4) {
return null;
}
if (numComponents === 3 && colorTransform === 0) {
return null;
}
return exifOffsets || {};
if (numComponents === 4) {
jpegInfo.cmyk = true;
}
return jpegInfo;
}

parse(data, { dnlScanLines = null } = {}) {
Expand Down