geotiff 3.0.0 → 3.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 (164) hide show
  1. package/dist-browser/geotiff.js +3 -2
  2. package/dist-browser/geotiff.js.map +1 -1
  3. package/dist-module/compression/basedecoder.d.ts +4 -0
  4. package/dist-module/compression/basedecoder.d.ts.map +1 -1
  5. package/dist-module/compression/basedecoder.js +6 -0
  6. package/dist-module/compression/index.d.ts +4 -4
  7. package/dist-module/compression/index.d.ts.map +1 -1
  8. package/dist-module/compression/index.js +4 -4
  9. package/dist-module/compression/jpeg.d.ts +6 -1
  10. package/dist-module/compression/jpeg.d.ts.map +1 -1
  11. package/dist-module/compression/jpeg.js +50 -5
  12. package/dist-module/compression/lzw.js +1 -1
  13. package/dist-module/compression/webimage.d.ts +1 -1
  14. package/dist-module/compression/webimage.d.ts.map +1 -1
  15. package/dist-module/compression/webimage.js +1 -1
  16. package/dist-module/dataslice.d.ts.map +1 -1
  17. package/dist-module/dataslice.js +2 -2
  18. package/dist-module/dataview64.d.ts +2 -2
  19. package/dist-module/dataview64.d.ts.map +1 -1
  20. package/dist-module/dataview64.js +4 -4
  21. package/dist-module/geotiff.d.ts +161 -45
  22. package/dist-module/geotiff.d.ts.map +1 -1
  23. package/dist-module/geotiff.js +111 -20
  24. package/dist-module/geotiffimage.d.ts +76 -110
  25. package/dist-module/geotiffimage.d.ts.map +1 -1
  26. package/dist-module/geotiffimage.js +98 -70
  27. package/dist-module/geotiffwriter.js +2 -2
  28. package/dist-module/globals.d.ts +48 -40
  29. package/dist-module/globals.d.ts.map +1 -1
  30. package/dist-module/globals.js +14 -10
  31. package/dist-module/imagefiledirectory.d.ts +2 -2
  32. package/dist-module/imagefiledirectory.d.ts.map +1 -1
  33. package/dist-module/imagefiledirectory.js +23 -12
  34. package/dist-module/logging.js +7 -7
  35. package/dist-module/pool.d.ts +2 -3
  36. package/dist-module/pool.d.ts.map +1 -1
  37. package/dist-module/pool.js +18 -16
  38. package/dist-module/predictor.js +1 -1
  39. package/dist-module/resample.d.ts +18 -18
  40. package/dist-module/resample.d.ts.map +1 -1
  41. package/dist-module/resample.js +12 -12
  42. package/dist-module/source/basesource.d.ts +7 -7
  43. package/dist-module/source/basesource.d.ts.map +1 -1
  44. package/dist-module/source/basesource.js +7 -7
  45. package/dist-module/source/blockedsource.d.ts +10 -10
  46. package/dist-module/source/blockedsource.d.ts.map +1 -1
  47. package/dist-module/source/blockedsource.js +12 -9
  48. package/dist-module/source/client/base.d.ts +8 -10
  49. package/dist-module/source/client/base.d.ts.map +1 -1
  50. package/dist-module/source/client/base.js +4 -3
  51. package/dist-module/source/client/fetch.d.ts +2 -7
  52. package/dist-module/source/client/fetch.d.ts.map +1 -1
  53. package/dist-module/source/client/fetch.js +7 -2
  54. package/dist-module/source/client/http.d.ts +4 -1
  55. package/dist-module/source/client/http.d.ts.map +1 -1
  56. package/dist-module/source/client/http.js +4 -4
  57. package/dist-module/source/client/xhr.d.ts +4 -1
  58. package/dist-module/source/client/xhr.d.ts.map +1 -1
  59. package/dist-module/source/client/xhr.js +1 -1
  60. package/dist-module/source/file.js +4 -4
  61. package/dist-module/source/filereader.js +1 -1
  62. package/dist-module/source/httputils.d.ts +14 -6
  63. package/dist-module/source/httputils.d.ts.map +1 -1
  64. package/dist-module/source/httputils.js +13 -12
  65. package/dist-module/source/remote.d.ts +31 -22
  66. package/dist-module/source/remote.d.ts.map +1 -1
  67. package/dist-module/source/remote.js +37 -13
  68. package/dist-module/utils.d.ts +7 -1
  69. package/dist-module/utils.d.ts.map +1 -1
  70. package/dist-module/utils.js +6 -0
  71. package/dist-module/worker/create.js +1 -1
  72. package/dist-node/compression/basedecoder.d.ts +4 -0
  73. package/dist-node/compression/basedecoder.d.ts.map +1 -1
  74. package/dist-node/compression/basedecoder.js +6 -0
  75. package/dist-node/compression/basedecoder.js.map +1 -1
  76. package/dist-node/compression/index.d.ts +4 -4
  77. package/dist-node/compression/index.d.ts.map +1 -1
  78. package/dist-node/compression/index.js +4 -4
  79. package/dist-node/compression/jpeg.d.ts +6 -1
  80. package/dist-node/compression/jpeg.d.ts.map +1 -1
  81. package/dist-node/compression/jpeg.js +50 -5
  82. package/dist-node/compression/jpeg.js.map +1 -1
  83. package/dist-node/compression/lzw.js +1 -1
  84. package/dist-node/compression/lzw.js.map +1 -1
  85. package/dist-node/compression/webimage.js +1 -1
  86. package/dist-node/compression/webimage.js.map +1 -1
  87. package/dist-node/dataslice.js +2 -2
  88. package/dist-node/dataslice.js.map +1 -1
  89. package/dist-node/dataview64.d.ts +2 -2
  90. package/dist-node/dataview64.d.ts.map +1 -1
  91. package/dist-node/dataview64.js +4 -4
  92. package/dist-node/dataview64.js.map +1 -1
  93. package/dist-node/geotiff.d.ts +161 -45
  94. package/dist-node/geotiff.d.ts.map +1 -1
  95. package/dist-node/geotiff.js +110 -20
  96. package/dist-node/geotiff.js.map +1 -1
  97. package/dist-node/geotiffimage.d.ts +77 -111
  98. package/dist-node/geotiffimage.d.ts.map +1 -1
  99. package/dist-node/geotiffimage.js +98 -70
  100. package/dist-node/geotiffimage.js.map +1 -1
  101. package/dist-node/geotiffwriter.js +2 -2
  102. package/dist-node/geotiffwriter.js.map +1 -1
  103. package/dist-node/globals.d.ts +48 -40
  104. package/dist-node/globals.d.ts.map +1 -1
  105. package/dist-node/globals.js +14 -10
  106. package/dist-node/globals.js.map +1 -1
  107. package/dist-node/imagefiledirectory.d.ts +2 -2
  108. package/dist-node/imagefiledirectory.d.ts.map +1 -1
  109. package/dist-node/imagefiledirectory.js +23 -12
  110. package/dist-node/imagefiledirectory.js.map +1 -1
  111. package/dist-node/logging.js +7 -7
  112. package/dist-node/logging.js.map +1 -1
  113. package/dist-node/pool.d.ts +2 -3
  114. package/dist-node/pool.d.ts.map +1 -1
  115. package/dist-node/pool.js +18 -16
  116. package/dist-node/pool.js.map +1 -1
  117. package/dist-node/predictor.js +1 -1
  118. package/dist-node/predictor.js.map +1 -1
  119. package/dist-node/resample.d.ts +18 -18
  120. package/dist-node/resample.d.ts.map +1 -1
  121. package/dist-node/resample.js +12 -12
  122. package/dist-node/source/basesource.d.ts +7 -7
  123. package/dist-node/source/basesource.d.ts.map +1 -1
  124. package/dist-node/source/basesource.js +7 -7
  125. package/dist-node/source/basesource.js.map +1 -1
  126. package/dist-node/source/blockedsource.d.ts +10 -10
  127. package/dist-node/source/blockedsource.d.ts.map +1 -1
  128. package/dist-node/source/blockedsource.js +12 -9
  129. package/dist-node/source/blockedsource.js.map +1 -1
  130. package/dist-node/source/client/base.d.ts +8 -10
  131. package/dist-node/source/client/base.d.ts.map +1 -1
  132. package/dist-node/source/client/base.js +4 -3
  133. package/dist-node/source/client/base.js.map +1 -1
  134. package/dist-node/source/client/fetch.d.ts +2 -6
  135. package/dist-node/source/client/fetch.d.ts.map +1 -1
  136. package/dist-node/source/client/fetch.js +7 -2
  137. package/dist-node/source/client/fetch.js.map +1 -1
  138. package/dist-node/source/client/http.d.ts +4 -1
  139. package/dist-node/source/client/http.d.ts.map +1 -1
  140. package/dist-node/source/client/http.js +4 -4
  141. package/dist-node/source/client/http.js.map +1 -1
  142. package/dist-node/source/client/xhr.d.ts +4 -1
  143. package/dist-node/source/client/xhr.d.ts.map +1 -1
  144. package/dist-node/source/client/xhr.js +1 -1
  145. package/dist-node/source/client/xhr.js.map +1 -1
  146. package/dist-node/source/file.js +4 -4
  147. package/dist-node/source/file.js.map +1 -1
  148. package/dist-node/source/filereader.js +1 -1
  149. package/dist-node/source/filereader.js.map +1 -1
  150. package/dist-node/source/httputils.d.ts +14 -6
  151. package/dist-node/source/httputils.d.ts.map +1 -1
  152. package/dist-node/source/httputils.js +13 -12
  153. package/dist-node/source/httputils.js.map +1 -1
  154. package/dist-node/source/remote.d.ts +31 -22
  155. package/dist-node/source/remote.d.ts.map +1 -1
  156. package/dist-node/source/remote.js +37 -13
  157. package/dist-node/source/remote.js.map +1 -1
  158. package/dist-node/utils.d.ts +7 -1
  159. package/dist-node/utils.d.ts.map +1 -1
  160. package/dist-node/utils.js +6 -0
  161. package/dist-node/utils.js.map +1 -1
  162. package/dist-node/worker/create.js +1 -1
  163. package/dist-node/worker/create.js.map +1 -1
  164. package/package.json +3 -54
@@ -6,30 +6,10 @@ import { photometricInterpretations, ExtraSamplesValues } from './globals.js';
6
6
  import { fromWhiteIsZero, fromBlackIsZero, fromPalette, fromCMYK, fromYCbCr, fromCIELab } from './rgb.js';
7
7
  import { getDecoder, getDecoderParameters } from './compression/index.js';
8
8
  import { resample, resampleInterleaved } from './resample.js';
9
- /**
10
- * @typedef {Object} ReadRasterOptions
11
- * @property {Array<number>} [window=whole window] the subset to read data from in pixels.
12
- * @property {Array<number>} [bbox=whole image] the subset to read data from in
13
- * geographical coordinates.
14
- * @property {Array<number>} [samples=all samples] the selection of samples to read from. Default is all samples.
15
- * @property {boolean} [interleave=false] whether the data shall be read
16
- * in one single array or separate
17
- * arrays.
18
- * @property {Pool} [pool=null] The optional decoder pool to use.
19
- * @property {number} [width] The desired width of the output. When the width is not the
20
- * same as the images, resampling will be performed.
21
- * @property {number} [height] The desired height of the output. When the width is not the
22
- * same as the images, resampling will be performed.
23
- * @property {string} [resampleMethod='nearest'] The desired resampling method.
24
- * @property {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
25
- * to be aborted
26
- * @property {number|number[]} [fillValue] The value to use for parts of the image
27
- * outside of the images extent. When multiple
28
- * samples are requested, an array of fill values
29
- * can be passed.
30
- */
31
- /** @typedef {import("./geotiff.js").TypedArray} TypedArray */
32
- /** @typedef {import("./geotiff.js").ReadRasterResult} ReadRasterResult */
9
+ /** @import {TypedArray} from "./geotiff" */
10
+ /** @import {ReadRasterResult} from "./geotiff" */
11
+ /** @import {ReadRastersOptions} from "./geotiff" */
12
+ /** @import {ReadRGBOptions} from "./geotiff" */
33
13
  function sum(array, start, end) {
34
14
  let s = 0;
35
15
  for (let i = start; i < end; ++i) {
@@ -170,35 +150,34 @@ function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel,
170
150
  class GeoTIFFImage {
171
151
  /**
172
152
  * @constructor
173
- * @param {import("./imagefiledirectory.js").ImageFileDirectory} fileDirectory The parsed file directory
174
- * @param {DataView} dataView The DataView for the underlying file.
153
+ * @param {import("./imagefiledirectory").ImageFileDirectory} fileDirectory The parsed file directory
175
154
  * @param {Boolean} littleEndian Whether the file is encoded in little or big endian
176
155
  * @param {Boolean} cache Whether or not decoded tiles shall be cached
177
- * @param {import('./source/basesource').BaseSource} source The datasource to read from
156
+ * @param {import('./source/basesource.js').BaseSource} source The datasource to read from
178
157
  */
179
- constructor(fileDirectory, dataView, littleEndian, cache, source) {
158
+ constructor(fileDirectory, littleEndian, cache, source) {
180
159
  this.fileDirectory = fileDirectory;
181
- this.dataView = dataView;
182
160
  this.littleEndian = littleEndian;
183
161
  this.tiles = cache ? {} : null;
184
162
  this.isTiled = !fileDirectory.hasTag('StripOffsets');
185
- const planarConfiguration = fileDirectory.getValue('PlanarConfiguration');
186
- this.planarConfiguration = (typeof planarConfiguration === 'undefined') ? 1 : planarConfiguration;
187
- if (this.planarConfiguration !== 1 && this.planarConfiguration !== 2) {
163
+ const planarConfiguration = fileDirectory.getValue('PlanarConfiguration') ?? 1;
164
+ if (planarConfiguration !== 1 && planarConfiguration !== 2) {
188
165
  throw new Error('Invalid planar configuration.');
189
166
  }
167
+ /** @type {1 | 2} */
168
+ this.planarConfiguration = planarConfiguration;
190
169
  this.source = source;
191
170
  }
192
171
  /**
193
172
  * Returns the associated parsed file directory.
194
- * @returns {import("./imagefiledirectory.js").ImageFileDirectory} the parsed file directory
173
+ * @returns {import("./imagefiledirectory").ImageFileDirectory} the parsed file directory
195
174
  */
196
175
  getFileDirectory() {
197
176
  return this.fileDirectory;
198
177
  }
199
178
  /**
200
179
  * Returns the associated parsed geo keys.
201
- * @returns {Record<import('./globals.js').GeoKeyName, *>|null} the parsed geo keys
180
+ * @returns {Partial<Record<import('./globals.js').GeoKeyName, *>>|null} the parsed geo keys
202
181
  */
203
182
  getGeoKeys() {
204
183
  return this.fileDirectory.parseGeoKeyDirectory();
@@ -355,6 +334,9 @@ class GeoTIFFImage {
355
334
  else if (this.planarConfiguration === 2) {
356
335
  index = (sample * numTilesPerRow * numTilesPerCol) + (y * numTilesPerRow) + x;
357
336
  }
337
+ if (index === undefined) {
338
+ throw new Error('Could not determine tile or strip index.');
339
+ }
358
340
  let offset;
359
341
  let byteCount;
360
342
  if (this.isTiled) {
@@ -404,11 +386,11 @@ class GeoTIFFImage {
404
386
  * @param {Array} imageWindow The image window in pixel coordinates
405
387
  * @param {Array} samples The selected samples (0-based indices)
406
388
  * @param {TypedArray|TypedArray[]} valueArrays The array(s) to write into
407
- * @param {Boolean} interleave Whether or not to write in an interleaved manner
408
- * @param {import("./geotiff").Pool|AbstractDecoder} poolOrDecoder the decoder or decoder pool
409
- * @param {number} width the width of window to be read into
410
- * @param {number} height the height of window to be read into
411
- * @param {number} resampleMethod the resampling method to be used when interpolating
389
+ * @param {boolean|undefined} interleave Whether or not to write in an interleaved manner
390
+ * @param {import("./geotiff").Pool|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
391
+ * @param {number} [width] the width of window to be read into
392
+ * @param {number} [height] the height of window to be read into
393
+ * @param {string} [resampleMethod] the resampling method to be used when interpolating
412
394
  * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
413
395
  * to be aborted
414
396
  * @returns {Promise<ReadRasterResult>}
@@ -450,6 +432,9 @@ class GeoTIFFImage {
450
432
  bytesPerPixel = this.getSampleByteSize(sample);
451
433
  getPromise = this.getTileOrStrip(xTile, yTile, sample, poolOrDecoder, signal);
452
434
  }
435
+ if (!getPromise) {
436
+ throw new Error('Could not get tile or strip data.');
437
+ }
453
438
  const promise = getPromise.then((tile) => {
454
439
  const buffer = tile.data;
455
440
  const dataView = new DataView(buffer);
@@ -488,29 +473,57 @@ class GeoTIFFImage {
488
473
  || (height && (imageWindow[3] - imageWindow[1]) !== height)) {
489
474
  let resampled;
490
475
  if (interleave) {
491
- resampled = resampleInterleaved(valueArrays, imageWindow[2] - imageWindow[0], imageWindow[3] - imageWindow[1], width, height, samples.length, resampleMethod);
476
+ resampled = resampleInterleaved(
477
+ /** @type {TypedArray} */ (valueArrays), imageWindow[2] - imageWindow[0], imageWindow[3] - imageWindow[1],
478
+ /** @type {number} */ (width), /** @type {number} */ (height), samples.length, resampleMethod);
492
479
  }
493
480
  else {
494
- resampled = resample(valueArrays, imageWindow[2] - imageWindow[0], imageWindow[3] - imageWindow[1], width, height, resampleMethod);
481
+ resampled = resample(
482
+ /** @type {TypedArray[]} */ (valueArrays), imageWindow[2] - imageWindow[0], imageWindow[3] - imageWindow[1],
483
+ /** @type {number} */ (width), /** @type {number} */ (height), resampleMethod);
495
484
  }
496
- resampled.width = width;
497
- resampled.height = height;
498
- return resampled;
485
+ const resampledWithDimensions = /** @type {ReadRasterResult} */ (resampled);
486
+ resampledWithDimensions.width = width ?? imageWindow[2] - imageWindow[0];
487
+ resampledWithDimensions.height = height ?? imageWindow[3] - imageWindow[1];
488
+ return resampledWithDimensions;
499
489
  }
500
- valueArrays.width = width || imageWindow[2] - imageWindow[0];
501
- valueArrays.height = height || imageWindow[3] - imageWindow[1];
502
- return valueArrays;
490
+ const valueArraysWithDimensions = /** @type {ReadRasterResult} */ (valueArrays);
491
+ valueArraysWithDimensions.width = width || imageWindow[2] - imageWindow[0];
492
+ valueArraysWithDimensions.height = height || imageWindow[3] - imageWindow[1];
493
+ return valueArraysWithDimensions;
503
494
  }
495
+ /**
496
+ * @overload
497
+ * @param {ReadRastersOptions & {interleave: true}} options optional parameters
498
+ * @returns {Promise<import("./geotiff").TypedArrayWithDimensions>} the decoded arrays as a promise
499
+ */
500
+ /**
501
+ * @overload
502
+ * @param {ReadRastersOptions & {interleave: false}} options optional parameters
503
+ * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
504
+ */
505
+ /**
506
+ * @overload
507
+ * @param {ReadRastersOptions & {interleave: boolean}} options optional parameters
508
+ * @returns {Promise<ReadRasterResult>} the decoded arrays as a promise
509
+ */
510
+ /**
511
+ * @overload
512
+ * @param {ReadRastersOptions} [options={}] optional parameters
513
+ * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
514
+ */
504
515
  /**
505
516
  * Reads raster data from the image. This function reads all selected samples
506
517
  * into separate arrays of the correct type for that sample or into a single
507
518
  * combined array when `interleave` is set. When provided, only a subset
508
519
  * of the raster is read for each sample.
509
520
  *
510
- * @param {ReadRasterOptions} [options={}] optional parameters
521
+ * @param {ReadRastersOptions} [options={}] optional parameters
511
522
  * @returns {Promise<ReadRasterResult>} the decoded arrays as a promise
512
523
  */
513
- async readRasters({ window: wnd, samples = [], interleave, pool = null, width, height, resampleMethod, fillValue, signal, } = {}) {
524
+ async readRasters(options = {}) {
525
+ const { window: wnd, samples = [], pool = null, width, height, resampleMethod, fillValue, signal, } = options;
526
+ const interleave = 'interleave' in options && options.interleave;
514
527
  const imageWindow = wnd || [0, 0, this.getWidth(), this.getHeight()];
515
528
  // check parameters
516
529
  if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
@@ -532,6 +545,7 @@ class GeoTIFFImage {
532
545
  }
533
546
  }
534
547
  }
548
+ /** @type {TypedArray|TypedArray[]} */
535
549
  let valueArrays;
536
550
  if (interleave) {
537
551
  const format = this.fileDirectory.hasTag('SampleFormat')
@@ -539,6 +553,9 @@ class GeoTIFFImage {
539
553
  const bitsPerSample = Math.max.apply(null, this.fileDirectory.getValue('BitsPerSample'));
540
554
  valueArrays = arrayForType(format, bitsPerSample, numPixels * samples.length);
541
555
  if (fillValue) {
556
+ if (Array.isArray(fillValue)) {
557
+ throw new Error('When reading interleaved data, fillValue must be a single number.');
558
+ }
542
559
  valueArrays.fill(fillValue);
543
560
  }
544
561
  }
@@ -563,6 +580,26 @@ class GeoTIFFImage {
563
580
  const result = await this._readRaster(imageWindow, samples, valueArrays, interleave, poolOrDecoder, width, height, resampleMethod, signal);
564
581
  return result;
565
582
  }
583
+ /**
584
+ * @overload
585
+ * @param {ReadRGBOptions & {interleave: true}} options optional parameters
586
+ * @returns {Promise<import("./geotiff").TypedArrayWithDimensions>} the RGB array as a Promise
587
+ */
588
+ /**
589
+ * @overload
590
+ * @param {ReadRGBOptions & {interleave: false}} options optional parameters
591
+ * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the RGB array as a Promise
592
+ */
593
+ /**
594
+ * @overload
595
+ * @param {ReadRGBOptions & {interleave: boolean}} options optional parameters
596
+ * @returns {Promise<ReadRasterResult>} the RGB array as a Promise
597
+ */
598
+ /**
599
+ * @overload
600
+ * @param {ReadRGBOptions} [options={}] optional parameters
601
+ * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the RGB array as a Promise
602
+ */
566
603
  /**
567
604
  * Reads raster data from the image as RGB.
568
605
  * Colorspaces other than RGB will be transformed to RGB, color maps expanded.
@@ -570,23 +607,12 @@ class GeoTIFFImage {
570
607
  * grayscale image.
571
608
  * When provided, only a subset of the raster is read for each sample.
572
609
  *
573
- * @param {Object} [options] optional parameters
574
- * @param {Array<number>} [options.window] the subset to read data from in pixels.
575
- * @param {boolean} [options.interleave=true] whether the data shall be read
576
- * in one single array or separate
577
- * arrays.
578
- * @param {import("./geotiff").Pool} [options.pool=null] The optional decoder pool to use.
579
- * @param {number} [options.width] The desired width of the output. When the width is no the
580
- * same as the images, resampling will be performed.
581
- * @param {number} [options.height] The desired height of the output. When the width is no the
582
- * same as the images, resampling will be performed.
583
- * @param {string} [options.resampleMethod='nearest'] The desired resampling method.
584
- * @param {boolean} [options.enableAlpha=false] Enable reading alpha channel if present.
585
- * @param {AbortSignal} [options.signal] An AbortSignal that may be signalled if the request is
586
- * to be aborted
610
+ * @param {ReadRGBOptions} [options] optional parameters
587
611
  * @returns {Promise<ReadRasterResult>} the RGB array as a Promise
588
612
  */
589
- async readRGB({ window, interleave = true, pool = null, width, height, resampleMethod, enableAlpha = false, signal } = {}) {
613
+ async readRGB(options = {}) {
614
+ const { window, pool = null, width, height, resampleMethod, enableAlpha = false, signal } = options;
615
+ const interleave = ('interleave' in options && options.interleave) ?? false;
590
616
  const imageWindow = window || [0, 0, this.getWidth(), this.getHeight()];
591
617
  // check parameters
592
618
  if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
@@ -631,6 +657,7 @@ class GeoTIFFImage {
631
657
  }
632
658
  const subOptions = {
633
659
  window: imageWindow,
660
+ /** @type {true} */
634
661
  interleave: true,
635
662
  samples,
636
663
  pool,
@@ -678,9 +705,10 @@ class GeoTIFFImage {
678
705
  }
679
706
  data = [red, green, blue];
680
707
  }
681
- data.width = raster.width;
682
- data.height = raster.height;
683
- return data;
708
+ const dataWithDimensions = /** @type {import("./geotiff").ReadRasterResult} */ (data);
709
+ dataWithDimensions.width = raster.width;
710
+ dataWithDimensions.height = raster.height;
711
+ return dataWithDimensions;
684
712
  }
685
713
  /**
686
714
  * Returns an array of tiepoints.
@@ -710,7 +738,7 @@ class GeoTIFFImage {
710
738
  * If sample is passed to null, dataset-level metadata will be returned.
711
739
  * Otherwise only metadata specific to the provided sample will be returned.
712
740
  *
713
- * @param {number} [sample=null] The sample index.
741
+ * @param {number|null} [sample=null] The sample index.
714
742
  * @returns {Promise<Object>}
715
743
  */
716
744
  async getGDALMetadata(sample = null) {
@@ -770,7 +798,7 @@ class GeoTIFFImage {
770
798
  /**
771
799
  * Returns the image resolution as a XYZ-vector. When the image has no affine
772
800
  * transformation, then an exception is thrown.
773
- * @param {GeoTIFFImage} [referenceImage=null] A reference image to calculate the resolution from
801
+ * @param {GeoTIFFImage|null} [referenceImage=null] A reference image to calculate the resolution from
774
802
  * in cases when the current image does not have the
775
803
  * required tags on its own.
776
804
  * @returns {Array<number>} The resolution as a vector
@@ -816,7 +844,7 @@ class GeoTIFFImage {
816
844
  * @returns {Boolean} Whether the pixels are a point
817
845
  */
818
846
  pixelIsArea() {
819
- return this.geoKeys.GTRasterTypeGeoKey === 1;
847
+ return this.getGeoKeys()?.GTRasterTypeGeoKey === 1;
820
848
  }
821
849
  /**
822
850
  * Returns the image bounding box as an array of 4 values: min-x, min-y,
@@ -315,7 +315,7 @@ export function writeGeotiff(data, metadata) {
315
315
  if (!metadata.BitsPerSample) {
316
316
  let bitsPerSample = 8;
317
317
  if (ArrayBuffer.isView(flattenedValues)) {
318
- bitsPerSample = 8 * flattenedValues.BYTES_PER_ELEMENT;
318
+ bitsPerSample = 8 * Object.getPrototypeOf(flattenedValues).BYTES_PER_ELEMENT;
319
319
  }
320
320
  metadata.BitsPerSample = times(numBands, () => bitsPerSample);
321
321
  }
@@ -340,7 +340,7 @@ export function writeGeotiff(data, metadata) {
340
340
  // default for Float64
341
341
  let elementSize = 8;
342
342
  if (ArrayBuffer.isView(flattenedValues)) {
343
- elementSize = flattenedValues.BYTES_PER_ELEMENT;
343
+ elementSize = Object.getPrototypeOf(flattenedValues).BYTES_PER_ELEMENT;
344
344
  }
345
345
  metadata.StripByteCounts = [numBands * elementSize * height * width];
346
346
  }
@@ -1,63 +1,67 @@
1
+ /** @typedef {fieldTypeSizes[keyof typeof fieldTypeSizes]} FieldTypeSize */
1
2
  /**
2
3
  * Get the byte size for a given field type.
3
- * @param {number} fieldType The TIFF field type constant
4
+ * @param {FieldType} fieldType The TIFF field type constant
4
5
  * @returns {number} The size in bytes
5
6
  * @throws {RangeError} If the field type is invalid
6
7
  */
7
- export function getFieldTypeSize(fieldType: number): number;
8
+ export function getFieldTypeSize(fieldType: FieldType): number;
8
9
  /**
9
10
  * Registers a new field tag
10
11
  * @param {number} tag the numeric tiff tag
11
12
  * @param {string} name the name of the tag that will be reported in the IFD
12
- * @param {string|number} type the tags data type
13
+ * @param {string|number|undefined} type the tags data type
13
14
  * @param {Boolean} isArray whether the tag is an array
14
15
  * @param {boolean} [eager=false] whether to eagerly fetch deferred fields.
15
16
  * When false (default), tags are loaded lazily on-demand.
16
17
  * When true, all tags are loaded immediately during parsing.
17
18
  */
18
- export function registerTag(tag: number, name: string, type?: string | number, isArray?: boolean, eager?: boolean): void;
19
+ export function registerTag(tag: number, name: string, type: string | number | undefined, isArray?: boolean, eager?: boolean): void;
19
20
  /**
20
21
  * @param {number|string} tagIdentifier The field tag ID or name
21
22
  * @returns {number} the resolved tag ID
22
23
  */
23
24
  export function resolveTag(tagIdentifier: number | string): number;
24
25
  export function getTag(tagIdentifier: any): any;
25
- export namespace fieldTypes {
26
- let BYTE: number;
27
- let ASCII: number;
28
- let SHORT: number;
29
- let LONG: number;
30
- let RATIONAL: number;
31
- let SBYTE: number;
32
- let UNDEFINED: number;
33
- let SSHORT: number;
34
- let SLONG: number;
35
- let SRATIONAL: number;
36
- let FLOAT: number;
37
- let DOUBLE: number;
38
- let IFD: number;
39
- let LONG8: number;
40
- let SLONG8: number;
41
- let IFD8: number;
42
- }
43
- export const fieldTypeSizes: {
44
- [fieldTypes.BYTE]: number;
45
- [fieldTypes.ASCII]: number;
46
- [fieldTypes.SBYTE]: number;
47
- [fieldTypes.UNDEFINED]: number;
48
- [fieldTypes.SHORT]: number;
49
- [fieldTypes.SSHORT]: number;
50
- [fieldTypes.LONG]: number;
51
- [fieldTypes.SLONG]: number;
52
- [fieldTypes.FLOAT]: number;
53
- [fieldTypes.IFD]: number;
54
- [fieldTypes.RATIONAL]: number;
55
- [fieldTypes.SRATIONAL]: number;
56
- [fieldTypes.DOUBLE]: number;
57
- [fieldTypes.LONG8]: number;
58
- [fieldTypes.SLONG8]: number;
59
- [fieldTypes.IFD8]: number;
60
- };
26
+ export const fieldTypes: Readonly<{
27
+ BYTE: 1;
28
+ ASCII: 2;
29
+ SHORT: 3;
30
+ LONG: 4;
31
+ RATIONAL: 5;
32
+ SBYTE: 6;
33
+ UNDEFINED: 7;
34
+ SSHORT: 8;
35
+ SLONG: 9;
36
+ SRATIONAL: 10;
37
+ FLOAT: 11;
38
+ DOUBLE: 12;
39
+ IFD: 13;
40
+ LONG8: 16;
41
+ SLONG8: 17;
42
+ IFD8: 18;
43
+ }>;
44
+ /** @typedef {keyof fieldTypes} FieldTypeName */
45
+ /** @typedef {fieldTypes[keyof typeof fieldTypes]} FieldType */
46
+ /** @typedef {Record<FieldTypeName, number>} FieldTypeSizes */
47
+ export const fieldTypeSizes: Readonly<{
48
+ 1: 1;
49
+ 2: 1;
50
+ 6: 1;
51
+ 7: 1;
52
+ 3: 2;
53
+ 8: 2;
54
+ 4: 4;
55
+ 9: 4;
56
+ 11: 4;
57
+ 13: 4;
58
+ 5: 8;
59
+ 10: 8;
60
+ 12: 8;
61
+ 16: 8;
62
+ 17: 8;
63
+ 18: 8;
64
+ }>;
61
65
  /**
62
66
  * Maps tag names to their numeric values
63
67
  */
@@ -199,5 +203,9 @@ export const geoKeyNames: Readonly<{
199
203
  * @type {Record<GeoKeyName, number>}
200
204
  */
201
205
  export const geoKeys: Record<GeoKeyName, number>;
206
+ export type FieldTypeSize = 1 | 2 | 4 | 8;
207
+ export type FieldTypeName = "BYTE" | "ASCII" | "SHORT" | "LONG" | "RATIONAL" | "SBYTE" | "UNDEFINED" | "SSHORT" | "SLONG" | "SRATIONAL" | "FLOAT" | "DOUBLE" | "IFD" | "LONG8" | "SLONG8" | "IFD8";
208
+ export type FieldType = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18;
209
+ export type FieldTypeSizes = Record<FieldTypeName, number>;
202
210
  export type GeoKeyName = "GTModelTypeGeoKey" | "GTRasterTypeGeoKey" | "GTCitationGeoKey" | "GeographicTypeGeoKey" | "GeogCitationGeoKey" | "GeogGeodeticDatumGeoKey" | "GeogPrimeMeridianGeoKey" | "GeogLinearUnitsGeoKey" | "GeogLinearUnitSizeGeoKey" | "GeogAngularUnitsGeoKey" | "GeogAngularUnitSizeGeoKey" | "GeogEllipsoidGeoKey" | "GeogSemiMajorAxisGeoKey" | "GeogSemiMinorAxisGeoKey" | "GeogInvFlatteningGeoKey" | "GeogAzimuthUnitsGeoKey" | "GeogPrimeMeridianLongGeoKey" | "GeogTOWGS84GeoKey" | "ProjectedCSTypeGeoKey" | "PCSCitationGeoKey" | "ProjectionGeoKey" | "ProjCoordTransGeoKey" | "ProjLinearUnitsGeoKey" | "ProjLinearUnitSizeGeoKey" | "ProjStdParallel1GeoKey" | "ProjStdParallel2GeoKey" | "ProjNatOriginLongGeoKey" | "ProjNatOriginLatGeoKey" | "ProjFalseEastingGeoKey" | "ProjFalseNorthingGeoKey" | "ProjFalseOriginLongGeoKey" | "ProjFalseOriginLatGeoKey" | "ProjFalseOriginEastingGeoKey" | "ProjFalseOriginNorthingGeoKey" | "ProjCenterLongGeoKey" | "ProjCenterLatGeoKey" | "ProjCenterEastingGeoKey" | "ProjCenterNorthingGeoKey" | "ProjScaleAtNatOriginGeoKey" | "ProjScaleAtCenterGeoKey" | "ProjAzimuthAngleGeoKey" | "ProjStraightVertPoleLongGeoKey" | "ProjRectifiedGridAngleGeoKey" | "VerticalCSTypeGeoKey" | "VerticalCitationGeoKey" | "VerticalDatumGeoKey" | "VerticalUnitsGeoKey";
203
211
  //# sourceMappingURL=globals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.js"],"names":[],"mappings":"AAwCA;;;;;GAKG;AACH,4CAJW,MAAM,GACJ,MAAM,CASlB;AA+ND;;;;;;;;;GASG;AACH,iCARW,MAAM,QACN,MAAM,SACN,MAAM,GAAC,MAAM,6BAEb,OAAO,QAajB;AAMD;;;GAGG;AACH,0CAHW,MAAM,GAAC,MAAM,GACX,MAAM,CAOlB;AAED,gDAEC;;;;;;;;;;;;;;;;;;;AApSD;IACE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAG;IACpB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAG;IACrB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAG;IACrB,CAAC,UAAU,CAAC,SAAS,CAAC,SAAG;IACzB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAG;IACrB,CAAC,UAAU,CAAC,MAAM,CAAC,SAAG;IACtB,CAAC,UAAU,CAAC,IAAI,CAAC,SAAG;IACpB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAG;IACrB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAG;IACrB,CAAC,UAAU,CAAC,GAAG,CAAC,SAAG;IACnB,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAG;IACxB,CAAC,UAAU,CAAC,SAAS,CAAC,SAAG;IACzB,CAAC,UAAU,CAAC,MAAM,CAAC,SAAG;IACtB,CAAC,UAAU,CAAC,KAAK,CAAC,SAAG;IACrB,CAAC,UAAU,CAAC,MAAM,CAAC,SAAG;IACtB,CAAC,UAAU,CAAC,IAAI,CAAC,SAAG;EACpB;AAmOF;;GAEG;AACH,sBAAuB;AAEvB;;GAEG;AACH,gCAAiC;AA0CjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDE;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,kEAAkE;AAElE;;GAEG;AACH,sBAFU,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAEV"}
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.js"],"names":[],"mappings":"AA6CA,2EAA2E;AAE3E;;;;;GAKG;AACH,4CAJW,SAAS,GACP,MAAM,CASlB;AA+ND;;;;;;;;;GASG;AACH,iCARW,MAAM,QACN,MAAM,QACN,MAAM,GAAC,MAAM,GAAC,SAAS,6BAEvB,OAAO,QAajB;AAMD;;;GAGG;AACH,0CAHW,MAAM,GAAC,MAAM,GACX,MAAM,CAOlB;AAED,gDAEC;AAhUD;;;;;;;;;;;;;;;;;GAmBG;AAEH,gDAAgD;AAEhD,+DAA+D;AAE/D,8DAA8D;AAC9D;;;;;;;;;;;;;;;;;GAiBG;AAqOH;;GAEG;AACH,sBAAuB;AAEvB;;GAEG;AACH,gCAAiC;AA0CjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqDE;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,kEAAkE;AAElE;;GAEG;AACH,sBAFU,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAEkC;;;;6BArbxD,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC"}
@@ -1,4 +1,4 @@
1
- export const fieldTypes = {
1
+ export const fieldTypes = Object.freeze({
2
2
  BYTE: 0x0001,
3
3
  ASCII: 0x0002,
4
4
  SHORT: 0x0003,
@@ -17,8 +17,11 @@ export const fieldTypes = {
17
17
  LONG8: 0x0010,
18
18
  SLONG8: 0x0011,
19
19
  IFD8: 0x0012,
20
- };
21
- export const fieldTypeSizes = {
20
+ });
21
+ /** @typedef {keyof fieldTypes} FieldTypeName */
22
+ /** @typedef {fieldTypes[keyof typeof fieldTypes]} FieldType */
23
+ /** @typedef {Record<FieldTypeName, number>} FieldTypeSizes */
24
+ export const fieldTypeSizes = Object.freeze({
22
25
  [fieldTypes.BYTE]: 1,
23
26
  [fieldTypes.ASCII]: 1,
24
27
  [fieldTypes.SBYTE]: 1,
@@ -35,10 +38,11 @@ export const fieldTypeSizes = {
35
38
  [fieldTypes.LONG8]: 8,
36
39
  [fieldTypes.SLONG8]: 8,
37
40
  [fieldTypes.IFD8]: 8,
38
- };
41
+ });
42
+ /** @typedef {fieldTypeSizes[keyof typeof fieldTypeSizes]} FieldTypeSize */
39
43
  /**
40
44
  * Get the byte size for a given field type.
41
- * @param {number} fieldType The TIFF field type constant
45
+ * @param {FieldType} fieldType The TIFF field type constant
42
46
  * @returns {number} The size in bytes
43
47
  * @throws {RangeError} If the field type is invalid
44
48
  */
@@ -129,8 +133,8 @@ const tagSource = [
129
133
  isArray: true,
130
134
  eager: true,
131
135
  },
132
- { tag: 340, name: 'SMinSampleValue', type: fieldTypes.Any, isArray: true },
133
- { tag: 341, name: 'SMaxSampleValue', type: fieldTypes.Any, isArray: true },
136
+ { tag: 340, name: 'SMinSampleValue', isArray: true },
137
+ { tag: 341, name: 'SMaxSampleValue', isArray: true },
134
138
  { tag: 342, name: 'TransferRange', type: fieldTypes.SHORT, isArray: true },
135
139
  { tag: 512, name: 'JPEGProc', type: fieldTypes.SHORT },
136
140
  { tag: 513, name: 'JPEGInterchangeFormat', type: fieldTypes.LONG },
@@ -261,13 +265,13 @@ export const tagDefinitions = {};
261
265
  * Registers a new field tag
262
266
  * @param {number} tag the numeric tiff tag
263
267
  * @param {string} name the name of the tag that will be reported in the IFD
264
- * @param {string|number} type the tags data type
268
+ * @param {string|number|undefined} type the tags data type
265
269
  * @param {Boolean} isArray whether the tag is an array
266
270
  * @param {boolean} [eager=false] whether to eagerly fetch deferred fields.
267
271
  * When false (default), tags are loaded lazily on-demand.
268
272
  * When true, all tags are loaded immediately during parsing.
269
273
  */
270
- export function registerTag(tag, name, type = undefined, isArray = false, eager = false) {
274
+ export function registerTag(tag, name, type, isArray = false, eager = false) {
271
275
  tags[name] = tag;
272
276
  tagDefinitions[tag] = { tag, name, type: typeof type === 'string' ? fieldTypes[type] : type, isArray, eager };
273
277
  }
@@ -419,7 +423,7 @@ export const geoKeyNames = Object.freeze({
419
423
  /**
420
424
  * @type {Record<GeoKeyName, number>}
421
425
  */
422
- export const geoKeys = {};
426
+ export const geoKeys = /** @type {Record<GeoKeyName, number>} */ ({});
423
427
  for (const key in geoKeyNames) {
424
428
  if (geoKeyNames.hasOwnProperty(key)) {
425
429
  geoKeys[geoKeyNames[key]] = parseInt(key, 10);
@@ -41,11 +41,11 @@ export class ImageFileDirectory {
41
41
  * Parses the GeoTIFF GeoKeyDirectory tag into a structured object.
42
42
  * The GeoKeyDirectory is a special TIFF tag that contains geographic metadata
43
43
  * in a key-value format as defined by the GeoTIFF specification.
44
- * @returns {Record<import('./globals.js').GeoKeyName, *>|null} Parsed geo key directory
44
+ * @returns {Partial<Record<import('./globals.js').GeoKeyName, *>>|null} Parsed geo key directory
45
45
  * mapping key names to values, or null if not present
46
46
  * @throws {Error} If a referenced geo key value cannot be retrieved
47
47
  */
48
- parseGeoKeyDirectory(): Record<import("./globals.js").GeoKeyName, any> | null;
48
+ parseGeoKeyDirectory(): Partial<Record<import("./globals.js").GeoKeyName, any>> | null;
49
49
  toObject(): {};
50
50
  }
51
51
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"imagefiledirectory.d.ts","sourceRoot":"","sources":["../src/imagefiledirectory.js"],"names":[],"mappings":"AA6PA;IACE;;;;;;OAMG;IACH,8HAFW,MAAM,EAQhB;IALC,gCAAwC;IACxC,8BAAoC;IACpC,2CAA4C;IAC5C,8BAAoC;IACpC,0BAA0C;IAG5C;;;OAGG;IACH,sBAHW,MAAM,GAAC,MAAM,GACX,OAAO,CAKnB;IAED;;;;;OAKG;IACH,wBAJW,MAAM,GAAC,MAAM,OAoBvB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GAAC,MAAM,gBAmCvB;IAED;;;;;OAKG;IACH,gCAJW,MAAM,GAAC,MAAM,SACb,MAAM,gBAehB;IAED;;;;;;;OAOG;IACH,wBAJa,MAAM,CAAC,OAAO,cAAc,EAAE,UAAU,EAAE,GAAC,CAAC,GAAC,IAAI,CAqC7D;IAED,eAQC;CACF;AAED;;GAEG;AACH;IACE;;;;;;;OAOG;IACH,oBAPW,OAAO,wBAAwB,EAAE,UAAU,gBAC3C,OAAO,WACP,OAAO,UACP,OAAO,EASjB;IAJC,oDAAoB;IACpB,sBAAgC;IAChC,iBAAsB;IACtB,eAAkB;IAGpB;;;;;OAKG;IACH,iBAJW,MAAM,WACN,MAAM,GACJ,OAAO,CAAC,SAAS,CAAC,CAiB9B;IAED;;;;;;;OAOG;IACH,6BAHW,MAAM,GACJ,OAAO,CAAC,kBAAkB,CAAC,CA+HvC;CACF;sBA/kBqB,gBAAgB"}
1
+ {"version":3,"file":"imagefiledirectory.d.ts","sourceRoot":"","sources":["../src/imagefiledirectory.js"],"names":[],"mappings":"AAyQA;IACE;;;;;;OAMG;IACH,8HAFW,MAAM,EAQhB;IALC,gCAAwC;IACxC,8BAAoC;IACpC,2CAA4C;IAC5C,8BAAoC;IACpC,0BAA0C;IAG5C;;;OAGG;IACH,sBAHW,MAAM,GAAC,MAAM,GACX,OAAO,CAKnB;IAED;;;;;OAKG;IACH,wBAJW,MAAM,GAAC,MAAM,OAoBvB;IAED;;;;OAIG;IACH,yBAHW,MAAM,GAAC,MAAM,gBAmCvB;IAED;;;;;OAKG;IACH,gCAJW,MAAM,GAAC,MAAM,SACb,MAAM,gBAehB;IAED;;;;;;;OAOG;IACH,wBAJa,OAAO,CAAC,MAAM,CAAC,OAAO,cAAc,EAAE,UAAU,EAAE,GAAC,CAAC,CAAC,GAAC,IAAI,CAqCtE;IAED,eAQC;CACF;AAED;;GAEG;AACH;IACE;;;;;;;OAOG;IACH,oBAPW,OAAO,wBAAwB,EAAE,UAAU,gBAC3C,OAAO,WACP,OAAO,UACP,OAAO,EASjB;IAJC,oDAAoB;IACpB,sBAAgC;IAChC,iBAAsB;IACtB,eAAkB;IAGpB;;;;;OAKG;IACH,iBAJW,MAAM,WACN,MAAM,GACJ,OAAO,CAAC,SAAS,CAAC,CAiB9B;IAED;;;;;;;OAOG;IACH,6BAHW,MAAM,GACJ,OAAO,CAAC,kBAAkB,CAAC,CA+HvC;CACF;sBA3lBqB,gBAAgB"}
@@ -4,7 +4,7 @@ import { fieldTypes, geoKeyNames, tagDefinitions, resolveTag, getFieldTypeSize,
4
4
  * Allocates an appropriate TypedArray based on the TIFF field type.
5
5
  * @param {number} fieldType - TIFF field type constant from fieldTypes
6
6
  * @param {number} count - Number of elements to allocate
7
- * @returns {TypedArray} The allocated typed array for the given field type
7
+ * @returns {import('./geotiff.js').TypedArray|Array<number>} The allocated typed array for the given field type
8
8
  * @throws {RangeError} If the field type is invalid
9
9
  */
10
10
  function getArrayForSamples(fieldType, count) {
@@ -83,17 +83,28 @@ function getDataSliceReader(dataSlice, fieldType) {
83
83
  }
84
84
  }
85
85
  /**
86
- * Reads field values from a DataSlice.
87
- * @param {TypedArray|null} outValues - Optional pre-allocated output array
86
+ * @overload
87
+ * @param {import('./geotiff.js').TypedArray|Array<number>|null} outValues - Optional pre-allocated output array
88
88
  * @param {Function} readMethod - DataView read method (e.g., getUint16)
89
89
  * @param {DataSlice} dataSlice - Source data slice
90
90
  * @param {number} fieldType - TIFF field type constant
91
91
  * @param {number} count - Number of values to read
92
92
  * @param {number} offset - Byte offset to start reading
93
- * @param {boolean} isArray - Whether to always return an array (vs single value)
94
- * @returns {TypedArray|string|number} The decoded value(s)
93
+ * @param {true} isArray - Whether to always return an array (vs single value)
94
+ * @returns {import('./geotiff.js').TypedArray|Array<number>} The decoded value(s)
95
+ */
96
+ /**
97
+ * Reads field values from a DataSlice.
98
+ * @param {import('./geotiff.js').TypedArray|Array<number>|null} outValues - Optional pre-allocated output array
99
+ * @param {Function} readMethod - DataView read method (e.g., getUint16)
100
+ * @param {DataSlice} dataSlice - Source data slice
101
+ * @param {import('./globals.js').FieldType} fieldType - TIFF field type constant
102
+ * @param {number} count - Number of values to read
103
+ * @param {number} offset - Byte offset to start reading
104
+ * @param {boolean} [isArray] - Whether to always return an array (vs single value)
105
+ * @returns {import('./geotiff.js').TypedArray|Array<number>|string|number} The decoded value(s)
95
106
  */
96
- function getValues(outValues = null, readMethod, dataSlice, fieldType, count, offset, isArray) {
107
+ function getValues(outValues = null, readMethod, dataSlice, fieldType, count, offset, isArray = false) {
97
108
  const fieldTypeLength = getFieldTypeSize(fieldType);
98
109
  const values = outValues || getArrayForSamples(fieldType, count);
99
110
  // const readMethod = getDataSliceReader(dataSlice, fieldType);
@@ -112,7 +123,7 @@ function getValues(outValues = null, readMethod, dataSlice, fieldType, count, of
112
123
  }
113
124
  }
114
125
  if (fieldType === fieldTypes.ASCII) {
115
- return new TextDecoder('utf-8').decode(values);
126
+ return new TextDecoder('utf-8').decode(/** @type {Uint8Array} */ (values));
116
127
  }
117
128
  if (count === 1 && !isArray && !isRational) {
118
129
  return values[0];
@@ -130,7 +141,7 @@ class DeferredArray {
130
141
  * @param {import("./source/basesource.js").BaseSource} source - Data source for fetching
131
142
  * @param {number} arrayOffset - Byte offset where the array data starts
132
143
  * @param {boolean} littleEndian - Endianness of the data
133
- * @param {number} fieldType - TIFF field type constant
144
+ * @param {import('./globals.js').FieldType} fieldType - TIFF field type constant
134
145
  * @param {number} length - Number of elements in the array
135
146
  */
136
147
  constructor(source, arrayOffset, littleEndian, fieldType, length) {
@@ -148,7 +159,7 @@ class DeferredArray {
148
159
  /**
149
160
  * Loads all values in the deferred array at once.
150
161
  * Subsequent calls return the same promise to avoid redundant fetches.
151
- * @returns {Promise<TypedArray>} Promise resolving to the fully loaded array
162
+ * @returns {Promise<import('./geotiff.js').TypedArray|Array<number>>} Promise resolving to the fully loaded array
152
163
  */
153
164
  async loadAll() {
154
165
  if (!this.fullFetchPromise) {
@@ -305,7 +316,7 @@ export class ImageFileDirectory {
305
316
  * Parses the GeoTIFF GeoKeyDirectory tag into a structured object.
306
317
  * The GeoKeyDirectory is a special TIFF tag that contains geographic metadata
307
318
  * in a key-value format as defined by the GeoTIFF specification.
308
- * @returns {Record<import('./globals.js').GeoKeyName, *>|null} Parsed geo key directory
319
+ * @returns {Partial<Record<import('./globals.js').GeoKeyName, *>>|null} Parsed geo key directory
309
320
  * mapping key names to values, or null if not present
310
321
  * @throws {Error} If a referenced geo key value cannot be retrieved
311
322
  */
@@ -314,7 +325,7 @@ export class ImageFileDirectory {
314
325
  if (!rawGeoKeyDirectory) {
315
326
  return null;
316
327
  }
317
- /** @type {Record<import('./globals.js').GeoKeyName, *>} */
328
+ /** @type {Partial<Record<import('./globals.js').GeoKeyName, *>>} */
318
329
  const geoKeyDirectory = {};
319
330
  for (let i = 4; i <= rawGeoKeyDirectory[3] * 4; i += 4) {
320
331
  const key = geoKeyNames[rawGeoKeyDirectory[i]];
@@ -415,7 +426,7 @@ export class ImageFileDirectoryParser {
415
426
  let i = offset + (this.bigTiff ? 8 : 2);
416
427
  for (let entryCount = 0; entryCount < numDirEntries; i += entrySize, ++entryCount) {
417
428
  const fieldTag = dataSlice.readUint16(i);
418
- const fieldType = dataSlice.readUint16(i + 2);
429
+ const fieldType = /** @type {import('./globals.js').FieldType} */ (dataSlice.readUint16(i + 2));
419
430
  const typeCount = this.bigTiff
420
431
  ? dataSlice.readUint64(i + 4)
421
432
  : dataSlice.readUint32(i + 4);