|
|
|
@ -24,6 +24,15 @@ var PDFImage = (function PDFImageClosure() {
@@ -24,6 +24,15 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
promise.resolve(image); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* Decode and clamp a value. The formula is different from the spec because we |
|
|
|
|
* don't decode to float range [0,1], we decode it in the [0,max] range. |
|
|
|
|
*/ |
|
|
|
|
function decodeAndClamp(value, addend, coefficient, max) { |
|
|
|
|
value = addend + value * coefficient; |
|
|
|
|
// Clamp the value to the range
|
|
|
|
|
return value < 0 ? 0 : value > max ? max : value; |
|
|
|
|
} |
|
|
|
|
function PDFImage(xref, res, image, inline, smask) { |
|
|
|
|
this.image = image; |
|
|
|
|
if (image.getParams) { |
|
|
|
@ -69,6 +78,21 @@ var PDFImage = (function PDFImageClosure() {
@@ -69,6 +78,21 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.decode = dict.get('Decode', 'D'); |
|
|
|
|
this.needsDecode = false; |
|
|
|
|
if (this.decode && this.colorSpace && |
|
|
|
|
!this.colorSpace.isDefaultDecode(this.decode)) { |
|
|
|
|
this.needsDecode = true; |
|
|
|
|
// Do some preprocessing to avoid more math.
|
|
|
|
|
var max = (1 << bitsPerComponent) - 1; |
|
|
|
|
this.decodeCoefficients = []; |
|
|
|
|
this.decodeAddends = []; |
|
|
|
|
for (var i = 0, j = 0; i < this.decode.length; i += 2, ++j) { |
|
|
|
|
var dmin = this.decode[i]; |
|
|
|
|
var dmax = this.decode[i + 1]; |
|
|
|
|
this.decodeCoefficients[j] = dmax - dmin; |
|
|
|
|
this.decodeAddends[j] = max * dmin; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var mask = xref.fetchIfRef(dict.get('Mask')); |
|
|
|
|
|
|
|
|
@ -104,22 +128,43 @@ var PDFImage = (function PDFImageClosure() {
@@ -104,22 +128,43 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
PDFImage.prototype = { |
|
|
|
|
getComponents: function getComponents(buffer, decodeMap) { |
|
|
|
|
getComponents: function getComponents(buffer) { |
|
|
|
|
var bpc = this.bpc; |
|
|
|
|
if (bpc == 8) |
|
|
|
|
var needsDecode = this.needsDecode; |
|
|
|
|
var decodeMap = this.decode; |
|
|
|
|
|
|
|
|
|
// This image doesn't require any extra work.
|
|
|
|
|
if (bpc == 8 && !needsDecode) |
|
|
|
|
return buffer; |
|
|
|
|
|
|
|
|
|
var bufferLength = buffer.length; |
|
|
|
|
var width = this.width; |
|
|
|
|
var height = this.height; |
|
|
|
|
var numComps = this.numComps; |
|
|
|
|
|
|
|
|
|
var length = width * height; |
|
|
|
|
var length = width * height * numComps; |
|
|
|
|
var bufferPos = 0; |
|
|
|
|
var output = bpc <= 8 ? new Uint8Array(length) : |
|
|
|
|
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length); |
|
|
|
|
var rowComps = width * numComps; |
|
|
|
|
var decodeAddends, decodeCoefficients; |
|
|
|
|
if (needsDecode) { |
|
|
|
|
decodeAddends = this.decodeAddends; |
|
|
|
|
decodeCoefficients = this.decodeCoefficients; |
|
|
|
|
} |
|
|
|
|
var max = (1 << bpc) - 1; |
|
|
|
|
|
|
|
|
|
if (bpc == 1) { |
|
|
|
|
if (bpc == 8) { |
|
|
|
|
// Optimization for reading 8 bpc images that have a decode.
|
|
|
|
|
for (var i = 0, ii = length; i < ii; ++i) { |
|
|
|
|
var compIndex = i % numComps; |
|
|
|
|
var value = buffer[i]; |
|
|
|
|
value = decodeAndClamp(value, decodeAddends[compIndex], |
|
|
|
|
decodeCoefficients[compIndex], max); |
|
|
|
|
output[i] = value; |
|
|
|
|
} |
|
|
|
|
} else if (bpc == 1) { |
|
|
|
|
// Optimization for reading 1 bpc images.
|
|
|
|
|
var valueZero = 0, valueOne = 1; |
|
|
|
|
if (decodeMap) { |
|
|
|
|
valueZero = decodeMap[0] ? 1 : 0; |
|
|
|
@ -144,8 +189,7 @@ var PDFImage = (function PDFImageClosure() {
@@ -144,8 +189,7 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
output[i] = !(buf & mask) ? valueZero : valueOne; |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
if (decodeMap != null) |
|
|
|
|
TODO('interpolate component values'); |
|
|
|
|
// The general case that handles all other bpc values.
|
|
|
|
|
var bits = 0, buf = 0; |
|
|
|
|
for (var i = 0, ii = length; i < ii; ++i) { |
|
|
|
|
if (i % rowComps == 0) { |
|
|
|
@ -159,7 +203,13 @@ var PDFImage = (function PDFImageClosure() {
@@ -159,7 +203,13 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var remainingBits = bits - bpc; |
|
|
|
|
output[i] = buf >> remainingBits; |
|
|
|
|
var value = buf >> remainingBits; |
|
|
|
|
if (needsDecode) { |
|
|
|
|
var compIndex = i % numComps; |
|
|
|
|
value = decodeAndClamp(value, decodeAddends[compIndex], |
|
|
|
|
decodeCoefficients[compIndex], max); |
|
|
|
|
} |
|
|
|
|
output[i] = value; |
|
|
|
|
buf = buf & ((1 << remainingBits) - 1); |
|
|
|
|
bits = remainingBits; |
|
|
|
|
} |
|
|
|
@ -210,7 +260,7 @@ var PDFImage = (function PDFImageClosure() {
@@ -210,7 +260,7 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}, |
|
|
|
|
fillRgbaBuffer: function fillRgbaBuffer(buffer, decodeMap) { |
|
|
|
|
fillRgbaBuffer: function fillRgbaBuffer(buffer) { |
|
|
|
|
var numComps = this.numComps; |
|
|
|
|
var width = this.width; |
|
|
|
|
var height = this.height; |
|
|
|
@ -221,7 +271,7 @@ var PDFImage = (function PDFImageClosure() {
@@ -221,7 +271,7 @@ var PDFImage = (function PDFImageClosure() {
|
|
|
|
|
var imgArray = this.getImageBytes(height * rowBytes); |
|
|
|
|
|
|
|
|
|
var comps = this.colorSpace.getRgbBuffer( |
|
|
|
|
this.getComponents(imgArray, decodeMap), bpc); |
|
|
|
|
this.getComponents(imgArray), bpc); |
|
|
|
|
var compsPos = 0; |
|
|
|
|
var opacity = this.getOpacity(); |
|
|
|
|
var opacityPos = 0; |
|
|
|
|