Skip to content

Commit

Permalink
feat: add support for Zlib/deflate compression
Browse files Browse the repository at this point in the history
  • Loading branch information
targos committed Dec 3, 2020
1 parent b1179c8 commit 7d3a04c
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 8 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,15 @@ npm i tiff

## Compatibility

### Platform

This package is written using ES2015 features. It is natively compatible with
recent web browsers and Node.js. You can transpile it with a tool like
[babel](https://babeljs.io/) if you need to support more JavaScript engines.

### [TIFF standard](./TIFF6.pdf)

The library can currently decode greyscale and RGB images (8, 16 or 32 bits).
It supports LZW compression and images with an additional alpha channel.

### Extensions

Images compressed with Zlib/deflate algorithm are also supported.

## API

### tiff.decode(data[, options])
Expand Down
Binary file added img/color-5x5-deflate.tif
Binary file not shown.
Binary file added img/tile_rgb_deflate.tif
Binary file not shown.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@
"testEnvironment": "node"
},
"dependencies": {
"iobuffer": "^5.0.2"
"iobuffer": "^5.0.2",
"pako": "^2.0.2"
},
"devDependencies": {
"@types/jest": "^26.0.16",
"@types/node": "^14.14.10",
"@types/pako": "^1.0.1",
"eslint": "^7.14.0",
"eslint-config-cheminfo-typescript": "^8.0.5",
"jest": "^26.6.3",
Expand Down
20 changes: 20 additions & 0 deletions src/__tests__/decode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ const files: TiffFile[] = [
bitsPerSample: 8,
components: 3,
},
{
name: 'color-5x5-deflate.tif',
width: 5,
height: 5,
bitsPerSample: 8,
components: 3,
},
{
name: 'color-alpha-2x2.tif',
width: 2,
Expand Down Expand Up @@ -229,3 +236,16 @@ test('should decode palette', () => {
// @ts-ignore
expect(palette[0]).toStrictEqual([65535, 0, 0]);
});

test('should decode image compressed with deflate algorithm', () => {
const decoded = decode(readImage('tile_rgb_deflate.tif'));
expect(decoded).toHaveLength(1);
expect(decoded[0]).toMatchObject({
alpha: false,
bitsPerSample: 16,
components: 3,
compression: 8,
width: 128,
height: 128,
});
});
8 changes: 7 additions & 1 deletion src/tiffDecoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { getByteLength, readData } from './ifdValue';
import { decompressLzw } from './lzw';
import TiffIfd from './tiffIfd';
import { BufferType, IDecodeOptions, IFDKind, DataArray } from './types';
import { decompressZlib } from './zlib';

const defaultOptions: IDecodeOptions = {
ignoreImageData: false,
Expand Down Expand Up @@ -228,12 +229,17 @@ export default class TIFFDecoder extends IOBuffer {
dataToFill = decompressLzw(stripData);
break;
}
case 8: {
// Zlib compression
dataToFill = decompressZlib(stripData);
break;
}
case 2: // CCITT Group 3 1-Dimensional Modified Huffman run length encoding
throw unsupported('Compression', 'CCITT Group 3');
case 32773: // PackBits compression
throw unsupported('Compression', 'PackBits');
default:
throw new Error(`invalid compression: ${ifd.compression}`);
throw unsupported('Compression', ifd.compression);
}

pixel = this.fillUncompressed(
Expand Down
15 changes: 15 additions & 0 deletions src/zlib.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { inflate } from 'pako';

export function decompressZlib(stripData: DataView): DataView {
const stripUint8 = new Uint8Array(
stripData.buffer,
stripData.byteOffset,
stripData.byteLength,
);
const inflated = inflate(stripUint8);
return new DataView(
inflated.buffer,
inflated.byteOffset,
inflated.byteLength,
);
}

0 comments on commit 7d3a04c

Please sign in to comment.