Browse Source

Scale smask and image to the max dimensions of either one. Fix grayscale to scale the input value based on bpc.

Brendan Dahl 14 years ago
parent
commit
87d72023dc
  1. 8
      src/evaluator.js
  2. 63
      src/image.js

8
src/evaluator.js

@ -222,12 +222,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { @@ -222,12 +222,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
PDFImage.buildImage(function(imageObj) {
var imgData = {
width: w,
height: h,
data: new Uint8Array(w * h * 4)
width: imageObj.maxWidth,
height: imageObj.maxHeight,
data: new Uint8Array(imageObj.maxWidth * imageObj.maxHeight * 4)
};
var pixels = imgData.data;
imageObj.fillRgbaBuffer(pixels);
imageObj.fillRgbaBuffer(pixels, imageObj.maxWidth, imageObj.maxHeight);
handler.send('obj', [objId, 'Image', imgData]);
}, handler, xref, resources, image, inline);
}

63
src/image.js

@ -131,28 +131,52 @@ var PDFImage = (function PDFImageClosure() { @@ -131,28 +131,52 @@ var PDFImage = (function PDFImageClosure() {
* Resize an image using the nearest neighbor algorithm. Currently only
* supports one component images.
* @param {TypedArray} pixels The original image with one component.
* @param {Number} bpc Number of bits per component.
* @param {Number} components Number of color components, 1 or 3 is supported.
* @param {Number} w1 Original width.
* @param {Number} h1 Original height.
* @param {Number} w2 New width.
* @param {Number} h2 New height.
* @return {TypedArray} Resized image data.
*/
PDFImage.resize = function resize(pixels, w1, h1, w2, h2) {
var temp = new Uint8Array(w2 * h2);
PDFImage.resize = function resize(pixels, bpc, components, w1, h1, w2, h2) {
var length = w2 * h2 * components;
var temp = bpc <= 8 ? new Uint8Array(length) :
bpc <= 16 ? new Uint16Array(length) : new Uint32Array(length);
var xRatio = w1 / w2;
var yRatio = h1 / h2;
var px, py;
var px, py, newIndex, oldIndex;
for (var i = 0; i < h2; i++) {
for (var j = 0; j < w2; j++) {
px = Math.floor(j * xRatio);
py = Math.floor(i * yRatio);
temp[(i * w2) + j] = pixels[((py * w1) + px)];
newIndex = (i * w2) + j;
oldIndex = ((py * w1) + px);
if (components === 1) {
temp[newIndex] = pixels[oldIndex];
} else if(components === 3) {
newIndex *= 3;
oldIndex *= 3;
temp[newIndex] = pixels[oldIndex];
temp[newIndex + 1] = pixels[oldIndex + 1];
temp[newIndex + 2] = pixels[oldIndex + 2];
}
}
}
return temp;
};
PDFImage.prototype = {
get maxWidth() {
if (!this.smask)
return this.width;
return Math.max(this.width, this.smask.width);
},
get maxHeight() {
if (!this.smask)
return this.height;
return Math.max(this.height, this.smask.height);
},
getComponents: function getComponents(buffer) {
var bpc = this.bpc;
var needsDecode = this.needsDecode;
@ -241,10 +265,10 @@ var PDFImage = (function PDFImageClosure() { @@ -241,10 +265,10 @@ var PDFImage = (function PDFImageClosure() {
}
return output;
},
getOpacity: function getOpacity() {
getOpacity: function getOpacity(width, height) {
var smask = this.smask;
var width = this.width;
var height = this.height;
var originalWidth = this.width;
var originalHeight = this.height;
var buf;
if (smask) {
@ -252,9 +276,8 @@ var PDFImage = (function PDFImageClosure() { @@ -252,9 +276,8 @@ var PDFImage = (function PDFImageClosure() {
var sh = smask.height;
buf = new Uint8Array(sw * sh);
smask.fillGrayBuffer(buf);
if (sw != this.width || sh != this.height)
buf = PDFImage.resize(buf, sw, sh, this.width, this.height);
return buf;
if (sw != width || sh != height)
buf = PDFImage.resize(buf, smask.bps, 1, sw, sh, width, height);
} else {
buf = new Uint8Array(width * height);
for (var i = 0, ii = width * height; i < ii; ++i)
@ -285,20 +308,23 @@ var PDFImage = (function PDFImageClosure() { @@ -285,20 +308,23 @@ var PDFImage = (function PDFImageClosure() {
}
}
},
fillRgbaBuffer: function fillRgbaBuffer(buffer) {
fillRgbaBuffer: function fillRgbaBuffer(buffer, width, height) {
var numComps = this.numComps;
var width = this.width;
var height = this.height;
var originalWidth = this.width;
var originalHeight = this.height;
var bpc = this.bpc;
// rows start at byte boundary;
var rowBytes = (width * numComps * bpc + 7) >> 3;
var imgArray = this.getImageBytes(height * rowBytes);
var rowBytes = (originalWidth * numComps * bpc + 7) >> 3;
var imgArray = this.getImageBytes(originalHeight * rowBytes);
var comps = this.colorSpace.getRgbBuffer(
this.getComponents(imgArray), bpc);
if (originalWidth != width || originalHeight != height)
comps = PDFImage.resize(comps, this.bpc, 3, originalWidth, originalHeight,
width, height);
var compsPos = 0;
var opacity = this.getOpacity();
var opacity = this.getOpacity(width, height);
var opacityPos = 0;
var length = width * height * 4;
@ -324,9 +350,10 @@ var PDFImage = (function PDFImageClosure() { @@ -324,9 +350,10 @@ var PDFImage = (function PDFImageClosure() {
var comps = this.getComponents(imgArray);
var length = width * height;
// we aren't using a colorspace so we need to scale the value
var scale = 255 / ((1 << bpc) - 1);
for (var i = 0; i < length; ++i)
buffer[i] = comps[i];
buffer[i] = (scale * comps[i]) | 0;
},
getImageBytes: function getImageBytes(length) {
this.image.reset();

Loading…
Cancel
Save