@cogeotiff/core 7.2.0 → 8.0.1

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 (147) hide show
  1. package/CHANGELOG.md +3 -500
  2. package/README.md +28 -10
  3. package/build/__benchmark__/cog.read.benchmark.d.ts +0 -1
  4. package/build/__benchmark__/cog.read.benchmark.js +6 -4
  5. package/build/__benchmark__/cog.read.benchmark.js.map +1 -0
  6. package/build/__benchmark__/source.file.d.ts +9 -0
  7. package/build/__benchmark__/source.file.js +29 -0
  8. package/build/__benchmark__/source.file.js.map +1 -0
  9. package/build/__benchmark__/source.memory.d.ts +9 -0
  10. package/build/__benchmark__/source.memory.js +32 -0
  11. package/build/__benchmark__/source.memory.js.map +1 -0
  12. package/build/__test__/cog.image.test.d.ts +1 -2
  13. package/build/__test__/cog.image.test.js +82 -90
  14. package/build/__test__/cog.image.test.js.map +1 -0
  15. package/build/__test__/cog.read.test.d.ts +1 -2
  16. package/build/__test__/cog.read.test.js +37 -55
  17. package/build/__test__/cog.read.test.js.map +1 -0
  18. package/build/__test__/example.d.ts +1 -0
  19. package/build/__test__/example.js +27 -0
  20. package/build/__test__/example.js.map +1 -0
  21. package/build/cog.tiff.d.ts +22 -28
  22. package/build/cog.tiff.image.d.ts +16 -28
  23. package/build/cog.tiff.image.js +147 -101
  24. package/build/cog.tiff.image.js.map +1 -0
  25. package/build/cog.tiff.js +141 -97
  26. package/build/cog.tiff.js.map +1 -0
  27. package/build/const/index.d.ts +1 -2
  28. package/build/const/index.js +2 -2
  29. package/build/const/index.js.map +1 -0
  30. package/build/const/tiff.endian.d.ts +0 -1
  31. package/build/const/tiff.endian.js +1 -1
  32. package/build/const/tiff.endian.js.map +1 -0
  33. package/build/const/tiff.mime.d.ts +10 -11
  34. package/build/const/tiff.mime.js +22 -22
  35. package/build/const/tiff.mime.js.map +1 -0
  36. package/build/const/tiff.tag.id.d.ts +5 -5
  37. package/build/const/tiff.tag.id.js +155 -154
  38. package/build/const/tiff.tag.id.js.map +1 -0
  39. package/build/const/tiff.tag.value.d.ts +15 -16
  40. package/build/const/tiff.tag.value.js +16 -16
  41. package/build/const/tiff.tag.value.js.map +1 -0
  42. package/build/const/tiff.version.d.ts +0 -1
  43. package/build/const/tiff.version.js +1 -1
  44. package/build/const/tiff.version.js.map +1 -0
  45. package/build/index.d.ts +11 -6
  46. package/build/index.js +9 -5
  47. package/build/index.js.map +1 -0
  48. package/build/read/data.view.offset.d.ts +15 -0
  49. package/build/read/data.view.offset.js +19 -0
  50. package/build/read/data.view.offset.js.map +1 -0
  51. package/build/read/tiff.gdal.d.ts +9 -12
  52. package/build/read/tiff.gdal.js +22 -17
  53. package/build/read/tiff.gdal.js.map +1 -0
  54. package/build/read/tiff.ifd.config.d.ts +6 -4
  55. package/build/read/tiff.ifd.config.js +2 -2
  56. package/build/read/tiff.ifd.config.js.map +1 -0
  57. package/build/read/tiff.tag.d.ts +37 -20
  58. package/build/read/tiff.tag.factory.d.ts +16 -0
  59. package/build/read/tiff.tag.factory.js +130 -0
  60. package/build/read/tiff.tag.factory.js.map +1 -0
  61. package/build/read/tiff.tag.js +2 -37
  62. package/build/read/tiff.tag.js.map +1 -0
  63. package/build/read/tiff.value.reader.d.ts +2 -6
  64. package/build/read/tiff.value.reader.js +16 -54
  65. package/build/read/tiff.value.reader.js.map +1 -0
  66. package/build/source.d.ts +5 -0
  67. package/build/source.js +2 -0
  68. package/build/source.js.map +1 -0
  69. package/build/util/bytes.d.ts +17 -0
  70. package/build/util/bytes.js +42 -0
  71. package/build/util/bytes.js.map +1 -0
  72. package/build/util/util.hex.d.ts +2 -3
  73. package/build/util/util.hex.js +4 -5
  74. package/build/util/util.hex.js.map +1 -0
  75. package/build/vector.d.ts +0 -1
  76. package/build/vector.js +1 -1
  77. package/build/vector.js.map +1 -0
  78. package/package.json +25 -30
  79. package/src/__benchmark__/cog.read.benchmark.ts +12 -10
  80. package/src/__benchmark__/source.file.ts +23 -0
  81. package/src/__benchmark__/source.memory.ts +23 -0
  82. package/src/__test__/cog.image.test.ts +188 -197
  83. package/src/__test__/cog.read.test.ts +50 -72
  84. package/src/__test__/example.ts +31 -0
  85. package/src/cog.tiff.image.ts +456 -448
  86. package/src/cog.tiff.ts +143 -146
  87. package/src/const/index.ts +1 -1
  88. package/src/const/tiff.endian.ts +2 -2
  89. package/src/const/tiff.mime.ts +21 -21
  90. package/src/const/tiff.tag.id.ts +159 -158
  91. package/src/const/tiff.tag.value.ts +16 -16
  92. package/src/const/tiff.version.ts +11 -11
  93. package/src/index.ts +11 -5
  94. package/src/read/data.view.offset.ts +23 -0
  95. package/src/read/tiff.gdal.ts +61 -63
  96. package/src/read/tiff.ifd.config.ts +35 -31
  97. package/src/read/tiff.tag.factory.ts +163 -0
  98. package/src/read/tiff.tag.ts +38 -39
  99. package/src/read/tiff.value.reader.ts +25 -73
  100. package/src/source.ts +5 -0
  101. package/src/util/bytes.ts +44 -0
  102. package/src/util/util.hex.ts +5 -7
  103. package/src/vector.ts +5 -5
  104. package/tsconfig.json +8 -10
  105. package/build/__benchmark__/cog.read.benchmark.d.ts.map +0 -1
  106. package/build/__test__/cog.image.test.d.ts.map +0 -1
  107. package/build/__test__/cog.read.test.d.ts.map +0 -1
  108. package/build/cog.tiff.d.ts.map +0 -1
  109. package/build/cog.tiff.image.d.ts.map +0 -1
  110. package/build/const/index.d.ts.map +0 -1
  111. package/build/const/tiff.endian.d.ts.map +0 -1
  112. package/build/const/tiff.mime.d.ts.map +0 -1
  113. package/build/const/tiff.tag.id.d.ts.map +0 -1
  114. package/build/const/tiff.tag.value.d.ts.map +0 -1
  115. package/build/const/tiff.version.d.ts.map +0 -1
  116. package/build/index.d.ts.map +0 -1
  117. package/build/read/tag/__test__/tag.test.d.ts +0 -2
  118. package/build/read/tag/__test__/tag.test.d.ts.map +0 -1
  119. package/build/read/tag/__test__/tag.test.js +0 -23
  120. package/build/read/tag/tiff.tag.base.d.ts +0 -55
  121. package/build/read/tag/tiff.tag.base.d.ts.map +0 -1
  122. package/build/read/tag/tiff.tag.base.js +0 -79
  123. package/build/read/tag/tiff.tag.lazy.d.ts +0 -7
  124. package/build/read/tag/tiff.tag.lazy.d.ts.map +0 -1
  125. package/build/read/tag/tiff.tag.lazy.js +0 -18
  126. package/build/read/tag/tiff.tag.offset.d.ts +0 -21
  127. package/build/read/tag/tiff.tag.offset.d.ts.map +0 -1
  128. package/build/read/tag/tiff.tag.offset.js +0 -54
  129. package/build/read/tag/tiff.tag.static.d.ts +0 -8
  130. package/build/read/tag/tiff.tag.static.d.ts.map +0 -1
  131. package/build/read/tag/tiff.tag.static.js +0 -17
  132. package/build/read/tiff.gdal.d.ts.map +0 -1
  133. package/build/read/tiff.ifd.config.d.ts.map +0 -1
  134. package/build/read/tiff.tag.d.ts.map +0 -1
  135. package/build/read/tiff.value.reader.d.ts.map +0 -1
  136. package/build/source/cog.source.view.d.ts +0 -33
  137. package/build/source/cog.source.view.d.ts.map +0 -1
  138. package/build/source/cog.source.view.js +0 -65
  139. package/build/util/util.hex.d.ts.map +0 -1
  140. package/build/vector.d.ts.map +0 -1
  141. package/src/@types/ieee754.d.ts +0 -18
  142. package/src/read/tag/__test__/tag.test.ts +0 -27
  143. package/src/read/tag/tiff.tag.base.ts +0 -126
  144. package/src/read/tag/tiff.tag.lazy.ts +0 -17
  145. package/src/read/tag/tiff.tag.offset.ts +0 -61
  146. package/src/read/tag/tiff.tag.static.ts +0 -15
  147. package/src/source/cog.source.view.ts +0 -77
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Convert a number to a formated hex string
2
+ * Convert a number to a formatted hex string
3
3
  *
4
4
  * @param num number to convert
5
5
  * @param padding number of 0's to pad the digit with
@@ -7,11 +7,10 @@
7
7
  *
8
8
  * @returns hex string eg 0x0015
9
9
  **/
10
- export function toHexString(num, padding = 4, prefix = true) {
10
+ export function toHex(num, padding = 4, prefix = true) {
11
11
  const hex = num.toString(16).padStart(padding, '0');
12
- if (prefix) {
12
+ if (prefix)
13
13
  return '0x' + hex;
14
- }
15
14
  return hex;
16
15
  }
17
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5oZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbC91dGlsLmhleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7SUFRSTtBQUNKLE1BQU0sVUFBVSxXQUFXLENBQUMsR0FBVyxFQUFFLE9BQU8sR0FBRyxDQUFDLEVBQUUsTUFBTSxHQUFHLElBQUk7SUFDL0QsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3BELElBQUksTUFBTSxFQUFFO1FBQ1IsT0FBTyxJQUFJLEdBQUcsR0FBRyxDQUFDO0tBQ3JCO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDZixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb252ZXJ0IGEgbnVtYmVyIHRvIGEgZm9ybWF0ZWQgaGV4IHN0cmluZ1xuICpcbiAqIEBwYXJhbSBudW0gbnVtYmVyIHRvIGNvbnZlcnRcbiAqIEBwYXJhbSBwYWRkaW5nIG51bWJlciBvZiAwJ3MgdG8gcGFkIHRoZSBkaWdpdCB3aXRoXG4gKiBAcGFyYW0gcHJlZml4IHNob3VsZCBhIGAweGAgYmUgcHJlZml4ZWQgdG8gdGhlIHN0cmluZ1xuICpcbiAqIEByZXR1cm5zIGhleCBzdHJpbmcgZWcgMHgwMDE1XG4gKiovXG5leHBvcnQgZnVuY3Rpb24gdG9IZXhTdHJpbmcobnVtOiBudW1iZXIsIHBhZGRpbmcgPSA0LCBwcmVmaXggPSB0cnVlKTogc3RyaW5nIHtcbiAgICBjb25zdCBoZXggPSBudW0udG9TdHJpbmcoMTYpLnBhZFN0YXJ0KHBhZGRpbmcsICcwJyk7XG4gICAgaWYgKHByZWZpeCkge1xuICAgICAgICByZXR1cm4gJzB4JyArIGhleDtcbiAgICB9XG4gICAgcmV0dXJuIGhleDtcbn1cbiJdfQ==
16
+ //# sourceMappingURL=util.hex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.hex.js","sourceRoot":"","sources":["../../src/util/util.hex.ts"],"names":[],"mappings":"AAAA;;;;;;;;IAQI;AACJ,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,OAAO,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;IAC3D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,MAAM;QAAE,OAAO,IAAI,GAAG,GAAG,CAAC;IAC9B,OAAO,GAAG,CAAC;AACb,CAAC"}
package/build/vector.d.ts CHANGED
@@ -11,4 +11,3 @@ export interface BoundingBox extends Point, Size {
11
11
  export interface Vector extends Point {
12
12
  z: number;
13
13
  }
14
- //# sourceMappingURL=vector.d.ts.map
package/build/vector.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3ZlY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGludGVyZmFjZSBTaXplIHtcbiAgICB3aWR0aDogbnVtYmVyO1xuICAgIGhlaWdodDogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBvaW50IHtcbiAgICB4OiBudW1iZXI7XG4gICAgeTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJvdW5kaW5nQm94IGV4dGVuZHMgUG9pbnQsIFNpemUge31cbmV4cG9ydCBpbnRlcmZhY2UgVmVjdG9yIGV4dGVuZHMgUG9pbnQge1xuICAgIHo6IG51bWJlcjtcbn1cbiJdfQ==
2
+ //# sourceMappingURL=vector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector.js","sourceRoot":"","sources":["../src/vector.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,32 +1,27 @@
1
1
  {
2
- "name": "@cogeotiff/core",
3
- "version": "7.2.0",
4
- "repository": {
5
- "type": "git",
6
- "url": "https://github.com/blacha/cogeotiff.git",
7
- "directory": "packages/core"
8
- },
9
- "type": "module",
10
- "engines": {
11
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
12
- },
13
- "main": "./build/index.js",
14
- "types": "./build/index.d.ts",
15
- "author": "Blayne Chard",
16
- "license": "MIT",
17
- "scripts": {
18
- "test": "ospec --globs 'build/**/*.test.js'"
19
- },
20
- "dependencies": {
21
- "@chunkd/core": "^8.1.0",
22
- "ieee754": "^1.1.13"
23
- },
24
- "devDependencies": {
25
- "@types/node": "^18.0.0",
26
- "@types/ospec": "^4.0.3"
27
- },
28
- "publishConfig": {
29
- "access": "public"
30
- },
31
- "gitHead": "64a437a3590a1fc8395d1f4294a5fc74cbbe6127"
2
+ "name": "@cogeotiff/core",
3
+ "version": "8.0.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/blacha/cogeotiff.git",
7
+ "directory": "packages/core"
8
+ },
9
+ "type": "module",
10
+ "engines": {
11
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
12
+ },
13
+ "main": "./build/index.js",
14
+ "types": "./build/index.d.ts",
15
+ "author": "Blayne Chard",
16
+ "license": "MIT",
17
+ "scripts": {
18
+ "test": "node --test"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "^20.0.0"
22
+ },
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "gitHead": "6e7b4f6250189ce8a3fa88641eaf35538b104ddd"
32
27
  }
@@ -1,19 +1,21 @@
1
- import { SourceMemory } from '@chunkd/core';
2
1
  import { readFile } from 'fs/promises';
3
2
  import { CogTiff } from '../cog.tiff.js';
3
+ import { SourceMemory } from './source.memory.js';
4
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(): Promise<void> {
7
- const buf = await readFile(process.argv[process.argv.length - 1]);
8
- const source = new SourceMemory('buf', buf);
9
- for (let i = 0; i < 5_000; i++) {
10
- const tiff = new CogTiff(source);
11
- await tiff.init();
8
+ const buf = await readFile(process.argv[process.argv.length - 1]);
9
+ const source = new SourceMemory(buf);
10
+ for (let i = 0; i < 5_000; i++) {
11
+ performance.mark('cog:init');
12
+ const tiff = new CogTiff(source);
13
+ await tiff.init();
14
+ performance.mark('cog:init:done');
12
15
 
13
- // 6 images
14
- for (const img of tiff.images) await img.getTile(0, 0);
15
- await tiff.close();
16
- }
16
+ // 6 images
17
+ for (const img of tiff.images) await img.getTile(0, 0);
18
+ }
17
19
  }
18
20
 
19
21
  main();
@@ -0,0 +1,23 @@
1
+ import { readFile, stat } from 'fs/promises';
2
+ import { Source } from '../source.js';
3
+
4
+ export class TestFileSource implements Source {
5
+ url: URL;
6
+ data: Promise<Buffer>;
7
+
8
+ constructor(fileName: URL) {
9
+ this.url = fileName;
10
+ this.data = readFile(this.url);
11
+ }
12
+
13
+ async fetch(offset: number, length: number): Promise<ArrayBuffer> {
14
+ const fileData = await this.data;
15
+ return fileData.buffer.slice(fileData.byteOffset + offset, fileData.byteOffset + offset + length);
16
+ }
17
+
18
+ get size(): Promise<number> {
19
+ return Promise.resolve()
20
+ .then(() => stat(this.url))
21
+ .then((f) => f.size);
22
+ }
23
+ }
@@ -0,0 +1,23 @@
1
+ import { Source } from '../source.js';
2
+
3
+ export class SourceMemory implements Source {
4
+ url: URL;
5
+ data: ArrayBuffer;
6
+
7
+ static toArrayBuffer(buf: Buffer | Uint8Array | ArrayBuffer): ArrayBuffer {
8
+ if (buf instanceof ArrayBuffer) return buf;
9
+ if (buf.byteLength === buf.buffer.byteLength) return buf.buffer;
10
+ return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
11
+ }
12
+
13
+ constructor(bytes: Buffer | Uint8Array | ArrayBuffer) {
14
+ this.url = new URL('memory://fake-file');
15
+ this.data = SourceMemory.toArrayBuffer(bytes);
16
+ }
17
+
18
+ async fetch(offset: number, length?: number): Promise<ArrayBuffer> {
19
+ // console.log('Fetch', offset, length);
20
+ if (offset < 0) offset = this.data.byteLength + offset;
21
+ return this.data.slice(offset, length == null ? undefined : offset + length);
22
+ }
23
+ }
@@ -1,214 +1,205 @@
1
- import o from 'ospec';
2
- import * as path from 'path';
3
1
  import { promises as fs } from 'fs';
4
-
5
- import 'source-map-support/register.js';
6
-
7
- import { TestFileChunkSource } from '@chunkd/core/build/__test__/chunk.source.fake.js';
2
+ import assert from 'node:assert';
3
+ import { beforeEach, describe, it } from 'node:test';
4
+ import { TestFileSource } from '../__benchmark__/source.file.js';
5
+ import { SourceMemory } from '../__benchmark__/source.memory.js';
6
+ import { ByteSize } from '../util/bytes.js';
8
7
  import { CogTiff } from '../cog.tiff.js';
9
- import { TiffMimeType } from '../const/index.js';
10
- import { ByteSize, SourceMemory } from '@chunkd/core';
11
- import { fileURLToPath } from 'url';
8
+ import { TiffMimeType } from '../const/tiff.mime.js';
12
9
 
13
- const __dirname = fileURLToPath(import.meta.url);
14
10
  // 900913 properties.
15
11
  const A = 6378137.0;
16
12
  const InitialResolution = (2 * Math.PI * A) / 256;
17
13
 
18
14
  function getResolution(zoom: number): number {
19
- return InitialResolution / 2 ** zoom;
15
+ return InitialResolution / 2 ** zoom;
20
16
  }
21
17
 
22
- o.spec('CogTiled', () => {
23
- const cogSourceFile = new TestFileChunkSource(path.join(__dirname, '../../../data/rgba8_tiled.tiff'));
24
- const cog = new CogTiff(cogSourceFile);
25
-
26
- o.beforeEach(() => cog.init());
27
-
28
- o('should match resolutions to web mercator zoom levels', () => {
29
- for (let i = 0; i < 14; i++) {
30
- o(cog.getImageByResolution(getResolution(i)).id).equals(4);
31
- }
32
-
33
- o(cog.getImageByResolution(getResolution(14)).id).equals(3);
34
- o(cog.getImageByResolution(getResolution(15)).id).equals(2);
35
- o(cog.getImageByResolution(getResolution(16)).id).equals(1);
36
- o(cog.getImageByResolution(getResolution(17)).id).equals(0);
37
- o(cog.getImageByResolution(getResolution(18)).id).equals(0);
38
-
39
- for (let i = 19; i < 32; i++) {
40
- o(cog.getImageByResolution(getResolution(i)).id).equals(0);
41
- }
42
- });
43
-
44
- o('should get origin from all images', () => {
45
- const baseOrigin = cog.images[0].origin;
46
- for (const img of cog.images) {
47
- o(img.origin).deepEquals(baseOrigin);
48
- }
49
- });
50
-
51
- o('should get bounding box from all images', () => {
52
- const baseOrigin = cog.images[0].bbox;
53
- for (const img of cog.images) {
54
- o(img.bbox).deepEquals(baseOrigin);
55
- }
56
- });
57
-
58
- o('should be geolocated', () => {
59
- for (const img of cog.images) o(img.isGeoLocated).equals(true);
60
- });
61
-
62
- o('should scale image resolution for all images', () => {
63
- const [resX, resY, resZ] = cog.images[0].resolution;
64
- for (let i = 0; i < cog.images.length; i++) {
65
- const img = cog.images[i];
66
- const scale = 2 ** i; // This tiff is scaled at a factor of two per zoom level
67
- o(img.resolution).deepEquals([resX * scale, resY * scale, resZ]);
68
- }
69
- });
70
-
71
- o('should have tile information', () => {
72
- const [firstImage] = cog.images;
73
- o(firstImage.stripCount).equals(0);
74
- o(firstImage.isTiled()).equals(true);
75
- });
76
-
77
- o('should hasTile for every tile', async () => {
78
- const [firstImage] = cog.images;
79
-
80
- for (let x = 0; x < firstImage.tileCount.x; x++) {
81
- for (let y = 0; y < firstImage.tileCount.y; y++) {
82
- o(await firstImage.hasTile(x, y)).equals(true);
83
- }
84
- }
85
- });
18
+ describe('CogTiled', () => {
19
+ const cogSourceFile = new TestFileSource(new URL('../../data/rgba8_tiled.tiff', import.meta.url));
20
+ const cog = new CogTiff(cogSourceFile);
21
+
22
+ beforeEach(() => cog.init());
23
+
24
+ it('should match resolutions to web mercator zoom levels', () => {
25
+ for (let i = 0; i < 14; i++) {
26
+ assert.equal(cog.getImageByResolution(getResolution(i)).id, 4);
27
+ }
28
+
29
+ assert.equal(cog.getImageByResolution(getResolution(14)).id, 3);
30
+ assert.equal(cog.getImageByResolution(getResolution(15)).id, 2);
31
+ assert.equal(cog.getImageByResolution(getResolution(16)).id, 1);
32
+ assert.equal(cog.getImageByResolution(getResolution(17)).id, 0);
33
+ assert.equal(cog.getImageByResolution(getResolution(18)).id, 0);
34
+
35
+ for (let i = 19; i < 32; i++) {
36
+ assert.equal(cog.getImageByResolution(getResolution(i)).id, 0);
37
+ }
38
+ });
39
+
40
+ it('should get origin from all images', () => {
41
+ const baseOrigin = cog.images[0].origin;
42
+ for (const img of cog.images) {
43
+ assert.deepEqual(img.origin, baseOrigin);
44
+ }
45
+ });
46
+
47
+ it('should get bounding box from all images', () => {
48
+ const baseOrigin = cog.images[0].bbox;
49
+ for (const img of cog.images) {
50
+ assert.deepEqual(img.bbox, baseOrigin);
51
+ }
52
+ });
53
+
54
+ it('should be geolocated', () => {
55
+ for (const img of cog.images) assert.equal(img.isGeoLocated, true);
56
+ });
57
+
58
+ it('should scale image resolution for all images', () => {
59
+ const [resX, resY, resZ] = cog.images[0].resolution;
60
+ for (let i = 0; i < cog.images.length; i++) {
61
+ const img = cog.images[i];
62
+ const scale = 2 ** i; // This tiff is scaled at a factor of two per zoom level
63
+ assert.deepEqual(img.resolution, [resX * scale, resY * scale, resZ]);
64
+ }
65
+ });
66
+
67
+ it('should have tile information', () => {
68
+ const [firstImage] = cog.images;
69
+ assert.equal(firstImage.stripCount, 0);
70
+ assert.equal(firstImage.isTiled(), true);
71
+ });
72
+
73
+ it('should hasTile for every tile', async () => {
74
+ const [firstImage] = cog.images;
75
+
76
+ for (let x = 0; x < firstImage.tileCount.x; x++) {
77
+ for (let y = 0; y < firstImage.tileCount.y; y++) {
78
+ assert.equal(await firstImage.hasTile(x, y), true);
79
+ }
80
+ }
81
+ });
86
82
  });
87
83
 
88
- o.spec('Cog.Big', () => {
89
- o('should support reading from memory', async () => {
90
- const fullSource = new TestFileChunkSource(path.join(__dirname, '../../../data/sparse.tiff'));
91
- fullSource.chunkSize = 27902;
92
- await fullSource.loadBytes(0, 27902);
93
- const cog = new CogTiff(fullSource);
94
- await cog.init();
95
-
96
- o(fullSource.chunkSize).equals(27902);
97
- o(fullSource.chunks.size).equals(1);
98
- const [firstImage] = cog.images;
99
- o(firstImage.stripCount).equals(0);
100
- o(firstImage.isTiled()).equals(true);
101
-
102
- const img = cog.getImage(4);
103
- o(img.tileCount).deepEquals({ x: 2, y: 2 });
104
- });
105
-
106
- o('should read using a memory source', async () => {
107
- const bytes = await fs.readFile(path.join(__dirname, '../../../data/sparse.tiff'));
108
- const source = new SourceMemory('Sparse.tiff', bytes.buffer);
109
- const cog = new CogTiff(source);
110
- await cog.init();
111
-
112
- o(source.chunkSize).equals(27902);
113
- o(source.chunks.size).equals(1);
114
- const [firstImage] = cog.images;
115
- o(firstImage.stripCount).equals(0);
116
- o(firstImage.isTiled()).equals(true);
117
-
118
- const img = cog.getImage(4);
119
- o(img.tileCount).deepEquals({ x: 2, y: 2 });
120
- });
84
+ describe('Cog.Big', () => {
85
+ it('should support reading from memory', async () => {
86
+ const fullSource = new TestFileSource(new URL('../../data/sparse.tiff', import.meta.url));
87
+
88
+ const cog = new CogTiff(fullSource);
89
+ await cog.init();
90
+
91
+ const [firstImage] = cog.images;
92
+ assert.equal(firstImage.stripCount, 0);
93
+ assert.equal(firstImage.isTiled(), true);
94
+
95
+ const img = cog.images[4];
96
+ assert.deepEqual(img.tileCount, { x: 2, y: 2 });
97
+ });
98
+
99
+ it('should read using a memory source', async () => {
100
+ const bytes = await fs.readFile(new URL('../../data/sparse.tiff', import.meta.url));
101
+ const source = new SourceMemory(bytes.buffer);
102
+ const cog = new CogTiff(source);
103
+ await cog.init();
104
+
105
+ const [firstImage] = cog.images;
106
+ assert.equal(firstImage.stripCount, 0);
107
+ assert.equal(firstImage.isTiled(), true);
108
+
109
+ const img = cog.images[4];
110
+ assert.deepEqual(img.tileCount, { x: 2, y: 2 });
111
+ });
121
112
  });
122
113
 
123
- o.spec('Cog.Sparse', () => {
124
- const cogSourceFile = new TestFileChunkSource(path.join(__dirname, '../../../data/sparse.tiff'));
125
- const cog = new CogTiff(cogSourceFile);
126
- o.beforeEach(() => cog.init(true));
127
-
128
- o('should read metadata', () => {
129
- o(cog.getImage(0).epsg).equals(2193);
130
- });
131
-
132
- o('should be geolocated', () => {
133
- for (const img of cog.images) o(img.isGeoLocated).equals(true);
134
- });
135
-
136
- o('should support sparse cogs', async () => {
137
- const z = 4;
138
- const img = cog.getImage(z);
139
-
140
- const { tileCount } = img;
141
- o(tileCount).deepEquals({ x: 2, y: 2 });
142
-
143
- for (let x = 0; x < tileCount.x; x++) {
144
- for (let y = 0; y < tileCount.y; y++) {
145
- const hasTile = await img.hasTile(x, y);
146
- o(hasTile).equals(false);
147
- const tileXy = await img.getTile(x, y);
148
- const tileXyz = await cog.getTile(x, y, z);
149
- o(tileXy).equals(null)(`Tile x:${x} y:${y} should be empty`);
150
- o(tileXyz).equals(null)(`Tile x:${x} y:${y} z: ${z} should be empty`);
151
- }
152
- }
153
- });
154
-
155
- o('should have ghost options', () => {
156
- o(cog.options.options.size).equals(6);
157
- o(cog.options.tileLeaderByteSize).equals(ByteSize.UInt32);
158
- o(cog.options.isCogOptimized).equals(true);
159
-
160
- const entries = [...cog.options.options.entries()];
161
- o(entries).deepEquals([
162
- ['GDAL_STRUCTURAL_METADATA_SIZE', '000140 bytes'],
163
- ['LAYOUT', 'IFDS_BEFORE_DATA'],
164
- ['BLOCK_ORDER', 'ROW_MAJOR'],
165
- ['BLOCK_LEADER', 'SIZE_AS_UINT4'],
166
- ['BLOCK_TRAILER', 'LAST_4_BYTES_REPEATED'],
167
- ['KNOWN_INCOMPATIBLE_EDITION', 'NO'],
168
- ]);
169
- });
114
+ describe('Cog.Sparse', () => {
115
+ const cogSourceFile = new TestFileSource(new URL('../../data/sparse.tiff', import.meta.url));
116
+ const cog = new CogTiff(cogSourceFile);
117
+
118
+ it('should read metadata', async () => {
119
+ await cog.init();
120
+ assert.equal(cog.images[0].epsg, 2193);
121
+ });
122
+
123
+ it('should be geolocated', () => {
124
+ for (const img of cog.images) assert.equal(img.isGeoLocated, true);
125
+ });
126
+
127
+ it('should support sparse cogs', async () => {
128
+ const z = 4;
129
+ const img = cog.images[z];
130
+
131
+ const { tileCount } = img;
132
+ assert.deepEqual(tileCount, { x: 2, y: 2 });
133
+
134
+ for (let x = 0; x < tileCount.x; x++) {
135
+ for (let y = 0; y < tileCount.y; y++) {
136
+ const hasTile = await img.hasTile(x, y);
137
+ assert.equal(hasTile, false);
138
+ const tileXy = await img.getTile(x, y);
139
+ const tileXyz = await cog.images[z].getTile(x, y);
140
+ assert.equal(tileXy, null, `Tile x:${x} y:${y} should be empty`);
141
+ assert.equal(tileXyz, null, `Tile x:${x} y:${y} z: ${z} should be empty`);
142
+ }
143
+ }
144
+ });
145
+
146
+ it('should have ghost options', () => {
147
+ assert.equal(cog.options?.options.size, 6);
148
+ assert.equal(cog.options?.tileLeaderByteSize, ByteSize.UInt32);
149
+ assert.equal(cog.options?.isCogOptimized, true);
150
+
151
+ const entries = [...(cog.options?.options.entries() ?? [])];
152
+ assert.deepEqual(entries, [
153
+ ['GDAL_STRUCTURAL_METADATA_SIZE', '000140 bytes'],
154
+ ['LAYOUT', 'IFDS_BEFORE_DATA'],
155
+ ['BLOCK_ORDER', 'ROW_MAJOR'],
156
+ ['BLOCK_LEADER', 'SIZE_AS_UINT4'],
157
+ ['BLOCK_TRAILER', 'LAST_4_BYTES_REPEATED'],
158
+ ['KNOWN_INCOMPATIBLE_EDITION', 'NO'],
159
+ ]);
160
+ });
170
161
  });
171
162
 
172
- o.spec('CogStrip', () => {
173
- const cogSourceFile = new TestFileChunkSource(path.join(__dirname, '../../../data/rgba8_strip.tiff'));
174
- const cog = new CogTiff(cogSourceFile);
175
-
176
- o.beforeEach(() => cog.init());
177
-
178
- o('should get origin from all images', () => {
179
- const baseOrigin = cog.images[0].origin;
180
- for (const img of cog.images) {
181
- o(img.origin).deepEquals(baseOrigin);
182
- }
183
- });
184
-
185
- o('should get bounding box from all images', () => {
186
- const baseOrigin = cog.images[0].bbox;
187
- for (const img of cog.images) {
188
- o(img.bbox).deepEquals(baseOrigin);
189
- }
190
- });
191
-
192
- o('should scale image resolution for all images', () => {
193
- const [resX, resY, resZ] = cog.images[0].resolution;
194
- for (let i = 0; i < cog.images.length; i++) {
195
- const img = cog.images[i];
196
- const scale = 2 ** i; // This tiff is scaled at a factor of two per zoom level
197
- o(img.resolution).deepEquals([resX * scale, resY * scale, resZ]);
198
- }
199
- });
200
-
201
- o('should have strip information', async () => {
202
- const [firstImage] = cog.images;
203
- o(firstImage.isTiled()).equals(false);
204
- o(firstImage.stripCount).equals(2);
205
-
206
- const stripA = await firstImage.getStrip(0);
207
- o(stripA?.mimeType).equals(TiffMimeType.WEBP);
208
- o(stripA?.bytes.byteLength).equals(152);
209
-
210
- const stripB = await firstImage.getStrip(1);
211
- o(stripB?.mimeType).equals(TiffMimeType.WEBP);
212
- o(stripB?.bytes.byteLength).equals(152);
213
- });
163
+ describe('CogStrip', () => {
164
+ const cogSourceFile = new TestFileSource(new URL('../../data/rgba8_strip.tiff', import.meta.url));
165
+ const cog = new CogTiff(cogSourceFile);
166
+
167
+ beforeEach(() => cog.init());
168
+
169
+ it('should get origin from all images', () => {
170
+ const baseOrigin = cog.images[0].origin;
171
+ for (const img of cog.images) {
172
+ assert.deepEqual(img.origin, baseOrigin);
173
+ }
174
+ });
175
+
176
+ it('should get bounding box from all images', () => {
177
+ const baseOrigin = cog.images[0].bbox;
178
+ for (const img of cog.images) {
179
+ assert.deepEqual(img.bbox, baseOrigin);
180
+ }
181
+ });
182
+
183
+ it('should scale image resolution for all images', () => {
184
+ const [resX, resY, resZ] = cog.images[0].resolution;
185
+ for (let i = 0; i < cog.images.length; i++) {
186
+ const img = cog.images[i];
187
+ const scale = 2 ** i; // This tiff is scaled at a factor of two per zoom level
188
+ assert.deepEqual(img.resolution, [resX * scale, resY * scale, resZ]);
189
+ }
190
+ });
191
+
192
+ it('should have strip information', async () => {
193
+ const [firstImage] = cog.images;
194
+ assert.equal(firstImage.isTiled(), false);
195
+ assert.equal(firstImage.stripCount, 2);
196
+
197
+ const stripA = await firstImage.getStrip(0);
198
+ assert.equal(stripA?.mimeType, TiffMimeType.Webp);
199
+ assert.equal(stripA?.bytes.byteLength, 152);
200
+
201
+ const stripB = await firstImage.getStrip(1);
202
+ assert.equal(stripB?.mimeType, TiffMimeType.Webp);
203
+ assert.equal(stripB?.bytes.byteLength, 152);
204
+ });
214
205
  });