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