From 6e6584234a9e2403717f84e47645a932fa8a7667 Mon Sep 17 00:00:00 2001 From: Rdataflow Date: Wed, 8 Jan 2025 17:53:11 +0100 Subject: [PATCH 1/2] feat: add zstd compression Closes: https://github.com/geotiffjs/geotiff.js/issues/372 --- src/compression/index.js | 7 +++++++ src/compression/zstd.js | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/compression/zstd.js diff --git a/src/compression/index.js b/src/compression/index.js index 81c53b01..7a1b51e7 100644 --- a/src/compression/index.js +++ b/src/compression/index.js @@ -32,4 +32,11 @@ addDecoder(34887, () => import('./lerc.js') }) .then((m) => m.default), ); +addDecoder(50000, () => import('./zstd.js') + .then(async (m) => { + await m.zstd.init(); + return m; + }) + .then((m) => m.default), +); addDecoder(50001, () => import('./webimage.js').then((m) => m.default)); diff --git a/src/compression/zstd.js b/src/compression/zstd.js new file mode 100644 index 00000000..4199a2bd --- /dev/null +++ b/src/compression/zstd.js @@ -0,0 +1,10 @@ +import { ZSTDDecoder } from 'zstddec'; +import BaseDecoder from './basedecoder.js'; + +export const zstd = new ZSTDDecoder(); + +export default class ZstdDecoder extends BaseDecoder { + decodeBlock(buffer) { + return zstd.decode(new Uint8Array(buffer), 1000_000_000).buffer; + } +} From d49770850b8d3abb90934649cbab7898268f60b5 Mon Sep 17 00:00:00 2001 From: Rdataflow Date: Wed, 8 Jan 2025 17:59:42 +0100 Subject: [PATCH 2/2] ci: add tests for zstd --- test/data/setup_data.sh | 2 ++ test/geotiff.spec.js | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/test/data/setup_data.sh b/test/data/setup_data.sh index 29fdc2d4..55f77994 100755 --- a/test/data/setup_data.sh +++ b/test/data/setup_data.sh @@ -26,10 +26,12 @@ gdal_translate -of GTiff -co COMPRESS=LERC -co MAX_Z_ERROR=1000 stripped.tiff le gdal_translate -of GTiff -co COMPRESS=LERC -co MAX_Z_ERROR=1000 -co INTERLEAVE=BAND stripped.tiff lerc_interleave.tiff gdal_translate -of GTiff -co COMPRESS=LERC_DEFLATE -co MAX_Z_ERROR=1000 stripped.tiff lerc_deflate.tiff gdal_translate -of GTiff -co COMPRESS=LERC_ZSTD -co MAX_Z_ERROR=1000 stripped.tiff lerc_zstd.tiff +gdal_translate -of GTiff -co COMPRESS=ZSTD stripped.tiff zstd.tiff gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC -co MAX_Z_ERROR=1000 stripped.tiff float32lerc.tiff gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC -co MAX_Z_ERROR=1000 -co INTERLEAVE=BAND stripped.tiff float32lerc_interleave.tiff gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC_DEFLATE -co MAX_Z_ERROR=1000 stripped.tiff float32lerc_deflate.tiff gdal_translate -of GTiff -ot Float32 -co COMPRESS=LERC_ZSTD -co MAX_Z_ERROR=1000 stripped.tiff float32lerc_zstd.tiff +gdal_translate -of GTiff -ot Float32 -co COMPRESS=ZSTD stripped.tiff float32zstd.tiff gdal_translate -of COG initial.tiff cog.tiff diff --git a/test/geotiff.spec.js b/test/geotiff.spec.js index ad6e2829..9b529f0b 100644 --- a/test/geotiff.spec.js +++ b/test/geotiff.spec.js @@ -248,6 +248,11 @@ describe('GeoTIFF', () => { await performTiffTests(tiff, 539, 448, 15, Uint16Array); }); + it('should work on Zstandard compressed tiffs', async () => { + const tiff = await GeoTIFF.fromSource(createSource('zstd.tiff')); + await performTiffTests(tiff, 539, 448, 15, Uint16Array); + }); + it('should work on Float32 and LERC compressed tiffs', async () => { const tiff = await GeoTIFF.fromSource(createSource('float32lerc.tiff')); await performTiffTests(tiff, 539, 448, 15, Float32Array); @@ -268,6 +273,11 @@ describe('GeoTIFF', () => { await performTiffTests(tiff, 539, 448, 15, Float32Array); }); + it('should work on Float32 and Zstandard compressed tiffs', async () => { + const tiff = await GeoTIFF.fromSource(createSource('float32zstd.tiff')); + await performTiffTests(tiff, 539, 448, 15, Float32Array); + }); + it('should work with worker pool', async () => { const testPool = new Pool(); const tiff = await GeoTIFF.fromSource(createSource('nasa_raster.tiff'));