From f59a1bf609592ebe78597ae67a826db20aa2dc6e Mon Sep 17 00:00:00 2001 From: Blayne Chard <bchard@linz.govt.nz> Date: Wed, 29 Jan 2025 16:16:35 +1300 Subject: [PATCH] refactor: default to libvips for lzw decoding --- .../pipeline/__tests__/decompress.lzw.test.ts | 17 +++++++---------- .../src/pipeline/decompressor.lzw.ts | 12 +----------- .../tiler-sharp/src/pipeline/decompressors.ts | 4 ++-- packages/tiler-sharp/src/pipeline/lzw/lzw.ts | 1 - 4 files changed, 10 insertions(+), 24 deletions(-) diff --git a/packages/tiler-sharp/src/pipeline/__tests__/decompress.lzw.test.ts b/packages/tiler-sharp/src/pipeline/__tests__/decompress.lzw.test.ts index b27b03261..90d889cc1 100644 --- a/packages/tiler-sharp/src/pipeline/__tests__/decompress.lzw.test.ts +++ b/packages/tiler-sharp/src/pipeline/__tests__/decompress.lzw.test.ts @@ -1,20 +1,17 @@ import assert from 'node:assert'; import { createHash } from 'node:crypto'; -import { writeFileSync } from 'node:fs'; import { before, describe, it } from 'node:test'; import { fsa, LogConfig } from '@basemaps/shared'; -// import { TestTiff } from '@basemaps/test'; +import { TestTiff } from '@basemaps/test'; import { Tiff } from '@cogeotiff/core'; -import { LzwDecompressor, LzwDecompressorSharp } from '../decompressor.lzw.js'; +import { LzwDecompressorJs, LzwDecompressorSharp } from '../decompressor.lzw.js'; describe('decompressor.lzw', () => { let tiff: Tiff; before(async () => { - tiff = await Tiff.create( - fsa.source(fsa.toUrl('file:///home/blacha/data/elevation/nz-8m-dem-2012/8m-dem-small/qd.lzw.tiff')), - ); + tiff = await Tiff.create(fsa.source(TestTiff.CompressLzw)); }); it('should decode a 64x64 lzw tile', async () => { @@ -22,6 +19,7 @@ describe('decompressor.lzw', () => { const hashes: Record<string, { hash: string; duration: number }> = {}; const hashesSharp: Record<string, { hash: string; duration: number }> = {}; + let tileCount = 0; for (const img of tiff.images) { const imageId = img.id; for (let x = 0; x < img.tileCount.x; x++) { @@ -46,7 +44,7 @@ describe('decompressor.lzw', () => { }; const startTimeB = performance.now(); - const retB = await LzwDecompressor.decompress({ + const retB = await LzwDecompressorJs.decompress({ tiff, imageId, x, @@ -61,11 +59,10 @@ describe('decompressor.lzw', () => { }; assert.equal(hashLzw, hashSharp, tileId); + tileCount++; } } + assert.equal(tileCount, 1); } - // writeFileSync('./hashes.json', JSON.stringify(hashes, null, 2)); - - // writeFileSync('./hashesSharp.json', JSON.stringify(hashesSharp, null, 2)); }); }); diff --git a/packages/tiler-sharp/src/pipeline/decompressor.lzw.ts b/packages/tiler-sharp/src/pipeline/decompressor.lzw.ts index a0dae6f02..1062e968d 100644 --- a/packages/tiler-sharp/src/pipeline/decompressor.lzw.ts +++ b/packages/tiler-sharp/src/pipeline/decompressor.lzw.ts @@ -51,25 +51,19 @@ async function toDecompressedInterleaved( throw new Error('Output has missmatched tile size'); } -export const LzwDecompressor: Decompressor = { +export const LzwDecompressorJs: Decompressor = { type: 'application/lzw', async decompress(ctx: DecompressionContext): Promise<DecompressedInterleaved> { // TODO: this decompressor is very slow it can take over 100ms+ to deocode a 512x512 tile // for comparison the lerc decompressor takes <1ms for the same amount of data. - console.time('decompress-js'); const bytes = decompress(ctx.bytes); - console.timeEnd('decompress-js'); - - // console.log(ctx.tiff.source.url.href); return toDecompressedInterleaved(bytes, ctx); }, }; export const LzwDecompressorSharp: Decompressor = { type: 'application/lzw', async decompress(ctx: DecompressionContext): Promise<DecompressedInterleaved> { - // TODO: this decompressor is very slow it can take over 100ms+ to deocode a 512x512 tile - // for comparison the lerc decompressor takes <1ms for the same amount of data. const image = ctx.tiff.images[ctx.imageId]; const [bitsPerSample, sampleFormat] = await Promise.all([ image.fetch(TiffTag.BitsPerSample), @@ -80,11 +74,7 @@ export const LzwDecompressorSharp: Decompressor = { const depth = tiffToDepth(bitsPerSample, sampleFormat?.[0]); - console.time('decompress-sharp'); const bytes = await decodeLzwTiff(image, depth, bitsPerSample.length, ctx.bytes); - console.timeEnd('decompress-sharp'); - - // console.log(ctx.tiff.source.url.href); return toDecompressedInterleaved(bytes.decoded, ctx); }, }; diff --git a/packages/tiler-sharp/src/pipeline/decompressors.ts b/packages/tiler-sharp/src/pipeline/decompressors.ts index 9c3cacb07..64d5ee33f 100644 --- a/packages/tiler-sharp/src/pipeline/decompressors.ts +++ b/packages/tiler-sharp/src/pipeline/decompressors.ts @@ -2,9 +2,9 @@ import { Compression } from '@cogeotiff/core'; import { Decompressor } from './decompressor.js'; import { LercDecompressor } from './decompressor.lerc.js'; -import { LzwDecompressor } from './decompressor.lzw.js'; +import { LzwDecompressorSharp } from './decompressor.lzw.js'; export const Decompressors: Record<string, Decompressor> = { [Compression.Lerc]: LercDecompressor, - [Compression.Lzw]: LzwDecompressor, + [Compression.Lzw]: LzwDecompressorSharp, }; diff --git a/packages/tiler-sharp/src/pipeline/lzw/lzw.ts b/packages/tiler-sharp/src/pipeline/lzw/lzw.ts index f0b667d58..0e521e25d 100644 --- a/packages/tiler-sharp/src/pipeline/lzw/lzw.ts +++ b/packages/tiler-sharp/src/pipeline/lzw/lzw.ts @@ -111,7 +111,6 @@ export function decompress(input: ArrayBuffer): Uint8Array { appendReversed(result, oldVal); result.push(oldVal[oldVal.length - 1]); addToDictionary(oldCode as number, oldVal[oldVal.length - 1]); - // console.log(oldCode, oldVal[oldVal.length - 1]); oldCode = code; }