Merge pull request #10031 from Snuffleupagus/JPEG-CMYK-invert
Add a new parameter to `JpegImage.getData` to indicate the source of the image data (issue 9513)
This commit is contained in:
commit
d409c42068
@ -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>.
|
||||
//
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
@ -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) {
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user