@cogeotiff/core 8.0.1 → 8.1.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 (42) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/build/__benchmark__/cog.read.benchmark.js +4 -0
  3. package/build/__benchmark__/cog.read.benchmark.js.map +1 -1
  4. package/build/__test__/cog.read.test.js +15 -1
  5. package/build/__test__/cog.read.test.js.map +1 -1
  6. package/build/cog.tiff.image.d.ts +44 -16
  7. package/build/cog.tiff.image.js +98 -70
  8. package/build/cog.tiff.image.js.map +1 -1
  9. package/build/cog.tiff.js +11 -1
  10. package/build/cog.tiff.js.map +1 -1
  11. package/build/const/index.d.ts +1 -1
  12. package/build/const/index.js +1 -1
  13. package/build/const/index.js.map +1 -1
  14. package/build/const/tiff.endian.d.ts +2 -1
  15. package/build/const/tiff.endian.js +2 -1
  16. package/build/const/tiff.endian.js.map +1 -1
  17. package/build/const/tiff.tag.id.d.ts +2 -2
  18. package/build/const/tiff.tag.id.js +154 -154
  19. package/build/const/tiff.tag.id.js.map +1 -1
  20. package/build/index.d.ts +3 -3
  21. package/build/index.js +1 -1
  22. package/build/index.js.map +1 -1
  23. package/build/read/tiff.gdal.d.ts +4 -4
  24. package/build/read/tiff.gdal.js +4 -4
  25. package/build/read/tiff.tag.d.ts +8 -5
  26. package/build/read/tiff.tag.factory.d.ts +7 -1
  27. package/build/read/tiff.tag.factory.js +27 -8
  28. package/build/read/tiff.tag.factory.js.map +1 -1
  29. package/build/source.d.ts +12 -0
  30. package/package.json +2 -2
  31. package/src/__benchmark__/cog.read.benchmark.ts +5 -0
  32. package/src/__test__/cog.read.test.ts +18 -1
  33. package/src/cog.tiff.image.ts +106 -80
  34. package/src/cog.tiff.ts +17 -4
  35. package/src/const/index.ts +1 -1
  36. package/src/const/tiff.endian.ts +2 -1
  37. package/src/const/tiff.tag.id.ts +2 -2
  38. package/src/index.ts +3 -3
  39. package/src/read/tiff.gdal.ts +4 -4
  40. package/src/read/tiff.tag.factory.ts +32 -11
  41. package/src/read/tiff.tag.ts +8 -5
  42. package/src/source.ts +15 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [8.1.0](https://github.com/blacha/cogeotiff/compare/core-v8.0.2...core-v8.1.0) (2023-08-23)
4
+
5
+
6
+ ### Features
7
+
8
+ * **cli:** fetch all tiff tags with --fetch-tags ([#1155](https://github.com/blacha/cogeotiff/issues/1155)) ([4067751](https://github.com/blacha/cogeotiff/commit/406775184eed18ab10ae2816ecbedea9706b20f5))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **core:** do not read past the end of a file ([#1152](https://github.com/blacha/cogeotiff/issues/1152)) ([fd0be56](https://github.com/blacha/cogeotiff/commit/fd0be56eee6944239502cd8ffd7a6fe89e76b984))
14
+
15
+ ## [8.0.2](https://github.com/blacha/cogeotiff/compare/core-v8.0.1...core-v8.0.2) (2023-08-05)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **core:** expose TiffTag and TiffTagGeo ([d538bdc](https://github.com/blacha/cogeotiff/commit/d538bdc833bf76ba8d730a1062156916715585b4))
21
+
3
22
  ## [8.0.1](https://github.com/blacha/cogeotiff/compare/core-v8.0.0...core-v8.0.1) (2023-08-05)
4
23
 
5
24
 
@@ -1,6 +1,7 @@
1
1
  import { readFile } from 'fs/promises';
2
2
  import { CogTiff } from '../cog.tiff.js';
3
3
  import { SourceMemory } from './source.memory.js';
4
+ import { TiffTag } from '../index.js';
4
5
  // console.log = console.trace;
5
6
  /** Read a tile from every image inside of a tiff 300 tiles read */
6
7
  async function main() {
@@ -14,6 +15,9 @@ async function main() {
14
15
  // 6 images
15
16
  for (const img of tiff.images)
16
17
  await img.getTile(0, 0);
18
+ // Force loading all the byte arrays in which benchmarks the bulk array loading
19
+ await tiff.images[0].fetch(TiffTag.TileByteCounts);
20
+ await tiff.images[0].fetch(TiffTag.TileOffsets);
17
21
  }
18
22
  }
19
23
  main();
@@ -1 +1 @@
1
- {"version":3,"file":"cog.read.benchmark.js","sourceRoot":"","sources":["../../src/__benchmark__/cog.read.benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,+BAA+B;AAC/B,mEAAmE;AACnE,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAElC,WAAW;QACX,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;KACxD;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"cog.read.benchmark.js","sourceRoot":"","sources":["../../src/__benchmark__/cog.read.benchmark.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,+BAA+B;AAC/B,mEAAmE;AACnE,KAAK,UAAU,IAAI;IACjB,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAK,EAAE,CAAC,EAAE,EAAE;QAC9B,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAElC,WAAW;QACX,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEvD,+EAA+E;QAC/E,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACnD,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;KACjD;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -1,9 +1,10 @@
1
1
  import assert from 'node:assert';
2
2
  import { describe, it } from 'node:test';
3
+ import { TestFileSource } from '../__benchmark__/source.file.js';
3
4
  import { CogTiff } from '../cog.tiff.js';
4
5
  import { TiffMimeType } from '../const/tiff.mime.js';
5
- import { TestFileSource } from '../__benchmark__/source.file.js';
6
6
  import { TiffVersion } from '../const/tiff.version.js';
7
+ import { TiffTag, TiffTagGeo } from '../index.js';
7
8
  function validate(tif) {
8
9
  assert.equal(tif.images.length, 5);
9
10
  const [firstTif] = tif.images;
@@ -50,5 +51,18 @@ describe('CogRead', () => {
50
51
  await tiff.init();
51
52
  assert.equal(tiff.images.length, 5);
52
53
  });
54
+ it('should read ifds from anywhere in the file', async () => {
55
+ const source = new TestFileSource(new URL('../../data/DEM_BS28_2016_1000_1141.tif', import.meta.url));
56
+ const tiff = await CogTiff.create(source);
57
+ assert.equal(tiff.images.length, 1);
58
+ const im = tiff.images[0];
59
+ assert.equal(im.isGeoTagsLoaded, true);
60
+ assert.equal(im.epsg, 2193);
61
+ assert.equal(im.compression, TiffMimeType.None);
62
+ assert.equal(im.isTiled(), false);
63
+ assert.equal(im.tagsGeo.get(TiffTagGeo.GTCitationGeoKey), 'NZGD2000 / New Zealand Transverse Mercator 2000');
64
+ assert.equal(im.tagsGeo.get(TiffTagGeo.GeogCitationGeoKey), 'NZGD2000');
65
+ assert.deepEqual(await im.fetch(TiffTag.StripByteCounts), [8064, 8064, 8064, 8064, 8064, 8064, 8064, 5040]);
66
+ });
53
67
  });
54
68
  //# sourceMappingURL=cog.read.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cog.read.test.js","sourceRoot":"","sources":["../../src/__test__/cog.read.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cog.read.test.js","sourceRoot":"","sources":["../../src/__test__/cog.read.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAElD,SAAS,QAAQ,CAAC,GAAY;IAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEnC,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAC9B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACjE,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,mCAAmC;IACnC,6CAA6C;IAC7C,8FAA8F;IAC9F,wCAAwC;IAExC,yBAAyB;IAEzB,gDAAgD;IAChD,uDAAuD;IACvD,sBAAsB;IACtB,MAAM;IAEN,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,yBAAyB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACvF,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAElB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;QAChD,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kBAAkB,EAAE,KAAK,IAAI,EAAE;QAChC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAElB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,qBAAqB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAEpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,IAAI,GAAG,CAAC,wCAAwC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACtG,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAE1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACpC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAE1B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,iDAAiD,CAAC,CAAC;QAC7G,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,CAAC;QACxE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC9G,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import { CogTiff } from './cog.tiff.js';
2
2
  import { TiffMimeType } from './const/tiff.mime.js';
3
- import { TagId, TagGeoId } from './const/tiff.tag.id.js';
3
+ import { TiffTag, TiffTagGeo } from './const/tiff.tag.id.js';
4
4
  import { Tag, TagOffset } from './read/tiff.tag.js';
5
5
  import { BoundingBox, Size } from './vector.js';
6
+ /** Invalid EPSG code */
6
7
  export declare const InvalidProjectionCode = 32767;
7
8
  /**
8
9
  * Number of tiles used inside this image
@@ -14,7 +15,7 @@ export interface CogTiffImageTiledCount {
14
15
  y: number;
15
16
  }
16
17
  /** Tags that are commonly accessed for geotiffs */
17
- export declare const ImportantTags: Set<TagId>;
18
+ export declare const ImportantTags: Set<TiffTag>;
18
19
  /**
19
20
  * Size of a individual tile
20
21
  */
@@ -26,15 +27,21 @@ export interface CogTiffImageTileSize {
26
27
  }
27
28
  export declare class CogTiffImage {
28
29
  /** All IFD tags that have been read for the image */
29
- tags: Map<TagId, Tag>;
30
- /** Id of the tif image, generally the image index inside the tif */
30
+ tags: Map<TiffTag, Tag>;
31
+ /**
32
+ * Id of the tif image, generally the image index inside the tif
33
+ * where 0 is the root image, and every sub image is +1
34
+ *
35
+ * @example 0, 1, 2
36
+ */
31
37
  id: number;
38
+ /** Reference to the TIFF that owns this image */
32
39
  tiff: CogTiff;
33
40
  /** Has loadGeoTiffTags been called */
34
41
  isGeoTagsLoaded: boolean;
35
42
  /** Sub tags stored in TiffTag.GeoKeyDirectory */
36
- tagsGeo: Map<TagGeoId, string | number>;
37
- constructor(tiff: CogTiff, id: number, tags: Map<TagId, Tag>);
43
+ tagsGeo: Map<TiffTagGeo, string | number>;
44
+ constructor(tiff: CogTiff, id: number, tags: Map<TiffTag, Tag>);
38
45
  /**
39
46
  * Force loading of important tags if they have not already been loaded
40
47
  *
@@ -42,22 +49,34 @@ export declare class CogTiffImage {
42
49
  */
43
50
  init(loadGeoTags?: boolean): Promise<void>;
44
51
  /**
45
- * Get the value of a TiffTag if it exists null otherwise
52
+ * Get the value of a TiffTag if it has been loaded, null otherwise
53
+ *
54
+ * if the value is not loaded @see {CogTiffImage.fetch}
55
+ * @returns value if loaded, null otherwise
46
56
  */
47
- value<T>(tag: TagId): T | null;
57
+ value<T>(tag: TiffTag): T | null;
48
58
  /**
49
59
  * Load and unpack the GeoKeyDirectory
60
+ *
61
+ * @see {TiffTag.GeoKeyDirectory}
50
62
  */
51
63
  loadGeoTiffTags(): Promise<void>;
52
64
  /**
53
- * Get the associated GeoTiffTags
65
+ * Get the associated TiffTagGeo
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * image.valueGeo(TiffTagGeo.GTRasterTypeGeoKey)
70
+ * ```
71
+ * @throws if {@link loadGeoTiffTags} has not been called
54
72
  */
55
- valueGeo(tag: TagGeoId): string | number | undefined;
73
+ valueGeo(tag: TiffTagGeo): string | number | undefined;
56
74
  /**
57
75
  * Load a tag, if it is not currently loaded, fetch the required data for the tag.
76
+ *
58
77
  * @param tag tag to fetch
59
78
  */
60
- fetch<T>(tag: TagId): Promise<T | null>;
79
+ fetch<T>(tag: TiffTag): Promise<T | null>;
61
80
  /**
62
81
  * Get the origin point for the image
63
82
  *
@@ -81,7 +100,7 @@ export declare class CogTiffImage {
81
100
  /**
82
101
  * Get the compression used by the tile
83
102
  *
84
- * @see TiffCompression
103
+ * @see {@link TiffCompression}
85
104
  *
86
105
  * @returns Compression type eg webp
87
106
  */
@@ -128,7 +147,9 @@ export declare class CogTiffImage {
128
147
  get stripCount(): number;
129
148
  getTileBounds(x: number, y: number): BoundingBox;
130
149
  /**
131
- * Read a strip into a uint8 array
150
+ * Read a strip into a ArrayBuffer
151
+ *
152
+ * Image has to be striped see {@link stripCount}
132
153
  *
133
154
  * @param index Strip index to read
134
155
  */
@@ -141,9 +162,9 @@ export declare class CogTiffImage {
141
162
  /** Read image bytes at the given offset */
142
163
  private getBytes;
143
164
  /**
144
- * Load the tile buffer, this works best with webp
165
+ * Load a tile into a ArrayBuffer
145
166
  *
146
- * This will also apply the JPEG compression tables
167
+ * if the tile compression is JPEG, This will also apply the JPEG compression tables to the resulting ArrayBuffer see {@link getJpegHeader}
147
168
  *
148
169
  * @param x Tile x offset
149
170
  * @param y Tile y offset
@@ -155,13 +176,20 @@ export declare class CogTiffImage {
155
176
  /**
156
177
  * Does this tile exist in the tiff and does it actually have a value
157
178
  *
158
- * Sparse tiffs can have a lot of empty tiles, this checks to see if the tile actually has data.
179
+ * Sparse tiffs can have a lot of empty tiles, they set the tile size to `0 bytes` when the tile is empty
180
+ * this checks the tile byte size to validate if it actually has any data.
159
181
  *
160
182
  * @param x Tile x offset
161
183
  * @param y Tile y offset
184
+ *
162
185
  * @returns if the tile exists and has data
163
186
  */
164
187
  hasTile(x: number, y: number): Promise<boolean>;
188
+ /**
189
+ * Load the offset and byteCount of a tile
190
+ * @param index index in the tile array
191
+ * @returns Offset and byteCount for the tile
192
+ */
165
193
  getTileSize(index: number): Promise<{
166
194
  offset: number;
167
195
  imageSize: number;
@@ -1,23 +1,23 @@
1
1
  import { getUint } from './util/bytes.js';
2
2
  import { TiffCompression, TiffMimeType } from './const/tiff.mime.js';
3
- import { TagId, TagGeoId } from './const/tiff.tag.id.js';
4
- import { fetchLazy, getValueAt } from './read/tiff.tag.factory.js';
5
- // /** Invalid EPSG code */
3
+ import { TiffTag, TiffTagGeo } from './const/tiff.tag.id.js';
4
+ import { fetchAllOffsets, fetchLazy, getValueAt } from './read/tiff.tag.factory.js';
5
+ /** Invalid EPSG code */
6
6
  export const InvalidProjectionCode = 32767;
7
7
  /** Tags that are commonly accessed for geotiffs */
8
8
  export const ImportantTags = new Set([
9
- TagId.Compression,
10
- TagId.ImageHeight,
11
- TagId.ImageWidth,
12
- TagId.ModelPixelScale,
13
- TagId.ModelTiePoint,
14
- TagId.ModelTransformation,
15
- TagId.TileHeight,
16
- TagId.TileWidth,
17
- TagId.GeoKeyDirectory,
18
- TagId.GeoAsciiParams,
19
- TagId.GeoDoubleParams,
20
- TagId.TileOffsets,
9
+ TiffTag.Compression,
10
+ TiffTag.ImageHeight,
11
+ TiffTag.ImageWidth,
12
+ TiffTag.ModelPixelScale,
13
+ TiffTag.ModelTiePoint,
14
+ TiffTag.ModelTransformation,
15
+ TiffTag.TileHeight,
16
+ TiffTag.TileWidth,
17
+ TiffTag.GeoKeyDirectory,
18
+ TiffTag.GeoAsciiParams,
19
+ TiffTag.GeoDoubleParams,
20
+ TiffTag.TileOffsets,
21
21
  ]);
22
22
  export class CogTiffImage {
23
23
  constructor(tiff, id, tags) {
@@ -28,13 +28,19 @@ export class CogTiffImage {
28
28
  writable: true,
29
29
  value: void 0
30
30
  });
31
- /** Id of the tif image, generally the image index inside the tif */
31
+ /**
32
+ * Id of the tif image, generally the image index inside the tif
33
+ * where 0 is the root image, and every sub image is +1
34
+ *
35
+ * @example 0, 1, 2
36
+ */
32
37
  Object.defineProperty(this, "id", {
33
38
  enumerable: true,
34
39
  configurable: true,
35
40
  writable: true,
36
41
  value: void 0
37
42
  });
43
+ /** Reference to the TIFF that owns this image */
38
44
  Object.defineProperty(this, "tiff", {
39
45
  enumerable: true,
40
46
  configurable: true,
@@ -66,26 +72,29 @@ export class CogTiffImage {
66
72
  */
67
73
  async init(loadGeoTags = true) {
68
74
  const requiredTags = [
69
- this.fetch(TagId.Compression),
70
- this.fetch(TagId.ImageHeight),
71
- this.fetch(TagId.ImageWidth),
72
- this.fetch(TagId.ModelPixelScale),
73
- this.fetch(TagId.ModelTiePoint),
74
- this.fetch(TagId.ModelTransformation),
75
- this.fetch(TagId.TileHeight),
76
- this.fetch(TagId.TileWidth),
75
+ this.fetch(TiffTag.Compression),
76
+ this.fetch(TiffTag.ImageHeight),
77
+ this.fetch(TiffTag.ImageWidth),
78
+ this.fetch(TiffTag.ModelPixelScale),
79
+ this.fetch(TiffTag.ModelTiePoint),
80
+ this.fetch(TiffTag.ModelTransformation),
81
+ this.fetch(TiffTag.TileHeight),
82
+ this.fetch(TiffTag.TileWidth),
77
83
  ];
78
84
  if (loadGeoTags) {
79
- requiredTags.push(this.fetch(TagId.GeoKeyDirectory));
80
- requiredTags.push(this.fetch(TagId.GeoAsciiParams));
81
- requiredTags.push(this.fetch(TagId.GeoDoubleParams));
85
+ requiredTags.push(this.fetch(TiffTag.GeoKeyDirectory));
86
+ requiredTags.push(this.fetch(TiffTag.GeoAsciiParams));
87
+ requiredTags.push(this.fetch(TiffTag.GeoDoubleParams));
82
88
  }
83
89
  await Promise.all(requiredTags);
84
90
  if (loadGeoTags)
85
91
  await this.loadGeoTiffTags();
86
92
  }
87
93
  /**
88
- * Get the value of a TiffTag if it exists null otherwise
94
+ * Get the value of a TiffTag if it has been loaded, null otherwise
95
+ *
96
+ * if the value is not loaded @see {CogTiffImage.fetch}
97
+ * @returns value if loaded, null otherwise
89
98
  */
90
99
  value(tag) {
91
100
  const sourceTag = this.tags.get(tag);
@@ -97,12 +106,14 @@ export class CogTiffImage {
97
106
  }
98
107
  /**
99
108
  * Load and unpack the GeoKeyDirectory
109
+ *
110
+ * @see {TiffTag.GeoKeyDirectory}
100
111
  */
101
112
  async loadGeoTiffTags() {
102
113
  // Already loaded
103
114
  if (this.isGeoTagsLoaded)
104
115
  return;
105
- const sourceTag = this.tags.get(TagId.GeoKeyDirectory);
116
+ const sourceTag = this.tags.get(TiffTag.GeoKeyDirectory);
106
117
  if (sourceTag == null) {
107
118
  this.isGeoTagsLoaded = true;
108
119
  return;
@@ -110,9 +121,9 @@ export class CogTiffImage {
110
121
  if (sourceTag.type === 'lazy' && sourceTag.value == null) {
111
122
  // Load all the required keys
112
123
  await Promise.all([
113
- this.fetch(TagId.GeoKeyDirectory),
114
- this.fetch(TagId.GeoAsciiParams),
115
- this.fetch(TagId.GeoDoubleParams),
124
+ this.fetch(TiffTag.GeoKeyDirectory),
125
+ this.fetch(TiffTag.GeoAsciiParams),
126
+ this.fetch(TiffTag.GeoDoubleParams),
116
127
  ]);
117
128
  }
118
129
  this.isGeoTagsLoaded = true;
@@ -123,26 +134,32 @@ export class CogTiffImage {
123
134
  throw new Error('Invalid geo tags found');
124
135
  for (let i = 4; i <= geoTags[3] * 4; i += 4) {
125
136
  const key = geoTags[i];
126
- const location = geoTags[i + 1];
137
+ const locationTagId = geoTags[i + 1];
127
138
  const offset = geoTags[i + 3];
128
- if (location === 0) {
139
+ if (locationTagId === 0) {
129
140
  this.tagsGeo.set(key, offset);
130
141
  continue;
131
142
  }
132
- const tag = this.tags.get(location);
143
+ const tag = this.tags.get(locationTagId);
133
144
  if (tag == null || tag.value == null)
134
145
  continue;
135
146
  const count = geoTags[i + 2];
136
- if (Array.isArray(tag.value)) {
137
- this.tagsGeo.set(key, tag.value[offset + count - 1]);
138
- }
139
- else if (typeof tag.value === 'string') {
147
+ if (typeof tag.value === 'string') {
140
148
  this.tagsGeo.set(key, tag.value.slice(offset, offset + count - 1).trim());
141
149
  }
150
+ else {
151
+ throw new Error('Failed to extract GeoTiffTags');
152
+ }
142
153
  }
143
154
  }
144
155
  /**
145
- * Get the associated GeoTiffTags
156
+ * Get the associated TiffTagGeo
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * image.valueGeo(TiffTagGeo.GTRasterTypeGeoKey)
161
+ * ```
162
+ * @throws if {@link loadGeoTiffTags} has not been called
146
163
  */
147
164
  valueGeo(tag) {
148
165
  if (this.isGeoTagsLoaded === false)
@@ -151,6 +168,7 @@ export class CogTiffImage {
151
168
  }
152
169
  /**
153
170
  * Load a tag, if it is not currently loaded, fetch the required data for the tag.
171
+ *
154
172
  * @param tag tag to fetch
155
173
  */
156
174
  async fetch(tag) {
@@ -163,6 +181,8 @@ export class CogTiffImage {
163
181
  return fetchLazy(sourceTag, this.tiff);
164
182
  if (sourceTag.isLoaded)
165
183
  return sourceTag.value;
184
+ if (sourceTag.type === 'offset')
185
+ return fetchAllOffsets(this.tiff, sourceTag);
166
186
  throw new Error('Cannot fetch:' + tag);
167
187
  }
168
188
  /**
@@ -171,27 +191,27 @@ export class CogTiffImage {
171
191
  * @returns origin point of the image
172
192
  */
173
193
  get origin() {
174
- const tiePoints = this.value(TagId.ModelTiePoint);
194
+ const tiePoints = this.value(TiffTag.ModelTiePoint);
175
195
  if (tiePoints != null && tiePoints.length === 6) {
176
196
  return [tiePoints[3], tiePoints[4], tiePoints[5]];
177
197
  }
178
- const modelTransformation = this.value(TagId.ModelTransformation);
198
+ const modelTransformation = this.value(TiffTag.ModelTransformation);
179
199
  if (modelTransformation != null) {
180
200
  return [modelTransformation[3], modelTransformation[7], modelTransformation[11]];
181
201
  }
182
202
  // If this is a sub image, use the origin from the top level image
183
- if (this.value(TagId.NewSubFileType) === 1 && this.id !== 0) {
203
+ if (this.value(TiffTag.NewSubFileType) === 1 && this.id !== 0) {
184
204
  return this.tiff.images[0].origin;
185
205
  }
186
206
  throw new Error('Image does not have a geo transformation.');
187
207
  }
188
208
  /** Is there enough geo information on this image to figure out where its actually located */
189
209
  get isGeoLocated() {
190
- const isImageLocated = this.value(TagId.ModelPixelScale) != null || this.value(TagId.ModelTransformation) != null;
210
+ const isImageLocated = this.value(TiffTag.ModelPixelScale) != null || this.value(TiffTag.ModelTransformation) != null;
191
211
  if (isImageLocated)
192
212
  return true;
193
213
  // If this is a sub image, use the isGeoLocated from the top level image
194
- if (this.value(TagId.NewSubFileType) === 1 && this.id !== 0)
214
+ if (this.value(TiffTag.NewSubFileType) === 1 && this.id !== 0)
195
215
  return this.tiff.images[0].isGeoLocated;
196
216
  return false;
197
217
  }
@@ -201,16 +221,16 @@ export class CogTiffImage {
201
221
  * @returns [x,y,z] pixel scale
202
222
  */
203
223
  get resolution() {
204
- const modelPixelScale = this.value(TagId.ModelPixelScale);
224
+ const modelPixelScale = this.value(TiffTag.ModelPixelScale);
205
225
  if (modelPixelScale != null) {
206
226
  return [modelPixelScale[0], -modelPixelScale[1], modelPixelScale[2]];
207
227
  }
208
- const modelTransformation = this.value(TagId.ModelTransformation);
228
+ const modelTransformation = this.value(TiffTag.ModelTransformation);
209
229
  if (modelTransformation != null) {
210
230
  return [modelTransformation[0], modelTransformation[5], modelTransformation[10]];
211
231
  }
212
232
  // If this is a sub image, use the resolution from the top level image
213
- if (this.value(TagId.NewSubFileType) === 1 && this.id !== 0) {
233
+ if (this.value(TiffTag.NewSubFileType) === 1 && this.id !== 0) {
214
234
  const firstImg = this.tiff.images[0];
215
235
  const [resX, resY, resZ] = firstImg.resolution;
216
236
  const firstImgSize = firstImg.size;
@@ -241,12 +261,12 @@ export class CogTiffImage {
241
261
  /**
242
262
  * Get the compression used by the tile
243
263
  *
244
- * @see TiffCompression
264
+ * @see {@link TiffCompression}
245
265
  *
246
266
  * @returns Compression type eg webp
247
267
  */
248
268
  get compression() {
249
- const compression = this.value(TagId.Compression);
269
+ const compression = this.value(TiffTag.Compression);
250
270
  if (compression == null || typeof compression !== 'number')
251
271
  return null;
252
272
  return TiffCompression[compression];
@@ -257,7 +277,7 @@ export class CogTiffImage {
257
277
  * @returns EPSG Code if it exists
258
278
  */
259
279
  get epsg() {
260
- const projection = this.valueGeo(TagGeoId.ProjectedCSTypeGeoKey);
280
+ const projection = this.valueGeo(TiffTagGeo.ProjectedCSTypeGeoKey);
261
281
  if (projection === InvalidProjectionCode)
262
282
  return null;
263
283
  return projection;
@@ -269,23 +289,23 @@ export class CogTiffImage {
269
289
  */
270
290
  get size() {
271
291
  return {
272
- width: this.value(TagId.ImageWidth),
273
- height: this.value(TagId.ImageHeight),
292
+ width: this.value(TiffTag.ImageWidth),
293
+ height: this.value(TiffTag.ImageHeight),
274
294
  };
275
295
  }
276
296
  /**
277
297
  * Determine if this image is tiled
278
298
  */
279
299
  isTiled() {
280
- return this.value(TagId.TileWidth) !== null;
300
+ return this.value(TiffTag.TileWidth) !== null;
281
301
  }
282
302
  /**
283
303
  * Get size of individual tiles
284
304
  */
285
305
  get tileSize() {
286
306
  return {
287
- width: this.value(TagId.TileWidth),
288
- height: this.value(TagId.TileHeight),
307
+ width: this.value(TiffTag.TileWidth),
308
+ height: this.value(TiffTag.TileHeight),
289
309
  };
290
310
  }
291
311
  /**
@@ -306,7 +326,7 @@ export class CogTiffImage {
306
326
  * @returns file offset to where the tiffs are stored
307
327
  */
308
328
  get tileOffset() {
309
- const tileOffset = this.tags.get(TagId.TileOffsets);
329
+ const tileOffset = this.tags.get(TiffTag.TileOffsets);
310
330
  if (tileOffset == null)
311
331
  throw new Error('No tile offsets found');
312
332
  return tileOffset;
@@ -319,7 +339,7 @@ export class CogTiffImage {
319
339
  * @returns number of strips present
320
340
  */
321
341
  get stripCount() {
322
- const tileOffset = this.tags.get(TagId.StripByteCounts);
342
+ const tileOffset = this.tags.get(TiffTag.StripByteCounts);
323
343
  if (tileOffset == null)
324
344
  return 0;
325
345
  return tileOffset.count;
@@ -334,15 +354,17 @@ export class CogTiffImage {
334
354
  return { x: left, y: top, width, height };
335
355
  }
336
356
  /**
337
- * Read a strip into a uint8 array
357
+ * Read a strip into a ArrayBuffer
358
+ *
359
+ * Image has to be striped see {@link stripCount}
338
360
  *
339
361
  * @param index Strip index to read
340
362
  */
341
363
  async getStrip(index) {
342
364
  if (this.isTiled())
343
365
  throw new Error('Cannot read stripes, tiff is tiled: ' + index);
344
- const byteCounts = this.tags.get(TagId.StripByteCounts);
345
- const offsets = this.tags.get(TagId.StripOffsets);
366
+ const byteCounts = this.tags.get(TiffTag.StripByteCounts);
367
+ const offsets = this.tags.get(TiffTag.StripOffsets);
346
368
  if (index >= byteCounts.count)
347
369
  throw new Error('Cannot read strip, index out of bounds');
348
370
  const [byteCount, offset] = await Promise.all([
@@ -355,7 +377,7 @@ export class CogTiffImage {
355
377
  getJpegHeader(bytes) {
356
378
  // Both the JPEGTable and the Bytes with have the start of image and end of image markers
357
379
  // StartOfImage 0xffd8 EndOfImage 0xffd9
358
- const tables = this.value(TagId.JPEGTables);
380
+ const tables = this.value(TiffTag.JPEGTables);
359
381
  if (tables == null)
360
382
  throw new Error('Unable to find Jpeg header');
361
383
  // Remove EndOfImage marker
@@ -369,7 +391,7 @@ export class CogTiffImage {
369
391
  async getBytes(offset, byteCount) {
370
392
  const mimeType = this.compression;
371
393
  if (mimeType == null)
372
- throw new Error('Unsupported compression: ' + this.value(TagId.Compression));
394
+ throw new Error('Unsupported compression: ' + this.value(TiffTag.Compression));
373
395
  if (byteCount === 0)
374
396
  return null;
375
397
  const bytes = await this.tiff.source.fetch(offset, byteCount);
@@ -381,9 +403,9 @@ export class CogTiffImage {
381
403
  return { mimeType, bytes };
382
404
  }
383
405
  /**
384
- * Load the tile buffer, this works best with webp
406
+ * Load a tile into a ArrayBuffer
385
407
  *
386
- * This will also apply the JPEG compression tables
408
+ * if the tile compression is JPEG, This will also apply the JPEG compression tables to the resulting ArrayBuffer see {@link getJpegHeader}
387
409
  *
388
410
  * @param x Tile x offset
389
411
  * @param y Tile y offset
@@ -395,7 +417,7 @@ export class CogTiffImage {
395
417
  if (tiles == null)
396
418
  throw new Error('Tiff is not tiled');
397
419
  if (mimeType == null)
398
- throw new Error('Unsupported compression: ' + this.value(TagId.Compression));
420
+ throw new Error('Unsupported compression: ' + this.value(TiffTag.Compression));
399
421
  // TODO support GhostOptionTileOrder
400
422
  const nyTiles = Math.ceil(size.height / tiles.height);
401
423
  const nxTiles = Math.ceil(size.width / tiles.width);
@@ -407,16 +429,17 @@ export class CogTiffImage {
407
429
  if (idx >= totalTiles)
408
430
  throw new Error(`Tile index is outside of tile range: ${idx} >= ${totalTiles}`);
409
431
  const { offset, imageSize } = await this.getTileSize(idx);
410
- // console.log({ x, y, offset, imageSize });
411
432
  return this.getBytes(offset, imageSize);
412
433
  }
413
434
  /**
414
435
  * Does this tile exist in the tiff and does it actually have a value
415
436
  *
416
- * Sparse tiffs can have a lot of empty tiles, this checks to see if the tile actually has data.
437
+ * Sparse tiffs can have a lot of empty tiles, they set the tile size to `0 bytes` when the tile is empty
438
+ * this checks the tile byte size to validate if it actually has any data.
417
439
  *
418
440
  * @param x Tile x offset
419
441
  * @param y Tile y offset
442
+ *
420
443
  * @returns if the tile exists and has data
421
444
  */
422
445
  async hasTile(x, y) {
@@ -433,6 +456,11 @@ export class CogTiffImage {
433
456
  const ret = await this.getTileSize(idx);
434
457
  return ret.offset > 0;
435
458
  }
459
+ /**
460
+ * Load the offset and byteCount of a tile
461
+ * @param index index in the tile array
462
+ * @returns Offset and byteCount for the tile
463
+ */
436
464
  async getTileSize(index) {
437
465
  // GDAL optimizes tiles by storing the size of the tile in
438
466
  // the few bytes leading up to the tile
@@ -447,7 +475,7 @@ export class CogTiffImage {
447
475
  const bytes = await this.tiff.source.fetch(offset - leaderBytes, leaderBytes);
448
476
  return { offset, imageSize: getUint(new DataView(bytes), 0, leaderBytes, this.tiff.isLittleEndian) };
449
477
  }
450
- const byteCounts = this.tags.get(TagId.TileByteCounts);
478
+ const byteCounts = this.tags.get(TiffTag.TileByteCounts);
451
479
  if (byteCounts == null)
452
480
  throw new Error('No tile byte counts found');
453
481
  const [offset, imageSize] = await Promise.all([
@@ -461,7 +489,7 @@ function getOffset(tiff, x, index) {
461
489
  if (index > x.count || index < 0)
462
490
  throw new Error('TagIndex: out of bounds ' + x.id + ' @ ' + index);
463
491
  if (x.type === 'inline') {
464
- if (Array.isArray(x.value))
492
+ if (x.count > 1)
465
493
  return x.value[index];
466
494
  return x.value;
467
495
  }