@cogeotiff/core 9.2.0 → 9.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/build/__benchmark__/cog.read.benchmark.js +4 -2
  3. package/build/__benchmark__/source.file.d.ts +4 -0
  4. package/build/__benchmark__/source.file.d.ts.map +1 -1
  5. package/build/__benchmark__/source.file.js +2 -0
  6. package/build/__test__/cog.read.test.js +94 -1
  7. package/build/const/tiff.mime.d.ts +3 -0
  8. package/build/const/tiff.mime.d.ts.map +1 -1
  9. package/build/const/tiff.mime.js +23 -0
  10. package/build/const/tiff.tag.id.d.ts +35 -8
  11. package/build/const/tiff.tag.id.d.ts.map +1 -1
  12. package/build/const/tiff.tag.id.js +30 -2
  13. package/build/index.d.ts +3 -1
  14. package/build/index.d.ts.map +1 -1
  15. package/build/index.js +1 -1
  16. package/build/read/endian.d.ts +2 -0
  17. package/build/read/endian.d.ts.map +1 -0
  18. package/build/read/endian.js +5 -0
  19. package/build/read/tiff.tag.d.ts +1 -1
  20. package/build/read/tiff.tag.d.ts.map +1 -1
  21. package/build/read/tiff.tag.factory.d.ts +14 -1
  22. package/build/read/tiff.tag.factory.d.ts.map +1 -1
  23. package/build/read/tiff.tag.factory.js +60 -3
  24. package/build/tiff.d.ts +6 -2
  25. package/build/tiff.d.ts.map +1 -1
  26. package/build/tiff.image.d.ts +3 -0
  27. package/build/tiff.image.d.ts.map +1 -1
  28. package/build/tiff.image.js +23 -6
  29. package/build/tiff.js +4 -3
  30. package/package.json +2 -2
  31. package/src/__benchmark__/cog.read.benchmark.ts +4 -2
  32. package/src/__benchmark__/source.file.ts +2 -0
  33. package/src/__test__/cog.read.test.ts +127 -2
  34. package/src/const/tiff.mime.ts +23 -0
  35. package/src/const/tiff.tag.id.ts +35 -7
  36. package/src/index.ts +3 -0
  37. package/src/read/endian.ts +6 -0
  38. package/src/read/tiff.tag.factory.ts +73 -3
  39. package/src/read/tiff.tag.ts +1 -1
  40. package/src/tiff.image.ts +23 -6
  41. package/src/tiff.ts +12 -3
@@ -3,6 +3,7 @@ import { TiffTag, TiffTagConvertArray } from '../const/tiff.tag.id.js';
3
3
  import { TiffTagValueType } from '../const/tiff.tag.value.js';
4
4
  import { getUint, getUint64 } from '../util/bytes.js';
5
5
  import { hasBytes } from './data.view.offset.js';
6
+ import { isLittleEndian } from './endian.js';
6
7
  import { getTiffTagSize } from './tiff.value.reader.js';
7
8
  function readTagValue(fieldType, bytes, offset, isLittleEndian) {
8
9
  switch (fieldType) {
@@ -36,6 +37,31 @@ function readTagValue(fieldType, bytes, offset, isLittleEndian) {
36
37
  throw new Error(`Unknown read type "${fieldType}" "${TiffTagValueType[fieldType]}"`);
37
38
  }
38
39
  }
40
+ /**
41
+ * Convert a tiff tag value to a typed array if the local endian matches the tiff endian
42
+ *
43
+ * @param tiff
44
+ * @param bytes
45
+ * @param offset Offset in the data view to read from
46
+ * @param length Number of bytes to read
47
+ * @param type type of tiff tag
48
+ * @returns the value if the type is a typed array and the endianness matches otherwise null
49
+ */
50
+ export function readTypedValue(tiff, bytes, offset, length, type) {
51
+ switch (type) {
52
+ case TiffTagValueType.Uint8:
53
+ return new Uint8Array(bytes.buffer.slice(bytes.byteOffset + offset, bytes.byteOffset + offset + length));
54
+ case TiffTagValueType.Uint16:
55
+ if (tiff.isLittleEndian !== isLittleEndian)
56
+ return null;
57
+ return new Uint16Array(bytes.buffer.slice(bytes.byteOffset + offset, bytes.byteOffset + offset + length));
58
+ case TiffTagValueType.Uint32:
59
+ if (tiff.isLittleEndian !== isLittleEndian)
60
+ return null;
61
+ return new Uint32Array(bytes.buffer.slice(bytes.byteOffset + offset, bytes.byteOffset + offset + length));
62
+ }
63
+ return null;
64
+ }
39
65
  function readValue(tiff, tagId, bytes, offset, type, count) {
40
66
  const typeSize = getTiffTagSize(type);
41
67
  const dataLength = count * typeSize;
@@ -51,6 +77,15 @@ function readValue(tiff, tagId, bytes, offset, type, count) {
51
77
  case TiffTagValueType.Ascii:
52
78
  return String.fromCharCode.apply(null, new Uint8Array(bytes.buffer, offset, dataLength - 1));
53
79
  }
80
+ // TODO should we convert all tag values to typed arrays if possible?
81
+ if (tagId === TiffTag.TileOffsets ||
82
+ tagId === TiffTag.TileByteCounts ||
83
+ tagId === TiffTag.StripOffsets ||
84
+ tagId === TiffTag.StripByteCounts) {
85
+ const typedOutput = readTypedValue(tiff, bytes, offset, dataLength, type);
86
+ if (typedOutput)
87
+ return typedOutput;
88
+ }
54
89
  const output = [];
55
90
  for (let i = 0; i < dataLength; i += typeSize) {
56
91
  output.push(readTagValue(type, bytes, offset + i, tiff.isLittleEndian));
@@ -94,9 +129,16 @@ export function createTag(tiff, view, offset) {
94
129
  value: [],
95
130
  tagOffset: offset,
96
131
  };
97
- // Some offsets are quite long and don't need to read them often, so only read the tags we are interested in when we need to
98
- if (tagId === TiffTag.TileOffsets && hasBytes(view, dataOffset, dataLength))
99
- setBytes(tag, view);
132
+ if (hasBytes(view, dataOffset, dataLength)) {
133
+ const val = readTypedValue(tiff, view, dataOffset - view.sourceOffset, dataLength, dataType);
134
+ if (val) {
135
+ tag.value = val;
136
+ tag.isLoaded = true;
137
+ }
138
+ else {
139
+ setBytes(tag, view);
140
+ }
141
+ }
100
142
  return tag;
101
143
  }
102
144
  // If we already have the bytes in the view read them in
@@ -128,6 +170,7 @@ export async function fetchAllOffsets(tiff, tag) {
128
170
  tag.view.sourceOffset = tag.dataOffset;
129
171
  }
130
172
  tag.value = readValue(tiff, tag.id, tag.view, 0, tag.dataType, tag.count);
173
+ tag.view = undefined;
131
174
  tag.isLoaded = true;
132
175
  return tag.value;
133
176
  }
@@ -161,3 +204,17 @@ export async function getValueAt(tiff, tag, index) {
161
204
  tag.value[index] = value;
162
205
  return value;
163
206
  }
207
+ export function getValueAtSync(tiff, tag, index) {
208
+ if (index > tag.count || index < 0)
209
+ throw new Error('TagOffset: out of bounds :' + index);
210
+ if (tag.value[index] != null)
211
+ return tag.value[index];
212
+ if (tag.view == null)
213
+ return null;
214
+ const dataTypeSize = getTiffTagSize(tag.dataType);
215
+ const value = readValue(tiff, undefined, tag.view, index * dataTypeSize, tag.dataType, 1);
216
+ if (typeof value !== 'number')
217
+ throw new Error('Value is not a number');
218
+ tag.value[index] = value;
219
+ return value;
220
+ }
package/build/tiff.d.ts CHANGED
@@ -3,6 +3,10 @@ import { TiffGhostOptions } from './read/tiff.gdal.js';
3
3
  import type { TiffIfdConfig } from './read/tiff.ifd.config.js';
4
4
  import type { Source } from './source.js';
5
5
  import { TiffImage } from './tiff.image.js';
6
+ export interface TiffCreationOptions {
7
+ /** When initializing the tiff, read data in blocks of this size (in KB) */
8
+ defaultReadSize: number;
9
+ }
6
10
  export declare class Tiff {
7
11
  /** Read 16KB blocks at a time */
8
12
  static DefaultReadSize: number;
@@ -24,9 +28,9 @@ export declare class Tiff {
24
28
  isInitialized: boolean;
25
29
  private _initPromise?;
26
30
  /** A Tiff constructed from a source will not be pre-initialized with {@link init}. */
27
- constructor(source: Source);
31
+ constructor(source: Source, options?: TiffCreationOptions);
28
32
  /** Create a tiff and initialize it by reading the tiff headers */
29
- static create(source: Source): Promise<Tiff>;
33
+ static create(source: Source, options?: TiffCreationOptions): Promise<Tiff>;
30
34
  /**
31
35
  * Initialize the tiff loading in the header and all image headers.
32
36
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tiff.d.ts","sourceRoot":"","sources":["../src/tiff.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAItD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,qBAAa,IAAI;IACf,iCAAiC;IACjC,MAAM,CAAC,eAAe,SAAa;IACnC,iCAAiC;IACjC,eAAe,SAAwB;IACvC,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,OAAO,cAAoB;IAC3B,0CAA0C;IAC1C,MAAM,EAAE,SAAS,EAAE,CAAM;IACzB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,4CAA4C;IAC5C,SAAS,EAAE,aAAa,CAAiB;IACzC,8CAA8C;IAC9C,cAAc,UAAS;IACvB,6BAA6B;IAC7B,aAAa,UAAS;IAEtB,OAAO,CAAC,YAAY,CAAC,CAAgB;IAErC,sFAAsF;gBAC1E,MAAM,EAAE,MAAM;IAI1B,kEAAkE;IAClE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C;;;;;OAKG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB;;;;OAIG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;IAoBnD,qEAAqE;YACvD,UAAU;IAgExB;;;;;OAKG;IACH,OAAO,CAAC,OAAO;CAsBhB"}
1
+ {"version":3,"file":"tiff.d.ts","sourceRoot":"","sources":["../src/tiff.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAItD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,IAAI;IACf,iCAAiC;IACjC,MAAM,CAAC,eAAe,SAAa;IACnC,iCAAiC;IACjC,eAAe,SAAwB;IACvC,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,OAAO,cAAoB;IAC3B,0CAA0C;IAC1C,MAAM,EAAE,SAAS,EAAE,CAAM;IACzB,2BAA2B;IAC3B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,4CAA4C;IAC5C,SAAS,EAAE,aAAa,CAAiB;IACzC,8CAA8C;IAC9C,cAAc,UAAS;IACvB,6BAA6B;IAC7B,aAAa,UAAS;IAEtB,OAAO,CAAC,YAAY,CAAC,CAAgB;IAErC,sFAAsF;gBAC1E,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAA+D;IAKpG,kEAAkE;IAClE,MAAM,CAAC,MAAM,CACX,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,mBAA+D,GACvE,OAAO,CAAC,IAAI,CAAC;IAIhB;;;;;OAKG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB;;;;OAIG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;IAoBnD,qEAAqE;YACvD,UAAU;IAgExB;;;;;OAKG;IACH,OAAO,CAAC,OAAO;CAsBhB"}
@@ -235,6 +235,9 @@ export declare class TiffImage {
235
235
  hasTile(x: number, y: number): Promise<boolean>;
236
236
  /**
237
237
  * Load the offset and byteCount of a tile
238
+ *
239
+ * if the tiff is sparse, offset and byteCount will be zero if the tile is empty
240
+ *
238
241
  * @param index index in the tile array
239
242
  * @returns Offset and byteCount for the tile
240
243
  */
@@ -1 +1 @@
1
- {"version":3,"file":"tiff.image.d.ts","sourceRoot":"","sources":["../src/tiff.image.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tiff.image.d.ts","sourceRoot":"","sources":["../src/tiff.image.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { getCompressionMimeType, TiffCompressionMimeType, TiffMimeType } from './const/tiff.mime.js';
2
2
  import { Compression, ModelTypeCode, SubFileType, TiffTag, TiffTagGeo } from './const/tiff.tag.id.js';
3
- import { fetchAllOffsets, fetchLazy, getValueAt } from './read/tiff.tag.factory.js';
3
+ import { fetchAllOffsets, fetchLazy, getValueAt, getValueAtSync } from './read/tiff.tag.factory.js';
4
4
  import { getUint } from './util/bytes.js';
5
5
  /** Invalid EPSG code */
6
6
  export const InvalidProjectionCode = 32767;
@@ -494,15 +494,25 @@ export class TiffImage {
494
494
  }
495
495
  /**
496
496
  * Load the offset and byteCount of a tile
497
+ *
498
+ * if the tiff is sparse, offset and byteCount will be zero if the tile is empty
499
+ *
497
500
  * @param index index in the tile array
498
501
  * @returns Offset and byteCount for the tile
499
502
  */
500
503
  async getTileSize(index) {
504
+ // If both the tile offset and tile byte counts are loaded,
505
+ // we can get the offset and byte count synchronously without needing to fetch any additional data
506
+ const byteCounts = this.tags.get(TiffTag.TileByteCounts);
507
+ const tileOffset = getOffsetSync(this.tiff, this.tileOffset, index);
508
+ const tileSize = getOffsetSync(this.tiff, byteCounts, index);
509
+ if (tileOffset != null && tileSize != null)
510
+ return { offset: tileOffset, imageSize: tileSize };
501
511
  // GDAL optimizes tiles by storing the size of the tile in
502
512
  // the few bytes leading up to the tile
503
513
  const leaderBytes = this.tiff.options?.tileLeaderByteSize;
504
514
  if (leaderBytes) {
505
- const offset = await getOffset(this.tiff, this.tileOffset, index);
515
+ const offset = tileOffset ?? (await getOffset(this.tiff, this.tileOffset, index));
506
516
  // Sparse tiff no data found
507
517
  if (offset === 0)
508
518
  return { offset: 0, imageSize: 0 };
@@ -511,17 +521,22 @@ export class TiffImage {
511
521
  const bytes = await this.tiff.source.fetch(offset - leaderBytes, leaderBytes);
512
522
  return { offset, imageSize: getUint(new DataView(bytes), 0, leaderBytes, this.tiff.isLittleEndian) };
513
523
  }
514
- const byteCounts = this.tags.get(TiffTag.TileByteCounts);
515
524
  if (byteCounts == null)
516
525
  throw new Error('No tile byte counts found');
517
526
  const [offset, imageSize] = await Promise.all([
518
- getOffset(this.tiff, this.tileOffset, index),
519
- getOffset(this.tiff, byteCounts, index),
527
+ tileOffset ?? getOffset(this.tiff, this.tileOffset, index),
528
+ tileSize ?? getOffset(this.tiff, byteCounts, index),
520
529
  ]);
521
530
  return { offset, imageSize };
522
531
  }
523
532
  }
524
533
  function getOffset(tiff, x, index) {
534
+ const val = getOffsetSync(tiff, x, index);
535
+ if (val != null)
536
+ return Promise.resolve(val);
537
+ return getValueAt(tiff, x, index);
538
+ }
539
+ function getOffsetSync(tiff, x, index) {
525
540
  if (index < 0) {
526
541
  throw new Error(`Tiff: ${tiff.source.url.href} out of bounds ${TiffTag[x.id]} index:${index} total:${x.count}`);
527
542
  }
@@ -530,5 +545,7 @@ function getOffset(tiff, x, index) {
530
545
  return 0;
531
546
  if (x.type === 'inline')
532
547
  return x.value[index];
533
- return getValueAt(tiff, x, index);
548
+ if (x.isLoaded)
549
+ return x.value[index];
550
+ return getValueAtSync(tiff, x, index);
534
551
  }
package/build/tiff.js CHANGED
@@ -28,12 +28,13 @@ export class Tiff {
28
28
  isInitialized = false;
29
29
  _initPromise;
30
30
  /** A Tiff constructed from a source will not be pre-initialized with {@link init}. */
31
- constructor(source) {
31
+ constructor(source, options = { defaultReadSize: Tiff.DefaultReadSize }) {
32
32
  this.source = source;
33
+ this.defaultReadSize = options.defaultReadSize;
33
34
  }
34
35
  /** Create a tiff and initialize it by reading the tiff headers */
35
- static create(source) {
36
- return new Tiff(source).init();
36
+ static create(source, options = { defaultReadSize: Tiff.DefaultReadSize }) {
37
+ return new Tiff(source, options).init();
37
38
  }
38
39
  /**
39
40
  * Initialize the tiff loading in the header and all image headers.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cogeotiff/core",
3
- "version": "9.2.0",
3
+ "version": "9.4.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/blacha/cogeotiff.git",
@@ -23,5 +23,5 @@
23
23
  "publishConfig": {
24
24
  "access": "public"
25
25
  },
26
- "gitHead": "62a59096f2df47bd12cc969afdda1d90c31d679e"
26
+ "gitHead": "2cb33fbbd63f87fc2535282a4dd4426a449dd758"
27
27
  }
@@ -4,6 +4,7 @@ import { TiffTag } from '../index.js';
4
4
  import { Tiff } from '../tiff.js';
5
5
  import { SourceMemory } from './source.memory.js';
6
6
 
7
+ Tiff.DefaultReadSize = 64 * 1024;
7
8
  // console.log = console.trace;
8
9
  /** Read a tile from every image inside of a tiff 300 tiles read */
9
10
  async function main(): Promise<void> {
@@ -18,9 +19,10 @@ async function main(): Promise<void> {
18
19
  // 6 images
19
20
  for (const img of tiff.images) await img.getTile(0, 0);
20
21
 
22
+ const img = tiff.images[0];
21
23
  // Force loading all the byte arrays in which benchmarks the bulk array loading
22
- await tiff.images[0].fetch(TiffTag.TileByteCounts);
23
- await tiff.images[0].fetch(TiffTag.TileOffsets);
24
+ await img.fetch(TiffTag.TileByteCounts);
25
+ await img.fetch(TiffTag.TileOffsets);
24
26
  }
25
27
  }
26
28
 
@@ -9,6 +9,7 @@ const gunzipP = promisify(gunzip);
9
9
  export class TestFileSource implements Source {
10
10
  url: URL;
11
11
  data: Promise<Buffer>;
12
+ fetches: { offset: number; length: number }[] = [];
12
13
 
13
14
  constructor(fileName: URL) {
14
15
  this.url = fileName;
@@ -20,6 +21,7 @@ export class TestFileSource implements Source {
20
21
 
21
22
  async fetch(offset: number, length: number): Promise<ArrayBuffer> {
22
23
  const fileData = await this.data;
24
+ this.fetches.push({ offset, length });
23
25
  return fileData.buffer.slice(fileData.byteOffset + offset, fileData.byteOffset + offset + length) as ArrayBuffer;
24
26
  }
25
27
 
@@ -7,7 +7,7 @@ import { SourceMemory } from '../__benchmark__/source.memory.js';
7
7
  import { TiffMimeType } from '../const/tiff.mime.js';
8
8
  import { Photometric, SampleFormat } from '../const/tiff.tag.id.js';
9
9
  import { TiffVersion } from '../const/tiff.version.js';
10
- import { TiffTag, TiffTagGeo } from '../index.js';
10
+ import { TagOffset, TiffTag, TiffTagGeo } from '../index.js';
11
11
  import { Tiff } from '../tiff.js';
12
12
 
13
13
  function validate(tif: Tiff): void {
@@ -19,6 +19,12 @@ function validate(tif: Tiff): void {
19
19
  assert.deepEqual(firstTif.size, { width: 64, height: 64 });
20
20
  }
21
21
 
22
+ describe('TiffTag', () => {
23
+ it('should have the correct ModelTransformation tag id', () => {
24
+ assert.equal(TiffTag.ModelTransformation, 34264);
25
+ });
26
+ });
27
+
22
28
  describe('CogRead', () => {
23
29
  it('should read big endian', async () => {
24
30
  const source = new TestFileSource(new URL('../../data/big.endian.tiff', import.meta.url));
@@ -30,6 +36,8 @@ describe('CogRead', () => {
30
36
  assert.equal(tiff.version, TiffVersion.Tiff);
31
37
  assert.equal(tiff.images.length, 1);
32
38
  const firstImage = tiff.images[0];
39
+ const byteCounts = await firstImage.fetch(TiffTag.TileByteCounts);
40
+ assert.deepEqual([...(byteCounts ?? [])], [511]);
33
41
 
34
42
  assert.equal(firstImage.compression, 'application/zstd');
35
43
  assert.equal(firstImage.isTiled(), true);
@@ -48,6 +56,14 @@ describe('CogRead', () => {
48
56
  assert.equal(tiff.version, TiffVersion.BigTiff);
49
57
  assert.equal(tiff.images[0].epsg, null);
50
58
  validate(tiff);
59
+
60
+ const [byteCounts, tileOffsets] = await Promise.all([
61
+ tiff.images[0].fetch(TiffTag.TileByteCounts),
62
+ tiff.images[0].fetch(TiffTag.TileOffsets),
63
+ ]);
64
+
65
+ assert.deepEqual([...(byteCounts ?? [])], [196608]);
66
+ assert.deepEqual([...(tileOffsets ?? [])], [272]);
51
67
  });
52
68
 
53
69
  it('should fail reading a empty byte tiff', async () => {
@@ -87,6 +103,88 @@ describe('CogRead', () => {
87
103
  assert.equal(tiff.images.length, 5);
88
104
  });
89
105
 
106
+ it('should read the byte count array if it is loaded', async () => {
107
+ const source = new TestFileSource(new URL('../../data/rgba8_cog.tiff', import.meta.url));
108
+ const fetchSize = 16 * 1024;
109
+
110
+ const tiff = new Tiff(source);
111
+ tiff.defaultReadSize = fetchSize;
112
+ await tiff.init();
113
+
114
+ assert.equal(source.fetches.length, 1);
115
+ assert.equal(source.fetches[0].length, fetchSize);
116
+
117
+ const img = tiff.images[0];
118
+ const byteCounts = img.tags.get(TiffTag.TileByteCounts) as TagOffset;
119
+ const tileOffsets = img.tags.get(TiffTag.TileOffsets) as TagOffset;
120
+ assert.equal(source.fetches.length, 1);
121
+
122
+ assert.equal(byteCounts.type, 'offset');
123
+ assert.equal(byteCounts.isLoaded, true);
124
+
125
+ assert.equal(tileOffsets.type, 'offset');
126
+ assert.equal(tileOffsets.isLoaded, true);
127
+
128
+ const tile = await img.getTile(0, 0);
129
+ assert.equal(tile?.bytes.byteLength, byteCounts.value[0]);
130
+ assert.equal(source.fetches.length, 2);
131
+ assert.deepEqual(source.fetches[1], { offset: tileOffsets.value[0], length: byteCounts.value[0] });
132
+
133
+ // force the offset to be unloaded
134
+ byteCounts.isLoaded = false;
135
+ const oldValue = byteCounts.value;
136
+ byteCounts.value = [];
137
+ const tileB = await img.getTile(0, 0);
138
+ assert.equal(tileB?.bytes.byteLength, oldValue[0]);
139
+ assert.equal(source.fetches.length, 4);
140
+
141
+ // Read the tile offset then the tile
142
+ assert.deepEqual(source.fetches[2], { offset: tileOffsets.value[0] - 4, length: 4 });
143
+ assert.deepEqual(source.fetches[3], { offset: tileOffsets.value[0], length: oldValue[0] });
144
+ });
145
+
146
+ it('should read the byte count array if it is loaded (BigTiff)', async () => {
147
+ const source = new TestFileSource(new URL('../../data/rgba8_cog_big.tiff', import.meta.url));
148
+ const fetchSize = 16 * 1024;
149
+
150
+ const tiff = new Tiff(source);
151
+ tiff.defaultReadSize = fetchSize;
152
+ await tiff.init();
153
+
154
+ assert.equal(source.fetches.length, 1);
155
+ assert.equal(source.fetches[0].length, fetchSize);
156
+
157
+ const img = tiff.images[0];
158
+ const byteCounts = img.tags.get(TiffTag.TileByteCounts) as TagOffset;
159
+ const tileOffsets = img.tags.get(TiffTag.TileOffsets) as TagOffset;
160
+ assert.equal(source.fetches.length, 1);
161
+
162
+ assert.equal(byteCounts.type, 'offset');
163
+ assert.equal(byteCounts.isLoaded, true);
164
+ assert.equal(byteCounts.view == null, true);
165
+
166
+ assert.equal(tileOffsets.type, 'offset');
167
+ assert.equal(tileOffsets.isLoaded, false);
168
+ assert.equal(tileOffsets.view == null, false);
169
+
170
+ const tile = await img.getTile(0, 0);
171
+ assert.equal(tile?.bytes.byteLength, byteCounts.value[0]);
172
+ assert.equal(source.fetches.length, 2);
173
+ assert.deepEqual(source.fetches[1], { offset: tileOffsets.value[0], length: byteCounts.value[0] });
174
+
175
+ // force the offset to be unloaded
176
+ byteCounts.isLoaded = false;
177
+ const oldValue = byteCounts.value;
178
+ byteCounts.value = [];
179
+ byteCounts.view = undefined;
180
+ const tileB = await img.getTile(0, 0);
181
+ assert.equal(tileB?.bytes.byteLength, oldValue[0]);
182
+ assert.equal(source.fetches.length, 4);
183
+ // Read the tile offset then the tile
184
+ assert.deepEqual(source.fetches[2], { offset: tileOffsets.value[0] - 4, length: 4 });
185
+ assert.deepEqual(source.fetches[3], { offset: tileOffsets.value[0], length: oldValue[0] });
186
+ });
187
+
90
188
  it('should read ifds from anywhere in the file', async () => {
91
189
  const source = new TestFileSource(new URL('../../data/DEM_BS28_2016_1000_1141.tif', import.meta.url));
92
190
  const tiff = await Tiff.create(source);
@@ -109,7 +207,9 @@ describe('CogRead', () => {
109
207
 
110
208
  assert.equal(im.valueGeo(TiffTagGeo.GTCitationGeoKey), 'NZGD2000 / New Zealand Transverse Mercator 2000');
111
209
  assert.equal(im.valueGeo(TiffTagGeo.GeodeticCitationGeoKey), 'NZGD2000');
112
- assert.deepEqual(await im.fetch(TiffTag.StripByteCounts), [8064, 8064, 8064, 8064, 8064, 8064, 8064, 5040]);
210
+
211
+ const stripCount = await im.fetch(TiffTag.StripByteCounts);
212
+ assert.deepEqual([...(stripCount ?? [])], [8064, 8064, 8064, 8064, 8064, 8064, 8064, 5040]);
113
213
  });
114
214
 
115
215
  it('should read sub array ifds', async () => {
@@ -167,5 +267,30 @@ describe('CogRead', () => {
167
267
  const tiff = await Tiff.create(source);
168
268
  assert.equal(tiff.images.length, 5);
169
269
  assert.equal(tiff.images[0].epsg, 3857);
270
+
271
+ const [byteCounts, tileOffsets] = await Promise.all([
272
+ tiff.images[0].fetch(TiffTag.TileByteCounts),
273
+ tiff.images[0].fetch(TiffTag.TileOffsets),
274
+ ]);
275
+
276
+ assert.deepEqual([...(byteCounts ?? [])], [64, 64, 68, 64, 64, 68, 64, 64, 68, 64, 64, 64, 64, 64, 64, 68]);
277
+ assert.deepEqual(
278
+ [...(tileOffsets ?? [])],
279
+ [797, 861, 925, 993, 1057, 1121, 1189, 1253, 1317, 1385, 1449, 1513, 1577, 1641, 1705, 1769],
280
+ );
281
+ });
282
+
283
+ it('should load a file with a model transformation tag', async () => {
284
+ const cogSourceFile = new URL('../../data/model_transformation.tif', import.meta.url);
285
+
286
+ const buf = await readFile(cogSourceFile);
287
+ const source = new SourceMemory(buf);
288
+
289
+ const tiff = await Tiff.create(source);
290
+ assert.equal(tiff.images.length, 1);
291
+ assert.deepEqual(
292
+ tiff.images[0].tags.get(TiffTag.ModelTransformation)?.value,
293
+ [10, 0, 0, 418080, 0, 10, 0, 4423680, 0, 0, 0, 0, 0, 0, 0, 1],
294
+ );
170
295
  });
171
296
  });
@@ -5,6 +5,9 @@ import { Compression } from './tiff.tag.id.js';
5
5
  */
6
6
  export enum TiffMimeType {
7
7
  None = 'application/octet-stream',
8
+ Jbig = 'image/jbig',
9
+ Dcs = 'image/x-kodak-dcs',
10
+ PackBits = 'application/packbits',
8
11
  Jpeg = 'image/jpeg',
9
12
  Jp2000 = 'image/jp2',
10
13
  JpegXl = 'image/jpegxl',
@@ -29,6 +32,26 @@ export const TiffCompressionMimeType: Record<Compression, TiffMimeType> = {
29
32
  [Compression.Zstd]: TiffMimeType.Zstd,
30
33
  [Compression.Webp]: TiffMimeType.Webp,
31
34
  [Compression.JpegXl]: TiffMimeType.JpegXl,
35
+ [Compression.Ccittrle]: TiffMimeType.None,
36
+ [Compression.CcittT4]: TiffMimeType.None,
37
+ [Compression.CcittT6]: TiffMimeType.None,
38
+ [Compression.T85]: TiffMimeType.Jbig,
39
+ [Compression.T43]: TiffMimeType.Jbig,
40
+ [Compression.Next]: TiffMimeType.None,
41
+ [Compression.Ccittrlew]: TiffMimeType.None,
42
+ [Compression.PackBits]: TiffMimeType.PackBits,
43
+ [Compression.ThunderScan]: TiffMimeType.None,
44
+ [Compression.It8ctpad]: TiffMimeType.None,
45
+ [Compression.It8lw]: TiffMimeType.None,
46
+ [Compression.It8mp]: TiffMimeType.None,
47
+ [Compression.It8bl]: TiffMimeType.None,
48
+ [Compression.PixarFilm]: TiffMimeType.None,
49
+ [Compression.PixarLog]: TiffMimeType.None,
50
+ [Compression.Dcs]: TiffMimeType.Dcs,
51
+ [Compression.Jbig]: TiffMimeType.Jbig,
52
+ [Compression.SgiLog]: TiffMimeType.None,
53
+ [Compression.SgiLog24]: TiffMimeType.None,
54
+ [Compression.JpegXlDng17]: TiffMimeType.JpegXl,
32
55
  };
33
56
 
34
57
  /**
@@ -66,17 +66,37 @@ export enum OldSubFileType {
66
66
  /** Tiff compression types */
67
67
  export enum Compression {
68
68
  None = 1,
69
+ Ccittrle = 2,
70
+ CcittT4 = 3,
71
+ CcittT6 = 4,
69
72
  Lzw = 5,
70
73
  Jpeg6 = 6,
71
74
  Jpeg = 7,
72
75
  DeflateOther = 8,
76
+ T85 = 9,
77
+ T43 = 10,
78
+ Next = 32766,
79
+ Ccittrlew = 32771,
80
+ PackBits = 32773,
81
+ ThunderScan = 32809,
82
+ It8ctpad = 32895,
83
+ It8lw = 32896,
84
+ It8mp = 32897,
85
+ It8bl = 32898,
86
+ PixarFilm = 32908,
87
+ PixarLog = 32909,
73
88
  Deflate = 32946,
74
- Jp2000 = 3417,
89
+ Dcs = 32947,
90
+ Jbig = 34661,
91
+ SgiLog = 34676,
92
+ SgiLog24 = 34677,
93
+ Jp2000 = 34712,
75
94
  Lerc = 34887,
76
95
  Lzma = 34925,
77
96
  Zstd = 50000,
78
97
  Webp = 50001,
79
98
  JpegXl = 50002,
99
+ JpegXlDng17 = 52546,
80
100
  }
81
101
 
82
102
  export enum PlanarConfiguration {
@@ -86,6 +106,14 @@ export enum PlanarConfiguration {
86
106
  Separate = 2,
87
107
  }
88
108
 
109
+ export enum Predictor {
110
+ None = 1,
111
+ /** Horizontal differencing */
112
+ Horizontal = 2,
113
+ /** Floating point */
114
+ FloatingPoint = 3,
115
+ }
116
+
89
117
  export enum SampleFormat {
90
118
  /** Unsigned integer data */
91
119
  Uint = 1,
@@ -293,7 +321,7 @@ export enum TiffTag {
293
321
  * 0, 0, 0, 1]
294
322
  * ```
295
323
  */
296
- ModelTransformation = 34744,
324
+ ModelTransformation = 34264,
297
325
  /**
298
326
  * List of GeoTiff tags
299
327
  * {@link TiffTagGeo}
@@ -417,12 +445,12 @@ export interface TiffTagType {
417
445
 
418
446
  [TiffTag.TileWidth]: number;
419
447
  [TiffTag.TileHeight]: number;
420
- [TiffTag.TileOffsets]: number[];
421
- [TiffTag.TileByteCounts]: number[];
448
+ [TiffTag.TileOffsets]: number[] | Uint32Array | Uint16Array;
449
+ [TiffTag.TileByteCounts]: number[] | Uint32Array | Uint16Array;
422
450
  [TiffTag.JpegTables]: number[];
423
451
 
424
- [TiffTag.StripByteCounts]: number[];
425
- [TiffTag.StripOffsets]: number[];
452
+ [TiffTag.StripByteCounts]: number[] | Uint32Array | Uint16Array;
453
+ [TiffTag.StripOffsets]: number[] | Uint32Array | Uint16Array;
426
454
 
427
455
  [TiffTag.SamplesPerPixel]: number;
428
456
  [TiffTag.SampleFormat]: SampleFormat[];
@@ -437,6 +465,7 @@ export interface TiffTagType {
437
465
 
438
466
  [TiffTag.PlanarConfiguration]: PlanarConfiguration;
439
467
  [TiffTag.Orientation]: Orientation;
468
+ [TiffTag.Predictor]: Predictor;
440
469
 
441
470
  [TiffTag.LercParameters]: number[];
442
471
 
@@ -478,7 +507,6 @@ export interface TiffTagType {
478
507
  [TiffTag.Indexed]: unknown;
479
508
  [TiffTag.PageName]: unknown;
480
509
  [TiffTag.PageNumber]: unknown;
481
- [TiffTag.Predictor]: unknown;
482
510
  [TiffTag.PrimaryChromaticities]: unknown;
483
511
  [TiffTag.ReferenceBlackWhite]: unknown;
484
512
  [TiffTag.SMinSampleValue]: unknown;
package/src/index.ts CHANGED
@@ -11,6 +11,7 @@ export {
11
11
  Orientation,
12
12
  Photometric,
13
13
  PlanarConfiguration,
14
+ Predictor,
14
15
  RasterTypeKey,
15
16
  SampleFormat,
16
17
  SubFileType,
@@ -22,7 +23,9 @@ export { TiffVersion } from './const/tiff.version.js';
22
23
  export type { Tag, TagInline, TagLazy, TagOffset } from './read/tiff.tag.js';
23
24
  export { getTiffTagSize } from './read/tiff.value.reader.js';
24
25
  export type { Source } from './source.js';
26
+ export type { TiffImageTileCount } from './tiff.image.js';
25
27
  export { TiffImage } from './tiff.image.js';
28
+ export type { TiffCreationOptions } from './tiff.js';
26
29
  export { Tiff } from './tiff.js';
27
30
  export { toHex } from './util/util.hex.js';
28
31
  export type { BoundingBox, Point, Size, Vector } from './vector.js';
@@ -0,0 +1,6 @@
1
+ const buffer = new ArrayBuffer(4);
2
+ const uint32 = new Uint32Array(buffer);
3
+ const uint8 = new Uint8Array(buffer);
4
+ uint32[0] = 1;
5
+
6
+ export const isLittleEndian = uint8[0] === 1;