Fallback to the built-in JPEG decoder if 'JpegStream', in src/display/api.js
, fails to load the image
This works by making `PartialEvaluator.buildPaintImageXObject` wait for the success/failure of `loadJpegStream` on the API side *before* parsing continues. Please note that in practice, it should be quite rare for the browser to fail loading/decoding of a JPEG image. In the general case, it should thus not be completely surprising if even `src/core/jpg.js` will fail to decode the image.
This commit is contained in:
parent
76afe1018b
commit
80441346a3
@ -349,7 +349,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
},
|
||||
|
||||
buildPaintImageXObject({ resources, image, isInline = false, operatorList,
|
||||
cacheKey, imageCache, }) {
|
||||
cacheKey, imageCache,
|
||||
forceDisableNativeImageDecoder = false, }) {
|
||||
var dict = image.dict;
|
||||
var w = dict.get('Width', 'W');
|
||||
var h = dict.get('Height', 'H');
|
||||
@ -419,28 +420,47 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
var nativeImageDecoderSupport = this.options.nativeImageDecoderSupport;
|
||||
const nativeImageDecoderSupport = forceDisableNativeImageDecoder ?
|
||||
NativeImageDecoding.NONE : this.options.nativeImageDecoderSupport;
|
||||
// If there is no imageMask, create the PDFImage and a lot
|
||||
// of image processing can be done here.
|
||||
var objId = 'img_' + this.idFactory.createObjId();
|
||||
operatorList.addDependency(objId);
|
||||
args = [objId, w, h];
|
||||
|
||||
if (nativeImageDecoderSupport !== NativeImageDecoding.NONE &&
|
||||
!softMask && !mask && image instanceof JpegStream &&
|
||||
NativeImageDecoder.isSupported(image, this.xref, resources,
|
||||
this.pdfFunctionFactory)) {
|
||||
// These JPEGs don't need any more processing so we can just send it.
|
||||
operatorList.addOp(OPS.paintJpegXObject, args);
|
||||
this.handler.send('obj', [objId, this.pageIndex, 'JpegStream',
|
||||
image.getIR(this.options.forceDataSchema)]);
|
||||
if (cacheKey) {
|
||||
imageCache[cacheKey] = {
|
||||
fn: OPS.paintJpegXObject,
|
||||
args,
|
||||
};
|
||||
}
|
||||
return Promise.resolve();
|
||||
return this.handler.sendWithPromise('obj', [
|
||||
objId, this.pageIndex, 'JpegStream',
|
||||
image.getIR(this.options.forceDataSchema)
|
||||
]).then(function() {
|
||||
// Only add the dependency once we know that the native JPEG decoding
|
||||
// succeeded, to ensure that rendering will always complete.
|
||||
operatorList.addDependency(objId);
|
||||
args = [objId, w, h];
|
||||
|
||||
operatorList.addOp(OPS.paintJpegXObject, args);
|
||||
if (cacheKey) {
|
||||
imageCache[cacheKey] = {
|
||||
fn: OPS.paintJpegXObject,
|
||||
args,
|
||||
};
|
||||
}
|
||||
}, (reason) => {
|
||||
warn('Native JPEG decoding failed -- trying to recover: ' +
|
||||
(reason && reason.message));
|
||||
// Try to decode the JPEG image with the built-in decoder instead.
|
||||
return this.buildPaintImageXObject({
|
||||
resources,
|
||||
image,
|
||||
isInline,
|
||||
operatorList,
|
||||
cacheKey,
|
||||
imageCache,
|
||||
forceDisableNativeImageDecoder: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Creates native image decoder only if a JPEG image or mask is present.
|
||||
@ -457,6 +477,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
});
|
||||
}
|
||||
|
||||
// Ensure that the dependency is added before the image is decoded.
|
||||
operatorList.addDependency(objId);
|
||||
args = [objId, w, h];
|
||||
|
||||
PDFImage.buildImage({
|
||||
handler: this.handler,
|
||||
xref: this.xref,
|
||||
|
@ -1817,22 +1817,22 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
switch (type) {
|
||||
case 'JpegStream':
|
||||
imageData = data[3];
|
||||
new Promise((resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = function() {
|
||||
resolve(img);
|
||||
};
|
||||
img.onerror = function() {
|
||||
reject(new Error('Error during JPEG image loading'));
|
||||
// Note that when the browser image loading/decoding fails,
|
||||
// we'll fallback to the built-in PDF.js JPEG decoder; see
|
||||
// `PartialEvaluator.buildPaintImageXObject` in the
|
||||
// `src/core/evaluator.js` file.
|
||||
};
|
||||
img.src = imageData;
|
||||
}).then((img) => {
|
||||
pageProxy.objs.resolve(id, img);
|
||||
}, (reason) => {
|
||||
warn(reason);
|
||||
pageProxy.objs.resolve(id, null);
|
||||
});
|
||||
break;
|
||||
case 'Image':
|
||||
imageData = data[3];
|
||||
pageProxy.objs.resolve(id, imageData);
|
||||
|
Loading…
x
Reference in New Issue
Block a user