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