exiftool_vendored 13.37.0 → 13.40.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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +41 -3
  3. data/bin/MANIFEST +7 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +49 -47
  7. data/bin/config_files/local_time.config +55 -0
  8. data/bin/exiftool +83 -70
  9. data/bin/lib/Image/ExifTool/BMP.pm +1 -1
  10. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +2 -2
  11. data/bin/lib/Image/ExifTool/DJI.pm +256 -20
  12. data/bin/lib/Image/ExifTool/DSF.pm +138 -0
  13. data/bin/lib/Image/ExifTool/EXE.pm +3 -1
  14. data/bin/lib/Image/ExifTool/Font.pm +386 -118
  15. data/bin/lib/Image/ExifTool/Geolocation.pm +10 -7
  16. data/bin/lib/Image/ExifTool/Geotag.pm +21 -2
  17. data/bin/lib/Image/ExifTool/GoPro.pm +6 -3
  18. data/bin/lib/Image/ExifTool/Google.pm +16 -6
  19. data/bin/lib/Image/ExifTool/ID3.pm +11 -10
  20. data/bin/lib/Image/ExifTool/LNK.pm +63 -2
  21. data/bin/lib/Image/ExifTool/M2TS.pm +32 -23
  22. data/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  23. data/bin/lib/Image/ExifTool/OOXML.pm +3 -2
  24. data/bin/lib/Image/ExifTool/Olympus.pm +3 -1
  25. data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
  26. data/bin/lib/Image/ExifTool/QuickTime.pm +3 -3
  27. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +44 -35
  28. data/bin/lib/Image/ExifTool/Sony.pm +19 -14
  29. data/bin/lib/Image/ExifTool/TagLookup.pm +35 -1
  30. data/bin/lib/Image/ExifTool/TagNames.pod +1383 -1217
  31. data/bin/lib/Image/ExifTool/WavPack.pm +144 -0
  32. data/bin/lib/Image/ExifTool/XMP.pm +12 -7
  33. data/bin/lib/Image/ExifTool/XMP2.pl +11 -5
  34. data/bin/lib/Image/ExifTool.pm +46 -26
  35. data/bin/lib/Image/ExifTool.pod +64 -56
  36. data/bin/perl-Image-ExifTool.spec +47 -46
  37. data/lib/exiftool_vendored/version.rb +1 -1
  38. metadata +4 -1
@@ -18,22 +18,29 @@ use Image::ExifTool::XMP;
18
18
  use Image::ExifTool::GPS;
19
19
  use Image::ExifTool::Protobuf;
20
20
 
21
- $VERSION = '1.15';
21
+ $VERSION = '1.16';
22
22
 
23
23
  sub ProcessDJIInfo($$$);
24
24
  sub ProcessSettings($$$);
25
25
 
26
26
  %knownProtocol = (
27
- 'dvtm_ac203.proto' => 1, # Osmo Action 4
28
- 'dvtm_ac204.proto' => 1, # Osmo Action 5
29
- 'dvtm_AVATA2.proto' => 1, # Avata 2
30
- 'dvtm_wm265e.proto' => 1, # Mavic 3
31
- 'dvtm_pm320.proto' => 1, # Matrice 30
32
- 'dvtm_Mini4_Pro.proto' => 1, # Matrice 30
33
- 'dvtm_Mini4_Pro.proto' => 1, # Matrice 30
34
- 'dvtm_dji_neo.proto' => 1, # Neo
27
+ 'dvtm_ac203.proto' => 1, # Osmo Action 4
28
+ 'dvtm_ac204.proto' => 1, # Osmo Action 5
29
+ 'dvtm_AVATA2.proto' => 1, # Avata 2
30
+ 'dvtm_wm265e.proto' => 1, # Mavic 3
31
+ 'dvtm_pm320.proto' => 1, # Matrice 30
32
+ 'dvtm_Mini4_Pro.proto' => 1, # Mini 4
33
+ 'dvtm_dji_neo.proto' => 1, # Neo
34
+ 'dvtm_Air3.proto' => 1, # Air 3
35
+ 'dvtm_Air3s.proto' => 1, # Air 3s
36
+ 'dvtm_PP-101.proto' => 1, # Osmo Pocket 3
37
+ 'dvtm_oq101.proto' => 1, # Osmo 360
38
+ 'dvtm_wa345e.proto' => 1, # Matrice 4E
39
+ 'dvtm_wm261.proto' => 1, # Mavic Pro 3
40
+ # dvtm_wm169.proto seems to be DJI O3 but the structure is unknown
35
41
  );
36
42
 
43
+
37
44
  my %convFloat2 = (
38
45
  PrintConv => 'sprintf("%+.2f", $val)',
39
46
  PrintConvInv => '$val',
@@ -89,7 +96,7 @@ my %convFloat2 = (
89
96
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
90
97
  GROUPS => { 0 => 'APP4', 2 => 'Image' },
91
98
  NOTES => 'Thermal parameters extracted from APP4 of DJI RJPEG files from the ZH20T.',
92
- # 0x00 - 0xaa551206 - temperature header magic number
99
+ # 0x00 - 0xaa551206 - temperature header magic number
93
100
  0x24 => { Name => 'K1', Format => 'float' },
94
101
  0x28 => { Name => 'K2', Format => 'float' },
95
102
  0x2c => { Name => 'K3', Format => 'float' },
@@ -106,7 +113,7 @@ my %convFloat2 = (
106
113
  0x54 => { Name => 'KJ', Format => 'int16u' },
107
114
  0x56 => { Name => 'DB', Format => 'int16u' },
108
115
  0x58 => { Name => 'KK', Format => 'int16u' },
109
- # 0x500 - 0x55aa1206 - device header magic number
116
+ # 0x500 - 0x55aa1206 - device header magic number
110
117
  # (nothing yet decoded from device header)
111
118
  );
112
119
 
@@ -128,7 +135,7 @@ my %convFloat2 = (
128
135
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
129
136
  GROUPS => { 0 => 'APP4', 2 => 'Image' },
130
137
  NOTES => 'Thermal parameters extracted from APP4 of some DJI RJPEG files.',
131
- # 0x00 - 0xaa553800 - params3 magic number
138
+ # 0x00 - 0xaa553800 - params3 magic number
132
139
  0x04 => { Name => 'RelativeHumidity', Format => 'int16u' },
133
140
  0x06 => { Name => 'ObjectDistance', Format => 'int16u', ValueConv => '$val / 10' },
134
141
  0x08 => { Name => 'Emissivity', Format => 'int16u', ValueConv => '$val / 100' },
@@ -237,7 +244,10 @@ my %convFloat2 = (
237
244
  which use the following protocols: dvtm_AVATA2.proto (Avata 2),
238
245
  dvtm_ac203.proto (Osmo Action 4), dvtm_ac204.proto (Osmo Action 5),
239
246
  dvtm_wm265e.proto (Mavic 3), dvtm_pm320.proto (Matrice 30),
240
- dvtm_Mini4_Pro.proto (Mini 4 Pro) and dvtm_dji_neo.proto (DJI Neo).
247
+ dvtm_Mini4_Pro.proto (Mini 4 Pro), dvtm_dji_neo.proto (DJI Neo),
248
+ dvtm_Air3.proto (Air 3), dvtm_Air3s.proto (Air 3s), dvtm_PP-101.proto (Osmo
249
+ Pocket 3), dvtm_oq101.proto (Osmo 360), dvtm_wa345e.proto (Matrice 4E) and
250
+ dvtm_wm261.proto (Mavic Pro 3).
241
251
 
242
252
  Note that with the protobuf format, numerical tags missing from the output
243
253
  for a given protocol should be considered to have the default value of 0.
@@ -258,7 +268,7 @@ my %convFloat2 = (
258
268
  # dvtm_ac203_1-1-6 - some version number
259
269
  'dvtm_ac203_1-1-10' => 'Model',
260
270
  'dvtm_ac203_2-3' => {
261
- Name => 'FrameInfo',
271
+ Name => 'FrameInfo',
262
272
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
263
273
  },
264
274
  'dvtm_ac203_3-2-2-1' => { Name => 'ISO', Format => 'float' },
@@ -298,7 +308,7 @@ my %convFloat2 = (
298
308
  # dvtm_ac204_1-1-6 - some version number
299
309
  'dvtm_ac204_1-1-10' => 'Model',
300
310
  'dvtm_ac204_2-3' => {
301
- Name => 'FrameInfo',
311
+ Name => 'FrameInfo',
302
312
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
303
313
  },
304
314
  'dvtm_ac204_3-2-4-1' => { # (NC)
@@ -339,7 +349,7 @@ my %convFloat2 = (
339
349
  # dvtm_AVATA2_2-2-1-4 - model code?
340
350
  'dvtm_AVATA2_2-2-3-1' => 'SerialNumber2', # (NC)
341
351
  'dvtm_AVATA2_2-3' => {
342
- Name => 'FrameInfo',
352
+ Name => 'FrameInfo',
343
353
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
344
354
  },
345
355
  # dvtm_AVATA2_3-1-1 - frame number (starting at 1)
@@ -381,7 +391,7 @@ my %convFloat2 = (
381
391
  'dvtm_wm265e_1-1-5' => { Name => 'SerialNumber', Notes => 'Mavic 3' }, # (confirmed)
382
392
  'dvtm_wm265e_1-1-10' => 'Model',
383
393
  'dvtm_wm265e_2-2' => {
384
- Name => 'FrameInfo',
394
+ Name => 'FrameInfo',
385
395
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
386
396
  },
387
397
  # dvtm_wm265e_3-2-1-4 - model code?
@@ -413,7 +423,7 @@ my %convFloat2 = (
413
423
  'dvtm_pm320_1-1-5' => { Name => 'SerialNumber', Notes => 'Matrice 30' },
414
424
  'dvtm_pm320_1-1-10' => 'Model',
415
425
  'dvtm_pm320_2-2' => {
416
- Name => 'FrameInfo',
426
+ Name => 'FrameInfo',
417
427
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
418
428
  },
419
429
  'dvtm_pm320_3-2-2-1' => { Name => 'ISO', Format => 'float' },
@@ -448,7 +458,7 @@ my %convFloat2 = (
448
458
  'dvtm_Mini4_Pro_1-1-5' => { Name => 'SerialNumber', Notes => 'Mini 4 Pro' },
449
459
  'dvtm_Mini4_Pro_1-1-10' => 'Model',
450
460
  'dvtm_Mini4_Pro_2-3' => {
451
- Name => 'FrameInfo',
461
+ Name => 'FrameInfo',
452
462
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
453
463
  },
454
464
  'dvtm_Mini4_Pro_3-2-7-1' => { Name => 'ISO', Format => 'float' },
@@ -490,7 +500,7 @@ my %convFloat2 = (
490
500
  # dvtm_dji_neo_2-2-2-2 - some version number?
491
501
  'dvtm_dji_neo_2-2-3-1' => 'SerialNumber2', # (NC)
492
502
  'dvtm_dji_neo_2-3' => {
493
- Name => 'FrameInfo',
503
+ Name => 'FrameInfo',
494
504
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
495
505
  },
496
506
  # dvtm_dji_neo_3-1-1 - frame number (starting at 1)
@@ -525,6 +535,232 @@ my %convFloat2 = (
525
535
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
526
536
  },
527
537
  'dvtm_dji_neo_3-4-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' }, # (NC)
538
+ #
539
+ # Air 3
540
+ #
541
+ 'dvtm_Air3_1-1-5' => { Name => 'SerialNumber', Notes => 'Air 3' },
542
+ 'dvtm_Air3_2-3' => {
543
+ Name => 'FrameInfo',
544
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
545
+ },
546
+ 'dvtm_Air3_3-1-2' => {
547
+ Name => 'TimeStamp',
548
+ Groups => { 2 => 'Time' },
549
+ Format => 'unsigned',
550
+ ValueConv => '$val / 1e6',
551
+ },
552
+ 'dvtm_Air3_3-2-7-1' => { Name => 'ISO', Format => 'float' },
553
+ 'dvtm_Air3_3-2-10-1' => {
554
+ Name => 'ShutterSpeed',
555
+ Format => 'rational',
556
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
557
+ },
558
+ 'dvtm_Air3_3-2-32-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
559
+ 'dvtm_Air3_3-2-11-1' => {
560
+ Name => 'FNumber',
561
+ Format => 'rational',
562
+ PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
563
+ },
564
+ 'dvtm_Air3_3-3-3' => {
565
+ Name => 'DroneInfo',
566
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
567
+ },
568
+ 'dvtm_Air3_3-3-4-1' => {
569
+ Name => 'GPSInfo',
570
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
571
+ },
572
+ 'dvtm_Air3_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
573
+ 'dvtm_Air3_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
574
+ 'dvtm_Air3_3-4-3' => {
575
+ Name => 'GimbalInfo',
576
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
577
+ },
578
+ #
579
+ # Air 3s (same structure as Air 3)
580
+ #
581
+ 'dvtm_Air3s_1-1-5' => { Name => 'SerialNumber', Notes => 'Air 3s' },
582
+ 'dvtm_Air3s_2-3' => {
583
+ Name => 'FrameInfo',
584
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
585
+ },
586
+ 'dvtm_Air3s_3-1-2' => {
587
+ Name => 'TimeStamp',
588
+ Groups => { 2 => 'Time' },
589
+ Format => 'unsigned',
590
+ ValueConv => '$val / 1e6',
591
+ },
592
+ 'dvtm_Air3s_3-2-7-1' => { Name => 'ISO', Format => 'float' },
593
+ 'dvtm_Air3s_3-2-10-1' => {
594
+ Name => 'ShutterSpeed',
595
+ Format => 'rational',
596
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
597
+ },
598
+ 'dvtm_Air3s_3-2-32-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
599
+ 'dvtm_Air3s_3-2-11-1' => {
600
+ Name => 'FNumber',
601
+ Format => 'rational',
602
+ PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
603
+ },
604
+ 'dvtm_Air3s_3-3-3' => {
605
+ Name => 'DroneInfo',
606
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
607
+ },
608
+ 'dvtm_Air3s_3-3-4-1' => {
609
+ Name => 'GPSInfo',
610
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
611
+ },
612
+ 'dvtm_Air3s_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
613
+ 'dvtm_Air3s_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
614
+ 'dvtm_Air3s_3-4-3' => {
615
+ Name => 'GimbalInfo',
616
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
617
+ },
618
+ #
619
+ # Osmo 360 (similar to Action 4/5)
620
+ #
621
+ 'dvtm_oq101_1-1-5' => { Name => 'SerialNumber', Notes => 'Osmo 360' },
622
+ 'dvtm_oq101_1-1-10' => 'Model',
623
+ 'dvtm_oq101_3-1-2' => {
624
+ Name => 'TimeStamp',
625
+ Groups => { 2 => 'Time' },
626
+ Format => 'unsigned',
627
+ ValueConv => '$val / 1e6',
628
+ },
629
+ 'dvtm_oq101_3-2-3-1' => { Name => 'ISO', Format => 'float' },
630
+ 'dvtm_oq101_3-2-4-1' => {
631
+ Name => 'ShutterSpeed',
632
+ Format => 'rational',
633
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
634
+ },
635
+ 'dvtm_oq101_3-2-6-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
636
+ 'dvtm_oq101_1-14-1' => {
637
+ Name => 'FNumber',
638
+ Format => 'rational',
639
+ PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
640
+ },
641
+ 'dvtm_oq101_3-4-2-1' => {
642
+ Name => 'GPSInfo',
643
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
644
+ },
645
+ 'dvtm_oq101_3-4-2-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
646
+ 'dvtm_oq101_3-4-2-6-1' => {
647
+ Name => 'GPSDateTime',
648
+ Format => 'string',
649
+ Groups => { 2 => 'Time' },
650
+ RawConv => '$$self{GPSDateTime} = $val',
651
+ ValueConv => '$val =~ tr/-/:/; $val',
652
+ PrintConv => '$self->ConvertDateTime($val)',
653
+ },
654
+ 'dvtm_oq101_3-2-10-2' => { Name => 'AccelerometerX', Format => 'float' },
655
+ 'dvtm_oq101_3-2-10-3' => { Name => 'AccelerometerY', Format => 'float' },
656
+ 'dvtm_oq101_3-2-10-4' => { Name => 'AccelerometerZ', Format => 'float' },
657
+ #
658
+ # Osmo Pocket 3
659
+ #
660
+ 'dvtm_PP-101_1-1-5' => { Name => 'SerialNumber', Notes => 'Osmo Pocket 3' },
661
+ 'dvtm_PP-101_1-1-10' => 'Model',
662
+ 'dvtm_PP-101_2-3' => {
663
+ Name => 'FrameInfo',
664
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
665
+ },
666
+ 'dvtm_PP-101_3-1-2' => {
667
+ Name => 'TimeStamp',
668
+ Groups => { 2 => 'Time' },
669
+ Format => 'unsigned',
670
+ ValueConv => '$val / 1e6',
671
+ },
672
+ 'dvtm_PP-101_3-2-9-1' => { Name => 'ISO', Format => 'float' },
673
+ 'dvtm_PP-101_3-2-10-1' => {
674
+ Name => 'ShutterSpeed',
675
+ Format => 'rational',
676
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
677
+ },
678
+ 'dvtm_PP-101_3-2-24-1' => { Name => 'ColorTemperature', Format => 'unsigned' },
679
+ #
680
+ # Matrice 4E
681
+ #
682
+ 'dvtm_wa345e_1-1-5' => { Name => 'SerialNumber', Notes => 'Matrice 4E' },
683
+ 'dvtm_wa345e_1-1-10' => 'Model',
684
+ 'dvtm_wa345e_2-2' => {
685
+ Name => 'FrameInfo',
686
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
687
+ },
688
+ 'dvtm_wa345e_3-1-2' => {
689
+ Name => 'TimeStamp',
690
+ Groups => { 2 => 'Time' },
691
+ Format => 'unsigned',
692
+ ValueConv => '$val / 1e6',
693
+ },
694
+ 'dvtm_wa345e_3-3-3' => {
695
+ Name => 'DroneInfo',
696
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
697
+ },
698
+ 'dvtm_wa345e_3-3-4-1' => {
699
+ Name => 'GPSInfo',
700
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
701
+ },
702
+ 'dvtm_wa345e_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
703
+ 'dvtm_wa345e_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
704
+ 'dvtm_wa345e_3-4-3' => {
705
+ Name => 'GimbalInfo',
706
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
707
+ },
708
+ 'dvtm_wa345e_3-3-4-6-1' => {
709
+ Name => 'GPSDateTime',
710
+ Format => 'string',
711
+ Groups => { 2 => 'Time' },
712
+ RawConv => '$$self{GPSDateTime} = $val',
713
+ ValueConv => '$val =~ tr/-/:/; $val',
714
+ PrintConv => '$self->ConvertDateTime($val)',
715
+ },
716
+ #
717
+ # Mavic Pro 3
718
+ #
719
+ 'dvtm_wm261_1-1-5' => { Name => 'SerialNumber', Notes => 'Mavic Pro 3' },
720
+ 'dvtm_wm261_1-1-10' => 'Model',
721
+ 'dvtm_wm261_2-3' => {
722
+ Name => 'FrameInfo',
723
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
724
+ },
725
+ 'dvtm_wm261_3-1-2' => {
726
+ Name => 'TimeStamp',
727
+ Groups => { 2 => 'Time' },
728
+ Format => 'unsigned',
729
+ ValueConv => '$val / 1e6',
730
+ },
731
+ 'dvtm_wm261_3-2-9-1' => { Name => 'ISO', Format => 'float' },
732
+ 'dvtm_wm261_3-2-10-1' => {
733
+ Name => 'ShutterSpeed',
734
+ Format => 'rational',
735
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
736
+ },
737
+ 'dvtm_wm261_3-2-11-1'=> {
738
+ Name => 'FNumber',
739
+ Format => 'rational',
740
+ PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
741
+ },
742
+ 'dvtm_wm261_3-3-3' => {
743
+ Name => 'DroneInfo',
744
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
745
+ },
746
+ 'dvtm_wm261_3-3-4-1' => {
747
+ Name => 'GPSInfo',
748
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
749
+ },
750
+ 'dvtm_wm261_3-3-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' },
751
+ 'dvtm_wm261_3-3-5-1' => { Name => 'RelativeAltitude', Format => 'float', ValueConv => '$val / 1000' },
752
+ 'dvtm_wm261_3-4-3' => {
753
+ Name => 'GimbalInfo',
754
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
755
+ },
756
+ 'dvtm_wm261_3-3-4-6-1' => {
757
+ Name => 'GPSDateTime',
758
+ Format => 'string',
759
+ Groups => { 2 => 'Time' },
760
+ RawConv => '$$self{GPSDateTime} = $val',
761
+ ValueConv => '$val =~ tr/-/:/; $val',
762
+ PrintConv => '$self->ConvertDateTime($val)',
763
+ },
528
764
  );
529
765
 
530
766
  %Image::ExifTool::DJI::DroneInfo = (
@@ -0,0 +1,138 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: DSF.pm
3
+ #
4
+ # Description: Read DSF meta information
5
+ #
6
+ # Revisions: 2025-09-24 - P. Harvey Created
7
+ #
8
+ # References: 1) https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
9
+ #------------------------------------------------------------------------------
10
+
11
+ package Image::ExifTool::DSF;
12
+
13
+ use strict;
14
+ use vars qw($VERSION);
15
+ use Image::ExifTool qw(:DataAccess :Utils);
16
+
17
+ $VERSION = '1.00';
18
+
19
+ # DSF header format
20
+ %Image::ExifTool::DSF::Main = (
21
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
22
+ GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Audio' },
23
+ FORMAT => 'int32u',
24
+ NOTES => q{
25
+ Tags read from the 'fmt ' header of a DSF (DSD Stream File) audio files. As
26
+ well, ID3 metadata may also exist in these files. See
27
+ L<https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf>
28
+ for the specification.
29
+ },
30
+ 3 => 'FormatVersion',
31
+ 4 => { Name => 'FormatID', PrintConv => { 0 => 'DSD Raw' }},
32
+ 5 => {
33
+ Name => 'ChannelType',
34
+ PrintConv => {
35
+ 1 => 'Mono',
36
+ 2 => 'Stereo (Left, Right)',
37
+ 3 => '3 Channels (Left, Right, Center)',
38
+ 4 => 'Quad (Left, Right, Back L, Back R)',
39
+ 5 => '4 Channels (Left, Right, Center, Bass)',
40
+ 6 => '5 Channels (Left, Right, Center, Back L, Back R)',
41
+ 7 => '5.1 Channels (Left, Right, Center, Bass, Back L, Back R)',
42
+ },
43
+ },
44
+ 6 => 'ChannelCount',
45
+ 7 => 'SampleRate',
46
+ 8 => 'BitsPerSample',
47
+ 9 => { Name => 'SampleCount', Format => 'int64u' },
48
+ 11 => 'BlockSize',
49
+ );
50
+
51
+ #------------------------------------------------------------------------------
52
+ # Extract metadata from a DSF file
53
+ # Inputs: 0) ExifTool object reference, 1) dirInfo reference
54
+ # Returns: 1 on success, 0 if this wasn't a valid DSF file
55
+ sub ProcessDSF($$)
56
+ {
57
+ my ($et, $dirInfo) = @_;
58
+ my $raf = $$dirInfo{RAF};
59
+ my ($buff, $buf2, $tagTablePtr);
60
+
61
+ # verify this is a valid DSF file
62
+ return 0 unless $raf->Read($buff, 40) == 40;
63
+ return 0 unless $buff =~ /^DSD \x1c\0{7}.{16}fmt /s;
64
+ $et->SetFileType(); # set the FileType tag
65
+ my $tagTbl = GetTagTable('Image::ExifTool::DSF::Main');
66
+ SetByteOrder('II');
67
+ my $fmtLen = Get64u(\$buff,32);
68
+ unless ($fmtLen > 12 and $fmtLen < 1000 and
69
+ $raf->Read($buf2, $fmtLen - 12) == $fmtLen - 12)
70
+ {
71
+ $et->Warn('Error reading DSF fmt chunk');
72
+ return 1;
73
+ }
74
+ my $fileSize = Get64u(\$buff, 12);
75
+ my $metaPos = Get64u(\$buff, 20);
76
+ $buff = substr($buff, 28) . $buf2;
77
+ #
78
+ # process the DSF 'fmt ' chunk
79
+ #
80
+ my %dirInfo = (
81
+ DataPt => \$buff,
82
+ DirStart => 0,
83
+ DirLen => length($buff),
84
+ );
85
+ $et->ProcessBinaryData(\%dirInfo, $tagTbl);
86
+ #
87
+ # process ID3v2 if it exists
88
+ #
89
+ my $metaLen = $fileSize - $metaPos;
90
+ if ($metaPos and $metaLen > 0 and $metaLen < 20000000 and
91
+ $raf->Seek($metaPos, 0) and $raf->Read($buff, $metaLen) == $metaLen)
92
+ {
93
+ $dirInfo{DataPos} = $metaPos;
94
+ $dirInfo{DirLen} = $metaLen;
95
+ my $id3Tbl = GetTagTable('Image::ExifTool::ID3::Main');
96
+ $et->ProcessDirectory(\%dirInfo, $id3Tbl);
97
+ }
98
+ return 1;
99
+ }
100
+
101
+ 1; # end
102
+
103
+ __END__
104
+
105
+ =head1 NAME
106
+
107
+ Image::ExifTool::DSF - Read DSF meta information
108
+
109
+ =head1 SYNOPSIS
110
+
111
+ This module is used by Image::ExifTool
112
+
113
+ =head1 DESCRIPTION
114
+
115
+ This module contains definitions required by Image::ExifTool to read DSF
116
+ (DSD Stream File) audio files.
117
+
118
+ =head1 AUTHOR
119
+
120
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
121
+
122
+ This library is free software; you can redistribute it and/or modify it
123
+ under the same terms as Perl itself.
124
+
125
+ =head1 REFERENCES
126
+
127
+ =over 4
128
+
129
+ =item L<https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf>
130
+
131
+ =back
132
+
133
+ =head1 SEE ALSO
134
+
135
+ L<Image::ExifTool::TagNames/DSF Tags>,
136
+ L<Image::ExifTool(3pm)|Image::ExifTool>
137
+
138
+ =cut
@@ -22,7 +22,7 @@ use strict;
22
22
  use vars qw($VERSION);
23
23
  use Image::ExifTool qw(:DataAccess :Utils);
24
24
 
25
- $VERSION = '1.24';
25
+ $VERSION = '1.25';
26
26
 
27
27
  sub ProcessPEResources($$);
28
28
  sub ProcessPEVersion($$);
@@ -962,6 +962,7 @@ sub ProcessPEVersion($$)
962
962
  $pos = ($pos + 3) & 0xfffffffc; # align on a 4-byte boundary
963
963
  last if $pos + 6 > $end;
964
964
  $len = Get16u($dataPt, $pos);
965
+ return 0 if $pos + $len > $end;
965
966
  $valLen = Get16u($dataPt, $pos + 2);
966
967
  $type = Get16u($dataPt, $pos + 4);
967
968
  return 0 unless $len or $valLen; # prevent possible infinite loop
@@ -989,6 +990,7 @@ sub ProcessPEVersion($$)
989
990
  $valLen = Get16u($dataPt, $pt + 2);
990
991
  # $type = Get16u($dataPt, $pt + 4);
991
992
  my $entryEnd = $pt + $len;
993
+ return 0 if $entryEnd > $end;
992
994
  # get tag ID (converted to UTF8)
993
995
  ($string, $pt) = ReadUnicodeStr($dataPt, $pt + 6, $entryEnd);
994
996
  unless ($index) {