Skip to content

Commit

Permalink
Merge pull request #10031 from Snuffleupagus/JPEG-CMYK-invert
Browse files Browse the repository at this point in the history
Add a new parameter to `JpegImage.getData` to indicate the source of the image data (issue 9513)
  • Loading branch information
timvandermeij authored Sep 2, 2018
2 parents a096e0c + 663922f commit d409c42
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
6 changes: 5 additions & 1 deletion examples/image_decoders/jpeg_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,11 @@ var jpegImage = new pdfjsImageDecoders.JpegImage();
jpegImage.parse(typedArrayImage);

var width = jpegImage.width, height = jpegImage.height;
var jpegData = jpegImage.getData(width, height, /* forceRGB = */ true);
var jpegData = jpegImage.getData({
width,
height,
forceRGB: true,
});

// Render the JPEG image on a <canvas>.
//
Expand Down
8 changes: 6 additions & 2 deletions src/core/jpeg_stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,12 @@ let JpegStream = (function JpegStreamClosure() {
const jpegImage = new JpegImage(jpegOptions);

jpegImage.parse(this.bytes);
let data = jpegImage.getData(this.drawWidth, this.drawHeight,
this.forceRGB);
let data = jpegImage.getData({
width: this.drawWidth,
height: this.drawHeight,
forceRGB: this.forceRGB,
isSourcePDF: true,
});
this.buffer = data;
this.bufferLength = data.length;
this.eof = true;
Expand Down
39 changes: 28 additions & 11 deletions src/core/jpg.js
Original file line number Diff line number Diff line change
Expand Up @@ -975,7 +975,7 @@ var JpegImage = (function JpegImageClosure() {
this.numComponents = this.components.length;
},

_getLinearizedBlockData: function getLinearizedBlockData(width, height) {
_getLinearizedBlockData(width, height, isSourcePDF = false) {
var scaleX = this.width / width, scaleY = this.height / height;

var component, componentScaleX, componentScaleY, blocksPerScanline;
Expand Down Expand Up @@ -1013,7 +1013,24 @@ var JpegImage = (function JpegImageClosure() {
}

// decodeTransform contains pairs of multiplier (-256..256) and additive
const transform = this._decodeTransform;
let transform = this._decodeTransform;

// In PDF files, JPEG images with CMYK colour spaces are usually inverted
// (this can be observed by extracting the raw image data).
// Since the conversion algorithms (see below) were written primarily for
// the PDF use-cases, attempting to use `JpegImage` to parse standalone
// JPEG (CMYK) images may thus result in inverted images (see issue 9513).
//
// Unfortunately it's not (always) possible to tell, from the image data
// alone, if it needs to be inverted. Thus in an attempt to provide better
// out-of-box behaviour when `JpegImage` is used standalone, default to
// inverting JPEG (CMYK) images if and only if the image data does *not*
// come from a PDF file and no `decodeTransform` was passed by the user.
if (!transform && numComponents === 4 && !isSourcePDF) {
transform = new Int32Array([
-256, 255, -256, 255, -256, 255, -256, 255]);
}

if (transform) {
for (i = 0; i < dataLength;) {
for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
Expand All @@ -1024,7 +1041,7 @@ var JpegImage = (function JpegImageClosure() {
return data;
},

_isColorConversionNeeded() {
get _isColorConversionNeeded() {
if (this.adobe) {
// The adobe transform marker overrides any previous setting.
return !!this.adobe.transformCode;
Expand Down Expand Up @@ -1162,14 +1179,14 @@ var JpegImage = (function JpegImageClosure() {
return data.subarray(0, offset);
},

getData: function getData(width, height, forceRGBoutput) {
getData({ width, height, forceRGB = false, isSourcePDF = false, }) {
if (this.numComponents > 4) {
throw new JpegError('Unsupported color mode');
}
// type of data: Uint8Array(width * height * numComponents)
var data = this._getLinearizedBlockData(width, height);
// Type of data: Uint8ClampedArray(width * height * numComponents)
var data = this._getLinearizedBlockData(width, height, isSourcePDF);

if (this.numComponents === 1 && forceRGBoutput) {
if (this.numComponents === 1 && forceRGB) {
var dataLength = data.length;
var rgbData = new Uint8ClampedArray(dataLength * 3);
var offset = 0;
Expand All @@ -1180,15 +1197,15 @@ var JpegImage = (function JpegImageClosure() {
rgbData[offset++] = grayColor;
}
return rgbData;
} else if (this.numComponents === 3 && this._isColorConversionNeeded()) {
} else if (this.numComponents === 3 && this._isColorConversionNeeded) {
return this._convertYccToRgb(data);
} else if (this.numComponents === 4) {
if (this._isColorConversionNeeded()) {
if (forceRGBoutput) {
if (this._isColorConversionNeeded) {
if (forceRGB) {
return this._convertYcckToRgb(data);
}
return this._convertYcckToCmyk(data);
} else if (forceRGBoutput) {
} else if (forceRGB) {
return this._convertCmykToRgb(data);
}
}
Expand Down

0 comments on commit d409c42

Please sign in to comment.