diff --git a/src/core/image.js b/src/core/image.js index 32a26d157..1509a3e1e 100644 --- a/src/core/image.js +++ b/src/core/image.js @@ -14,7 +14,7 @@ */ import { assert, FormatError, ImageKind, info, warn } from '../shared/util'; -import { isStream, Name } from './primitives'; +import { isName, isStream, Name } from './primitives'; import { ColorSpace } from './colorspace'; import { DecodeStream } from './stream'; import { JpegStream } from './jpeg_stream'; @@ -84,27 +84,47 @@ var PDFImage = (function PDFImageClosure() { this.image = image; var dict = image.dict; if (dict.has('Filter')) { - var filter = dict.get('Filter').name; - if (filter === 'JPXDecode') { - var jpxImage = new JpxImage(); - jpxImage.parseImageProperties(image.stream); - image.stream.reset(); - image.bitsPerComponent = jpxImage.bitsPerComponent; - image.numComps = jpxImage.componentsCount; - } else if (filter === 'JBIG2Decode') { - image.bitsPerComponent = 1; - image.numComps = 1; + const filter = dict.get('Filter'); + if (isName(filter)) { + switch (filter.name) { + case 'JPXDecode': + var jpxImage = new JpxImage(); + jpxImage.parseImageProperties(image.stream); + image.stream.reset(); + + image.width = jpxImage.width; + image.height = jpxImage.height; + image.bitsPerComponent = jpxImage.bitsPerComponent; + image.numComps = jpxImage.componentsCount; + break; + case 'JBIG2Decode': + image.bitsPerComponent = 1; + image.numComps = 1; + break; + } + } else { + warn(`PDFImage - invalid /Filter entry in dictionary: "${filter}".`); } } // TODO cache rendered images? - this.width = dict.get('Width', 'W'); - this.height = dict.get('Height', 'H'); + let width = dict.get('Width', 'W'); + let height = dict.get('Height', 'H'); - if (this.width < 1 || this.height < 1) { - throw new FormatError(`Invalid image width: ${this.width} or ` + - `height: ${this.height}`); + if ((Number.isInteger(image.width) && image.width > 0) && + (Number.isInteger(image.height) && image.height > 0) && + (image.width !== width || image.height !== height)) { + warn('PDFImage - using the Width/Height of the image data, ' + + 'rather than the image dictionary.'); + width = image.width; + height = image.height; } + if (width < 1 || height < 1) { + throw new FormatError(`Invalid image width: ${width} or ` + + `height: ${height}`); + } + this.width = width; + this.height = height; this.interpolate = dict.get('Interpolate', 'I') || false; this.imageMask = dict.get('ImageMask', 'IM') || false; @@ -139,7 +159,7 @@ var PDFImage = (function PDFImageClosure() { colorSpace = Name.get('DeviceCMYK'); break; default: - throw new Error(`JPX images with ${this.numComps} ` + + throw new Error(`JPX images with ${image.numComps} ` + 'color components not supported.'); } } diff --git a/src/core/jpx.js b/src/core/jpx.js index b484f5ba4..da80ad2a3 100644 --- a/src/core/jpx.js +++ b/src/core/jpx.js @@ -142,7 +142,7 @@ var JpxImage = (function JpxImageClosure() { this.width = Xsiz - XOsiz; this.height = Ysiz - YOsiz; this.componentsCount = Csiz; - // Results are always returned as Uint8Arrays + // Results are always returned as `Uint8ClampedArray`s. this.bitsPerComponent = 8; return; } diff --git a/test/pdfs/issue9650.pdf.link b/test/pdfs/issue9650.pdf.link new file mode 100644 index 000000000..b76a808e1 --- /dev/null +++ b/test/pdfs/issue9650.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/1898753/Kred.Eingangsrechnungen.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index defb40f4f..0cd02a1a8 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -3259,6 +3259,14 @@ "lastPage": 1, "type": "eq" }, + { "id": "issue9650", + "file": "pdfs/issue9650.pdf", + "md5": "20d50bda6b1080b6d9088811299c791e", + "rounds": 1, + "link": true, + "lastPage": 1, + "type": "eq" + }, { "id": "issue9679", "file": "pdfs/issue9679.pdf", "md5": "3077d06add3875705aa1021c7b116023",