@gisatcz/deckgl-geolib 2.4.0-dev.2 → 2.4.0-dev.5

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.
package/dist/esm/index.js CHANGED
@@ -445,30 +445,31 @@ function findTagsByName(xml, tagName, options) {
445
445
  return tags;
446
446
  }
447
447
 
448
- const fieldTypes = Object.freeze({
449
- BYTE: 0x0001,
450
- ASCII: 0x0002,
451
- SHORT: 0x0003,
452
- LONG: 0x0004,
453
- RATIONAL: 0x0005,
454
- SBYTE: 0x0006,
455
- UNDEFINED: 0x0007,
456
- SSHORT: 0x0008,
457
- SLONG: 0x0009,
458
- SRATIONAL: 0x000a,
459
- FLOAT: 0x000b,
460
- DOUBLE: 0x000c,
448
+ /** @import {TypedArray} from './geotiff.js' */
449
+ const fieldTypes = {
450
+ BYTE: /** @type {1} */ (0x0001),
451
+ ASCII: /** @type {2} */ (0x0002),
452
+ SHORT: /** @type {3} */ (0x0003),
453
+ LONG: /** @type {4} */ (0x0004),
454
+ RATIONAL: /** @type {5} */ (0x0005),
455
+ SBYTE: /** @type {6} */ (0x0006),
456
+ UNDEFINED: /** @type {7} */ (0x0007),
457
+ SSHORT: /** @type {8} */ (0x0008),
458
+ SLONG: /** @type {9} */ (0x0009),
459
+ SRATIONAL: /** @type {10} */ (0x000a),
460
+ FLOAT: /** @type {11} */ (0x000b),
461
+ DOUBLE: /** @type {12} */ (0x000c),
461
462
  // IFD offset, suggested by https://owl.phy.queensu.ca/~phil/exiftool/standards.html
462
- IFD: 0x000d,
463
+ IFD: /** @type {13} */ (0x000d),
463
464
  // introduced by BigTIFF
464
- LONG8: 0x0010,
465
- SLONG8: 0x0011,
466
- IFD8: 0x0012,
467
- });
465
+ LONG8: /** @type {16} */ (0x0010),
466
+ SLONG8: /** @type {17} */ (0x0011),
467
+ IFD8: /** @type {18} */ (0x0012),
468
+ };
468
469
  /** @typedef {keyof fieldTypes} FieldTypeName */
469
470
  /** @typedef {fieldTypes[keyof typeof fieldTypes]} FieldType */
470
471
  /** @typedef {Record<FieldTypeName, number>} FieldTypeSizes */
471
- const fieldTypeSizes = Object.freeze({
472
+ const fieldTypeSizes = /** @type {const} */ ({
472
473
  [fieldTypes.BYTE]: 1,
473
474
  [fieldTypes.ASCII]: 1,
474
475
  [fieldTypes.SBYTE]: 1,
@@ -500,219 +501,196 @@ function getFieldTypeSize(fieldType) {
500
501
  }
501
502
  return size;
502
503
  }
503
- const tagSource = [
504
- { tag: 254, name: 'NewSubfileType', fieldTypes: fieldTypes.LONG },
505
- { tag: 255, name: 'SubfileType', type: fieldTypes.SHORT },
506
- { tag: 256, name: 'ImageWidth', type: fieldTypes.SHORT },
507
- { tag: 257, name: 'ImageLength', type: fieldTypes.SHORT },
508
- {
509
- tag: 258,
510
- name: 'BitsPerSample',
511
- type: fieldTypes.SHORT,
512
- isArray: true,
513
- eager: true,
514
- },
515
- { tag: 259, name: 'Compression', type: fieldTypes.SHORT },
516
- { tag: 262, name: 'PhotometricInterpretation', type: fieldTypes.SHORT },
517
- { tag: 263, name: 'Threshholding', type: fieldTypes.SHORT },
518
- { tag: 264, name: 'CellWidth', type: fieldTypes.SHORT },
519
- { tag: 265, name: 'CellLength', type: fieldTypes.SHORT },
520
- { tag: 266, name: 'FillOrder', type: fieldTypes.SHORT },
521
- { tag: 269, name: 'DocumentName', type: fieldTypes.ASCII },
522
- { tag: 270, name: 'ImageDescription', type: fieldTypes.ASCII },
523
- { tag: 271, name: 'Make', type: fieldTypes.ASCII },
524
- { tag: 272, name: 'Model', type: fieldTypes.ASCII },
525
- { tag: 273, name: 'StripOffsets', type: fieldTypes.SHORT, isArray: true },
526
- { tag: 274, name: 'Orientation', type: fieldTypes.SHORT },
527
- { tag: 277, name: 'SamplesPerPixel', type: fieldTypes.SHORT },
528
- { tag: 278, name: 'RowsPerStrip', type: fieldTypes.SHORT },
529
- { tag: 279, name: 'StripByteCounts', type: fieldTypes.LONG, isArray: true },
530
- { tag: 280, name: 'MinSampleValue', type: fieldTypes.SHORT, isArray: true },
531
- { tag: 281, name: 'MaxSampleValue', type: fieldTypes.SHORT, isArray: true },
532
- { tag: 282, name: 'XResolution', type: fieldTypes.RATIONAL },
533
- { tag: 283, name: 'YResolution', type: fieldTypes.RATIONAL },
534
- { tag: 284, name: 'PlanarConfiguration', fieldTypes: fieldTypes.SHORT },
535
- { tag: 285, name: 'PageName', type: fieldTypes.ASCII },
536
- { tag: 286, name: 'XPosition', type: fieldTypes.RATIONAL },
537
- { tag: 287, name: 'YPosition', type: fieldTypes.RATIONAL },
538
- { tag: 288, name: 'FreeOffsets', type: fieldTypes.LONG },
539
- { tag: 289, name: 'FreeByteCounts', type: fieldTypes.LONG },
540
- { tag: 290, name: 'GrayResponseUnit', type: fieldTypes.SHORT },
541
- {
542
- tag: 291,
543
- name: 'GrayResponseCurve',
544
- type: fieldTypes.SHORT,
545
- isArray: true,
546
- },
547
- { tag: 292, name: 'T4Options', type: fieldTypes.LONG },
548
- { tag: 293, name: 'T6Options', type: fieldTypes.LONG },
549
- { tag: 296, name: 'ResolutionUnit', type: fieldTypes.SHORT },
550
- { tag: 297, name: 'PageNumber', type: fieldTypes.SHORT, isArray: true },
551
- { tag: 301, name: 'TransferFunction', type: fieldTypes.SHORT, isArray: true },
552
- { tag: 305, name: 'Software', type: fieldTypes.ASCII },
553
- { tag: 306, name: 'DateTime', type: fieldTypes.ASCII },
554
- { tag: 315, name: 'Artist', type: fieldTypes.ASCII },
555
- { tag: 316, name: 'HostComputer', type: fieldTypes.ASCII },
556
- { tag: 317, name: 'Predictor', type: fieldTypes.SHORT },
557
- { tag: 318, name: 'WhitePoint', type: fieldTypes.RATIONAL, isArray: true },
558
- {
559
- tag: 319,
560
- name: 'PrimaryChromaticities',
561
- type: fieldTypes.RATIONAL,
562
- isArray: true,
563
- },
564
- { tag: 320, name: 'ColorMap', type: fieldTypes.SHORT, isArray: true },
565
- { tag: 321, name: 'HalftoneHints', type: fieldTypes.SHORT, isArray: true },
566
- { tag: 322, name: 'TileWidth', type: fieldTypes.SHORT },
567
- { tag: 323, name: 'TileLength', type: fieldTypes.SHORT },
568
- { tag: 324, name: 'TileOffsets', type: fieldTypes.LONG, isArray: true },
569
- { tag: 325, name: 'TileByteCounts', type: fieldTypes.SHORT, isArray: true },
570
- { tag: 332, name: 'InkSet', type: fieldTypes.SHORT },
571
- { tag: 333, name: 'InkNames', type: fieldTypes.ASCII },
572
- { tag: 334, name: 'NumberOfInks', type: fieldTypes.SHORT },
573
- { tag: 336, name: 'DotRange', type: fieldTypes.BYTE, isArray: true },
574
- { tag: 337, name: 'TargetPrinter', type: fieldTypes.ASCII },
575
- { tag: 338, name: 'ExtraSamples', type: fieldTypes.BYTE, isArray: true },
576
- {
577
- tag: 339,
578
- name: 'SampleFormat',
579
- type: fieldTypes.SHORT,
580
- isArray: true,
581
- eager: true,
582
- },
583
- { tag: 340, name: 'SMinSampleValue', isArray: true },
584
- { tag: 341, name: 'SMaxSampleValue', isArray: true },
585
- { tag: 342, name: 'TransferRange', type: fieldTypes.SHORT, isArray: true },
586
- { tag: 512, name: 'JPEGProc', type: fieldTypes.SHORT },
587
- { tag: 513, name: 'JPEGInterchangeFormat', type: fieldTypes.LONG },
588
- { tag: 514, name: 'JPEGInterchangeFormatLngth', type: fieldTypes.LONG },
589
- { tag: 515, name: 'JPEGRestartInterval', type: fieldTypes.SHORT },
590
- {
591
- tag: 517,
592
- name: 'JPEGLosslessPredictors',
593
- type: fieldTypes.SHORT,
594
- isArray: true,
595
- },
596
- {
597
- tag: 518,
598
- name: 'JPEGPointTransforms',
599
- type: fieldTypes.SHORT,
600
- isArray: true,
601
- },
602
- { tag: 519, name: 'JPEGQTables', type: fieldTypes.LONG, isArray: true },
603
- { tag: 520, name: 'JPEGDCTables', type: fieldTypes.LONG, isArray: true },
604
- { tag: 521, name: 'JPEGACTables', type: fieldTypes.LONG, isArray: true },
605
- {
606
- tag: 529,
607
- name: 'YCbCrCoefficients',
608
- type: fieldTypes.RATIONAL,
609
- isArray: true,
610
- },
611
- { tag: 530, name: 'YCbCrSubSampling', type: fieldTypes.SHORT, isArray: true },
612
- { tag: 531, name: 'YCbCrPositioning', type: fieldTypes.SHORT },
613
- {
614
- tag: 532,
615
- name: 'ReferenceBlackWhite',
616
- type: fieldTypes.LONG,
617
- isArray: true,
618
- },
619
- { tag: 33432, name: 'Copyright', type: fieldTypes.ASCII },
620
- // TIFF Extended
621
- { tag: 326, name: 'BadFaxLines' },
622
- { tag: 327, name: 'CleanFaxData' },
623
- { tag: 343, name: 'ClipPath' },
624
- { tag: 328, name: 'ConsecutiveBadFaxLines' },
625
- { tag: 433, name: 'Decode' },
626
- { tag: 434, name: 'DefaultImageColor' },
627
- { tag: 346, name: 'Indexed' },
628
- { tag: 347, name: 'JPEGTables', isArray: true, eager: true },
629
- { tag: 559, name: 'StripRowCounts', isArray: true },
630
- { tag: 330, name: 'SubIFDs', isArray: true },
631
- { tag: 344, name: 'XClipPathUnits' },
632
- { tag: 345, name: 'YClipPathUnits' },
633
- // EXIF
634
- { tag: 37378, name: 'ApertureValue' },
635
- { tag: 40961, name: 'ColorSpace' },
636
- { tag: 36868, name: 'DateTimeDigitized' },
637
- { tag: 36867, name: 'DateTimeOriginal' },
638
- { tag: 34665, name: 'Exif IFD', type: fieldTypes.LONG },
639
- { tag: 36864, name: 'ExifVersion' },
640
- { tag: 33434, name: 'ExposureTime' },
641
- { tag: 41728, name: 'FileSource' },
642
- { tag: 37385, name: 'Flash' },
643
- { tag: 40960, name: 'FlashpixVersion' },
644
- { tag: 33437, name: 'FNumber' },
645
- { tag: 42016, name: 'ImageUniqueID' },
646
- { tag: 37384, name: 'LightSource' },
647
- { tag: 37500, name: 'MakerNote' },
648
- { tag: 37377, name: 'ShutterSpeedValue' },
649
- { tag: 37510, name: 'UserComment' },
650
- // IPTC
651
- { tag: 33723, name: 'IPTC' },
652
- // Laser Scanning Microscopy
653
- { tag: 34412, name: 'CZ_LSMINFO' },
654
- // ICC
655
- { tag: 34675, name: 'ICC Profile' },
656
- // XMP
657
- { tag: 700, name: 'XMP' },
658
- // GDAL
659
- { tag: 42112, name: 'GDAL_METADATA' },
660
- { tag: 42113, name: 'GDAL_NODATA', type: fieldTypes.ASCII },
661
- // Photoshop
662
- { tag: 34377, name: 'Photoshop' },
663
- // GeoTiff
664
- {
665
- tag: 33550,
666
- name: 'ModelPixelScale',
667
- type: fieldTypes.DOUBLE,
668
- isArray: true,
669
- eager: true,
670
- },
671
- {
672
- tag: 33922,
673
- name: 'ModelTiepoint',
674
- type: fieldTypes.DOUBLE,
675
- isArray: true,
676
- eager: true,
677
- },
678
- {
679
- tag: 34264,
680
- name: 'ModelTransformation',
681
- type: fieldTypes.DOUBLE,
682
- isArray: true,
683
- eager: true,
684
- },
685
- {
686
- tag: 34735,
687
- name: 'GeoKeyDirectory',
688
- type: fieldTypes.SHORT,
689
- isArray: true,
690
- eager: true,
691
- },
692
- {
693
- tag: 34736,
694
- name: 'GeoDoubleParams',
695
- type: fieldTypes.DOUBLE,
696
- isArray: true,
697
- eager: true,
698
- },
699
- { tag: 34737, name: 'GeoAsciiParams', type: fieldTypes.ASCII, eager: true },
700
- // LERC
701
- { tag: 50674, name: 'LercParameters', eager: true },
702
- ];
504
+ /**
505
+ * @typedef {Object} TagDictionaryEntry
506
+ * @property {number} tag
507
+ * @property {string} [name]
508
+ * @property {number} [type]
509
+ * @property {boolean} [isArray]
510
+ * @property {boolean} [eager]
511
+ */
512
+ const tagDictionary = /** @type {const} */ ({
513
+ NewSubfileType: { tag: 254, type: fieldTypes.LONG, eager: true },
514
+ SubfileType: { tag: 255, type: fieldTypes.SHORT, eager: true },
515
+ ImageWidth: { tag: 256, type: fieldTypes.SHORT, eager: true },
516
+ ImageLength: { tag: 257, type: fieldTypes.SHORT, eager: true },
517
+ BitsPerSample: { tag: 258, type: fieldTypes.SHORT, isArray: true, eager: true },
518
+ Compression: { tag: 259, type: fieldTypes.SHORT, eager: true },
519
+ PhotometricInterpretation: { tag: 262, type: fieldTypes.SHORT, eager: true },
520
+ Threshholding: { tag: 263, type: fieldTypes.SHORT },
521
+ CellWidth: { tag: 264, type: fieldTypes.SHORT },
522
+ CellLength: { tag: 265, type: fieldTypes.SHORT },
523
+ FillOrder: { tag: 266, type: fieldTypes.SHORT },
524
+ DocumentName: { tag: 269, type: fieldTypes.ASCII },
525
+ ImageDescription: { tag: 270, type: fieldTypes.ASCII },
526
+ Make: { tag: 271, type: fieldTypes.ASCII },
527
+ Model: { tag: 272, type: fieldTypes.ASCII },
528
+ StripOffsets: { tag: 273, type: fieldTypes.SHORT, isArray: true },
529
+ Orientation: { tag: 274, type: fieldTypes.SHORT },
530
+ SamplesPerPixel: { tag: 277, type: fieldTypes.SHORT, eager: true },
531
+ RowsPerStrip: { tag: 278, type: fieldTypes.SHORT, eager: true },
532
+ StripByteCounts: { tag: 279, type: fieldTypes.LONG, isArray: true },
533
+ MinSampleValue: { tag: 280, type: fieldTypes.SHORT, isArray: true },
534
+ MaxSampleValue: { tag: 281, type: fieldTypes.SHORT, isArray: true },
535
+ XResolution: { tag: 282, type: fieldTypes.RATIONAL },
536
+ YResolution: { tag: 283, type: fieldTypes.RATIONAL },
537
+ PlanarConfiguration: { tag: 284, type: fieldTypes.SHORT, eager: true },
538
+ PageName: { tag: 285, type: fieldTypes.ASCII },
539
+ XPosition: { tag: 286, type: fieldTypes.RATIONAL },
540
+ YPosition: { tag: 287, type: fieldTypes.RATIONAL },
541
+ FreeOffsets: { tag: 288, type: fieldTypes.LONG },
542
+ FreeByteCounts: { tag: 289, type: fieldTypes.LONG },
543
+ GrayResponseUnit: { tag: 290, type: fieldTypes.SHORT },
544
+ GrayResponseCurve: { tag: 291, type: fieldTypes.SHORT, isArray: true },
545
+ T4Options: { tag: 292, type: fieldTypes.LONG },
546
+ T6Options: { tag: 293, type: fieldTypes.LONG },
547
+ ResolutionUnit: { tag: 296, type: fieldTypes.SHORT },
548
+ PageNumber: { tag: 297, type: fieldTypes.SHORT, isArray: true },
549
+ TransferFunction: { tag: 301, type: fieldTypes.SHORT, isArray: true },
550
+ Software: { tag: 305, type: fieldTypes.ASCII },
551
+ DateTime: { tag: 306, type: fieldTypes.ASCII },
552
+ Artist: { tag: 315, type: fieldTypes.ASCII },
553
+ HostComputer: { tag: 316, type: fieldTypes.ASCII },
554
+ Predictor: { tag: 317, type: fieldTypes.SHORT },
555
+ WhitePoint: { tag: 318, type: fieldTypes.RATIONAL, isArray: true },
556
+ PrimaryChromaticities: { tag: 319, type: fieldTypes.RATIONAL, isArray: true },
557
+ ColorMap: { tag: 320, type: fieldTypes.SHORT, isArray: true },
558
+ HalftoneHints: { tag: 321, type: fieldTypes.SHORT, isArray: true },
559
+ TileWidth: { tag: 322, type: fieldTypes.SHORT, eager: true },
560
+ TileLength: { tag: 323, type: fieldTypes.SHORT, eager: true },
561
+ TileOffsets: { tag: 324, type: fieldTypes.LONG, isArray: true },
562
+ TileByteCounts: { tag: 325, type: fieldTypes.SHORT, isArray: true },
563
+ InkSet: { tag: 332, type: fieldTypes.SHORT },
564
+ InkNames: { tag: 333, type: fieldTypes.ASCII },
565
+ NumberOfInks: { tag: 334, type: fieldTypes.SHORT },
566
+ DotRange: { tag: 336, type: fieldTypes.BYTE, isArray: true },
567
+ TargetPrinter: { tag: 337, type: fieldTypes.ASCII },
568
+ ExtraSamples: { tag: 338, type: fieldTypes.BYTE, isArray: true, eager: true },
569
+ SampleFormat: { tag: 339, type: fieldTypes.SHORT, isArray: true, eager: true },
570
+ SMinSampleValue: { tag: 340, isArray: true },
571
+ SMaxSampleValue: { tag: 341, isArray: true },
572
+ TransferRange: { tag: 342, type: fieldTypes.SHORT, isArray: true },
573
+ JPEGProc: { tag: 512, type: fieldTypes.SHORT },
574
+ JPEGInterchangeFormat: { tag: 513, type: fieldTypes.LONG },
575
+ JPEGInterchangeFormatLngth: { tag: 514, type: fieldTypes.LONG },
576
+ JPEGRestartInterval: { tag: 515, type: fieldTypes.SHORT },
577
+ JPEGLosslessPredictors: { tag: 517, type: fieldTypes.SHORT, isArray: true },
578
+ JPEGPointTransforms: { tag: 518, type: fieldTypes.SHORT, isArray: true },
579
+ JPEGQTables: { tag: 519, type: fieldTypes.LONG, isArray: true },
580
+ JPEGDCTables: { tag: 520, type: fieldTypes.LONG, isArray: true },
581
+ JPEGACTables: { tag: 521, type: fieldTypes.LONG, isArray: true },
582
+ YCbCrCoefficients: { tag: 529, type: fieldTypes.RATIONAL, isArray: true },
583
+ YCbCrSubSampling: { tag: 530, type: fieldTypes.SHORT, isArray: true },
584
+ YCbCrPositioning: { tag: 531, type: fieldTypes.SHORT },
585
+ ReferenceBlackWhite: { tag: 532, type: fieldTypes.LONG, isArray: true },
586
+ Copyright: { tag: 33432, type: fieldTypes.ASCII },
587
+ BadFaxLines: { tag: 326 },
588
+ CleanFaxData: { tag: 327 },
589
+ ClipPath: { tag: 343 },
590
+ ConsecutiveBadFaxLines: { tag: 328 },
591
+ Decode: { tag: 433 },
592
+ DefaultImageColor: { tag: 434 },
593
+ Indexed: { tag: 346 },
594
+ JPEGTables: { tag: 347, isArray: true, eager: true },
595
+ StripRowCounts: { tag: 559, isArray: true },
596
+ SubIFDs: { tag: 330, isArray: true },
597
+ XClipPathUnits: { tag: 344 },
598
+ YClipPathUnits: { tag: 345 },
599
+ ApertureValue: { tag: 37378 },
600
+ ColorSpace: { tag: 40961 },
601
+ DateTimeDigitized: { tag: 36868 },
602
+ DateTimeOriginal: { tag: 36867 },
603
+ ExifIFD: { tag: 34665, name: 'Exif IFD', type: fieldTypes.LONG },
604
+ ExifVersion: { tag: 36864 },
605
+ ExposureTime: { tag: 33434 },
606
+ FileSource: { tag: 41728 },
607
+ Flash: { tag: 37385 },
608
+ FlashpixVersion: { tag: 40960 },
609
+ FNumber: { tag: 33437 },
610
+ ImageUniqueID: { tag: 42016 },
611
+ LightSource: { tag: 37384 },
612
+ MakerNote: { tag: 37500 },
613
+ ShutterSpeedValue: { tag: 37377 },
614
+ UserComment: { tag: 37510 },
615
+ IPTC: { tag: 33723 },
616
+ CZ_LSMINFO: { tag: 34412 },
617
+ ICCProfile: { tag: 34675, name: 'ICC Profile' },
618
+ XMP: { tag: 700 },
619
+ GDAL_METADATA: { tag: 42112 },
620
+ GDAL_NODATA: { tag: 42113, type: fieldTypes.ASCII, eager: true },
621
+ Photoshop: { tag: 34377 },
622
+ ModelPixelScale: { tag: 33550, type: fieldTypes.DOUBLE, isArray: true, eager: true },
623
+ ModelTiepoint: { tag: 33922, type: fieldTypes.DOUBLE, isArray: true, eager: true },
624
+ ModelTransformation: { tag: 34264, type: fieldTypes.DOUBLE, isArray: true, eager: true },
625
+ GeoKeyDirectory: { tag: 34735, type: fieldTypes.SHORT, isArray: true, eager: true },
626
+ GeoDoubleParams: { tag: 34736, type: fieldTypes.DOUBLE, isArray: true, eager: true },
627
+ GeoAsciiParams: { tag: 34737, type: fieldTypes.ASCII, eager: true },
628
+ LercParameters: { tag: 50674, eager: true },
629
+ });
630
+ /** @typedef {keyof typeof tagDictionary} TagName */
631
+ /** @typedef {typeof tagDictionary[keyof typeof tagDictionary]['tag']} Tag */
632
+ /**
633
+ * @typedef {Extract<keyof typeof tagDictionary,
634
+ * { [K in keyof typeof tagDictionary]: (typeof tagDictionary)[K] extends { eager: true }
635
+ * ? K : never }[keyof typeof tagDictionary]>} EagerTagName
636
+ */
637
+ /**
638
+ * @typedef {Extract<Tag, { [K in keyof typeof tagDictionary]: (typeof tagDictionary)[K] extends { eager: true }
639
+ * ? (typeof tagDictionary)[K]['tag'] : never }[keyof typeof tagDictionary]>} EagerTag
640
+ */
641
+ /** @typedef {Extract<typeof tagDictionary[keyof typeof tagDictionary], {type: any}>['type']} TagType */
642
+ /**
643
+ * @template {number} T
644
+ * @typedef {T extends 2 ? string : number} GeoTiffPrimitive
645
+ */
646
+ /**
647
+ * @template {TagName} T
648
+ * @typedef {typeof tagDictionary[T]} TagDef
649
+ */
650
+ /**
651
+ * @typedef {{
652
+ * 1: number;
653
+ * 2: string;
654
+ * 3: number;
655
+ * 4: number;
656
+ * 5: number;
657
+ * 6: number;
658
+ * 7: ArrayBuffer;
659
+ * 8: number;
660
+ * 9: number;
661
+ * 10: number;
662
+ * 11: number;
663
+ * 12: number;
664
+ * 16: number;
665
+ * 17: number;
666
+ * 18: number;
667
+ * }} FieldTypeMap
668
+ */
669
+ /**
670
+ * @template {TagName} T
671
+ * @typedef {TagDef<T> extends { isArray: true }
672
+ * ? (TagDef<T> extends { type: typeof fieldTypes.DOUBLE } ? number[] :
673
+ * TagDef<T> extends { type: typeof fieldTypes.ASCII } ? string[] :
674
+ * TagDef<T> extends { type: typeof fieldTypes.BYTE | typeof fieldTypes.SBYTE | typeof fieldTypes.UNDEFINED }
675
+ * ? Uint8Array | Int8Array :
676
+ * (number[] | TypedArray))
677
+ * : (TagDef<T> extends { type: keyof FieldTypeMap } ? FieldTypeMap[TagDef<T>['type']] : any)} TagValue
678
+ */
703
679
  /**
704
680
  * Maps tag names to their numeric values
681
+ * @type {Record<string, number>}
705
682
  */
706
683
  const tags = {};
707
684
  /**
708
685
  * Maps tag numbers to their definitions
686
+ * @type {Record<number, { tag: number, name: string, type: string|number|undefined, isArray: boolean, eager: boolean }>}
709
687
  */
710
688
  const tagDefinitions = {};
711
689
  /**
712
690
  * Registers a new field tag
713
691
  * @param {number} tag the numeric tiff tag
714
692
  * @param {string} name the name of the tag that will be reported in the IFD
715
- * @param {string|number|undefined} type the tags data type
693
+ * @param {keyof fieldTypes|number|undefined} type the tags data type
716
694
  * @param {Boolean} isArray whether the tag is an array
717
695
  * @param {boolean} [eager=false] whether to eagerly fetch deferred fields.
718
696
  * When false (default), tags are loaded lazily on-demand.
@@ -722,8 +700,9 @@ function registerTag(tag, name, type, isArray = false, eager = false) {
722
700
  tags[name] = tag;
723
701
  tagDefinitions[tag] = { tag, name, type: typeof type === 'string' ? fieldTypes[type] : type, isArray, eager };
724
702
  }
725
- for (const entry of tagSource) {
726
- registerTag(entry.tag, entry.name, entry.type, entry.isArray, entry.eager);
703
+ for (const [key, value] of Object.entries(tagDictionary)) {
704
+ const entry = /** @type {TagDictionaryEntry} */ (value);
705
+ registerTag(entry.tag, entry.name || key, entry.type, entry.isArray, entry.eager);
727
706
  }
728
707
  /**
729
708
  * @param {number|string} tagIdentifier The field tag ID or name
@@ -753,7 +732,7 @@ const LercAddCompression = {
753
732
  Deflate: 1,
754
733
  Zstandard: 2,
755
734
  };
756
- const geoKeyNames = Object.freeze({
735
+ const geoKeyNames = /** @type {const} */ ({
757
736
  1024: 'GTModelTypeGeoKey',
758
737
  1025: 'GTRasterTypeGeoKey',
759
738
  1026: 'GTCitationGeoKey',
@@ -802,15 +781,7 @@ const geoKeyNames = Object.freeze({
802
781
  4098: 'VerticalDatumGeoKey',
803
782
  4099: 'VerticalUnitsGeoKey',
804
783
  });
805
- /** @typedef {geoKeyNames[keyof typeof geoKeyNames]} GeoKeyName */
806
- /**
807
- * @type {Record<GeoKeyName, number>}
808
- */
809
- const geoKeys = /** @type {Record<GeoKeyName, number>} */ ({});
810
- for (const key in geoKeyNames) {
811
- if (geoKeyNames.hasOwnProperty(key)) {
812
- geoKeys[geoKeyNames[key]] = parseInt(key, 10);
813
- }
784
+ for (const [key, name] of Object.entries(geoKeyNames)) {
814
785
  }
815
786
 
816
787
  function fromWhiteIsZero(raster, max) {
@@ -910,39 +881,40 @@ function fromCIELab(cieLabRaster) {
910
881
  return rgbRaster;
911
882
  }
912
883
 
913
- const registry = new Map();
884
+ /** @import BaseDecoder, {BaseDecoderParameters} from "./basedecoder.js" */
914
885
  /**
915
- * @typedef {Object} DecoderParameters
916
- * @property {number} tileWidth
917
- * @property {number} tileHeight
918
- * @property {number} planarConfiguration
919
- * @property {number} bitsPerSample
920
- * @property {number} predictor
886
+ * @typedef {Object} RegistryEntry
887
+ * @property {function():Promise<typeof BaseDecoder>} importFn
888
+ * @property {function(import("../imagefiledirectory.js").ImageFileDirectory):Promise<BaseDecoderParameters>} decoderParameterFn
889
+ * @property {boolean} preferWorker
921
890
  */
891
+ /** @type {Map<number | undefined, RegistryEntry>} */
892
+ const registry = new Map();
922
893
  /**
923
894
  * Default decoder parameter retrieval function
924
- * @param {import("../imagefiledirectory").ImageFileDirectory} fileDirectory
925
- * @returns {Promise<DecoderParameters>}
895
+ * @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
896
+ * @returns {Promise<BaseDecoderParameters>}
926
897
  */
927
898
  async function defaultDecoderParameterFn(fileDirectory) {
928
899
  const isTiled = !fileDirectory.hasTag('StripOffsets');
929
- return {
930
- tileWidth: isTiled ? await fileDirectory.loadValue('TileWidth') : await fileDirectory.loadValue('ImageWidth'),
931
- tileHeight: isTiled ? await fileDirectory.loadValue('TileLength') : (await fileDirectory.loadValue('RowsPerStrip') || await fileDirectory.loadValue('ImageLength')),
900
+ return /** @type {BaseDecoderParameters} */ ({
901
+ tileWidth: isTiled
902
+ ? await fileDirectory.loadValue('TileWidth')
903
+ : await fileDirectory.loadValue('ImageWidth'),
904
+ tileHeight: isTiled
905
+ ? await fileDirectory.loadValue('TileLength')
906
+ : (await fileDirectory.loadValue('RowsPerStrip')
907
+ || await fileDirectory.loadValue('ImageLength')),
932
908
  planarConfiguration: await fileDirectory.loadValue('PlanarConfiguration'),
933
909
  bitsPerSample: await fileDirectory.loadValue('BitsPerSample'),
934
910
  predictor: await fileDirectory.loadValue('Predictor') || 1,
935
- };
911
+ });
936
912
  }
937
- /**
938
- * Either a number or undefined.
939
- * @typedef {(number|undefined)} NumberOrUndefined
940
- */
941
913
  /**
942
914
  * Register a decoder for a specific compression method or a range of compressions
943
- * @param {(NumberOrUndefined|(NumberOrUndefined[]))} cases ids of the compression methods to register for
944
- * @param {function():Promise} importFn the function to import the decoder
945
- * @param {function(import("../imagefiledirectory").ImageFileDirectory):Promise} decoderParameterFn
915
+ * @param {(number|undefined|(number|undefined)[])} cases ids of the compression methods to register for
916
+ * @param {function():Promise<typeof BaseDecoder>} importFn the function to import the decoder
917
+ * @param {function(import("../imagefiledirectory.js").ImageFileDirectory):Promise<BaseDecoderParameters>} decoderParameterFn
946
918
  * @param {boolean} preferWorker_ Whether to prefer running the decoder in a worker
947
919
  */
948
920
  function addDecoder(cases, importFn, decoderParameterFn = defaultDecoderParameterFn, preferWorker_ = true) {
@@ -955,27 +927,27 @@ function addDecoder(cases, importFn, decoderParameterFn = defaultDecoderParamete
955
927
  }
956
928
  /**
957
929
  * Get the required decoder parameters for a specific compression method
958
- * @param {NumberOrUndefined} compression
930
+ * @param {number|undefined} compression
959
931
  * @param {import('../imagefiledirectory.js').ImageFileDirectory} fileDirectory
960
932
  */
961
933
  async function getDecoderParameters(compression, fileDirectory) {
962
934
  if (!registry.has(compression)) {
963
935
  throw new Error(`Unknown compression method identifier: ${compression}`);
964
936
  }
965
- const { decoderParameterFn } = registry.get(compression);
937
+ const { decoderParameterFn } = /** @type {RegistryEntry} */ (registry.get(compression));
966
938
  return decoderParameterFn(fileDirectory);
967
939
  }
968
940
  /**
969
941
  * Get a decoder for a specific compression and parameters
970
942
  * @param {number} compression the compression method identifier
971
- * @param {DecoderParameters} decoderParameters the parameters for the decoder
943
+ * @param {BaseDecoderParameters} decoderParameters the parameters for the decoder
972
944
  * @returns {Promise<import('./basedecoder.js').default>}
973
945
  */
974
946
  async function getDecoder(compression, decoderParameters) {
975
947
  if (!registry.has(compression)) {
976
948
  throw new Error(`Unknown compression method identifier: ${compression}`);
977
949
  }
978
- const { importFn } = registry.get(compression);
950
+ const { importFn } = /** @type {RegistryEntry} */ (registry.get(compression));
979
951
  const Decoder = await importFn();
980
952
  return new Decoder(decoderParameters);
981
953
  }
@@ -1002,6 +974,9 @@ const defaultDecoderDefinitions = [
1002
974
  {
1003
975
  cases: 7,
1004
976
  importFn: () => Promise.resolve().then(function () { return jpeg; }).then((m) => m.default),
977
+ /**
978
+ * @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
979
+ */
1005
980
  decoderParameterFn: async (fileDirectory) => {
1006
981
  return {
1007
982
  ...await defaultDecoderParameterFn(fileDirectory),
@@ -1028,6 +1003,9 @@ const defaultDecoderDefinitions = [
1028
1003
  return m;
1029
1004
  })
1030
1005
  .then((m) => m.default),
1006
+ /**
1007
+ * @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
1008
+ */
1031
1009
  decoderParameterFn: async (fileDirectory) => {
1032
1010
  return {
1033
1011
  ...await defaultDecoderParameterFn(fileDirectory),
@@ -1049,10 +1027,13 @@ const defaultDecoderDefinitions = [
1049
1027
  {
1050
1028
  cases: 50001,
1051
1029
  importFn: () => Promise.resolve().then(function () { return webimage; }).then((m) => m.default),
1030
+ /**
1031
+ * @param {import("../imagefiledirectory.js").ImageFileDirectory} fileDirectory
1032
+ */
1052
1033
  decoderParameterFn: async (fileDirectory) => {
1053
1034
  return {
1054
1035
  ...await defaultDecoderParameterFn(fileDirectory),
1055
- samplesPerPixel: await fileDirectory.loadValue('SamplesPerPixel') || 4,
1036
+ samplesPerPixel: Number(await fileDirectory.loadValue('SamplesPerPixel')) || 4,
1056
1037
  };
1057
1038
  },
1058
1039
  preferWorker: false,
@@ -1067,17 +1048,23 @@ for (const decoderDefinition of defaultDecoderDefinitions) {
1067
1048
  /**
1068
1049
  * @module resample
1069
1050
  */
1051
+ /**
1052
+ * @param {import("./geotiff.js").TypedArray} array
1053
+ * @param {number} width
1054
+ * @param {number} height
1055
+ * @param {number} [samplesPerPixel=1]
1056
+ */
1070
1057
  function copyNewSize(array, width, height, samplesPerPixel = 1) {
1071
1058
  return new (Object.getPrototypeOf(array).constructor)(width * height * samplesPerPixel);
1072
1059
  }
1073
1060
  /**
1074
1061
  * Resample the input arrays using nearest neighbor value selection.
1075
- * @param {import("./geotiff").TypedArray[]} valueArrays The input arrays to resample
1062
+ * @param {import("./geotiff.js").TypedArray[]} valueArrays The input arrays to resample
1076
1063
  * @param {number} inWidth The width of the input rasters
1077
1064
  * @param {number} inHeight The height of the input rasters
1078
1065
  * @param {number} outWidth The desired width of the output rasters
1079
1066
  * @param {number} outHeight The desired height of the output rasters
1080
- * @returns {import("./geotiff").TypedArray[]} The resampled rasters
1067
+ * @returns {import("./geotiff.js").TypedArray[]} The resampled rasters
1081
1068
  */
1082
1069
  function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {
1083
1070
  const relX = inWidth / outWidth;
@@ -1097,17 +1084,22 @@ function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {
1097
1084
  }
1098
1085
  // simple linear interpolation, code from:
1099
1086
  // https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support
1087
+ /**
1088
+ * @param {number} v0
1089
+ * @param {number} v1
1090
+ * @param {number} t
1091
+ */
1100
1092
  function lerp(v0, v1, t) {
1101
1093
  return ((1 - t) * v0) + (t * v1);
1102
1094
  }
1103
1095
  /**
1104
1096
  * Resample the input arrays using bilinear interpolation.
1105
- * @param {import("./geotiff").TypedArray[]} valueArrays The input arrays to resample
1097
+ * @param {import("./geotiff.js").TypedArray[]} valueArrays The input arrays to resample
1106
1098
  * @param {number} inWidth The width of the input rasters
1107
1099
  * @param {number} inHeight The height of the input rasters
1108
1100
  * @param {number} outWidth The desired width of the output rasters
1109
1101
  * @param {number} outHeight The desired height of the output rasters
1110
- * @returns {import("./geotiff").TypedArray[]} The resampled rasters
1102
+ * @returns {import("./geotiff.js").TypedArray[]} The resampled rasters
1111
1103
  */
1112
1104
  function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {
1113
1105
  const relX = inWidth / outWidth;
@@ -1136,13 +1128,13 @@ function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {
1136
1128
  }
1137
1129
  /**
1138
1130
  * Resample the input arrays using the selected resampling method.
1139
- * @param {import("./geotiff").TypedArray[]} valueArrays The input arrays to resample
1131
+ * @param {import("./geotiff.js").TypedArray[]} valueArrays The input arrays to resample
1140
1132
  * @param {number} inWidth The width of the input rasters
1141
1133
  * @param {number} inHeight The height of the input rasters
1142
1134
  * @param {number} outWidth The desired width of the output rasters
1143
1135
  * @param {number} outHeight The desired height of the output rasters
1144
1136
  * @param {string} [method = 'nearest'] The desired resampling method
1145
- * @returns {import("./geotiff").TypedArray[]} The resampled rasters
1137
+ * @returns {import("./geotiff.js").TypedArray[]} The resampled rasters
1146
1138
  */
1147
1139
  function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method = 'nearest') {
1148
1140
  switch (method.toLowerCase()) {
@@ -1157,14 +1149,14 @@ function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method =
1157
1149
  }
1158
1150
  /**
1159
1151
  * Resample the pixel interleaved input array using nearest neighbor value selection.
1160
- * @param {import("./geotiff").TypedArray} valueArray The input array to resample
1152
+ * @param {import("./geotiff.js").TypedArray} valueArray The input array to resample
1161
1153
  * @param {number} inWidth The width of the input rasters
1162
1154
  * @param {number} inHeight The height of the input rasters
1163
1155
  * @param {number} outWidth The desired width of the output rasters
1164
1156
  * @param {number} outHeight The desired height of the output rasters
1165
1157
  * @param {number} samples The number of samples per pixel for pixel
1166
1158
  * interleaved data
1167
- * @returns {import("./geotiff").TypedArray} The resampled raster
1159
+ * @returns {import("./geotiff.js").TypedArray} The resampled raster
1168
1160
  */
1169
1161
  function resampleNearestInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
1170
1162
  const relX = inWidth / outWidth;
@@ -1184,14 +1176,14 @@ function resampleNearestInterleaved(valueArray, inWidth, inHeight, outWidth, out
1184
1176
  }
1185
1177
  /**
1186
1178
  * Resample the pixel interleaved input array using bilinear interpolation.
1187
- * @param {import("./geotiff").TypedArray} valueArray The input array to resample
1179
+ * @param {import("./geotiff.js").TypedArray} valueArray The input array to resample
1188
1180
  * @param {number} inWidth The width of the input rasters
1189
1181
  * @param {number} inHeight The height of the input rasters
1190
1182
  * @param {number} outWidth The desired width of the output rasters
1191
1183
  * @param {number} outHeight The desired height of the output rasters
1192
1184
  * @param {number} samples The number of samples per pixel for pixel
1193
1185
  * interleaved data
1194
- * @returns {import("./geotiff").TypedArray} The resampled raster
1186
+ * @returns {import("./geotiff.js").TypedArray} The resampled raster
1195
1187
  */
1196
1188
  function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
1197
1189
  const relX = inWidth / outWidth;
@@ -1220,7 +1212,7 @@ function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, ou
1220
1212
  }
1221
1213
  /**
1222
1214
  * Resample the pixel interleaved input array using the selected resampling method.
1223
- * @param {import("./geotiff").TypedArray} valueArray The input array to resample
1215
+ * @param {import("./geotiff.js").TypedArray} valueArray The input array to resample
1224
1216
  * @param {number} inWidth The width of the input rasters
1225
1217
  * @param {number} inHeight The height of the input rasters
1226
1218
  * @param {number} outWidth The desired width of the output rasters
@@ -1228,7 +1220,7 @@ function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, ou
1228
1220
  * @param {number} samples The number of samples per pixel for pixel
1229
1221
  * interleaved data
1230
1222
  * @param {string} [method = 'nearest'] The desired resampling method
1231
- * @returns {import("./geotiff").TypedArray} The resampled rasters
1223
+ * @returns {import("./geotiff.js").TypedArray} The resampled rasters
1232
1224
  */
1233
1225
  function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples, method = 'nearest') {
1234
1226
  switch (method.toLowerCase()) {
@@ -1243,10 +1235,16 @@ function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight,
1243
1235
  }
1244
1236
 
1245
1237
  /** @module geotiffimage */
1246
- /** @import {DecoderWorker, TypedArray} from "./geotiff" */
1247
- /** @import {ReadRasterResult} from "./geotiff" */
1248
- /** @import {ReadRastersOptions} from "./geotiff" */
1249
- /** @import {ReadRGBOptions} from "./geotiff" */
1238
+ /** @import {DecoderWorker, TypedArray} from "./geotiff.js" */
1239
+ /** @import {ReadRasterResult} from "./geotiff.js" */
1240
+ /** @import {ReadRastersOptions} from "./geotiff.js" */
1241
+ /** @import {ReadRGBOptions} from "./geotiff.js" */
1242
+ /**
1243
+ * @param {Array<number>|TypedArray} array
1244
+ * @param {number} start
1245
+ * @param {number} end
1246
+ * @returns {number}
1247
+ */
1250
1248
  function sum(array, start, end) {
1251
1249
  let s = 0;
1252
1250
  for (let i = start; i < end; ++i) {
@@ -1254,42 +1252,64 @@ function sum(array, start, end) {
1254
1252
  }
1255
1253
  return s;
1256
1254
  }
1257
- function arrayForType(format, bitsPerSample, size) {
1255
+ /**
1256
+ * @param {1|2|3} format
1257
+ * @param {number} bitsPerSample
1258
+ * @param {number|ArrayBufferLike} sizeOrData
1259
+ * @returns {TypedArray}
1260
+ */
1261
+ function arrayForType(format, bitsPerSample, sizeOrData) {
1262
+ let TypedArrayConstructor;
1258
1263
  switch (format) {
1259
1264
  case 1: // unsigned integer data
1260
1265
  if (bitsPerSample <= 8) {
1261
- return new Uint8Array(size);
1266
+ TypedArrayConstructor = Uint8Array;
1262
1267
  }
1263
1268
  else if (bitsPerSample <= 16) {
1264
- return new Uint16Array(size);
1269
+ TypedArrayConstructor = Uint16Array;
1265
1270
  }
1266
1271
  else if (bitsPerSample <= 32) {
1267
- return new Uint32Array(size);
1272
+ TypedArrayConstructor = Uint32Array;
1268
1273
  }
1269
1274
  break;
1270
1275
  case 2: // twos complement signed integer data
1271
1276
  if (bitsPerSample === 8) {
1272
- return new Int8Array(size);
1277
+ TypedArrayConstructor = Int8Array;
1273
1278
  }
1274
1279
  else if (bitsPerSample === 16) {
1275
- return new Int16Array(size);
1280
+ TypedArrayConstructor = Int16Array;
1276
1281
  }
1277
1282
  else if (bitsPerSample === 32) {
1278
- return new Int32Array(size);
1283
+ TypedArrayConstructor = Int32Array;
1279
1284
  }
1280
1285
  break;
1281
1286
  case 3: // floating point data
1282
1287
  switch (bitsPerSample) {
1283
1288
  case 16:
1284
1289
  case 32:
1285
- return new Float32Array(size);
1290
+ TypedArrayConstructor = Float32Array;
1291
+ break;
1286
1292
  case 64:
1287
- return new Float64Array(size);
1293
+ TypedArrayConstructor = Float64Array;
1294
+ break;
1288
1295
  }
1289
1296
  break;
1290
1297
  }
1298
+ if (TypedArrayConstructor) {
1299
+ if (typeof sizeOrData === 'number') {
1300
+ return new TypedArrayConstructor(sizeOrData);
1301
+ }
1302
+ else if (sizeOrData instanceof ArrayBuffer) {
1303
+ return new TypedArrayConstructor(sizeOrData);
1304
+ }
1305
+ }
1291
1306
  throw Error('Unsupported data format/bitsPerSample');
1292
1307
  }
1308
+ /**
1309
+ * @param {1|2|3} format
1310
+ * @param {number} bitsPerSample
1311
+ * @returns {boolean}
1312
+ */
1293
1313
  function needsNormalization(format, bitsPerSample) {
1294
1314
  if ((format === 1 || format === 2) && bitsPerSample <= 32 && bitsPerSample % 8 === 0) {
1295
1315
  return false;
@@ -1299,6 +1319,16 @@ function needsNormalization(format, bitsPerSample) {
1299
1319
  }
1300
1320
  return true;
1301
1321
  }
1322
+ /**
1323
+ * @param {ArrayBufferLike} inBuffer
1324
+ * @param {1|2|3} format
1325
+ * @param {1|2} planarConfiguration
1326
+ * @param {number} samplesPerPixel
1327
+ * @param {number} bitsPerSample
1328
+ * @param {number} tileWidth
1329
+ * @param {number} tileHeight
1330
+ * @returns {ArrayBufferLike}
1331
+ */
1302
1332
  function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel, bitsPerSample, tileWidth, tileHeight) {
1303
1333
  // const inByteArray = new Uint8Array(inBuffer);
1304
1334
  const view = new DataView(inBuffer);
@@ -1372,7 +1402,7 @@ function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel,
1372
1402
  class GeoTIFFImage {
1373
1403
  /**
1374
1404
  * @constructor
1375
- * @param {import("./imagefiledirectory").ImageFileDirectory} fileDirectory The parsed file directory
1405
+ * @param {import("./imagefiledirectory.js").ImageFileDirectory} fileDirectory The parsed file directory
1376
1406
  * @param {Boolean} littleEndian Whether the file is encoded in little or big endian
1377
1407
  * @param {Boolean} cache Whether or not decoded tiles shall be cached
1378
1408
  * @param {import('./source/basesource.js').BaseSource} source The datasource to read from
@@ -1380,7 +1410,8 @@ class GeoTIFFImage {
1380
1410
  constructor(fileDirectory, littleEndian, cache, source) {
1381
1411
  this.fileDirectory = fileDirectory;
1382
1412
  this.littleEndian = littleEndian;
1383
- this.tiles = cache ? {} : null;
1413
+ /** @type {Array<Promise<ArrayBufferLike>>|null} */
1414
+ this.tiles = cache ? [] : null;
1384
1415
  this.isTiled = !fileDirectory.hasTag('StripOffsets');
1385
1416
  const planarConfiguration = fileDirectory.getValue('PlanarConfiguration') ?? 1;
1386
1417
  if (planarConfiguration !== 1 && planarConfiguration !== 2) {
@@ -1392,7 +1423,7 @@ class GeoTIFFImage {
1392
1423
  }
1393
1424
  /**
1394
1425
  * Returns the associated parsed file directory.
1395
- * @returns {import("./imagefiledirectory").ImageFileDirectory} the parsed file directory
1426
+ * @returns {import("./imagefiledirectory.js").ImageFileDirectory} the parsed file directory
1396
1427
  */
1397
1428
  getFileDirectory() {
1398
1429
  return this.fileDirectory;
@@ -1409,46 +1440,50 @@ class GeoTIFFImage {
1409
1440
  * @returns {Number} the width of the image
1410
1441
  */
1411
1442
  getWidth() {
1412
- return this.fileDirectory.getValue('ImageWidth');
1443
+ return this.fileDirectory.getValue('ImageWidth') || 0;
1413
1444
  }
1414
1445
  /**
1415
1446
  * Returns the height of the image.
1416
1447
  * @returns {Number} the height of the image
1417
1448
  */
1418
1449
  getHeight() {
1419
- return this.fileDirectory.getValue('ImageLength');
1450
+ return this.fileDirectory.getValue('ImageLength') || 0;
1420
1451
  }
1421
1452
  /**
1422
1453
  * Returns the number of samples per pixel.
1423
- * @returns {Number} the number of samples per pixel
1454
+ * @returns {number} the number of samples per pixel
1424
1455
  */
1425
1456
  getSamplesPerPixel() {
1426
- return this.fileDirectory.hasTag('SamplesPerPixel')
1427
- ? this.fileDirectory.getValue('SamplesPerPixel') : 1;
1457
+ return this.fileDirectory.getValue('SamplesPerPixel') ?? 1;
1428
1458
  }
1429
1459
  /**
1430
1460
  * Returns the width of each tile.
1431
- * @returns {Number} the width of each tile
1461
+ * @returns {number} the width of each tile
1432
1462
  */
1433
1463
  getTileWidth() {
1434
- return this.isTiled ? this.fileDirectory.getValue('TileWidth') : this.getWidth();
1464
+ return this.isTiled ? (this.fileDirectory.getValue('TileWidth') || 0) : this.getWidth();
1435
1465
  }
1436
1466
  /**
1437
1467
  * Returns the height of each tile.
1438
- * @returns {Number} the height of each tile
1468
+ * @returns {number} the height of each tile
1439
1469
  */
1440
1470
  getTileHeight() {
1441
1471
  if (this.isTiled) {
1442
- return this.fileDirectory.getValue('TileLength');
1472
+ return this.fileDirectory.getValue('TileLength') || 0;
1443
1473
  }
1444
- if (this.fileDirectory.hasTag('RowsPerStrip')) {
1445
- return Math.min(this.fileDirectory.getValue('RowsPerStrip'), this.getHeight());
1474
+ const rowsPerStrip = this.fileDirectory.hasTag('RowsPerStrip') && this.fileDirectory.getValue('RowsPerStrip');
1475
+ if (rowsPerStrip) {
1476
+ return Math.min(rowsPerStrip, this.getHeight());
1446
1477
  }
1447
1478
  return this.getHeight();
1448
1479
  }
1449
1480
  getBlockWidth() {
1450
1481
  return this.getTileWidth();
1451
1482
  }
1483
+ /**
1484
+ * @param {number} y
1485
+ * @returns {number}
1486
+ */
1452
1487
  getBlockHeight(y) {
1453
1488
  if (this.isTiled || (y + 1) * this.getTileHeight() <= this.getHeight()) {
1454
1489
  return this.getTileHeight();
@@ -1465,22 +1500,32 @@ class GeoTIFFImage {
1465
1500
  getBytesPerPixel() {
1466
1501
  let bytes = 0;
1467
1502
  // this is a short list, so we assume this is already loaded
1468
- for (let i = 0; i < this.fileDirectory.getValue('BitsPerSample').length; ++i) {
1503
+ const bitsPerSample = this.fileDirectory.getValue('BitsPerSample') || [];
1504
+ for (let i = 0; i < bitsPerSample.length; ++i) {
1469
1505
  bytes += this.getSampleByteSize(i);
1470
1506
  }
1471
1507
  return bytes;
1472
1508
  }
1509
+ /**
1510
+ * @param {number} i
1511
+ * @returns {number}
1512
+ */
1473
1513
  getSampleByteSize(i) {
1474
- const bitsPerSample = this.fileDirectory.getValue('BitsPerSample');
1514
+ const bitsPerSample = this.fileDirectory.getValue('BitsPerSample') || [];
1475
1515
  if (i >= bitsPerSample.length) {
1476
1516
  throw new RangeError(`Sample index ${i} is out of range.`);
1477
1517
  }
1478
1518
  return Math.ceil(bitsPerSample[i] / 8);
1479
1519
  }
1520
+ /**
1521
+ * @param {number} sampleIndex
1522
+ * @returns {(this: DataView, byteOffset: number, littleEndian: boolean) => number}
1523
+ */
1480
1524
  getReaderForSample(sampleIndex) {
1481
- const format = this.fileDirectory.hasTag('SampleFormat')
1482
- ? this.fileDirectory.getValue('SampleFormat')[sampleIndex] : 1;
1483
- const bitsPerSample = this.fileDirectory.getValue('BitsPerSample')[sampleIndex];
1525
+ const sampleFormat = this.fileDirectory.getValue('SampleFormat');
1526
+ const format = sampleFormat
1527
+ ? sampleFormat[sampleIndex] : 1;
1528
+ const bitsPerSample = (this.fileDirectory.getValue('BitsPerSample') || [])[sampleIndex];
1484
1529
  switch (format) {
1485
1530
  case 1: // unsigned integer data
1486
1531
  if (bitsPerSample <= 8) {
@@ -1520,26 +1565,32 @@ class GeoTIFFImage {
1520
1565
  throw Error('Unsupported data format/bitsPerSample');
1521
1566
  }
1522
1567
  getSampleFormat(sampleIndex = 0) {
1523
- return this.fileDirectory.hasTag('SampleFormat')
1524
- ? this.fileDirectory.getValue('SampleFormat')[sampleIndex] : 1;
1568
+ const sampleFormat = this.fileDirectory.getValue('SampleFormat');
1569
+ return sampleFormat ? sampleFormat[sampleIndex] : 1;
1525
1570
  }
1526
1571
  getBitsPerSample(sampleIndex = 0) {
1527
- return this.fileDirectory.getValue('BitsPerSample')[sampleIndex];
1572
+ const bitsPerSample = this.fileDirectory.getValue('BitsPerSample');
1573
+ return bitsPerSample ? bitsPerSample[sampleIndex] : 0;
1528
1574
  }
1529
- getArrayForSample(sampleIndex, size) {
1530
- const format = this.getSampleFormat(sampleIndex);
1575
+ /**
1576
+ * @param {number} sampleIndex
1577
+ * @param {number|ArrayBufferLike} sizeOrData
1578
+ * @returns {TypedArray}
1579
+ */
1580
+ getArrayForSample(sampleIndex, sizeOrData) {
1581
+ const format = /** @type {1|2|3} */ (this.getSampleFormat(sampleIndex));
1531
1582
  const bitsPerSample = this.getBitsPerSample(sampleIndex);
1532
- return arrayForType(format, bitsPerSample, size);
1583
+ return arrayForType(format, bitsPerSample, sizeOrData);
1533
1584
  }
1534
1585
  /**
1535
1586
  * Returns the decoded strip or tile.
1536
1587
  * @param {Number} x the strip or tile x-offset
1537
1588
  * @param {Number} y the tile y-offset (0 for stripped images)
1538
1589
  * @param {Number} sample the sample to get for separated samples
1539
- * @param {DecoderWorker|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
1590
+ * @param {DecoderWorker|import("./geotiff.js").BaseDecoder} poolOrDecoder the decoder or decoder pool
1540
1591
  * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
1541
1592
  * to be aborted
1542
- * @returns {Promise.<{x: number, y: number, sample: number, data: ArrayBuffer}>} the decoded strip or tile
1593
+ * @returns {Promise.<{x: number, y: number, sample: number, data: ArrayBufferLike}>} the decoded strip or tile
1543
1594
  */
1544
1595
  async getTileOrStrip(x, y, sample, poolOrDecoder, signal) {
1545
1596
  const numTilesPerRow = Math.ceil(this.getWidth() / this.getTileWidth());
@@ -1558,12 +1609,12 @@ class GeoTIFFImage {
1558
1609
  let offset;
1559
1610
  let byteCount;
1560
1611
  if (this.isTiled) {
1561
- offset = await this.fileDirectory.loadValueIndexed('TileOffsets', index);
1562
- byteCount = await this.fileDirectory.loadValueIndexed('TileByteCounts', index);
1612
+ offset = Number(await this.fileDirectory.loadValueIndexed('TileOffsets', index));
1613
+ byteCount = Number(await this.fileDirectory.loadValueIndexed('TileByteCounts', index));
1563
1614
  }
1564
1615
  else {
1565
- offset = await this.fileDirectory.loadValueIndexed('StripOffsets', index);
1566
- byteCount = await this.fileDirectory.loadValueIndexed('StripByteCounts', index);
1616
+ offset = Number(await this.fileDirectory.loadValueIndexed('StripOffsets', index));
1617
+ byteCount = Number(await this.fileDirectory.loadValueIndexed('StripByteCounts', index));
1567
1618
  }
1568
1619
  if (byteCount === 0) {
1569
1620
  const nPixels = this.getBlockHeight(y) * this.getTileWidth();
@@ -1579,7 +1630,7 @@ class GeoTIFFImage {
1579
1630
  // resolve each request by potentially applying array normalization
1580
1631
  request = (async () => {
1581
1632
  let data = await poolOrDecoder.decode(slice);
1582
- const sampleFormat = this.getSampleFormat();
1633
+ const sampleFormat = /** @type {1|2|3} */ (this.getSampleFormat());
1583
1634
  const bitsPerSample = this.getBitsPerSample();
1584
1635
  if (needsNormalization(sampleFormat, bitsPerSample)) {
1585
1636
  data = normalizeArray(data, sampleFormat, this.planarConfiguration, this.getSamplesPerPixel(), bitsPerSample, this.getTileWidth(), this.getBlockHeight(y));
@@ -1601,11 +1652,11 @@ class GeoTIFFImage {
1601
1652
  /**
1602
1653
  * Internal read function.
1603
1654
  * @private
1604
- * @param {Array} imageWindow The image window in pixel coordinates
1605
- * @param {Array} samples The selected samples (0-based indices)
1655
+ * @param {Array<number>} imageWindow The image window in pixel coordinates
1656
+ * @param {Array<number>} samples The selected samples (0-based indices)
1606
1657
  * @param {TypedArray|TypedArray[]} valueArrays The array(s) to write into
1607
1658
  * @param {boolean|undefined} interleave Whether or not to write in an interleaved manner
1608
- * @param {DecoderWorker|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
1659
+ * @param {DecoderWorker|import("./geotiff.js").BaseDecoder} poolOrDecoder the decoder or decoder pool
1609
1660
  * @param {number} [width] the width of window to be read into
1610
1661
  * @param {number} [height] the height of window to be read into
1611
1662
  * @param {string} [resampleMethod] the resampling method to be used when interpolating
@@ -1624,11 +1675,17 @@ class GeoTIFFImage {
1624
1675
  const maxYTile = Math.min(Math.ceil(imageWindow[3] / tileHeight), Math.ceil(imageHeight / tileHeight));
1625
1676
  const windowWidth = imageWindow[2] - imageWindow[0];
1626
1677
  let bytesPerPixel = this.getBytesPerPixel();
1678
+ /** @type {Array<number>} */
1627
1679
  const srcSampleOffsets = [];
1680
+ /** @type {Array<(this: DataView, byteOffset: number, littleEndian: boolean) => number>} */
1628
1681
  const sampleReaders = [];
1629
1682
  for (let i = 0; i < samples.length; ++i) {
1630
1683
  if (this.planarConfiguration === 1) {
1631
- srcSampleOffsets.push(sum(await this.fileDirectory.loadValue('BitsPerSample'), 0, samples[i]) / 8);
1684
+ const bitsPerSample = await this.fileDirectory.loadValue('BitsPerSample');
1685
+ if (typeof bitsPerSample !== 'object') {
1686
+ throw new Error('Expected BitsPerSample to be an array or typed array.');
1687
+ }
1688
+ srcSampleOffsets.push(sum(bitsPerSample, 0, samples[i]) / 8);
1632
1689
  }
1633
1690
  else {
1634
1691
  srcSampleOffsets.push(0);
@@ -1677,7 +1734,7 @@ class GeoTIFFImage {
1677
1734
  }
1678
1735
  else {
1679
1736
  windowCoordinate = ((y + firstLine - imageWindow[1]) * windowWidth) + x + firstCol - imageWindow[0];
1680
- valueArrays[si][windowCoordinate] = value;
1737
+ /** @type {TypedArray} */ (valueArrays[si])[windowCoordinate] = value;
1681
1738
  }
1682
1739
  }
1683
1740
  }
@@ -1713,12 +1770,12 @@ class GeoTIFFImage {
1713
1770
  /**
1714
1771
  * @overload
1715
1772
  * @param {ReadRastersOptions & {interleave: true}} options optional parameters
1716
- * @returns {Promise<import("./geotiff").TypedArrayWithDimensions>} the decoded arrays as a promise
1773
+ * @returns {Promise<import("./geotiff.js").TypedArrayWithDimensions>} the decoded arrays as a promise
1717
1774
  */
1718
1775
  /**
1719
1776
  * @overload
1720
1777
  * @param {ReadRastersOptions & {interleave: false}} options optional parameters
1721
- * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
1778
+ * @returns {Promise<import("./geotiff.js").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
1722
1779
  */
1723
1780
  /**
1724
1781
  * @overload
@@ -1728,7 +1785,7 @@ class GeoTIFFImage {
1728
1785
  /**
1729
1786
  * @overload
1730
1787
  * @param {ReadRastersOptions} [options={}] optional parameters
1731
- * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
1788
+ * @returns {Promise<import("./geotiff.js").TypedArrayArrayWithDimensions>} the decoded arrays as a promise
1732
1789
  */
1733
1790
  /**
1734
1791
  * Reads raster data from the image. This function reads all selected samples
@@ -1766,9 +1823,16 @@ class GeoTIFFImage {
1766
1823
  /** @type {TypedArray|TypedArray[]} */
1767
1824
  let valueArrays;
1768
1825
  if (interleave) {
1769
- const format = this.fileDirectory.hasTag('SampleFormat')
1770
- ? Math.max.apply(null, this.fileDirectory.getValue('SampleFormat')) : 1;
1771
- const bitsPerSample = Math.max.apply(null, this.fileDirectory.getValue('BitsPerSample'));
1826
+ const { fileDirectory } = this;
1827
+ const sampleFormat = fileDirectory.getValue('SampleFormat');
1828
+ const format = sampleFormat
1829
+ ? Math.max.apply(null, Array.from(sampleFormat)) : 1;
1830
+ if (format !== 1 && format !== 2 && format !== 3) {
1831
+ throw new Error('Unsupported sample format for interleaved data. Must be 1, 2, or 3.');
1832
+ }
1833
+ const bitsPerSample_ = fileDirectory.getValue('BitsPerSample');
1834
+ const bitsPerSample = bitsPerSample_
1835
+ ? Math.max.apply(null, Array.from(bitsPerSample_)) : 8;
1772
1836
  valueArrays = arrayForType(format, bitsPerSample, numPixels * samples.length);
1773
1837
  if (fillValue) {
1774
1838
  if (Array.isArray(fillValue)) {
@@ -1801,12 +1865,12 @@ class GeoTIFFImage {
1801
1865
  /**
1802
1866
  * @overload
1803
1867
  * @param {ReadRGBOptions & {interleave: true}} options optional parameters
1804
- * @returns {Promise<import("./geotiff").TypedArrayWithDimensions>} the RGB array as a Promise
1868
+ * @returns {Promise<import("./geotiff.js").TypedArrayWithDimensions>} the RGB array as a Promise
1805
1869
  */
1806
1870
  /**
1807
1871
  * @overload
1808
1872
  * @param {ReadRGBOptions & {interleave: false}} options optional parameters
1809
- * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the RGB array as a Promise
1873
+ * @returns {Promise<import("./geotiff.js").TypedArrayArrayWithDimensions>} the RGB array as a Promise
1810
1874
  */
1811
1875
  /**
1812
1876
  * @overload
@@ -1816,7 +1880,7 @@ class GeoTIFFImage {
1816
1880
  /**
1817
1881
  * @overload
1818
1882
  * @param {ReadRGBOptions} [options={}] optional parameters
1819
- * @returns {Promise<import("./geotiff").TypedArrayArrayWithDimensions>} the RGB array as a Promise
1883
+ * @returns {Promise<import("./geotiff.js").TypedArrayArrayWithDimensions>} the RGB array as a Promise
1820
1884
  */
1821
1885
  /**
1822
1886
  * Reads raster data from the image as RGB.
@@ -1839,9 +1903,11 @@ class GeoTIFFImage {
1839
1903
  const pi = this.fileDirectory.getValue('PhotometricInterpretation');
1840
1904
  if (pi === photometricInterpretations.RGB) {
1841
1905
  let s = [0, 1, 2];
1842
- if ((!(this.fileDirectory.getValue('ExtraSamples') === ExtraSamplesValues.Unspecified)) && enableAlpha) {
1906
+ const extraSamples = this.fileDirectory.getValue('ExtraSamples');
1907
+ if (extraSamples && extraSamples[0] !== ExtraSamplesValues.Unspecified && enableAlpha) {
1843
1908
  s = [];
1844
- for (let i = 0; i < this.fileDirectory.getValue('BitsPerSample').length; i += 1) {
1909
+ const bitsPerSample = this.fileDirectory.getValue('BitsPerSample') || [];
1910
+ for (let i = 0; i < bitsPerSample.length; i += 1) {
1845
1911
  s.push(i);
1846
1912
  }
1847
1913
  }
@@ -1896,7 +1962,7 @@ class GeoTIFFImage {
1896
1962
  data = fromBlackIsZero(raster, max);
1897
1963
  break;
1898
1964
  case photometricInterpretations.Palette:
1899
- data = fromPalette(raster, await fileDirectory.loadValue('ColorMap'));
1965
+ data = fromPalette(raster, /** @type {Uint16Array} */ (await fileDirectory.loadValue('ColorMap')));
1900
1966
  break;
1901
1967
  case photometricInterpretations.CMYK:
1902
1968
  data = fromCMYK(raster);
@@ -1923,20 +1989,23 @@ class GeoTIFFImage {
1923
1989
  }
1924
1990
  data = [red, green, blue];
1925
1991
  }
1926
- const dataWithDimensions = /** @type {import("./geotiff").ReadRasterResult} */ (data);
1992
+ const dataWithDimensions = /** @type {import("./geotiff.js").ReadRasterResult} */ (data);
1927
1993
  dataWithDimensions.width = raster.width;
1928
1994
  dataWithDimensions.height = raster.height;
1929
1995
  return dataWithDimensions;
1930
1996
  }
1931
1997
  /**
1932
1998
  * Returns an array of tiepoints.
1933
- * @returns {Promise<Object[]>}
1999
+ * @returns {Promise<Array<{i: number, j: number, k: number, x: number, y: number, z: number}>>} the tiepoints
1934
2000
  */
1935
2001
  async getTiePoints() {
1936
2002
  if (!this.fileDirectory.hasTag('ModelTiepoint')) {
1937
2003
  return [];
1938
2004
  }
1939
2005
  const modelTiePoint = await this.fileDirectory.loadValue('ModelTiepoint');
2006
+ if (typeof modelTiePoint !== 'object') {
2007
+ throw new Error('Expected ModelTiepoint to be an array or typed array.');
2008
+ }
1940
2009
  const tiePoints = [];
1941
2010
  for (let i = 0; i < modelTiePoint.length; i += 6) {
1942
2011
  tiePoints.push({
@@ -1957,14 +2026,16 @@ class GeoTIFFImage {
1957
2026
  * Otherwise only metadata specific to the provided sample will be returned.
1958
2027
  *
1959
2028
  * @param {number|null} [sample=null] The sample index.
1960
- * @returns {Promise<Object>}
2029
+ * @returns {Promise<Record<string, unknown>|null>} The GDAL metadata items
1961
2030
  */
1962
2031
  async getGDALMetadata(sample = null) {
2032
+ /** @type {Record<string, unknown>} */
1963
2033
  const metadata = {};
1964
2034
  if (!this.fileDirectory.hasTag('GDAL_METADATA')) {
1965
2035
  return null;
1966
2036
  }
1967
2037
  const string = await this.fileDirectory.loadValue('GDAL_METADATA');
2038
+ /** @type {Array<{inner: unknown}>} */
1968
2039
  let items = findTagsByName(string, 'Item');
1969
2040
  if (sample === null) {
1970
2041
  items = items.filter((item) => getAttribute(item, 'sample') === undefined);
@@ -1983,10 +2054,10 @@ class GeoTIFFImage {
1983
2054
  * @returns {number|null}
1984
2055
  */
1985
2056
  getGDALNoData() {
1986
- if (!this.fileDirectory.hasTag('GDAL_NODATA')) {
2057
+ const string = this.fileDirectory.hasTag('GDAL_NODATA') && this.fileDirectory.getValue('GDAL_NODATA');
2058
+ if (!string) {
1987
2059
  return null;
1988
2060
  }
1989
- const string = this.fileDirectory.getValue('GDAL_NODATA');
1990
2061
  return Number(string.substring(0, string.length - 1));
1991
2062
  }
1992
2063
  /**
@@ -2075,9 +2146,9 @@ class GeoTIFFImage {
2075
2146
  getBoundingBox(tilegrid = false) {
2076
2147
  const height = this.getHeight();
2077
2148
  const width = this.getWidth();
2078
- if (this.fileDirectory.hasTag('ModelTransformation') && !tilegrid) {
2079
- // eslint-disable-next-line no-unused-vars
2080
- const [a, b, c, d, e, f, g, h] = this.fileDirectory.getValue('ModelTransformation');
2149
+ const modelTransformation = this.fileDirectory.getValue('ModelTransformation');
2150
+ if (modelTransformation && !tilegrid) {
2151
+ const [a, b, , d, e, f, , h] = modelTransformation;
2081
2152
  const corners = [
2082
2153
  [0, 0],
2083
2154
  [0, height],
@@ -2115,12 +2186,20 @@ class GeoTIFFImage {
2115
2186
  }
2116
2187
 
2117
2188
  class DataView64 {
2189
+ /**
2190
+ * @param {ArrayBufferLike} arrayBuffer
2191
+ */
2118
2192
  constructor(arrayBuffer) {
2119
2193
  this._dataView = new DataView(arrayBuffer);
2120
2194
  }
2121
2195
  get buffer() {
2122
2196
  return this._dataView.buffer;
2123
2197
  }
2198
+ /**
2199
+ * @param {number} offset
2200
+ * @param {boolean} littleEndian
2201
+ * @returns {number}
2202
+ */
2124
2203
  getUint64(offset, littleEndian) {
2125
2204
  const left = this.getUint32(offset, littleEndian);
2126
2205
  const right = this.getUint32(offset + 4, littleEndian);
@@ -2140,7 +2219,12 @@ class DataView64 {
2140
2219
  }
2141
2220
  return combined;
2142
2221
  }
2143
- // adapted from https://stackoverflow.com/a/55338384/8060591
2222
+ /**
2223
+ * Adapted from https://stackoverflow.com/a/55338384/8060591
2224
+ * @param {number} offset
2225
+ * @param {boolean} littleEndian
2226
+ * @returns {number}
2227
+ */
2144
2228
  getInt64(offset, littleEndian) {
2145
2229
  let value = 0;
2146
2230
  const isNegative = (this._dataView.getUint8(offset + (littleEndian ? 7 : 0)) & 0x80) > 0;
@@ -2165,36 +2249,85 @@ class DataView64 {
2165
2249
  }
2166
2250
  return value;
2167
2251
  }
2252
+ /**
2253
+ * @param {number} offset
2254
+ * @returns {number}
2255
+ */
2168
2256
  getUint8(offset) {
2169
2257
  return this._dataView.getUint8(offset);
2170
2258
  }
2259
+ /**
2260
+ * @param {number} offset
2261
+ * @returns {number}
2262
+ */
2171
2263
  getInt8(offset) {
2172
2264
  return this._dataView.getInt8(offset);
2173
2265
  }
2266
+ /**
2267
+ * @param {number} offset
2268
+ * @param {boolean} littleEndian
2269
+ * @returns {number}
2270
+ */
2174
2271
  getUint16(offset, littleEndian) {
2175
2272
  return this._dataView.getUint16(offset, littleEndian);
2176
2273
  }
2274
+ /**
2275
+ * @param {number} offset
2276
+ * @param {boolean} littleEndian
2277
+ * @returns {number}
2278
+ */
2177
2279
  getInt16(offset, littleEndian) {
2178
2280
  return this._dataView.getInt16(offset, littleEndian);
2179
2281
  }
2282
+ /**
2283
+ * @param {number} offset
2284
+ * @param {boolean} littleEndian
2285
+ * @returns {number}
2286
+ */
2180
2287
  getUint32(offset, littleEndian) {
2181
2288
  return this._dataView.getUint32(offset, littleEndian);
2182
2289
  }
2290
+ /**
2291
+ * @param {number} offset
2292
+ * @param {boolean} littleEndian
2293
+ * @returns {number}
2294
+ */
2183
2295
  getInt32(offset, littleEndian) {
2184
2296
  return this._dataView.getInt32(offset, littleEndian);
2185
2297
  }
2298
+ /**
2299
+ * @param {number} offset
2300
+ * @param {boolean} littleEndian
2301
+ * @returns {number}
2302
+ */
2186
2303
  getFloat16(offset, littleEndian) {
2187
2304
  return getFloat16(this._dataView, offset, littleEndian);
2188
2305
  }
2306
+ /**
2307
+ * @param {number} offset
2308
+ * @param {boolean} littleEndian
2309
+ * @returns {number}
2310
+ */
2189
2311
  getFloat32(offset, littleEndian) {
2190
2312
  return this._dataView.getFloat32(offset, littleEndian);
2191
2313
  }
2314
+ /**
2315
+ * @param {number} offset
2316
+ * @param {boolean} littleEndian
2317
+ * @returns {number}
2318
+ */
2192
2319
  getFloat64(offset, littleEndian) {
2193
2320
  return this._dataView.getFloat64(offset, littleEndian);
2194
2321
  }
2195
2322
  }
2196
2323
 
2197
2324
  class DataSlice {
2325
+ /**
2326
+ * @param {ArrayBufferLike} arrayBuffer
2327
+ * @param {number} sliceOffset
2328
+ * @param {boolean} littleEndian
2329
+ * @param {boolean} bigTiff
2330
+ */
2198
2331
  constructor(arrayBuffer, sliceOffset, littleEndian, bigTiff) {
2199
2332
  this._dataView = new DataView(arrayBuffer);
2200
2333
  this._sliceOffset = sliceOffset;
@@ -2216,33 +2349,74 @@ class DataSlice {
2216
2349
  get buffer() {
2217
2350
  return this._dataView.buffer;
2218
2351
  }
2352
+ /**
2353
+ * @param {number} offset
2354
+ * @param {number} length
2355
+ * @returns {boolean}
2356
+ */
2219
2357
  covers(offset, length) {
2220
2358
  return this.sliceOffset <= offset && this.sliceTop >= offset + length;
2221
2359
  }
2360
+ /**
2361
+ * @param {number} offset
2362
+ * @returns {number}
2363
+ */
2222
2364
  readUint8(offset) {
2223
2365
  return this._dataView.getUint8(offset - this._sliceOffset);
2224
2366
  }
2367
+ /**
2368
+ * @param {number} offset
2369
+ * @returns {number}
2370
+ */
2225
2371
  readInt8(offset) {
2226
2372
  return this._dataView.getInt8(offset - this._sliceOffset);
2227
2373
  }
2374
+ /**
2375
+ * @param {number} offset
2376
+ * @returns {number}
2377
+ */
2228
2378
  readUint16(offset) {
2229
2379
  return this._dataView.getUint16(offset - this._sliceOffset, this._littleEndian);
2230
2380
  }
2381
+ /**
2382
+ * @param {number} offset
2383
+ * @returns {number}
2384
+ */
2231
2385
  readInt16(offset) {
2232
2386
  return this._dataView.getInt16(offset - this._sliceOffset, this._littleEndian);
2233
2387
  }
2388
+ /**
2389
+ * @param {number} offset
2390
+ * @returns {number}
2391
+ */
2234
2392
  readUint32(offset) {
2235
2393
  return this._dataView.getUint32(offset - this._sliceOffset, this._littleEndian);
2236
2394
  }
2395
+ /**
2396
+ * @param {number} offset
2397
+ * @returns {number}
2398
+ */
2237
2399
  readInt32(offset) {
2238
2400
  return this._dataView.getInt32(offset - this._sliceOffset, this._littleEndian);
2239
2401
  }
2402
+ /**
2403
+ * @param {number} offset
2404
+ * @returns {number}
2405
+ */
2240
2406
  readFloat32(offset) {
2241
2407
  return this._dataView.getFloat32(offset - this._sliceOffset, this._littleEndian);
2242
2408
  }
2409
+ /**
2410
+ * @param {number} offset
2411
+ * @returns {number}
2412
+ */
2243
2413
  readFloat64(offset) {
2244
2414
  return this._dataView.getFloat64(offset - this._sliceOffset, this._littleEndian);
2245
2415
  }
2416
+ /**
2417
+ * @param {number} offset
2418
+ * @returns {number}
2419
+ */
2246
2420
  readUint64(offset) {
2247
2421
  const left = this.readUint32(offset);
2248
2422
  const right = this.readUint32(offset + 4);
@@ -2262,7 +2436,11 @@ class DataSlice {
2262
2436
  }
2263
2437
  return combined;
2264
2438
  }
2265
- // adapted from https://stackoverflow.com/a/55338384/8060591
2439
+ /**
2440
+ * Adapted from https://stackoverflow.com/a/55338384/8060591
2441
+ * @param {number} offset
2442
+ * @returns {number}
2443
+ */
2266
2444
  readInt64(offset) {
2267
2445
  let value = 0;
2268
2446
  const isNegative = (this._dataView.getUint8(offset + (this._littleEndian ? 7 : 0)) & 0x80)
@@ -2288,6 +2466,10 @@ class DataSlice {
2288
2466
  }
2289
2467
  return value;
2290
2468
  }
2469
+ /**
2470
+ * @param {number} offset
2471
+ * @returns {number}
2472
+ */
2291
2473
  readOffset(offset) {
2292
2474
  if (this._bigTiff) {
2293
2475
  return this.readUint64(offset);
@@ -2297,13 +2479,17 @@ class DataSlice {
2297
2479
  }
2298
2480
 
2299
2481
  const CRLFCRLF = '\r\n\r\n';
2300
- /*
2482
+ /**
2301
2483
  * Shim for 'Object.fromEntries'
2484
+ * @template T
2485
+ * @param {Array<[string, T]>} items
2486
+ * @return {Record<string, T>}
2302
2487
  */
2303
2488
  function itemsToObject(items) {
2304
2489
  if (typeof Object.fromEntries !== 'undefined') {
2305
2490
  return Object.fromEntries(items);
2306
2491
  }
2492
+ /** @type {Record<string, T>} */
2307
2493
  const obj = {};
2308
2494
  for (const [key, value] of items) {
2309
2495
  obj[key.toLowerCase()] = value;
@@ -2312,14 +2498,15 @@ function itemsToObject(items) {
2312
2498
  }
2313
2499
  /**
2314
2500
  * Parse HTTP headers from a given string.
2315
- * @param {String} text the text to parse the headers from
2316
- * @returns {Object} the parsed headers with lowercase keys
2501
+ * @param {string} text the text to parse the headers from
2502
+ * @returns {Record<string, string>} the parsed headers with lowercase keys
2317
2503
  */
2318
2504
  function parseHeaders(text) {
2505
+ /** @type {Array<[string, string]>} */
2319
2506
  const items = text
2320
2507
  .split('\r\n')
2321
2508
  .map((line) => {
2322
- const kv = line.split(':').map((str) => str.trim());
2509
+ const kv = /** @type {[string, string]} */ (line.split(':').map((str) => str.trim()));
2323
2510
  kv[0] = kv[0].toLowerCase();
2324
2511
  return kv;
2325
2512
  });
@@ -2327,8 +2514,8 @@ function parseHeaders(text) {
2327
2514
  }
2328
2515
  /**
2329
2516
  * Parse a 'Content-Type' header value to the content-type and parameters
2330
- * @param {string|null} rawContentType the raw string to parse from
2331
- * @returns {{type: string|null, params: Object}}}
2517
+ * @param {string|undefined} rawContentType the raw string to parse from
2518
+ * @returns {{type: string|null, params: Record<string, string>}}
2332
2519
  * the parsed content type with the fields: type and params
2333
2520
  */
2334
2521
  function parseContentType(rawContentType) {
@@ -2336,12 +2523,12 @@ function parseContentType(rawContentType) {
2336
2523
  return { type: null, params: {} };
2337
2524
  }
2338
2525
  const [type, ...rawParams] = rawContentType.split(';').map((s) => s.trim());
2339
- const paramsItems = rawParams.map((param) => param.split('='));
2526
+ const paramsItems = /** @type {Array<[string, string]>} */ (rawParams.map((param) => param.split('=')));
2340
2527
  return { type, params: itemsToObject(paramsItems) };
2341
2528
  }
2342
2529
  /**
2343
2530
  * Parse a 'Content-Range' header value to its start, end, and total parts
2344
- * @param {string|null} rawContentRange the raw string to parse from
2531
+ * @param {string|undefined} rawContentRange the raw string to parse from
2345
2532
  * @returns {{start: number, end: number, total: number}} the parsed parts
2346
2533
  */
2347
2534
  function parseContentRange(rawContentRange) {
@@ -2361,11 +2548,12 @@ function parseContentRange(rawContentRange) {
2361
2548
  * - offset: the offset of the byterange within its originating file
2362
2549
  * - length: the length of the byterange
2363
2550
  * @param {ArrayBuffer} responseArrayBuffer the response to be parsed and split
2364
- * @param {String} boundary the boundary string used to split the sections
2365
- * @returns {Object[]} the parsed byteranges
2551
+ * @param {string} boundary the boundary string used to split the sections
2552
+ * @returns {Array<{headers: Record<string, string>, data: ArrayBuffer, offset: number, length: number, fileSize: number}>}
2553
+ * the parsed byteranges
2366
2554
  */
2367
2555
  function parseByteRanges(responseArrayBuffer, boundary) {
2368
- let offset = null;
2556
+ let offset = -1;
2369
2557
  const decoder = new TextDecoder('ascii');
2370
2558
  const out = [];
2371
2559
  const startBoundary = `--${boundary}`;
@@ -2378,7 +2566,7 @@ function parseByteRanges(responseArrayBuffer, boundary) {
2378
2566
  offset = i;
2379
2567
  }
2380
2568
  }
2381
- if (offset === null) {
2569
+ if (offset === -1) {
2382
2570
  throw new Error('Could not find initial boundary');
2383
2571
  }
2384
2572
  while (offset < responseArrayBuffer.byteLength) {
@@ -2417,29 +2605,31 @@ function parseByteRanges(responseArrayBuffer, boundary) {
2417
2605
  }
2418
2606
 
2419
2607
  /**
2420
- * @typedef Slice
2608
+ * @typedef {Object} Slice
2421
2609
  * @property {number} offset
2422
2610
  * @property {number} length
2423
2611
  */
2612
+ /** @typedef {Slice & {data: ArrayBufferLike}} SliceWithData */
2424
2613
  class BaseSource {
2425
2614
  /**
2426
2615
  * @param {Array<Slice>} slices
2427
2616
  * @param {AbortSignal} [signal]
2428
- * @returns {Promise<*[]>}
2617
+ * @returns {Promise<ArrayBufferLike[]>}
2429
2618
  */
2430
2619
  async fetch(slices, signal) {
2431
- return Promise.all(slices.map((slice) => this.fetchSlice(slice, signal)));
2620
+ return Promise.all(slices.map(async (slice) => (await this.fetchSlice(slice, signal)).data));
2432
2621
  }
2433
2622
  /**
2434
2623
  * @param {Slice} slice
2435
2624
  * @param {AbortSignal} [_signal]
2436
- * @returns {Promise<*>}
2625
+ * @returns {Promise<SliceWithData>}
2437
2626
  */
2438
2627
  async fetchSlice(slice, _signal) {
2439
2628
  throw new Error(`fetching of slice ${slice} not possible, not implemented`);
2440
2629
  }
2441
2630
  /**
2442
2631
  * Returns the filesize if already determined and null otherwise
2632
+ * @returns {number|null}
2443
2633
  */
2444
2634
  get fileSize() {
2445
2635
  return null;
@@ -2733,18 +2923,14 @@ class QuickLRU extends Map {
2733
2923
  }
2734
2924
  }
2735
2925
 
2736
- /*
2926
+ /**
2737
2927
  * Promisified wrapper around 'setTimeout' to allow 'await'
2928
+ * @param {number} [milliseconds]
2929
+ * @returns {Promise<void>}
2738
2930
  */
2739
2931
  async function wait(milliseconds) {
2740
2932
  return new Promise((resolve) => setTimeout(resolve, milliseconds));
2741
2933
  }
2742
- /**
2743
- * @template T,U
2744
- * @param {Iterable<T>} a
2745
- * @param {Iterable<U>} b
2746
- * @returns {Array<[T, U]>}
2747
- */
2748
2934
  function zip(a, b) {
2749
2935
  const A = Array.isArray(a) ? a : Array.from(a);
2750
2936
  const B = Array.isArray(b) ? b : Array.from(b);
@@ -2752,14 +2938,15 @@ function zip(a, b) {
2752
2938
  }
2753
2939
  // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
2754
2940
  class AbortError extends Error {
2755
- constructor(params) {
2941
+ constructor(...args) {
2756
2942
  // Pass remaining arguments (including vendor specific ones) to parent constructor
2757
- super(params);
2943
+ super(...args);
2758
2944
  // Maintains proper stack trace for where our error was thrown (only available on V8)
2759
2945
  if (Error.captureStackTrace) {
2760
2946
  Error.captureStackTrace(this, AbortError);
2761
2947
  }
2762
2948
  this.name = 'AbortError';
2949
+ this.signal = undefined;
2763
2950
  }
2764
2951
  }
2765
2952
  class CustomAggregateError extends Error {
@@ -2834,7 +3021,7 @@ class BlockedSource extends BaseSource {
2834
3021
  return this.source.fileSize;
2835
3022
  }
2836
3023
  /**
2837
- * @param {import("./basesource").Slice[]} slices
3024
+ * @param {import("./basesource.js").Slice[]} slices
2838
3025
  * @param {AbortSignal} [signal]
2839
3026
  * @return {Promise<ArrayBuffer[]>}
2840
3027
  */
@@ -2916,24 +3103,25 @@ class BlockedSource extends BaseSource {
2916
3103
  if (this.blockIdsToFetch.size > 0) {
2917
3104
  const groups = this.groupBlocks(this.blockIdsToFetch);
2918
3105
  // start requesting slices of data
2919
- const groupRequests = this.source.fetch(groups, signal);
3106
+ const groupRequests = groups.map(async (group) => ({ ...group, ...(await this.source.fetchSlice(group, signal)) }));
2920
3107
  for (let groupIndex = 0; groupIndex < groups.length; ++groupIndex) {
2921
3108
  const group = groups[groupIndex];
2922
3109
  for (const blockId of group.blockIds) {
2923
3110
  // make an async IIFE for each block
2924
3111
  this.blockRequests.set(blockId, (async () => {
2925
3112
  try {
2926
- const response = (await groupRequests)[groupIndex];
3113
+ const response = (await Promise.all(groupRequests))[groupIndex];
2927
3114
  const blockOffset = blockId * this.blockSize;
2928
3115
  const o = blockOffset - response.offset;
2929
3116
  const t = Math.min(o + this.blockSize, response.data.byteLength);
2930
3117
  const data = response.data.slice(o, t);
2931
- const block = new Block(blockOffset, data.byteLength, data);
3118
+ const block = new Block(blockOffset, data.byteLength,
3119
+ /** @type {ArrayBuffer} */ (data));
2932
3120
  this.blockCache.set(blockId, block);
2933
3121
  this.abortedBlockIds.delete(blockId);
2934
3122
  }
2935
3123
  catch (err) {
2936
- if (err.name === 'AbortError') {
3124
+ if (err instanceof AbortError && err.name === 'AbortError') {
2937
3125
  // store the signal here, we need it to determine later if an
2938
3126
  // error was caused by this signal
2939
3127
  err.signal = signal;
@@ -2955,7 +3143,7 @@ class BlockedSource extends BaseSource {
2955
3143
  }
2956
3144
  /**
2957
3145
  *
2958
- * @param {Set} blockIds
3146
+ * @param {Set<number>} blockIds
2959
3147
  * @returns {BlockGroup[]}
2960
3148
  */
2961
3149
  groupBlocks(blockIds) {
@@ -2963,6 +3151,7 @@ class BlockedSource extends BaseSource {
2963
3151
  if (sortedBlockIds.length === 0) {
2964
3152
  return [];
2965
3153
  }
3154
+ /** @type {number[]} */
2966
3155
  let current = [];
2967
3156
  let lastBlockId = null;
2968
3157
  const groups = [];
@@ -2981,7 +3170,7 @@ class BlockedSource extends BaseSource {
2981
3170
  return groups;
2982
3171
  }
2983
3172
  /**
2984
- * @param {import("./basesource").Slice[]} slices
3173
+ * @param {import("./basesource.js").Slice[]} slices
2985
3174
  * @param {Map<number, Block>} blocks
2986
3175
  * @returns {ArrayBuffer[]}
2987
3176
  */
@@ -3041,10 +3230,10 @@ class BaseResponse {
3041
3230
  }
3042
3231
  /**
3043
3232
  * Returns the value of the specified header
3044
- * @param {string} headerName the header name
3045
- * @returns {string|null} the header value
3233
+ * @param {string} _headerName the header name
3234
+ * @returns {string|undefined} the header value
3046
3235
  */
3047
- getHeader(headerName) {
3236
+ getHeader(_headerName) {
3048
3237
  throw new Error('not implemented');
3049
3238
  }
3050
3239
  /**
@@ -3055,15 +3244,16 @@ class BaseResponse {
3055
3244
  }
3056
3245
  }
3057
3246
  class BaseClient {
3247
+ /** @param {string} url */
3058
3248
  constructor(url) {
3059
3249
  this.url = url;
3060
3250
  }
3061
3251
  /**
3062
3252
  * Send a request with the options
3063
- * @param {RequestInit} [options={}]
3253
+ * @param {RequestInit} [_options={}]
3064
3254
  * @returns {Promise<BaseResponse>}
3065
3255
  */
3066
- async request({ headers, signal } = {}) {
3256
+ async request(_options) {
3067
3257
  throw new Error('request is not implemented');
3068
3258
  }
3069
3259
  }
@@ -3082,10 +3272,10 @@ class FetchResponse extends BaseResponse {
3082
3272
  }
3083
3273
  /**
3084
3274
  * @param {string} name
3085
- * @returns {string|null}
3275
+ * @returns {string|undefined}
3086
3276
  */
3087
3277
  getHeader(name) {
3088
- return this.response.headers.get(name);
3278
+ return this.response.headers.get(name) || undefined;
3089
3279
  }
3090
3280
  async getData() {
3091
3281
  const data = this.response.arrayBuffer
@@ -3096,6 +3286,10 @@ class FetchResponse extends BaseResponse {
3096
3286
  }
3097
3287
  }
3098
3288
  class FetchClient extends BaseClient {
3289
+ /**
3290
+ * @param {string} url
3291
+ * @param {RequestCredentials} [credentials]
3292
+ */
3099
3293
  constructor(url, credentials) {
3100
3294
  super(url);
3101
3295
  this.credentials = credentials;
@@ -3126,14 +3320,23 @@ class XHRResponse extends BaseResponse {
3126
3320
  get status() {
3127
3321
  return this.xhr.status;
3128
3322
  }
3323
+ /**
3324
+ * @param {string} name
3325
+ * @returns {string|undefined}
3326
+ */
3129
3327
  getHeader(name) {
3130
- return this.xhr.getResponseHeader(name);
3328
+ return this.xhr.getResponseHeader(name) || undefined;
3131
3329
  }
3132
3330
  async getData() {
3133
3331
  return this.data;
3134
3332
  }
3135
3333
  }
3136
3334
  class XHRClient extends BaseClient {
3335
+ /**
3336
+ * @param {Object<string, string>} headers
3337
+ * @param {AbortSignal} [signal]
3338
+ * @returns {Promise<XHRResponse>}
3339
+ */
3137
3340
  constructRequest(headers, signal) {
3138
3341
  return new Promise((resolve, reject) => {
3139
3342
  const xhr = new XMLHttpRequest();
@@ -3158,7 +3361,7 @@ class XHRClient extends BaseClient {
3158
3361
  }
3159
3362
  });
3160
3363
  }
3161
- async request({ headers = undefined, signal = undefined } = {}) {
3364
+ async request({ headers = {}, signal = undefined } = {}) {
3162
3365
  const response = await this.constructRequest(headers, signal);
3163
3366
  return response;
3164
3367
  }
@@ -3170,6 +3373,7 @@ class HttpResponse extends BaseResponse {
3170
3373
  /**
3171
3374
  * BaseResponse facade for node HTTP/HTTPS API Response
3172
3375
  * @param {import('http').IncomingMessage} response
3376
+ * @param {Promise<ArrayBuffer>} dataPromise
3173
3377
  */
3174
3378
  constructor(response, dataPromise) {
3175
3379
  super();
@@ -3179,8 +3383,13 @@ class HttpResponse extends BaseResponse {
3179
3383
  get status() {
3180
3384
  return /** @type {number} */ (this.response.statusCode);
3181
3385
  }
3386
+ /**
3387
+ * @param {string} name
3388
+ * @returns {string|undefined}
3389
+ */
3182
3390
  getHeader(name) {
3183
- return /** @type {string|null} */ (this.response.headers[name]);
3391
+ const value = this.response.headers[name];
3392
+ return Array.isArray(value) ? value.join(', ') : value;
3184
3393
  }
3185
3394
  async getData() {
3186
3395
  const data = await this.dataPromise;
@@ -3188,11 +3397,17 @@ class HttpResponse extends BaseResponse {
3188
3397
  }
3189
3398
  }
3190
3399
  class HttpClient extends BaseClient {
3400
+ /** @param {string} url */
3191
3401
  constructor(url) {
3192
3402
  super(url);
3193
3403
  this.parsedUrl = fs.parse(this.url);
3194
3404
  this.httpApi = (this.parsedUrl.protocol === 'http:' ? fs : fs);
3195
3405
  }
3406
+ /**
3407
+ * @param {Object<string, string>} headers
3408
+ * @param {AbortSignal} [signal]
3409
+ * @returns {Promise<HttpResponse>}
3410
+ */
3196
3411
  constructRequest(headers, signal) {
3197
3412
  return new Promise((resolve, reject) => {
3198
3413
  const request = this.httpApi.get({
@@ -3200,6 +3415,7 @@ class HttpClient extends BaseClient {
3200
3415
  headers,
3201
3416
  }, (response) => {
3202
3417
  const dataPromise = new Promise((resolveData) => {
3418
+ /** @type {Uint8Array[]} */
3203
3419
  const chunks = [];
3204
3420
  // collect chunks
3205
3421
  response.on('data', (chunk) => {
@@ -3223,7 +3439,7 @@ class HttpClient extends BaseClient {
3223
3439
  }
3224
3440
  });
3225
3441
  }
3226
- async request({ headers = undefined, signal = undefined } = {}) {
3442
+ async request({ headers = {}, signal = undefined } = {}) {
3227
3443
  const response = await this.constructRequest(headers, signal);
3228
3444
  return response;
3229
3445
  }
@@ -3232,7 +3448,7 @@ class HttpClient extends BaseClient {
3232
3448
  /** @import { RemoteSourceOptions, BlockedSourceOptions } from '../geotiff.js' */
3233
3449
  class RemoteSource extends BaseSource {
3234
3450
  /**
3235
- * @param {import("../geotiff").BaseClient} client
3451
+ * @param {import("../geotiff.js").BaseClient} client
3236
3452
  * @param {RemoteSourceOptions} options
3237
3453
  */
3238
3454
  constructor(client, { headers, maxRanges = 0, allowFullFile } = {}) {
@@ -3246,24 +3462,29 @@ class RemoteSource extends BaseSource {
3246
3462
  /**
3247
3463
  * @param {import('./basesource.js').Slice[]} slices
3248
3464
  * @param {AbortSignal} [signal]
3249
- * @returns {Promise<*[]>}
3465
+ * @returns {Promise<ArrayBufferLike[]>}
3250
3466
  */
3251
3467
  async fetch(slices, signal) {
3252
3468
  // if we allow multi-ranges, split the incoming request into that many sub-requests
3253
3469
  // and join them afterwards
3254
3470
  if (this.maxRanges >= slices.length) {
3255
- return this.fetchSlices(slices, signal);
3471
+ return this.fetchSlices(slices, signal).then((results) => results.map((r) => r.data));
3256
3472
  }
3257
3473
  else if (this.maxRanges > 0 && slices.length > 1) ;
3258
3474
  // otherwise make a single request for each slice
3259
- return Promise.all(slices.map((slice) => this.fetchSlice(slice, signal)));
3475
+ return Promise.all(slices.map(async (slice) => (await this.fetchSlice(slice, signal)).data));
3260
3476
  }
3477
+ /**
3478
+ * @param {Array<import('./basesource.js').Slice>} slices
3479
+ * @param {AbortSignal} [signal]
3480
+ * @returns {Promise<Array<import('./basesource.js').SliceWithData>>}
3481
+ */
3261
3482
  async fetchSlices(slices, signal) {
3262
3483
  const response = await this.client.request({
3263
3484
  headers: {
3264
3485
  ...this.headers,
3265
3486
  Range: `bytes=${slices
3266
- .map(({ offset, length }) => `${offset}-${offset + length}`)
3487
+ .map(({ offset, length }) => `${offset}-${offset + length - 1}`)
3267
3488
  .join(',')}`,
3268
3489
  },
3269
3490
  signal,
@@ -3281,10 +3502,11 @@ class RemoteSource extends BaseSource {
3281
3502
  const data = await response.getData();
3282
3503
  const { start, end, total } = parseContentRange(response.getHeader('content-range'));
3283
3504
  this._fileSize = total || null;
3505
+ /** @type {import('./basesource.js').SliceWithData[]} */
3284
3506
  const first = [{
3285
3507
  data,
3286
3508
  offset: start,
3287
- length: end - start,
3509
+ length: end + 1 - start,
3288
3510
  }];
3289
3511
  if (slices.length > 1) {
3290
3512
  // we requested more than one slice, but got only the first
@@ -3309,12 +3531,17 @@ class RemoteSource extends BaseSource {
3309
3531
  }];
3310
3532
  }
3311
3533
  }
3534
+ /**
3535
+ * @param {import('./basesource.js').Slice} slice
3536
+ * @param {AbortSignal} [signal]
3537
+ * @returns {Promise<import('./basesource.js').SliceWithData>}
3538
+ */
3312
3539
  async fetchSlice(slice, signal) {
3313
3540
  const { offset, length } = slice;
3314
3541
  const response = await this.client.request({
3315
3542
  headers: {
3316
3543
  ...this.headers,
3317
- Range: `bytes=${offset}-${offset + length}`,
3544
+ Range: `bytes=${offset}-${offset + length - 1}`,
3318
3545
  },
3319
3546
  signal,
3320
3547
  });
@@ -3355,7 +3582,7 @@ class RemoteSource extends BaseSource {
3355
3582
  * @returns {BaseSource}
3356
3583
  */
3357
3584
  function maybeWrapInBlockedSource(source, { blockSize, cacheSize }) {
3358
- if (blockSize === null) {
3585
+ if (blockSize === undefined) {
3359
3586
  return source;
3360
3587
  }
3361
3588
  return new BlockedSource(source, { blockSize, cacheSize });
@@ -3406,17 +3633,30 @@ function makeRemoteSource(url, { forceXHR = false, ...clientOptions } = {}) {
3406
3633
  }
3407
3634
 
3408
3635
  class ArrayBufferSource extends BaseSource {
3636
+ /**
3637
+ * @param {ArrayBuffer} arrayBuffer
3638
+ */
3409
3639
  constructor(arrayBuffer) {
3410
3640
  super();
3411
3641
  this.arrayBuffer = arrayBuffer;
3412
3642
  }
3643
+ /**
3644
+ * @param {import('./basesource.js').Slice} slice
3645
+ * @param {AbortSignal} [signal]
3646
+ * @returns {Promise<import('./basesource.js').SliceWithData>}
3647
+ */
3413
3648
  fetchSlice(slice, signal) {
3414
3649
  if (signal && signal.aborted) {
3415
3650
  throw new AbortError('Request aborted');
3416
3651
  }
3417
- return this.arrayBuffer.slice(slice.offset, slice.offset + slice.length);
3652
+ return Promise.resolve({
3653
+ data: this.arrayBuffer.slice(slice.offset, slice.offset + slice.length),
3654
+ offset: slice.offset,
3655
+ length: slice.length,
3656
+ });
3418
3657
  }
3419
3658
  }
3659
+ /** @param {ArrayBuffer} arrayBuffer */
3420
3660
  function makeBufferSource(arrayBuffer) {
3421
3661
  return new ArrayBufferSource(arrayBuffer);
3422
3662
  }
@@ -3514,6 +3754,17 @@ function getDataSliceReader(dataSlice, fieldType) {
3514
3754
  * @param {true} isArray - Whether to always return an array (vs single value)
3515
3755
  * @returns {import('./geotiff.js').TypedArray|Array<number>} The decoded value(s)
3516
3756
  */
3757
+ /**
3758
+ * @overload
3759
+ * @param {import('./geotiff.js').TypedArray|Array<number>|null} outValues - Optional pre-allocated output array
3760
+ * @param {Function} readMethod - DataView read method (e.g., getUint16)
3761
+ * @param {DataSlice} dataSlice - Source data slice
3762
+ * @param {number} fieldType - TIFF field type constant
3763
+ * @param {number} count - Number of values to read
3764
+ * @param {number} offset - Byte offset to start reading
3765
+ * @param {boolean} [isArray] - Whether to always return an array (vs single value)
3766
+ * @returns {import('./geotiff.js').TypedArray|Array<number>|string|number} The decoded value(s)
3767
+ */
3517
3768
  /**
3518
3769
  * Reads field values from a DataSlice.
3519
3770
  * @param {import('./geotiff.js').TypedArray|Array<number>|null} outValues - Optional pre-allocated output array
@@ -3638,9 +3889,11 @@ class DeferredArray {
3638
3889
  class ImageFileDirectory {
3639
3890
  /**
3640
3891
  * Create an ImageFileDirectory.
3641
- * @param {Map} actualizedFields the file directory, mapping tag names to values
3642
- * @param {Map} deferredFields the deferred fields, mapping tag names to async functions
3643
- * @param {Map} deferredArrays the deferred arrays, mapping tag names to DeferredArray objects
3892
+ * @param {Map<string|number, number|string|Array<number|string>>} actualizedFields the file directory,
3893
+ * mapping tag names to values
3894
+ * @param {Map<string|number, Function>} deferredFields the deferred fields, mapping tag names to async functions
3895
+ * @param {Map<string|number, DeferredArray>} deferredArrays the deferred arrays, mapping tag names to
3896
+ * DeferredArray objects
3644
3897
  * @param {number} nextIFDByteOffset the byte offset to the next IFD
3645
3898
  */
3646
3899
  constructor(actualizedFields, deferredFields, deferredArrays, nextIFDByteOffset) {
@@ -3651,7 +3904,7 @@ class ImageFileDirectory {
3651
3904
  this.nextIFDByteOffset = nextIFDByteOffset;
3652
3905
  }
3653
3906
  /**
3654
- * @param {number|string} tagIdentifier The field tag ID or name
3907
+ * @param {import('./globals.js').TagName|number} tagIdentifier The field tag ID or name
3655
3908
  * @returns {boolean} whether the field exists (actualized or deferred)
3656
3909
  */
3657
3910
  hasTag(tagIdentifier) {
@@ -3660,8 +3913,11 @@ class ImageFileDirectory {
3660
3913
  }
3661
3914
  /**
3662
3915
  * Synchronously retrieves the value for a given tag. If it is deferred, an error is thrown.
3663
- * @param {number|string} tagIdentifier The field tag ID or name
3664
- * @returns the field value, or undefined if it does not exist
3916
+ * @template {import('./globals.js').EagerTagName | import('./globals.js').EagerTag} [T=any]
3917
+ * @param {T} tagIdentifier The field tag ID or name
3918
+ * @returns {T extends import('./globals.js').TagName ? (import('./globals.js').TagValue<T> | undefined) : any}
3919
+ * the field value,
3920
+ * or undefined if it does not exist
3665
3921
  * @throws {Error} If the tag is deferred and requires asynchronous loading
3666
3922
  */
3667
3923
  getValue(tagIdentifier) {
@@ -3672,25 +3928,27 @@ class ImageFileDirectory {
3672
3928
  throw new Error(`Field '${tagName}' (${tag}) is deferred. Use loadValue() to load it asynchronously.`);
3673
3929
  }
3674
3930
  if (!this.actualizedFields.has(tag)) {
3675
- return undefined;
3931
+ return /** @type {any} */ (undefined);
3676
3932
  }
3677
- return this.actualizedFields.get(tag);
3933
+ return /** @type {any} */ (this.actualizedFields.get(tag));
3678
3934
  }
3679
3935
  /**
3680
3936
  * Retrieves the value for a given tag. If it is deferred, it will be loaded first.
3681
- * @param {number|string} tagIdentifier The field tag ID or name
3682
- * @returns the field value, or undefined if it does not exist
3937
+ * @template {import('./globals.js').TagName} [T=any]
3938
+ * @param {T|number} tagIdentifier The field tag ID or name
3939
+ * @returns {Promise<T extends import('./globals.js').TagName ? (import('./globals.js').TagValue<T> | undefined) : any>}
3940
+ * the field value, or undefined if it does not exist
3683
3941
  */
3684
3942
  async loadValue(tagIdentifier) {
3685
3943
  const tag = resolveTag(tagIdentifier);
3686
3944
  if (this.actualizedFields.has(tag)) {
3687
- return this.actualizedFields.get(tag);
3945
+ return /** @type {any} */ (this.actualizedFields.get(tag));
3688
3946
  }
3689
3947
  if (this.deferredFieldsBeingResolved.has(tag)) {
3690
- return this.deferredFieldsBeingResolved.get(tag);
3948
+ return /** @type {any} */ (this.deferredFieldsBeingResolved.get(tag));
3691
3949
  }
3692
- if (this.deferredFields.has(tag)) {
3693
- const loaderFn = this.deferredFields.get(tag);
3950
+ const loaderFn = this.deferredFields.get(tag);
3951
+ if (loaderFn) {
3694
3952
  this.deferredFields.delete(tag);
3695
3953
  // Set promise BEFORE starting async work to prevent race conditions
3696
3954
  const valuePromise = (async () => {
@@ -3704,32 +3962,35 @@ class ImageFileDirectory {
3704
3962
  }
3705
3963
  })();
3706
3964
  this.deferredFieldsBeingResolved.set(tag, valuePromise);
3707
- return valuePromise;
3965
+ return /** @type {any} */ (valuePromise);
3708
3966
  }
3709
- if (this.deferredArrays.has(tag)) {
3710
- const deferredArray = this.deferredArrays.get(tag);
3711
- return deferredArray.loadAll();
3967
+ const deferredArray = this.deferredArrays.get(tag);
3968
+ if (deferredArray) {
3969
+ return /** @type {any} */ (deferredArray.loadAll());
3712
3970
  }
3713
- return undefined;
3971
+ return /** @type {any} */ (undefined);
3714
3972
  }
3715
3973
  /**
3716
3974
  * Retrieves the value at a given index for a tag that is an array. If it is deferred, it will be loaded first.
3717
3975
  * @param {number|string} tagIdentifier The field tag ID or name
3718
3976
  * @param {number} index The index within the array
3719
- * @returns the field value at the given index, or undefined if it does not exist
3977
+ * @returns {Promise<number|string|bigint|undefined>} the field value at the given index, or undefined if it does not exist
3720
3978
  */
3721
3979
  async loadValueIndexed(tagIdentifier, index) {
3722
3980
  const tag = resolveTag(tagIdentifier);
3723
3981
  if (this.actualizedFields.has(tag)) {
3724
3982
  const value = this.actualizedFields.get(tag);
3725
- return value[index];
3983
+ return /** @type {any} */ (value)[index];
3726
3984
  }
3727
3985
  else if (this.deferredArrays.has(tag)) {
3728
- const deferredArray = this.deferredArrays.get(tag);
3986
+ const deferredArray = /** @type {DeferredArray} */ (this.deferredArrays.get(tag));
3729
3987
  return deferredArray.get(index);
3730
3988
  }
3731
3989
  else if (this.hasTag(tag)) {
3732
- return (await this.loadValue(tag))[index];
3990
+ const value = await this.loadValue(tag);
3991
+ if (value && typeof value !== 'number') {
3992
+ return value[index];
3993
+ }
3733
3994
  }
3734
3995
  return undefined;
3735
3996
  }
@@ -3749,8 +4010,8 @@ class ImageFileDirectory {
3749
4010
  /** @type {Partial<Record<import('./globals.js').GeoKeyName, *>>} */
3750
4011
  const geoKeyDirectory = {};
3751
4012
  for (let i = 4; i <= rawGeoKeyDirectory[3] * 4; i += 4) {
3752
- const key = geoKeyNames[rawGeoKeyDirectory[i]];
3753
- const location = rawGeoKeyDirectory[i + 1] || null;
4013
+ const key = ( /** @type {Record<number, import('./globals.js').GeoKeyName>} */(geoKeyNames))[rawGeoKeyDirectory[i]];
4014
+ const location = /** @type {import('./globals.js').EagerTag} */ (rawGeoKeyDirectory[i + 1]) || null;
3754
4015
  const count = rawGeoKeyDirectory[i + 2];
3755
4016
  const offset = rawGeoKeyDirectory[i + 3];
3756
4017
  let value = null;
@@ -3777,9 +4038,10 @@ class ImageFileDirectory {
3777
4038
  return geoKeyDirectory;
3778
4039
  }
3779
4040
  toObject() {
4041
+ /** @type {Record<string, unknown>} */
3780
4042
  const obj = {};
3781
4043
  for (const [tag, value] of this.actualizedFields.entries()) {
3782
- const tagDefinition = tagDefinitions[tag];
4044
+ const tagDefinition = typeof tag === 'number' ? tagDefinitions[tag] : undefined;
3783
4045
  const tagName = tagDefinition ? tagDefinition.name : `Tag${tag}`;
3784
4046
  obj[tagName] = value;
3785
4047
  }
@@ -3903,6 +4165,10 @@ class ImageFileDirectoryParser {
3903
4165
  }
3904
4166
  }
3905
4167
 
4168
+ /**
4169
+ * @param {Uint8Array|Uint16Array|Uint32Array} row
4170
+ * @param {number} stride
4171
+ */
3906
4172
  function decodeRowAcc(row, stride) {
3907
4173
  let length = row.length - stride;
3908
4174
  let offset = 0;
@@ -3914,6 +4180,11 @@ function decodeRowAcc(row, stride) {
3914
4180
  length -= stride;
3915
4181
  } while (length > 0);
3916
4182
  }
4183
+ /**
4184
+ * @param {Uint8Array} row
4185
+ * @param {number} stride
4186
+ * @param {number} bytesPerSample
4187
+ */
3917
4188
  function decodeRowFloatingPoint(row, stride, bytesPerSample) {
3918
4189
  let index = 0;
3919
4190
  let count = row.length;
@@ -3932,6 +4203,15 @@ function decodeRowFloatingPoint(row, stride, bytesPerSample) {
3932
4203
  }
3933
4204
  }
3934
4205
  }
4206
+ /**
4207
+ * @param {ArrayBufferLike} block
4208
+ * @param {number} predictor
4209
+ * @param {number} width
4210
+ * @param {number} height
4211
+ * @param {number[]} bitsPerSample
4212
+ * @param {number} planarConfiguration
4213
+ * @returns
4214
+ */
3935
4215
  function applyPredictor(block, predictor, width, height, bitsPerSample, planarConfiguration) {
3936
4216
  if (!predictor || predictor === 1) {
3937
4217
  return block;
@@ -3976,21 +4256,41 @@ function applyPredictor(block, predictor, width, height, bitsPerSample, planarCo
3976
4256
  return block;
3977
4257
  }
3978
4258
 
4259
+ /**
4260
+ * @typedef {Object} BaseDecoderParameters
4261
+ * @property {number} tileWidth
4262
+ * @property {number} tileHeight
4263
+ * @property {number} predictor
4264
+ * @property {number|number[]|import('../geotiff.js').TypedArray} bitsPerSample
4265
+ * @property {number} planarConfiguration
4266
+ * @property {number} [samplesPerPixel]
4267
+ */
3979
4268
  class BaseDecoder {
4269
+ /**
4270
+ * @param {BaseDecoderParameters} parameters
4271
+ */
3980
4272
  constructor(parameters) {
3981
4273
  this.parameters = parameters;
3982
4274
  }
3983
4275
  /**
3984
4276
  * @abstract
4277
+ * @param {ArrayBufferLike} _buffer
4278
+ * @returns {Promise<ArrayBufferLike>|ArrayBufferLike}
3985
4279
  */
3986
4280
  decodeBlock(_buffer) {
3987
4281
  throw new Error('decodeBlock not implemented');
3988
4282
  }
4283
+ /**
4284
+ * @param {ArrayBufferLike} buffer
4285
+ * @returns {Promise<ArrayBufferLike>}
4286
+ */
3989
4287
  async decode(buffer) {
3990
4288
  const decoded = await this.decodeBlock(buffer);
3991
4289
  const { tileWidth, tileHeight, predictor, bitsPerSample, planarConfiguration, } = this.parameters;
3992
4290
  if (predictor !== 1) {
3993
- return applyPredictor(decoded, predictor, tileWidth, tileHeight, bitsPerSample, planarConfiguration);
4291
+ const isBitsPerSampleArray = Array.isArray(bitsPerSample) || ArrayBuffer.isView(bitsPerSample);
4292
+ const adaptedBitsPerSample = isBitsPerSampleArray ? Array.from(bitsPerSample) : [bitsPerSample];
4293
+ return applyPredictor(decoded, predictor, tileWidth, tileHeight, adaptedBitsPerSample, planarConfiguration);
3994
4294
  }
3995
4295
  return decoded;
3996
4296
  }
@@ -4016,6 +4316,43 @@ class BaseDecoder {
4016
4316
  * `TypedArray[] & { height: number; width: number}`
4017
4317
  * @typedef {TypedArray[] & Dimensions} TypedArrayArrayWithDimensions
4018
4318
  */
4319
+ /**
4320
+ * @typedef {Object} GeotiffWriterMetadata
4321
+ * @property {number | number[]} [ImageWidth]
4322
+ * @property {number | number[]} [ImageLength]
4323
+ * @property {number} [width]
4324
+ * @property {number} [height]
4325
+ * @property {number | number[]} [BitsPerSample]
4326
+ * @property {number | number[]} [Compression]
4327
+ * @property {number | number[]} [PlanarConfiguration]
4328
+ * @property {number | number[]} [ExtraSamples]
4329
+ * @property {number | number[]} [PhotometricInterpretation]
4330
+ * @property {number | number[]} [SamplesPerPixel]
4331
+ * @property {number | number[]} [StripByteCounts]
4332
+ * @property {number[]} [ModelPixelScale]
4333
+ * @property {number[]} [ModelTransformation]
4334
+ * @property {number[]} [ModelTiepoint]
4335
+ * @property {number[]} [GeoKeyDirectory]
4336
+ * @property {string} [GeoAsciiParams]
4337
+ * @property {number[]} [GeoDoubleParams]
4338
+ * @property {number | number[]} [Orientation]
4339
+ * @property {number | number[]} [ResolutionUnit]
4340
+ * @property {number | number[]} [XPosition]
4341
+ * @property {number | number[]} [YPosition]
4342
+ * @property {number | number[]} [RowsPerStrip]
4343
+ * @property {number[]} [SampleFormat]
4344
+ * @property {number | number[]} [TileWidth]
4345
+ * @property {number | number[]} [TileLength]
4346
+ * @property {number[]} [TileOffsets]
4347
+ * @property {number[]} [TileByteCounts]
4348
+ * @property {string} [GDAL_NODATA]
4349
+ * @property {number | number[]} [GeographicTypeGeoKey]
4350
+ * @property {number | number[]} [ProjectedCSTypeGeoKey]
4351
+ * @property {string} [GeogCitationGeoKey]
4352
+ * @property {string} [GTCitationGeoKey]
4353
+ * @property {number | number[]} [GTModelTypeGeoKey]
4354
+ * @property {number | number[]} [GTRasterTypeGeoKey]
4355
+ */
4019
4356
  /**
4020
4357
  * The autogenerated docs are a little confusing here. The effective type is:
4021
4358
  *
@@ -4027,7 +4364,7 @@ class BaseDecoder {
4027
4364
  * Use the {@link Pool.bindParameters} method to get a decoder worker for
4028
4365
  * a specific compression and its parameters.
4029
4366
  *
4030
- * @property {(buffer: ArrayBuffer) => Promise<ArrayBuffer>} decode
4367
+ * @property {(buffer: ArrayBufferLike) => Promise<ArrayBufferLike>} decode
4031
4368
  * A function that takes a compressed buffer and returns a promise resolving to the decoded buffer.
4032
4369
  */
4033
4370
  /**
@@ -4066,12 +4403,12 @@ class BaseDecoder {
4066
4403
  */
4067
4404
  /**
4068
4405
  * @typedef {Object} BlockedSourceOptions
4069
- * @property {number|null} [blockSize=null] Block size for a BlockedSource.
4406
+ * @property {number} [blockSize] Block size for a BlockedSource.
4070
4407
  * @property {number} [cacheSize=100] The number of blocks to cache.
4071
4408
  */
4072
4409
  /**
4073
4410
  * @typedef {Object} RemoteSourceOptions
4074
- * @property {Object} [headers={}] Additional headers to add to each request
4411
+ * @property {Record<string, string>} [headers={}] Additional headers to add to each request
4075
4412
  * @property {number} [maxRanges=0] Maximum number of ranges to request in a single HTTP request. 0 means no multi-range requests.
4076
4413
  * @property {boolean} [allowFullFile=false] Whether to allow full file responses when requesting ranges
4077
4414
  * @property {boolean} [forceXHR=false] When the Fetch API would be used, force using XMLHttpRequest instead.
@@ -4092,7 +4429,7 @@ class BaseDecoder {
4092
4429
  * @returns {TypedArray|Array<number>|string}
4093
4430
  */
4094
4431
  function getValues(dataSlice, fieldType, count, offset) {
4095
- /** @type {TypedArray|Array|null} */
4432
+ /** @type {TypedArray|Array<number>|null} */
4096
4433
  let values = null;
4097
4434
  let readMethod = null;
4098
4435
  const fieldTypeLength = getFieldTypeSize(fieldType);
@@ -4155,27 +4492,23 @@ function getValues(dataSlice, fieldType, count, offset) {
4155
4492
  throw new RangeError(`Invalid field type: ${fieldType}`);
4156
4493
  }
4157
4494
  // normal fields
4158
- if (!(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
4495
+ {
4159
4496
  for (let i = 0; i < count; ++i) {
4160
4497
  values[i] = readMethod.call(dataSlice, offset + (i * fieldTypeLength));
4161
4498
  }
4162
4499
  }
4163
- else { // RATIONAL or SRATIONAL
4164
- for (let i = 0; i < count; i += 2) {
4165
- values[i] = readMethod.call(dataSlice, offset + (i * fieldTypeLength));
4166
- values[i + 1] = readMethod.call(dataSlice, offset + ((i * fieldTypeLength) + 4));
4167
- }
4168
- }
4169
- if (fieldType === fieldTypes.ASCII) {
4500
+ {
4170
4501
  return new TextDecoder('utf-8').decode(/** @type {Uint8Array} */ (values));
4171
4502
  }
4172
- return values;
4173
4503
  }
4174
4504
  /**
4175
4505
  * Error class for cases when an IFD index was requested, that does not exist
4176
4506
  * in the file.
4177
4507
  */
4178
4508
  class GeoTIFFImageIndexError extends Error {
4509
+ /**
4510
+ * @param {number} index
4511
+ */
4179
4512
  constructor(index) {
4180
4513
  super(`No image at index ${index}`);
4181
4514
  this.index = index;
@@ -4260,7 +4593,7 @@ class GeoTIFFBase {
4260
4593
  const image = await this.getImage(i);
4261
4594
  const subfileType = image.fileDirectory.getValue('SubfileType');
4262
4595
  const newSubfileType = image.fileDirectory.getValue('NewSubfileType');
4263
- if (i === 0 || subfileType === 2 || newSubfileType & 1) {
4596
+ if (i === 0 || subfileType === 2 || (newSubfileType || 0) & 1) {
4264
4597
  allImages.push(image);
4265
4598
  }
4266
4599
  }
@@ -4320,9 +4653,16 @@ class GeoTIFF extends GeoTIFFBase {
4320
4653
  this.bigTiff = bigTiff;
4321
4654
  this.firstIFDOffset = firstIFDOffset;
4322
4655
  this.cache = options.cache || false;
4656
+ /** @type {Array<Promise<import('./imagefiledirectory.js').ImageFileDirectory> | undefined>} */
4323
4657
  this.ifdRequests = [];
4658
+ /** @type {Record<string, unknown>|null} */
4324
4659
  this.ghostValues = null;
4325
4660
  }
4661
+ /**
4662
+ * @param {number} offset
4663
+ * @param {number} [size]
4664
+ * @returns {Promise<DataSlice>}
4665
+ */
4326
4666
  async getSlice(offset, size) {
4327
4667
  const fallbackSize = this.bigTiff ? 4048 : 1024;
4328
4668
  return new DataSlice((await this.source.fetch([{
@@ -4330,6 +4670,10 @@ class GeoTIFF extends GeoTIFFBase {
4330
4670
  length: typeof size !== 'undefined' ? size : fallbackSize,
4331
4671
  }]))[0], offset, this.littleEndian, this.bigTiff);
4332
4672
  }
4673
+ /**
4674
+ * @param {number} index
4675
+ * @return {Promise<import('./imagefiledirectory.js').ImageFileDirectory>}
4676
+ */
4333
4677
  async requestIFD(index) {
4334
4678
  // see if we already have that IFD index requested.
4335
4679
  if (this.ifdRequests[index]) {
@@ -4360,7 +4704,11 @@ class GeoTIFF extends GeoTIFFBase {
4360
4704
  // if the previous IFD was loaded, we can finally fetch the one we are interested in.
4361
4705
  // we need to wrap this in an IIFE, otherwise this.ifdRequests[index] would be delayed
4362
4706
  this.ifdRequests[index] = (async () => {
4363
- const previousIfd = await this.ifdRequests[index - 1];
4707
+ const previousPromise = this.ifdRequests[index - 1];
4708
+ if (!previousPromise) {
4709
+ throw new Error('Previous IFD request missing');
4710
+ }
4711
+ const previousIfd = await previousPromise;
4364
4712
  if (previousIfd.nextIFDByteOffset === 0) {
4365
4713
  throw new GeoTIFFImageIndexError(index);
4366
4714
  }
@@ -4405,11 +4753,11 @@ class GeoTIFF extends GeoTIFFBase {
4405
4753
  /**
4406
4754
  * Get the values of the COG ghost area as a parsed map.
4407
4755
  * See https://gdal.org/drivers/raster/cog.html#header-ghost-area for reference
4408
- * @returns {Promise<Object>} the parsed ghost area or null, if no such area was found
4756
+ * @returns {Promise<Record<string, unknown>|null>} the parsed ghost area or null, if no such area was found
4409
4757
  */
4410
4758
  async getGhostValues() {
4411
4759
  const offset = this.bigTiff ? 16 : 8;
4412
- if (this.ghostValues) {
4760
+ if (this.ghostValues !== null) {
4413
4761
  return this.ghostValues;
4414
4762
  }
4415
4763
  const detectionString = 'GDAL_STRUCTURAL_METADATA_SIZE=';
@@ -4423,15 +4771,16 @@ class GeoTIFF extends GeoTIFFBase {
4423
4771
  slice = await this.getSlice(offset, metadataSize);
4424
4772
  }
4425
4773
  const fullString = getValues(slice, fieldTypes.ASCII, metadataSize, offset);
4426
- /** @type {Object} */
4427
- this.ghostValues = {};
4774
+ /** @type {Record<string, unknown>} */
4775
+ const ghostValues = {};
4428
4776
  fullString
4429
4777
  .split('\n')
4430
4778
  .filter((line) => line.length > 0)
4431
4779
  .map((line) => line.split('='))
4432
4780
  .forEach(([key, value]) => {
4433
- this.ghostValues[key] = value;
4781
+ ghostValues[key] = value;
4434
4782
  });
4783
+ this.ghostValues = ghostValues;
4435
4784
  }
4436
4785
  return this.ghostValues;
4437
4786
  }
@@ -4446,7 +4795,7 @@ class GeoTIFF extends GeoTIFFBase {
4446
4795
  static async fromSource(source, options, signal) {
4447
4796
  const headerData = (await source.fetch([{ offset: 0, length: 1024 }], signal))[0];
4448
4797
  const dataView = new DataView64(headerData);
4449
- const BOM = dataView.getUint16(0, 0);
4798
+ const BOM = dataView.getUint16(0, false);
4450
4799
  let littleEndian;
4451
4800
  if (BOM === 0x4949) {
4452
4801
  littleEndian = true;
@@ -5330,11 +5679,11 @@ class BitmapGenerator {
5330
5679
  }
5331
5680
  static getColorValue(dataArray, options, arrayLength, samplesPerPixel = 1) {
5332
5681
  // Normalize all colorScale entries for chroma.js compatibility
5333
- const colorScale = chroma.scale(options.colorScale?.map(c => Array.isArray(c) ? chroma(c) : c)).domain(options.colorScaleValueRange);
5682
+ const colorScale = chroma.scale(options.colorScale?.map(c => Array.isArray(c) ? chroma(c) : c)).domain(options.colorScaleValueRange ?? [0, 255]);
5334
5683
  const colorsArray = new Uint8ClampedArray(arrayLength);
5335
- const optAlpha = Math.floor(options.alpha * 2.55);
5336
- const rangeMin = options.colorScaleValueRange[0];
5337
- const rangeMax = options.colorScaleValueRange.slice(-1)[0];
5684
+ const optAlpha = Math.floor((options.alpha ?? 100) * 2.55);
5685
+ const rangeMin = options.colorScaleValueRange?.[0] ?? 0;
5686
+ const rangeMax = options.colorScaleValueRange?.[1] ?? 255;
5338
5687
  const is8Bit = dataArray instanceof Uint8Array || dataArray instanceof Uint8ClampedArray;
5339
5688
  const isFloatOrWide = !is8Bit && (dataArray instanceof Float32Array || dataArray instanceof Uint16Array || dataArray instanceof Int16Array);
5340
5689
  // 1. 8-BIT COMPREHENSIVE LUT
@@ -5647,6 +5996,7 @@ class TerrainGenerator {
5647
5996
  const cellSize = input.cellSizeMeters ?? ((input.bounds[2] - input.bounds[0]) / 256);
5648
5997
  const zFactor = options.zFactor ?? 1;
5649
5998
  if (options.useSlope && options.useHillshade) {
5999
+ // eslint-disable-next-line no-console
5650
6000
  console.warn('[TerrainGenerator] useSlope and useHillshade are mutually exclusive; useSlope takes precedence.');
5651
6001
  }
5652
6002
  // Build a separate raster for kernel computation that preserves noData samples.
@@ -5660,7 +6010,6 @@ class TerrainGenerator {
5660
6010
  for (let i = 0; i < terrain.length; i++) {
5661
6011
  // If the source raster marks this sample as noData, keep it as noData for the kernel.
5662
6012
  // Otherwise, use the processed terrain elevation value.
5663
- // eslint-disable-next-line eqeqeq
5664
6013
  kernelTerrain[i] = sourceRaster[i] == noData ? noData : terrain[i];
5665
6014
  }
5666
6015
  }
@@ -5902,8 +6251,8 @@ class CogTiles {
5902
6251
  cogResolutionLookup = [];
5903
6252
  cogOrigin = [0, 0];
5904
6253
  zoomRange = [0, 0];
5905
- tileSize;
5906
- bounds; // Or your Bounds type
6254
+ tileSize = 256;
6255
+ bounds = [0, 0, 0, 0];
5907
6256
  geo = new GeoImage();
5908
6257
  options;
5909
6258
  constructor(options) {
@@ -6097,7 +6446,7 @@ class CogTiles {
6097
6446
  if (missingLeft > 0 || missingTop > 0 || readWidth < FETCH_SIZE || readHeight < FETCH_SIZE) {
6098
6447
  const numChannels = this.options.numOfChannels || 1;
6099
6448
  // Initialize with a TypedArray of the full target size and correct data type
6100
- const validImageData = this.createTileBuffer(this.options.format, FETCH_SIZE, numChannels);
6449
+ const validImageData = this.createTileBuffer(this.options.format || 'Float32', FETCH_SIZE, numChannels);
6101
6450
  if (this.options.noDataValue !== undefined) {
6102
6451
  validImageData.fill(this.options.noDataValue);
6103
6452
  }
@@ -6106,7 +6455,7 @@ class CogTiles {
6106
6455
  // Place the valid pixel data into the tile buffer.
6107
6456
  for (let band = 0; band < validRasterData.length; band += 1) {
6108
6457
  // We must reset the buffer for each band, otherwise data from previous band persists in padding areas
6109
- const tileBuffer = this.createTileBuffer(this.options.format, FETCH_SIZE);
6458
+ const tileBuffer = this.createTileBuffer(this.options.format || 'Float32', FETCH_SIZE);
6110
6459
  if (this.options.noDataValue !== undefined) {
6111
6460
  tileBuffer.fill(this.options.noDataValue);
6112
6461
  }
@@ -6528,7 +6877,7 @@ class CogTerrainLayer extends CompositeLayer {
6528
6877
  static defaultProps = defaultProps;
6529
6878
  static layerName = 'CogTerrainLayer';
6530
6879
  // terrainCogTiles: CogTiles;
6531
- terrainUrl;
6880
+ terrainUrl = '';
6532
6881
  async initializeState(context) {
6533
6882
  super.initializeState(context);
6534
6883
  this.setState({
@@ -6650,16 +6999,19 @@ class CogTerrainLayer extends CompositeLayer {
6650
6999
  const { zRange } = this.state;
6651
7000
  const ranges = tiles
6652
7001
  .map((tile) => tile.content)
6653
- .filter((x) => x && x[0])
7002
+ .filter((x) => !!x && !!x[0])
6654
7003
  .map((arr) => {
7004
+ if (!arr || !arr[0])
7005
+ return undefined;
6655
7006
  const bounds = arr[0]?.map?.header?.boundingBox;
6656
7007
  return bounds?.map((bound) => bound[2]);
6657
- });
7008
+ })
7009
+ .filter((x) => x !== undefined);
6658
7010
  if (ranges.length === 0) {
6659
7011
  return;
6660
7012
  }
6661
- const minZ = Math.min(...ranges.map((x) => x[0]));
6662
- const maxZ = Math.max(...ranges.map((x) => x[1]));
7013
+ const minZ = Math.min(...ranges.map((x) => x?.[0] ?? 0).filter((n) => Number.isFinite(n)));
7014
+ const maxZ = Math.max(...ranges.map((x) => x?.[1] ?? 0).filter((n) => Number.isFinite(n)));
6663
7015
  if (!zRange || minZ < zRange[0] || maxZ > zRange[1]) {
6664
7016
  this.setState({ zRange: [Number.isFinite(minZ) ? minZ : 0, Number.isFinite(maxZ) ? maxZ : 0] });
6665
7017
  }
@@ -6706,10 +7058,12 @@ class CogTerrainLayer extends CompositeLayer {
6706
7058
  refinementStrategy,
6707
7059
  });
6708
7060
  }
7061
+ return null;
6709
7062
  }
6710
7063
  }
6711
7064
 
6712
7065
  class RawDecoder extends BaseDecoder {
7066
+ /** @param {ArrayBuffer} buffer */
6713
7067
  decodeBlock(buffer) {
6714
7068
  return buffer;
6715
7069
  }
@@ -6724,6 +7078,12 @@ const MIN_BITS = 9;
6724
7078
  const CLEAR_CODE = 256; // clear code
6725
7079
  const EOI_CODE = 257; // end of information
6726
7080
  const MAX_BYTELENGTH = 12;
7081
+ /**
7082
+ * @param {Uint8Array} array
7083
+ * @param {number} position
7084
+ * @param {number} length
7085
+ * @returns {number}
7086
+ */
6727
7087
  function getByte(array, position, length) {
6728
7088
  const d = position % 8;
6729
7089
  const a = Math.floor(position / 8);
@@ -6751,12 +7111,21 @@ function getByte(array, position, length) {
6751
7111
  }
6752
7112
  return chunks;
6753
7113
  }
7114
+ /**
7115
+ * @template T
7116
+ * @param {Array<T>} dest
7117
+ * @param {Array<T>} source
7118
+ * @returns {Array<T>}
7119
+ */
6754
7120
  function appendReversed(dest, source) {
6755
7121
  for (let i = source.length - 1; i >= 0; i--) {
6756
7122
  dest.push(source[i]);
6757
7123
  }
6758
7124
  return dest;
6759
7125
  }
7126
+ /**
7127
+ * @param {ArrayBuffer} input
7128
+ */
6760
7129
  function decompress(input) {
6761
7130
  const dictionaryIndex = new Uint16Array(4093);
6762
7131
  const dictionaryChar = new Uint8Array(4093);
@@ -6771,17 +7140,23 @@ function decompress(input) {
6771
7140
  dictionaryLength = 258;
6772
7141
  byteLength = MIN_BITS;
6773
7142
  }
7143
+ /** @param {Uint8Array} array */
6774
7144
  function getNext(array) {
6775
7145
  const byte = getByte(array, position, byteLength);
6776
7146
  position += byteLength;
6777
7147
  return byte;
6778
7148
  }
7149
+ /**
7150
+ * @param {number} i
7151
+ * @param {number} c
7152
+ */
6779
7153
  function addToDictionary(i, c) {
6780
7154
  dictionaryChar[dictionaryLength] = c;
6781
7155
  dictionaryIndex[dictionaryLength] = i;
6782
7156
  dictionaryLength++;
6783
7157
  return dictionaryLength - 1;
6784
7158
  }
7159
+ /** @param {number} n */
6785
7160
  function getDictionaryReversed(n) {
6786
7161
  const rev = [];
6787
7162
  for (let i = n; i !== 4096; i = dictionaryIndex[i]) {
@@ -6816,10 +7191,15 @@ function decompress(input) {
6816
7191
  else if (code < dictionaryLength) {
6817
7192
  const val = getDictionaryReversed(code);
6818
7193
  appendReversed(result, val);
6819
- addToDictionary(oldCode, val[val.length - 1]);
7194
+ if (oldCode !== undefined) {
7195
+ addToDictionary(oldCode, val[val.length - 1]);
7196
+ }
6820
7197
  oldCode = code;
6821
7198
  }
6822
7199
  else {
7200
+ if (oldCode === undefined) {
7201
+ throw new Error(`Invalid LZW code: ${code} with no previous code`);
7202
+ }
6823
7203
  const oldVal = getDictionaryReversed(oldCode);
6824
7204
  if (!oldVal) {
6825
7205
  throw new Error(`Bogus entry. Not in dictionary, ${oldCode} / ${dictionaryLength}, position: ${position}`);
@@ -6842,6 +7222,7 @@ function decompress(input) {
6842
7222
  return new Uint8Array(result);
6843
7223
  }
6844
7224
  class LZWDecoder extends BaseDecoder {
7225
+ /** @param {ArrayBuffer} buffer */
6845
7226
  decodeBlock(buffer) {
6846
7227
  return decompress(buffer).buffer;
6847
7228
  }
@@ -6900,6 +7281,33 @@ const dctSqrt2 = 5793; // sqrt(2)
6900
7281
  const dctSqrt1d2 = 2896; // sqrt(2) / 2
6901
7282
  /** @typedef {(number|HuffmanNode)[]} HuffmanNode */
6902
7283
  /** @typedef {{children: HuffmanNode, index: number}} Code */
7284
+ /**
7285
+ * @typedef {Object} JpegComponent
7286
+ * @property {number} h
7287
+ * @property {number} v
7288
+ * @property {number} [quantizationIdx]
7289
+ * @property {Int32Array} [quantizationTable]
7290
+ * @property {number} blocksPerLine
7291
+ * @property {number} blocksPerColumn
7292
+ * @property {Int32Array[][]} blocks
7293
+ * @property {HuffmanNode} [huffmanTableDC]
7294
+ * @property {HuffmanNode} [huffmanTableAC]
7295
+ * @property {number} [pred]
7296
+ */
7297
+ /**
7298
+ * @typedef {Object} JpegFrame
7299
+ * @property {boolean} extended
7300
+ * @property {boolean} progressive
7301
+ * @property {number} precision
7302
+ * @property {number} scanLines
7303
+ * @property {number} samplesPerLine
7304
+ * @property {Object.<string, JpegComponent>} components
7305
+ * @property {number[]} componentsOrder
7306
+ * @property {number} maxH
7307
+ * @property {number} maxV
7308
+ * @property {number} mcusPerLine
7309
+ * @property {number} mcusPerColumn
7310
+ */
6903
7311
  /**
6904
7312
  * @param {Uint8Array<ArrayBuffer>} codeLengths
6905
7313
  * @param {Uint8Array<ArrayBuffer>} values
@@ -6949,8 +7357,25 @@ function buildHuffmanTable(codeLengths, values) {
6949
7357
  }
6950
7358
  return code[0].children;
6951
7359
  }
7360
+ /**
7361
+ * @param {Uint8Array} data
7362
+ * @param {number} initialOffset
7363
+ * @param {JpegFrame} frame
7364
+ * @param {JpegComponent[]} components
7365
+ * @param {number} resetInterval
7366
+ * @param {number} spectralStart
7367
+ * @param {number} spectralEnd
7368
+ * @param {number} successivePrev
7369
+ * @param {number} successive
7370
+ */
6952
7371
  function decodeScan(data, initialOffset, frame, components, resetInterval, spectralStart, spectralEnd, successivePrev, successive) {
6953
7372
  const { mcusPerLine, progressive } = frame;
7373
+ if (components.length > 1 && (mcusPerLine === undefined || frame.mcusPerColumn === undefined)) {
7374
+ throw new Error('Missing MCU dimensions');
7375
+ }
7376
+ if (components.length === 1 && (components[0].blocksPerLine === undefined || components[0].blocksPerColumn === undefined)) {
7377
+ throw new Error('Missing block dimensions');
7378
+ }
6954
7379
  const startOffset = initialOffset;
6955
7380
  let offset = initialOffset;
6956
7381
  let bitsData = 0;
@@ -6971,20 +7396,26 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
6971
7396
  bitsCount = 7;
6972
7397
  return bitsData >>> 7;
6973
7398
  }
7399
+ /** @param {HuffmanNode|undefined} tree */
6974
7400
  function decodeHuffman(tree) {
7401
+ if (!tree) {
7402
+ throw new Error('Huffman table not found');
7403
+ }
6975
7404
  let node = tree;
6976
7405
  let bit;
6977
7406
  while ((bit = readBit()) !== null) { // eslint-disable-line no-cond-assign
6978
- node = node[bit];
6979
- if (typeof node === 'number') {
6980
- return node;
7407
+ const next = node[bit];
7408
+ if (typeof next === 'number') {
7409
+ return next;
6981
7410
  }
6982
- if (typeof node !== 'object') {
7411
+ if (typeof next !== 'object') {
6983
7412
  throw new Error('invalid huffman sequence');
6984
7413
  }
7414
+ node = next;
6985
7415
  }
6986
7416
  return null;
6987
7417
  }
7418
+ /** @param {number} initialLength */
6988
7419
  function receive(initialLength) {
6989
7420
  let length = initialLength;
6990
7421
  let n = 0;
@@ -6998,6 +7429,7 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
6998
7429
  }
6999
7430
  return n;
7000
7431
  }
7432
+ /** @param {number} length */
7001
7433
  function receiveAndExtend(length) {
7002
7434
  const n = receive(length);
7003
7435
  if (n === undefined) {
@@ -7008,9 +7440,22 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7008
7440
  }
7009
7441
  return n + (-1 << length) + 1;
7010
7442
  }
7443
+ /**
7444
+ * @param {JpegComponent} component
7445
+ * @param {Int32Array} zz
7446
+ */
7011
7447
  function decodeBaseline(component, zz) {
7012
7448
  const t = decodeHuffman(component.huffmanTableDC);
7449
+ if (t === null) {
7450
+ throw new Error('Huffman error');
7451
+ }
7013
7452
  const diff = t === 0 ? 0 : receiveAndExtend(t);
7453
+ if (diff === undefined) {
7454
+ throw new Error('Unexpected end of stream');
7455
+ }
7456
+ if (component.pred === undefined) {
7457
+ component.pred = 0;
7458
+ }
7014
7459
  component.pred += diff;
7015
7460
  zz[0] = component.pred;
7016
7461
  let k = 1;
@@ -7030,25 +7475,51 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7030
7475
  else {
7031
7476
  k += r;
7032
7477
  const z = dctZigZag[k];
7033
- zz[z] = receiveAndExtend(s);
7478
+ const val = receiveAndExtend(s);
7479
+ if (val === undefined) {
7480
+ throw new Error('Unexpected end of stream');
7481
+ }
7482
+ zz[z] = val;
7034
7483
  k++;
7035
7484
  }
7036
7485
  }
7037
7486
  }
7487
+ /**
7488
+ * @param {JpegComponent} component
7489
+ * @param {Int32Array} zz
7490
+ */
7038
7491
  function decodeDCFirst(component, zz) {
7039
7492
  const t = decodeHuffman(component.huffmanTableDC);
7493
+ if (t === null) {
7494
+ throw new Error('Huffman error');
7495
+ }
7040
7496
  const value = receiveAndExtend(t);
7041
7497
  if (value === undefined) {
7042
7498
  throw new Error('Unexpected end of data in DC coefficient decoding');
7043
7499
  }
7044
7500
  const diff = t === 0 ? 0 : (value << successive);
7501
+ if (component.pred === undefined) {
7502
+ component.pred = 0;
7503
+ }
7045
7504
  component.pred += diff;
7046
7505
  zz[0] = component.pred;
7047
7506
  }
7048
- function decodeDCSuccessive(component, zz) {
7049
- zz[0] |= readBit() << successive;
7507
+ /**
7508
+ * @param {JpegComponent} _
7509
+ * @param {Int32Array} zz
7510
+ */
7511
+ function decodeDCSuccessive(_, zz) {
7512
+ const bit = readBit();
7513
+ if (bit === null) {
7514
+ throw new Error('Unexpected end of data in DC coefficient decoding');
7515
+ }
7516
+ zz[0] |= bit << successive;
7050
7517
  }
7051
7518
  let eobrun = 0;
7519
+ /**
7520
+ * @param {JpegComponent} component
7521
+ * @param {Int32Array} zz
7522
+ */
7052
7523
  function decodeACFirst(component, zz) {
7053
7524
  if (eobrun > 0) {
7054
7525
  eobrun--;
@@ -7087,7 +7558,12 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7087
7558
  }
7088
7559
  }
7089
7560
  let successiveACState = 0;
7561
+ /** @type {number} */
7090
7562
  let successiveACNextValue;
7563
+ /**
7564
+ * @param {JpegComponent} component
7565
+ * @param {Int32Array} zz
7566
+ */
7091
7567
  function decodeACSuccessive(component, zz) {
7092
7568
  let k = spectralStart;
7093
7569
  const e = spectralEnd;
@@ -7121,7 +7597,11 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7121
7597
  if (s !== 1) {
7122
7598
  throw new Error('invalid ACn encoding');
7123
7599
  }
7124
- successiveACNextValue = receiveAndExtend(s);
7600
+ const nextVal = receiveAndExtend(s);
7601
+ if (nextVal === undefined) {
7602
+ throw new Error('Unexpected end of data in AC coefficient decoding');
7603
+ }
7604
+ successiveACNextValue = nextVal;
7125
7605
  successiveACState = r ? 2 : 3;
7126
7606
  }
7127
7607
  continue; // eslint-disable-line no-continue
@@ -7129,7 +7609,11 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7129
7609
  case 1: // skipping r zero items
7130
7610
  case 2:
7131
7611
  if (zz[z]) {
7132
- zz[z] += (readBit() << successive) * direction;
7612
+ const bit = readBit();
7613
+ if (bit === null) {
7614
+ throw new Error('Unexpected end of data in AC coefficient decoding');
7615
+ }
7616
+ zz[z] += (bit << successive) * direction;
7133
7617
  }
7134
7618
  else {
7135
7619
  r--;
@@ -7140,7 +7624,11 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7140
7624
  break;
7141
7625
  case 3: // set value for a zero item
7142
7626
  if (zz[z]) {
7143
- zz[z] += (readBit() << successive) * direction;
7627
+ const bit = readBit();
7628
+ if (bit === null) {
7629
+ throw new Error('Unexpected end of data in AC coefficient decoding');
7630
+ }
7631
+ zz[z] += (bit << successive) * direction;
7144
7632
  }
7145
7633
  else {
7146
7634
  zz[z] = successiveACNextValue << successive;
@@ -7149,7 +7637,11 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7149
7637
  break;
7150
7638
  case 4: // eob
7151
7639
  if (zz[z]) {
7152
- zz[z] += (readBit() << successive) * direction;
7640
+ const bit = readBit();
7641
+ if (bit === null) {
7642
+ throw new Error('Unexpected end of data in AC coefficient decoding');
7643
+ }
7644
+ zz[z] += (bit << successive) * direction;
7153
7645
  }
7154
7646
  break;
7155
7647
  }
@@ -7162,16 +7654,34 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7162
7654
  }
7163
7655
  }
7164
7656
  }
7657
+ /**
7658
+ * @param {JpegComponent} component
7659
+ * @param {function} decodeFunction
7660
+ * @param {number} mcu
7661
+ * @param {number} row
7662
+ * @param {number} col
7663
+ */
7165
7664
  function decodeMcu(component, decodeFunction, mcu, row, col) {
7166
7665
  const mcuRow = (mcu / mcusPerLine) | 0;
7167
7666
  const mcuCol = mcu % mcusPerLine;
7168
7667
  const blockRow = (mcuRow * component.v) + row;
7169
7668
  const blockCol = (mcuCol * component.h) + col;
7669
+ if (!component.blocks) {
7670
+ throw new Error('Missing blocks');
7671
+ }
7170
7672
  decodeFunction(component, component.blocks[blockRow][blockCol]);
7171
7673
  }
7674
+ /**
7675
+ * @param {JpegComponent} component
7676
+ * @param {function} decodeFunction
7677
+ * @param {number} mcu
7678
+ */
7172
7679
  function decodeBlock(component, decodeFunction, mcu) {
7173
7680
  const blockRow = (mcu / component.blocksPerLine) | 0;
7174
7681
  const blockCol = mcu % component.blocksPerLine;
7682
+ if (!component.blocks) {
7683
+ throw new Error('Missing blocks');
7684
+ }
7175
7685
  decodeFunction(component, component.blocks[blockRow][blockCol]);
7176
7686
  }
7177
7687
  const componentsLength = components.length;
@@ -7248,9 +7758,15 @@ function decodeScan(data, initialOffset, frame, components, resetInterval, spect
7248
7758
  }
7249
7759
  return offset - startOffset;
7250
7760
  }
7251
- function buildComponentData(frame, component) {
7761
+ /**
7762
+ * @param {JpegComponent} component
7763
+ */
7764
+ function buildComponentData(component) {
7252
7765
  const lines = [];
7253
7766
  const { blocksPerLine, blocksPerColumn } = component;
7767
+ if (!blocksPerLine || !blocksPerColumn || !component.blocks) {
7768
+ throw new Error('Missing component data');
7769
+ }
7254
7770
  const samplesPerLine = blocksPerLine << 3;
7255
7771
  const R = new Int32Array(64);
7256
7772
  const r = new Uint8Array(64);
@@ -7259,8 +7775,16 @@ function buildComponentData(frame, component) {
7259
7775
  // "Practical Fast 1-D DCT Algorithms with 11 Multiplications",
7260
7776
  // IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989,
7261
7777
  // 988-991.
7778
+ /**
7779
+ * @param {Int32Array} zz
7780
+ * @param {Uint8Array} dataOut
7781
+ * @param {Int32Array} dataIn
7782
+ */
7262
7783
  function quantizeAndInverse(zz, dataOut, dataIn) {
7263
7784
  const qt = component.quantizationTable;
7785
+ if (!qt) {
7786
+ throw new Error('No quantization table found');
7787
+ }
7264
7788
  let v0;
7265
7789
  let v1;
7266
7790
  let v2;
@@ -7439,14 +7963,21 @@ class JpegStreamReader {
7439
7963
  constructor() {
7440
7964
  this.jfif = null;
7441
7965
  this.adobe = null;
7966
+ /** @type {number} */
7967
+ this.resetInterval = 0;
7968
+ /** @type {Int32Array[]} */
7442
7969
  this.quantizationTables = [];
7970
+ /** @type {HuffmanNode[]} */
7443
7971
  this.huffmanTablesAC = [];
7972
+ /** @type {HuffmanNode[]} */
7444
7973
  this.huffmanTablesDC = [];
7974
+ /** @type {JpegFrame[]} */
7445
7975
  this.frames = [];
7446
7976
  }
7447
7977
  resetFrames() {
7448
7978
  this.frames = [];
7449
7979
  }
7980
+ /** @param {Uint8Array} data */
7450
7981
  parse(data) {
7451
7982
  let offset = 0;
7452
7983
  // const { length } = data;
@@ -7461,6 +7992,7 @@ class JpegStreamReader {
7461
7992
  offset += array.length;
7462
7993
  return array;
7463
7994
  }
7995
+ /** @param {JpegFrame} frame */
7464
7996
  function prepareComponents(frame) {
7465
7997
  let maxH = 0;
7466
7998
  let maxV = 0;
@@ -7587,15 +8119,21 @@ class JpegStreamReader {
7587
8119
  case 0xFFC1: // SOF1 (Start of Frame, Extended DCT)
7588
8120
  case 0xFFC2: { // SOF2 (Start of Frame, Progressive DCT)
7589
8121
  readUint16(); // skip data length
8122
+ /** @type {JpegFrame} */
7590
8123
  const frame = {
7591
8124
  extended: (fileMarker === 0xFFC1),
7592
8125
  progressive: (fileMarker === 0xFFC2),
7593
8126
  precision: data[offset++],
7594
8127
  scanLines: readUint16(),
7595
8128
  samplesPerLine: readUint16(),
8129
+ /** @type {Object.<string, JpegComponent>} */
7596
8130
  components: {},
7597
- /** @type {any[]} */
8131
+ /** @type {number[]} */
7598
8132
  componentsOrder: [],
8133
+ maxH: 0,
8134
+ maxV: 0,
8135
+ mcusPerLine: 0,
8136
+ mcusPerColumn: 0,
7599
8137
  };
7600
8138
  const componentsCount = data[offset++];
7601
8139
  let componentId;
@@ -7611,6 +8149,9 @@ class JpegStreamReader {
7611
8149
  h,
7612
8150
  v,
7613
8151
  quantizationIdx: qId,
8152
+ blocksPerLine: 0,
8153
+ blocksPerColumn: 0,
8154
+ blocks: [],
7614
8155
  };
7615
8156
  offset += 3;
7616
8157
  }
@@ -7695,11 +8236,17 @@ class JpegStreamReader {
7695
8236
  for (let i = 0; i < this.frames.length; i++) {
7696
8237
  const cp = this.frames[i].components;
7697
8238
  for (const j of Object.keys(cp)) {
7698
- cp[j].quantizationTable = this.quantizationTables[cp[j].quantizationIdx];
7699
- delete cp[j].quantizationIdx;
8239
+ const qIdx = cp[j].quantizationIdx;
8240
+ if (typeof qIdx === 'number') {
8241
+ cp[j].quantizationTable = this.quantizationTables[qIdx];
8242
+ delete cp[j].quantizationIdx;
8243
+ }
7700
8244
  }
7701
8245
  }
7702
8246
  const frame = frames[0];
8247
+ if (!frame.maxH || !frame.maxV) {
8248
+ throw new Error('Invalid frame dimensions');
8249
+ }
7703
8250
  const { components, componentsOrder } = frame;
7704
8251
  const outComponents = [];
7705
8252
  const width = frame.samplesPerLine;
@@ -7707,7 +8254,7 @@ class JpegStreamReader {
7707
8254
  for (let i = 0; i < componentsOrder.length; i++) {
7708
8255
  const component = components[componentsOrder[i]];
7709
8256
  outComponents.push({
7710
- lines: buildComponentData(frame, component),
8257
+ lines: buildComponentData(component),
7711
8258
  scaleX: component.h / frame.maxH,
7712
8259
  scaleY: component.v / frame.maxV,
7713
8260
  });
@@ -7727,6 +8274,9 @@ class JpegStreamReader {
7727
8274
  }
7728
8275
  }
7729
8276
  class JpegDecoder extends BaseDecoder {
8277
+ /**
8278
+ * @param {import('./basedecoder.js').BaseDecoderParameters & { JPEGTables?: Uint8Array }} parameters
8279
+ */
7730
8280
  constructor(parameters) {
7731
8281
  super(parameters);
7732
8282
  this.reader = new JpegStreamReader();
@@ -7734,6 +8284,7 @@ class JpegDecoder extends BaseDecoder {
7734
8284
  this.reader.parse(parameters.JPEGTables);
7735
8285
  }
7736
8286
  }
8287
+ /** @param {ArrayBuffer} buffer */
7737
8288
  decodeBlock(buffer) {
7738
8289
  this.reader.resetFrames();
7739
8290
  this.reader.parse(new Uint8Array(buffer));
@@ -10982,6 +11533,7 @@ const { inflate} = inflate_1$1;
10982
11533
  var inflate_1 = inflate;
10983
11534
 
10984
11535
  class DeflateDecoder extends BaseDecoder {
11536
+ /** @param {ArrayBuffer} buffer */
10985
11537
  decodeBlock(buffer) {
10986
11538
  return inflate_1(new Uint8Array(buffer)).buffer;
10987
11539
  }
@@ -10993,6 +11545,7 @@ var deflate = /*#__PURE__*/Object.freeze({
10993
11545
  });
10994
11546
 
10995
11547
  class PackbitsDecoder extends BaseDecoder {
11548
+ /** @param {ArrayBuffer} buffer */
10996
11549
  decodeBlock(buffer) {
10997
11550
  const dataView = new DataView(buffer);
10998
11551
  const out = [];
@@ -13440,23 +13993,33 @@ let ZSTDDecoder$1 = class ZSTDDecoder {
13440
13993
  // wasm:begin
13441
13994
  const wasm$1 = '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AikACDcACCAHIDo3AAAgEUEZSA0BIARBGGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgCkkNAAsMAQsCQAJAIAUoAswCIhEgBUHgAWogJUEHcUEMbGoiDygCACICaiIHIBxLDQAgCSAPKAIEIgogAmoiBmogG0sNACAGQSBqIBQgCWtNDQELIAUgDygCCDYCoAEgBSAPKQIANwOYASAJIBQgBUGYAWogBUHMAmogHCALIBcgIhAgIQYMAQsgAiAJaiEEIA8oAgghFSARKQAAITogCSARKQAINwAIIAkgOjcAAAJAIAJBEUkNACARKQAQITogCSARKQAYNwAYIAkgOjcAECACQRBrQRFIDQAgEUEQaiECIAlBIGohEgNAIAIpABAhOiASIAIpABg3AAggEiA6NwAAIAIpACAhOiASIAIpACg3ABggEiA6NwAQIAJBIGohAiASQSBqIhIgBEkNAAsLIAQgFWshAiAFIAc2AswCIAQgC2sgFUkEQCAVIAQgF2tLDQwgIiAiIAIgC2siD2oiByAKak8EQCAKRQ0CIAQgByAK/AoAAAwCC0EAIA9rIgIEQCAEIAcgAvwKAAALIAogD2ohCiAEIA9rIQQgCyECCyAVQRBPBEAgAikAACE6IAQgAikACDcACCAEIDo3AAAgCkERSA0BIAQgCmohByAEQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAdJDQALDAELAkAgFUEHTQRAIAQgAi0AADoAACAEIAItAAE6AAEgBCACLQACOgACIAQgAi0AAzoAAyAEIAIgFUECdCIHQeAaaigCAGoiAigAADYABCACIAdBgBtqKAIAayECDAELIAQgAikAADcAAAsgCkEJSQ0AIAQgCmohDyAEQQhqIgcgAkEIaiICa0EPTARAA0AgByACKQAANwAAIAJBCGohAiAHQQhqIgcgD0kNAAwCCwALIAIpAAAhOiAHIAIpAAg3AAggByA6NwAAIApBGUgNACAEQRhqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIA9JDQALCyAGQYh/SwRAIAYhAwwLCyAFQeABaiAlQQdxQQxsaiICIA02AgggAiAMNgIEIAIgEDYCAAsgBiAJaiEJICVBAWohJSAQIC1qIAxqIS0MAQsLIAUoArABIAUoArQBRw0HIAUoAqwBQSBHDQcgDiAoayEQA0ACQCAOIBBMBEBBACECA0AgAkEDRg0CIDIgAkECdCIDaiADICZqKAIANgIAIAJBAWohAgwACwALIAVB4AFqIBBBB3FBDGxqIQoCfwJAIAgoAoTsAUECRgRAIAUoAswCIg8gCigCACIEaiIHIAgoAoDsASICSwRAIAIgD0cEQCACIA9rIgIgFCAJa0sNCyAJIA8gAhAfIAogBCACayIENgIAIAIgCWohCQsgBSAWNgLMAiAIQQA2AoTsAQJAAkACQCAEQYCABEoNACAJIAooAgQiDSAEaiIGaiAbSw0AIAZBIGogFCAJa00NAQsgBSAKKAIINgJQIAUgCikCADcDSCAJIBQgBUHIAGogBUHMAmogGSALIBcgIhAgIQYMAQsgBCAWaiEHIAQgCWohDCAKKAIIIQogFikAACE6IAkgFikACDcACCAJIDo3AAACQCAEQRFJDQAgHikAACE6IAkgHikACDcAGCAJIDo3ABAgBEEQa0ERSA0AIAlBIGohAiAeIQQDQCAEKQAQITogAiAEKQAYNwAIIAIgOjcAACAEKQAgITogAiAEKQAoNwAYIAIgOjcAECAEQSBqIQQgAkEgaiICIAxJDQALCyAMIAprIQIgBSAHNgLMAiAMIAtrIApJBEAgCiAMIBdrSw0PICIgIiACIAtrIgdqIgQgDWpPBEAgDUUNAiAMIAQgDfwKAAAMAgtBACAHayICBEAgDCAEIAL8CgAACyAHIA1qIQ0gDCAHayEMIAshAgsgCkEQTwRAIAIpAAAhOiAMIAIpAAg3AAggDCA6NwAAIA1BEUgNASAMIA1qIQcgDEEQaiEEA0AgAikAECE6IAQgAikAGDcACCAEIDo3AAAgAikAICE6IAQgAikAKDcAGCAEIDo3ABAgAkEgaiECIARBIGoiBCAHSQ0ACwwBCwJAIApBB00EQCAMIAItAAA6AAAgDCACLQABOgABIAwgAi0AAjoAAiAMIAItAAM6AAMgDCACIApBAnQiBEHgGmooAgBqIgIoAAA2AAQgAiAEQYAbaigCAGshAgwBCyAMIAIpAAA3AAALIA1BCUkNACAMIA1qIQcgDEEIaiIEIAJBCGoiAmtBD0wEQANAIAQgAikAADcAACACQQhqIQIgBEEIaiIEIAdJDQAMAgsACyACKQAAITogBCACKQAINwAIIAQgOjcAACANQRlIDQAgDEEYaiEEA0AgAikAECE6IAQgAikAGDcACCAEIDo3AAAgAikAICE6IAQgAikAKDcAGCAEIDo3ABAgAkEgaiECIARBIGoiBCAHSQ0ACwsgBkGJf08EQCAGIQMMDgsgGSEcIAYgCWoMAwsgB0EgayECAkACQCAHIBxLDQAgCSAKKAIEIhIgBGoiDGogAksNACAMQSBqIBQgCWtNDQELIAUgCigCCDYCYCAFIAopAgA3A1ggCSAUIAIgBUHYAGogBUHMAmogHCALIBcgIhAhIQwMAgsgBCAJaiEGIAooAgghCiAPKQAAITogCSAPKQAINwAIIAkgOjcAAAJAIARBEUkNACAPKQAQITogCSAPKQAYNwAYIAkgOjcAECAEQRBrQRFIDQAgD0EQaiECIAlBIGohBANAIAIpABAhOiAEIAIpABg3AAggBCA6NwAAIAIpACAhOiAEIAIpACg3ABggBCA6NwAQIAJBIGohAiAEQSBqIgQgBkkNAAsLIAYgCmshAiAFIAc2AswCIAYgC2sgCkkEQCAKIAYgF2tLDQ0gIiAiIAIgC2siB2oiBCASak8EQCASRQ0DIAYgBCAS/AoAAAwDC0EAIAdrIgIEQCAGIAQgAvwKAAALIAcgEmohEiAGIAdrIQYgCyECCyAKQRBPBEAgAikAACE6IAYgAikACDcACCAGIDo3AAAgEkERSA0CIAYgEmohByAGQRBqIQQDQCACKQAQITogBCACKQAYNwAIIAQgOjcAACACKQAgITogBCACKQAoNwAYIAQgOjcAECACQSBqIQIgBEEgaiIEIAdJDQALDAILAkAgCkEHTQRAIAYgAi0AADoAACAGIAItAAE6AAEgBiACLQACOgACIAYgAi0AAzoAAyAGIAIgCkECdCIEQeAaaigCAGoiAigAADYABCACIARBgBtqKAIAayECDAELIAYgAikAADcAAAsgEkEJSQ0BIAYgEmohByAGQQhqIgQgAkEIaiICa0EPTARAA0AgBCACKQAANwAAIAJBCGohAiAE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';
13442
13995
 
13996
+ /**
13997
+ * @typedef {import('./basedecoder.js').BaseDecoderParameters & { LercParameters?: any }} LercDecoderParameters
13998
+ */
13443
13999
  const zstd$2 = new ZSTDDecoder$1();
13444
14000
  class LercDecoder extends BaseDecoder {
14001
+ /**
14002
+ * @param {ArrayBufferLike} buffer
14003
+ * @returns {ArrayBufferLike}
14004
+ */
13445
14005
  decodeBlock(buffer) {
13446
- const addCompression = this.parameters.LercParameters[LercParameters.AddCompression];
14006
+ const params = /** @type {LercDecoderParameters} */ (this.parameters);
14007
+ const addCompression = params.LercParameters?.[LercParameters.AddCompression];
14008
+ /** @type {ArrayBufferLike} */
14009
+ let decoded = buffer;
13447
14010
  switch (addCompression) {
13448
14011
  case LercAddCompression.None:
13449
14012
  break;
13450
14013
  case LercAddCompression.Deflate:
13451
- buffer = inflate_1(new Uint8Array(buffer)).buffer; // eslint-disable-line no-param-reassign, prefer-destructuring
14014
+ decoded = inflate_1(new Uint8Array(decoded)).buffer;
13452
14015
  break;
13453
14016
  case LercAddCompression.Zstandard:
13454
- buffer = zstd$2.decode(new Uint8Array(buffer)).buffer; // eslint-disable-line no-param-reassign, prefer-destructuring
14017
+ decoded = zstd$2.decode(new Uint8Array(decoded)).buffer;
13455
14018
  break;
13456
14019
  default:
13457
14020
  throw new Error(`Unsupported LERC additional compression method identifier: ${addCompression}`);
13458
14021
  }
13459
- const lercResult = Lerc.decode(buffer, { returnPixelInterleavedDims: this.parameters.planarConfiguration === 1 });
14022
+ const lercResult = Lerc.decode(decoded, { returnPixelInterleavedDims: this.parameters.planarConfiguration === 1 });
13460
14023
  const lercData = lercResult.pixels[0];
13461
14024
  return lercData.buffer;
13462
14025
  }
@@ -13632,8 +14195,9 @@ const wasm = 'AGFzbQEAAAABpgEVYAF/AGADf39/AX9gA39/fwBgAX8Bf2AFf39/f38Bf2ACf38AYA
13632
14195
 
13633
14196
  const zstd = new ZSTDDecoder();
13634
14197
  class ZstdDecoder extends BaseDecoder {
14198
+ /** @param {ArrayBuffer} buffer */
13635
14199
  decodeBlock(buffer) {
13636
- return zstd.decode(new Uint8Array(buffer)).buffer;
14200
+ return /** @type {ArrayBuffer} */ (zstd.decode(new Uint8Array(buffer)).buffer);
13637
14201
  }
13638
14202
  }
13639
14203
 
@@ -13650,6 +14214,9 @@ var zstd$1 = /*#__PURE__*/Object.freeze({
13650
14214
  * formats like WebP when supported.
13651
14215
  */
13652
14216
  class WebImageDecoder extends BaseDecoder {
14217
+ /**
14218
+ * @param {import('./basedecoder.js').BaseDecoderParameters} parameters
14219
+ */
13653
14220
  constructor(parameters) {
13654
14221
  super(parameters);
13655
14222
  if (typeof createImageBitmap === 'undefined') {
@@ -13659,6 +14226,7 @@ class WebImageDecoder extends BaseDecoder {
13659
14226
  throw new Error('Cannot decode WebImage as neither `document` nor `OffscreenCanvas` is not available');
13660
14227
  }
13661
14228
  }
14229
+ /** @param {ArrayBuffer} buffer */
13662
14230
  async decodeBlock(buffer) {
13663
14231
  const blob = new Blob([buffer]);
13664
14232
  const imageBitmap = await createImageBitmap(blob);