Skip to content

Commit 8618f8a

Browse files
Merge pull request #305 from otfried/master
2 parents f0718e0 + 85ad082 commit 8618f8a

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

src/geotiffimage.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,16 @@ class GeoTIFFImage {
382382
offset = this.fileDirectory.StripOffsets[index];
383383
byteCount = this.fileDirectory.StripByteCounts[index];
384384
}
385+
386+
if (byteCount === 0) {
387+
const nPixels = this.getBlockHeight(y) * this.getTileWidth();
388+
const bytesPerPixel = (this.planarConfiguration === 2) ? this.getSampleByteSize(sample) : this.getBytesPerPixel();
389+
const data = new ArrayBuffer(nPixels * bytesPerPixel);
390+
const view = this.getArrayForSample(sample, data);
391+
view.fill(this.getGDALNoData() || 0);
392+
return { x, y, sample, data };
393+
}
394+
385395
const slice = (await this.source.fetch([{ offset, length: byteCount }], signal))[0];
386396

387397
let request;

test/data/setup_data.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ convert rgb.tiff -colorspace Lab cielab.tif
5555
gdal_translate -of GTiff -co COMPRESS=JPEG rgb.tiff jpeg.tiff
5656
gdal_translate -of GTiff -co COMPRESS=JPEG -co PHOTOMETRIC=YCBCR rgb.tiff jpeg_ycbcr.tiff
5757

58+
# with empty tiles/strips
59+
gdal_translate -of GTiff -co COMPRESS=DEFLATE -co SPARSE_OK=TRUE -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 rgb.tiff empty_tiles.tiff
60+
gdal_translate -of GTiff -a_nodata 0 -co COMPRESS=DEFLATE -co SPARSE_OK=TRUE -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 rgb.tiff empty_tiles_nodata.tiff
61+
gdal_translate -of GTiff -ot UInt16 -co COMPRESS=DEFLATE -co SPARSE_OK=TRUE -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 rgb.tiff empty_tiles_16.tiff
62+
gdalbuildvrt -srcnodata 0 -vrtnodata 256 empty_tiles_16_nodata256.vrt empty_tiles_16.tiff
63+
gdal_translate -of GTiff -a_nodata 256 -ot UInt16 -co COMPRESS=DEFLATE -co SPARSE_OK=TRUE -co TILED=YES -co BLOCKXSIZE=32 -co BLOCKYSIZE=32 empty_tiles_16_nodata256.vrt empty_tiles_16_nodata256.tiff
64+
rm empty_tiles_16_nodata256.vrt
65+
5866
# modeltransformation tag
5967
#wget https://s3.amazonaws.com/wdt-external/no_pixelscale_or_tiepoints.tiff
6068

test/geotiff.spec.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,78 @@ describe('ifdRequestTests', () => {
446446
});
447447
});
448448

449+
describe('Empty tile tests', () => {
450+
it('should be able to read tiffs with empty tiles', async () => {
451+
const tiff = await GeoTIFF.fromSource(createSource('empty_tiles.tiff'));
452+
const image = await tiff.getImage();
453+
expect(image).to.be.ok;
454+
expect(image.getWidth()).to.equal(541);
455+
expect(image.getHeight()).to.equal(449);
456+
expect(image.getSamplesPerPixel()).to.equal(3);
457+
});
458+
459+
it('should be able to read tiffs with empty uint16 tiles', async () => {
460+
const tiff = await GeoTIFF.fromSource(createSource('empty_tiles_16.tiff'));
461+
const image = await tiff.getImage();
462+
expect(image).to.be.ok;
463+
expect(image.getWidth()).to.equal(541);
464+
expect(image.getHeight()).to.equal(449);
465+
expect(image.getSamplesPerPixel()).to.equal(3);
466+
});
467+
468+
const options = { width: 541, height: 449, interleave: true, samples: [0, 1, 2] };
469+
const readImage = async (fname) => {
470+
const tiff = await GeoTIFF.fromSource(createSource(fname));
471+
const image = await tiff.getImage();
472+
return image.readRasters(options);
473+
};
474+
475+
it('should interpret empty tiles', async () => {
476+
const comp = await readImage('rgb.tiff');
477+
const rgb = await readImage('empty_tiles.tiff');
478+
expect(rgb).to.have.lengthOf(comp.length);
479+
let maxDiff = 0;
480+
for (let i = 0; i < rgb.length; ++i) {
481+
maxDiff = Math.max(maxDiff, Math.abs(comp[i] - rgb[i]));
482+
}
483+
expect(maxDiff).to.equal(0);
484+
});
485+
486+
it('should interpret empty tiles with nodata', async () => {
487+
const comp = await readImage('rgb.tiff');
488+
const rgb = await readImage('empty_tiles_nodata.tiff');
489+
expect(rgb).to.have.lengthOf(comp.length);
490+
let maxDiff = 0;
491+
for (let i = 0; i < rgb.length; ++i) {
492+
maxDiff = Math.max(maxDiff, Math.abs(comp[i] - rgb[i]));
493+
}
494+
expect(maxDiff).to.equal(0);
495+
});
496+
497+
it('should interpret empty uint16 tiles', async () => {
498+
const comp = await readImage('rgb.tiff');
499+
const rgb = await readImage('empty_tiles_16.tiff');
500+
expect(rgb).to.have.lengthOf(comp.length);
501+
let maxDiff = 0;
502+
for (let i = 0; i < rgb.length; ++i) {
503+
maxDiff = Math.max(maxDiff, Math.abs(comp[i] - rgb[i]));
504+
}
505+
expect(maxDiff).to.equal(0);
506+
});
507+
508+
it('should interpret empty uint16 tiles and nodata==256', async () => {
509+
const comp = await readImage('rgb.tiff');
510+
const rgb = await readImage('empty_tiles_16_nodata256.tiff');
511+
expect(rgb).to.have.lengthOf(comp.length);
512+
let maxDiff = 0;
513+
for (let i = 0; i < rgb.length; ++i) {
514+
const compSample = comp[i] === 0 ? 256 : comp[i];
515+
maxDiff = Math.max(maxDiff, Math.abs(compSample - rgb[i]));
516+
}
517+
expect(maxDiff).to.equal(0);
518+
});
519+
});
520+
449521
describe('RGB-tests', () => {
450522
const options = { window: [250, 250, 300, 300], interleave: true };
451523
const comparisonRaster = (async () => {

0 commit comments

Comments
 (0)