getTileOrStrip: function(x, y, plane) {
var numTilesPerRow = Math.ceil(this.getWidth() / this.getTileWidth());
var numTilesPerCol = Math.ceil(this.getHeight() / this.getTileHeight());
var index;
if (this.planarConfiguration === 1) {
index = y * numTilesPerRow + x;
}
else if (this.planarConfiguration === 2) {
index = plane * numTilesPerRow * numTilesPerCol + y * numTilesPerRow + x;
}
if (index in this.tiles && false) {
return this.tiles[index];
}
else {
var offset, byteCount;
if (this.isTiled) {
offset = this.fileDirectory.TileOffsets[index];
byteCount = this.fileDirectory.TileByteCounts[index];
}
else {
offset = this.fileDirectory.StripOffsets[index];
byteCount = this.fileDirectory.StripByteCounts[index];
}
return this.tiles[index] = this.decodeBlock(offset, byteCount);
}
},
_readRaster: function(imageWindow, samples, valueArrays) {
var tileWidth = this.getTileWidth();
var tileHeight = this.getTileHeight();
var minXTile = Math.floor(imageWindow[0] / tileWidth);
var maxXTile = Math.ceil(imageWindow[2] / tileWidth);
var minYTile = Math.floor(imageWindow[1] / tileHeight);
var maxYTile = Math.ceil(imageWindow[3] / tileHeight);
var numTilesPerRow = Math.ceil(this.getWidth() / tileWidth);
var windowWidth = imageWindow[2] - imageWindow[0];
var windowHeight = imageWindow[3] - imageWindow[1];
var bytesPerPixel = this.getBytesPerPixel();
var imageWidth = this.getWidth();
var srcSampleOffsets = [];
var sampleReaders = [];
for (var i = 0; i < samples.length; ++i) {
if (this.planarConfiguration === 1) {
srcSampleOffsets.push(sum(this.fileDirectory.BitsPerSample, 0, samples[i]) / 8);
}
else {
srcSampleOffsets.push(0);
}
sampleReaders.push(this.getReaderForSample(samples[i]));
}
for (var yTile = minYTile; yTile <= maxYTile; ++yTile) {
for (var xTile = minXTile; xTile <= maxXTile; ++xTile) {
var firstLine = yTile * tileHeight;
var firstCol = xTile * tileWidth;
var lastLine = (yTile + 1) * tileHeight;
var lastCol = (xTile + 1) * tileWidth;
for (var sampleIndex = 0; sampleIndex < samples.length; ++sampleIndex) {
var sample = samples[sampleIndex];
if (this.planarConfiguration === 2) {
bytesPerPixel = this.getSampleByteSize(sample);
}
var tile = new DataView(this.getTileOrStrip(xTile, yTile, sample));
for (var y = Math.max(0, imageWindow[1] - firstLine); y < Math.min(tileHeight, tileHeight - (lastLine - imageWindow[3])); ++y) {
for (var x = Math.max(0, imageWindow[0] - firstCol); x < Math.min(tileWidth, tileWidth - (lastCol - imageWindow[2])); ++x) {
var pixelOffset = (y * tileWidth + x) * bytesPerPixel;
var windowCoordinate = (
y + firstLine - imageWindow[1]
) * windowWidth + x + firstCol - imageWindow[0];
valueArrays[sampleIndex][windowCoordinate] = sampleReaders[sampleIndex].call(tile, pixelOffset + srcSampleOffsets[sampleIndex], this.littleEndian);
}
}
}
}
}
},
readRasters: function(imageWindow, samples) {
imageWindow = imageWindow || [0, 0, this.getWidth(), this.getHeight()];
if (imageWindow[0] < 0 || imageWindow[1] < 0 || imageWindow[2] > this.getWidth() || imageWindow[3] > this.getHeight()) {
throw new Error("Select window is out of image bounds.");
}
else if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
throw new Error("Invalid subsets");
}
var imageWindowWidth = imageWindow[2] - imageWindow[0];
var imageWindowHeight = imageWindow[3] - imageWindow[1];
var numPixels = imageWindowWidth * imageWindowHeight;
var i;
if (!samples) {
samples = [];
for (i=0; i < this.fileDirectory.SamplesPerPixel; ++i) {
samples.push(i);
}
}
else {
for (i = 0; i < samples.length; ++i) {
if (samples[i] >= this.fileDirectory.SamplesPerPixel) {
throw new RangeError("Invalid sample index '" + samples[i] + "'.");
}
}
}
var valueArrays = [];
for (i = 0; i < samples.length; ++i) {
valueArrays.push(this.getArrayForSample(samples[i], numPixels));
}
this._readRaster(imageWindow, samples, valueArrays);
return valueArrays;
},