exiftool_vendored 13.34.0 → 13.37.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +55 -1
  3. data/bin/MANIFEST +5 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/Makefile.PL +1 -0
  7. data/bin/README +2 -2
  8. data/bin/build_geolocation +7 -3
  9. data/bin/exiftool +43 -33
  10. data/bin/lib/Image/ExifTool/Audible.pm +1 -1
  11. data/bin/lib/Image/ExifTool/BMP.pm +1 -1
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +15 -8
  13. data/bin/lib/Image/ExifTool/CBOR.pm +1 -1
  14. data/bin/lib/Image/ExifTool/Canon.pm +86 -9
  15. data/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
  16. data/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  17. data/bin/lib/Image/ExifTool/DJI.pm +59 -8
  18. data/bin/lib/Image/ExifTool/DV.pm +1 -1
  19. data/bin/lib/Image/ExifTool/EXE.pm +3 -2
  20. data/bin/lib/Image/ExifTool/FLIF.pm +1 -1
  21. data/bin/lib/Image/ExifTool/FLIR.pm +3 -3
  22. data/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
  23. data/bin/lib/Image/ExifTool/FujiFilm.pm +91 -33
  24. data/bin/lib/Image/ExifTool/GIF.pm +1 -1
  25. data/bin/lib/Image/ExifTool/GM.pm +1 -1
  26. data/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  27. data/bin/lib/Image/ExifTool/Geolocation.pm +3 -1
  28. data/bin/lib/Image/ExifTool/Geotag.pm +10 -2
  29. data/bin/lib/Image/ExifTool/GoPro.pm +5 -5
  30. data/bin/lib/Image/ExifTool/Google.pm +804 -0
  31. data/bin/lib/Image/ExifTool/H264.pm +1 -1
  32. data/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
  33. data/bin/lib/Image/ExifTool/ID3.pm +3 -3
  34. data/bin/lib/Image/ExifTool/JPEG.pm +1 -1
  35. data/bin/lib/Image/ExifTool/JSON.pm +1 -1
  36. data/bin/lib/Image/ExifTool/LIF.pm +1 -1
  37. data/bin/lib/Image/ExifTool/LNK.pm +2 -2
  38. data/bin/lib/Image/ExifTool/Lytro.pm +1 -1
  39. data/bin/lib/Image/ExifTool/M2TS.pm +4 -6
  40. data/bin/lib/Image/ExifTool/MPEG.pm +1 -1
  41. data/bin/lib/Image/ExifTool/MWG.pm +1 -1
  42. data/bin/lib/Image/ExifTool/MXF.pm +1 -1
  43. data/bin/lib/Image/ExifTool/MacOS.pm +2 -2
  44. data/bin/lib/Image/ExifTool/MakerNotes.pm +30 -7
  45. data/bin/lib/Image/ExifTool/Microsoft.pm +4 -4
  46. data/bin/lib/Image/ExifTool/Nikon.pm +6 -5
  47. data/bin/lib/Image/ExifTool/OOXML.pm +1 -1
  48. data/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  49. data/bin/lib/Image/ExifTool/Olympus.pm +6 -1
  50. data/bin/lib/Image/ExifTool/Other.pm +1 -1
  51. data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
  52. data/bin/lib/Image/ExifTool/Pentax.pm +51 -39
  53. data/bin/lib/Image/ExifTool/Protobuf.pm +12 -6
  54. data/bin/lib/Image/ExifTool/Qualcomm.pm +2 -2
  55. data/bin/lib/Image/ExifTool/QuickTime.pm +30 -8
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1 -1
  57. data/bin/lib/Image/ExifTool/README +7 -6
  58. data/bin/lib/Image/ExifTool/RIFF.pm +5 -3
  59. data/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
  60. data/bin/lib/Image/ExifTool/Reconyx.pm +375 -91
  61. data/bin/lib/Image/ExifTool/Samsung.pm +1 -1
  62. data/bin/lib/Image/ExifTool/Shortcuts.pm +8 -5
  63. data/bin/lib/Image/ExifTool/Sony.pm +20 -3
  64. data/bin/lib/Image/ExifTool/TagInfoXML.pm +3 -2
  65. data/bin/lib/Image/ExifTool/TagLookup.pm +5749 -5695
  66. data/bin/lib/Image/ExifTool/TagNames.pod +690 -519
  67. data/bin/lib/Image/ExifTool/Text.pm +1 -1
  68. data/bin/lib/Image/ExifTool/Trailer.pm +1 -1
  69. data/bin/lib/Image/ExifTool/WPG.pm +1 -1
  70. data/bin/lib/Image/ExifTool/WTV.pm +1 -1
  71. data/bin/lib/Image/ExifTool/Writer.pl +2 -1
  72. data/bin/lib/Image/ExifTool/XMP.pm +39 -32
  73. data/bin/lib/Image/ExifTool/XMP2.pl +0 -482
  74. data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
  75. data/bin/lib/Image/ExifTool/iWork.pm +1 -1
  76. data/bin/lib/Image/ExifTool.pm +6 -4
  77. data/bin/lib/Image/ExifTool.pod +3 -3
  78. data/bin/perl-Image-ExifTool.spec +1 -1
  79. data/lib/exiftool_vendored/version.rb +1 -1
  80. metadata +4 -6
@@ -18,7 +18,7 @@ use Image::ExifTool::XMP;
18
18
  use Image::ExifTool::GPS;
19
19
  use Image::ExifTool::Protobuf;
20
20
 
21
- $VERSION = '1.14';
21
+ $VERSION = '1.15';
22
22
 
23
23
  sub ProcessDJIInfo($$$);
24
24
  sub ProcessSettings($$$);
@@ -30,6 +30,8 @@ sub ProcessSettings($$$);
30
30
  'dvtm_wm265e.proto' => 1, # Mavic 3
31
31
  'dvtm_pm320.proto' => 1, # Matrice 30
32
32
  'dvtm_Mini4_Pro.proto' => 1, # Matrice 30
33
+ 'dvtm_Mini4_Pro.proto' => 1, # Matrice 30
34
+ 'dvtm_dji_neo.proto' => 1, # Neo
33
35
  );
34
36
 
35
37
  my %convFloat2 = (
@@ -138,7 +140,7 @@ my %convFloat2 = (
138
140
  GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'Location' },
139
141
  NAMESPACE => 'drone-dji',
140
142
  TABLE_DESC => 'XMP DJI',
141
- VARS => { NO_ID => 1 },
143
+ VARS => { ID_FMT => 'none' },
142
144
  NOTES => 'XMP tags used by DJI for images from drones.',
143
145
  AbsoluteAltitude => { Writable => 'real' },
144
146
  RelativeAltitude => { Writable => 'real' },
@@ -234,13 +236,14 @@ my %convFloat2 = (
234
236
  ExifTool currently extracts timed GPS plus a few other tags from DJI devices
235
237
  which use the following protocols: dvtm_AVATA2.proto (Avata 2),
236
238
  dvtm_ac203.proto (Osmo Action 4), dvtm_ac204.proto (Osmo Action 5),
237
- dvtm_wm265e.proto (Mavic 3), dvtm_pm320.proto (Matrice 30) and
238
- dvtm_pm320.proto (Mini 4 Pro).
239
+ 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).
239
241
 
240
242
  Note that with the protobuf format, numerical tags missing from the output
241
243
  for a given protocol should be considered to have the default value of 0.
242
244
  },
243
245
  Protocol => {
246
+ Notes => "typically protobuf field 1-1-1, but ExifTool doesn't rely on this",
244
247
  RawConv => q{
245
248
  unless ($Image::ExifTool::DJI::knownProtocol{$val}) {
246
249
  $self->Warn("Unknown protocol $val (please submit sample for testing)");
@@ -475,12 +478,59 @@ my %convFloat2 = (
475
478
  Name => 'GimbalInfo',
476
479
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::GimbalInfo' },
477
480
  },
481
+ #
482
+ # DJI Neo (very similar to AVATA2)
483
+ #
484
+ # dvtm_dji_neo_1-1-2 - some version number
485
+ # dvtm_dji_neo_1-1-3 - some version number
486
+ 'dvtm_dji_neo_1-1-5' => { Name => 'SerialNumber', Notes => 'DJI Neo' }, # (NC)
487
+ 'dvtm_dji_neo_1-1-10' => 'Model',
488
+ # dvtm_dji_neo_2-2-1-4 - model code?
489
+ # dvtm_dji_neo_2-2-2-1 - some firmware version?
490
+ # dvtm_dji_neo_2-2-2-2 - some version number?
491
+ 'dvtm_dji_neo_2-2-3-1' => 'SerialNumber2', # (NC)
492
+ 'dvtm_dji_neo_2-3' => {
493
+ Name => 'FrameInfo',
494
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::FrameInfo' },
495
+ },
496
+ # dvtm_dji_neo_3-1-1 - frame number (starting at 1)
497
+ 'dvtm_dji_neo_3-1-2' => { # (also 3-2-1-6 and 3-4-1-6)
498
+ Name => 'TimeStamp',
499
+ Groups => { 2 => 'Time' },
500
+ Format => 'unsigned',
501
+ # milliseconds, but I don't know what the zero is
502
+ ValueConv => '$val / 1e6',
503
+ },
504
+ # dvtm_dji_neo_3-2-1-4 - model code?
505
+ # dvtm_dji_neo_3-2-1-5 - frame rate?
506
+ 'dvtm_dji_neo_3-2-2-1' => { Name => 'ISO', Format => 'float' }, # (NC)
507
+ 'dvtm_dji_neo_3-2-4-1' => {
508
+ Name => 'ShutterSpeed',
509
+ Format => 'rational',
510
+ PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
511
+ },
512
+ 'dvtm_dji_neo_3-2-6-1' => { Name => 'ColorTemperature', Format => 'unsigned' }, # (NC)
513
+ 'dvtm_dji_neo_3-2-10-1' => { # (NC)
514
+ Name => 'FNumber',
515
+ Format => 'rational',
516
+ PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
517
+ },
518
+ # dvtm_dji_neo_3-4-1-4 - model code?
519
+ 'dvtm_dji_neo_3-4-3' => { # (NC)
520
+ Name => 'DroneInfo',
521
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::DroneInfo' },
522
+ },
523
+ 'dvtm_dji_neo_3-4-4-1' => {
524
+ Name => 'GPSInfo',
525
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::GPSInfo' },
526
+ },
527
+ 'dvtm_dji_neo_3-4-4-2' => { Name => 'AbsoluteAltitude', Format => 'int64s', ValueConv => '$val / 1000' }, # (NC)
478
528
  );
479
529
 
480
530
  %Image::ExifTool::DJI::DroneInfo = (
481
531
  GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Camera' },
482
532
  PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
483
- VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
533
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Field #' },
484
534
  1 => { Name => 'DroneRoll', Format => 'int64s', ValueConv => '$val / 10' },
485
535
  2 => { Name => 'DronePitch', Format => 'int64s', ValueConv => '$val / 10' },
486
536
  3 => { Name => 'DroneYaw', Format => 'int64s', ValueConv => '$val / 10' },
@@ -489,7 +539,7 @@ my %convFloat2 = (
489
539
  %Image::ExifTool::DJI::GimbalInfo = (
490
540
  GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Camera' },
491
541
  PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
492
- VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
542
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Field #' },
493
543
  1 => { Name => 'GimbalPitch',Format => 'int64s', ValueConv => '$val / 10' },
494
544
  2 => { Name => 'GimbalRoll', Format => 'int64s', ValueConv => '$val / 10' }, # usually 0, so missing
495
545
  3 => { Name => 'GimbalYaw', Format => 'int64s', ValueConv => '$val / 10' },
@@ -498,16 +548,17 @@ my %convFloat2 = (
498
548
  %Image::ExifTool::DJI::FrameInfo = (
499
549
  GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Video' },
500
550
  PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
501
- VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
551
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Field #' },
502
552
  1 => { Name => 'FrameWidth', Format => 'unsigned' },
503
553
  2 => { Name => 'FrameHeight', Format => 'unsigned' },
504
554
  3 => { Name => 'FrameRate', Format => 'float' },
555
+ # 4-8: seen these values respectively for DJI Neo: 1,8,4,1,4
505
556
  );
506
557
 
507
558
  %Image::ExifTool::DJI::GPSInfo = (
508
559
  GROUPS => { 0 => 'Protobuf', 1 => 'DJI', 2 => 'Location' },
509
560
  PROCESS_PROC => \&Image::ExifTool::Protobuf::ProcessProtobuf,
510
- VARS => { HEX_ID => 0, ID_LABEL => 'Field #' },
561
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Field #' },
511
562
  1 => {
512
563
  Name => 'CoordinateUnits',
513
564
  Format => 'unsigned',
@@ -123,7 +123,7 @@ my @dvTags = (
123
123
  # DV tags
124
124
  %Image::ExifTool::DV::Main = (
125
125
  GROUPS => { 2 => 'Video' },
126
- VARS => { NO_ID => 1 },
126
+ VARS => { ID_FMT => 'none' },
127
127
  NOTES => 'The following tags are extracted from DV videos.',
128
128
  DateTimeOriginal => {
129
129
  Description => 'Date/Time Original',
@@ -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.23';
25
+ $VERSION = '1.24';
26
26
 
27
27
  sub ProcessPEResources($$);
28
28
  sub ProcessPEVersion($$);
@@ -450,7 +450,7 @@ my %int32uTime = (
450
450
  # (see http://msdn.microsoft.com/en-us/library/aa381049.aspx)
451
451
  %Image::ExifTool::EXE::PEString = (
452
452
  GROUPS => { 2 => 'Other' },
453
- VARS => { NO_ID => 1 },
453
+ VARS => { ID_FMT => 'none' },
454
454
  NOTES => q{
455
455
  Resource strings found in Windows PE files. The B<TagID>'s are not shown
456
456
  because they are the same as the B<Tag Name>. ExifTool will extract any
@@ -985,6 +985,7 @@ sub ProcessPEVersion($$)
985
985
  my $tagTablePtr = GetTagTable('Image::ExifTool::EXE::PEString');
986
986
  for ($index = 0; $pt + 6 < $pos; ++$index) {
987
987
  $len = Get16u($dataPt, $pt);
988
+ $len or $et->Warn('Invalid PEString entry'), last;
988
989
  $valLen = Get16u($dataPt, $pt + 2);
989
990
  # $type = Get16u($dataPt, $pt + 4);
990
991
  my $entryEnd = $pt + $len;
@@ -36,7 +36,7 @@ my %flifMap = (
36
36
  # FLIF tags
37
37
  %Image::ExifTool::FLIF::Main = (
38
38
  GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
39
- VARS => { HEX_ID => 0 },
39
+ VARS => { ID_FMT => 'dec' },
40
40
  NOTES => q{
41
41
  Information extracted from Free Lossless Image Format files. See
42
42
  L<http://flif.info/> for more information.
@@ -476,7 +476,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' );
476
476
  GROUPS => { 0 => 'APP1', 2 => 'Image' },
477
477
  PROCESS_PROC => \&ProcessMeasInfo,
478
478
  FORMAT => 'int16u',
479
- VARS => { NO_ID => 1 },
479
+ VARS => { ID_FMT => 'none' },
480
480
  NOTES => q{
481
481
  Tags listed below are only for the first measurement tool, however multiple
482
482
  measurements may be added, and information is extracted for all of them.
@@ -548,7 +548,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' );
548
548
  %Image::ExifTool::FLIR::TextInfo = (
549
549
  GROUPS => { 0 => 'APP1', 2 => 'Image' },
550
550
  PROCESS_PROC => \&ProcessFLIRText,
551
- VARS => { NO_ID => 1 },
551
+ VARS => { ID_FMT => 'none' },
552
552
  Label0 => { },
553
553
  Value0 => { },
554
554
  Label1 => { },
@@ -564,7 +564,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' );
564
564
  %Image::ExifTool::FLIR::ParamInfo = (
565
565
  GROUPS => { 0 => 'APP1', 2 => 'Image' },
566
566
  PROCESS_PROC => \&ProcessFLIRText,
567
- VARS => { NO_ID => 1 },
567
+ VARS => { ID_FMT => 'none' },
568
568
  Generated => {
569
569
  Name => 'DateTimeGenerated',
570
570
  Description => 'Date/Time Generated',
@@ -1093,7 +1093,7 @@ my %fpxFileType = (
1093
1093
  %Image::ExifTool::FlashPix::DocTable = (
1094
1094
  GROUPS => { 1 => 'MS-DOC', 2 => 'Document' },
1095
1095
  NOTES => 'Tags extracted from the Microsoft Word document table.',
1096
- VARS => { NO_ID => 1 },
1096
+ VARS => { ID_FMT => 'none' },
1097
1097
  CommentBy => {
1098
1098
  Groups => { 2 => 'Author' },
1099
1099
  Notes => 'enable L<Duplicates|../ExifTool.html#Duplicates> option to extract all entries',
@@ -31,7 +31,7 @@ use vars qw($VERSION);
31
31
  use Image::ExifTool qw(:DataAccess :Utils);
32
32
  use Image::ExifTool::Exif;
33
33
 
34
- $VERSION = '1.98';
34
+ $VERSION = '2.00';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -426,6 +426,16 @@ my %faceCategories = (
426
426
  0x300 => 'DR (Dynamic Range priority)',
427
427
  },
428
428
  },
429
+ 0x1037 => { #forum17591
430
+ Name => 'MultipleExposure',
431
+ Writable => 'int16u', # (NC)
432
+ PrintConv => {
433
+ 1 => 'Additive',
434
+ 2 => 'Average',
435
+ 3 => 'Light',
436
+ 4 => 'Dark',
437
+ },
438
+ },
429
439
  0x1040 => { #8
430
440
  Name => 'ShadowTone',
431
441
  Writable => 'int32s',
@@ -586,16 +596,44 @@ my %faceCategories = (
586
596
  Name => 'SequenceNumber',
587
597
  Writable => 'int16u',
588
598
  },
599
+ 0x1102 => { #forum17602
600
+ Name => 'WhiteBalanceBracketing',
601
+ Writable => 'int16u', # (NC)
602
+ PrintHex => 1,
603
+ PrintConv => {
604
+ 0x01ff => '+/- 1',
605
+ 0x02ff => '+/- 2',
606
+ 0x03ff => '+/- 3',
607
+ },
608
+ },
589
609
  0x1103 => {
590
610
  Name => 'DriveSettings',
591
611
  SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::DriveSettings' },
592
612
  },
593
613
  0x1105 => { Name => 'PixelShiftShots', Writable => 'int16u' }, #IB
594
614
  0x1106 => { Name => 'PixelShiftOffset', Writable => 'rational64s', Count => 2 }, #IB
595
- # (0x1150-0x1152 exist only for Pro Low-light and Pro Focus PictureModes)
596
- # 0x1150 - Pro Low-light - val=1; Pro Focus - val=2 (ref 7); HDR - val=128 (forum10799)
597
- # 0x1151 - Pro Low-light - val=4 (number of pictures taken?); Pro Focus - val=2,3 (ref 7); HDR - val=3 (forum10799)
598
- # 0x1152 - Pro Low-light - val=1,3,4 (stacked pictures used?); Pro Focus - val=1,2 (ref 7); HDR - val=3 (forum10799)
615
+ 0x1150 => {
616
+ Name => 'CompositeImageMode',
617
+ Writable => 'int32u',
618
+ PrintConv => {
619
+ 0 => 'n/a', #PH
620
+ 1 => 'Pro Low-light', #7
621
+ 2 => 'Pro Focus', #7
622
+ 32 => 'Panorama', #PH
623
+ 128 => 'HDR', #forum10799
624
+ 1024 => 'Multi-exposure', #forum17591
625
+ },
626
+ },
627
+ 0x1151 => {
628
+ Name => 'CompositeImageCount1',
629
+ Writable => 'int16u',
630
+ # Pro Low-light - val=4 (number of pictures taken?); Pro Focus - val=2,3 (ref 7); HDR - val=3 (forum10799)
631
+ },
632
+ 0x1152 => {
633
+ Name => 'CompositeImageCount2',
634
+ Writable => 'int16u',
635
+ # Pro Low-light - val=1,3,4 (stacked pictures used?); Pro Focus - val=1,2 (ref 7); HDR - val=3 (forum10799)
636
+ },
599
637
  0x1153 => { #forum7668
600
638
  Name => 'PanoramaAngle',
601
639
  Writable => 'int16u',
@@ -605,8 +643,8 @@ my %faceCategories = (
605
643
  Writable => 'int16u',
606
644
  PrintConv => {
607
645
  1 => 'Right',
608
- 2 => 'Up',
609
- 3 => 'Left',
646
+ 2 => 'Left', #forum17591
647
+ 3 => 'Up', #forum17591
610
648
  4 => 'Down',
611
649
  },
612
650
  },
@@ -922,6 +960,7 @@ my %faceCategories = (
922
960
  3 => 'Right Eye',
923
961
  7 => 'Body',
924
962
  8 => 'Head',
963
+ 9 => 'Both Eyes', #forum17635
925
964
  11 => 'Bike',
926
965
  12 => 'Body of Car',
927
966
  13 => 'Front of Car',
@@ -1152,7 +1191,7 @@ my %faceCategories = (
1152
1191
  %Image::ExifTool::FujiFilm::FaceRecInfo = (
1153
1192
  PROCESS_PROC => \&ProcessFaceRec,
1154
1193
  GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
1155
- VARS => { NO_ID => 1 },
1194
+ VARS => { ID_FMT => 'none' },
1156
1195
  NOTES => 'Face recognition information.',
1157
1196
  Face1Name => { },
1158
1197
  Face2Name => { },
@@ -1558,20 +1597,21 @@ my %faceCategories = (
1558
1597
  TAG_PREFIX => 'MRAW',
1559
1598
  NOTES => q{
1560
1599
  Tags extracted from the M-RAW header of multi-image RAF files. The family 1
1561
- group name for these tags is "M-RAW".
1562
- },
1563
- 1 => { Name => 'RawImageNumber', Format => 'int32u' },
1564
- # 3 - seen "0 100", "-300 100" and "300 100" for a sequence of 3 images
1565
- 3 => { Name => 'ExposureCompensation', Format => 'rational32s', Unknown => 1, Hidden => 1, PrintConv => 'sprintf("%+.2f",$val)' },
1566
- # 4 - (same value as 3 in all my samples)
1567
- 4 => { Name => 'ExposureCompensation2', Format => 'rational32s', Unknown => 1, Hidden => 1, PrintConv => 'sprintf("%+.2f",$val)' },
1568
- # 5 - seen "10 1600", "10 6800", "10 200", "10 35000" etc
1569
- 5 => { Name => 'ExposureTime', Format => 'rational64u', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)' },
1570
- # 6 - seen "450 100", "400 100" (all images in RAF have same value)
1571
- 6 => { Name => 'FNumber', Format => 'rational64u', PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)' },
1572
- # 7 - seen 200, 125, 250, 2000
1573
- 7 => 'ISO',
1574
- # 8 - seen 0, 65536
1600
+ group name for these tags is "M-RAW". Additional metadata may be extracted
1601
+ from the embedded RAW images with the ExtractEmbedded option.
1602
+ },
1603
+ 0x2001 => { Name => 'RawImageNumber', Format => 'int32u' },
1604
+ # 0x2003 - seen "0 100", "-300 100" and "300 100" for a sequence of 3 images
1605
+ 0x2003 => { Name => 'ExposureCompensation', Format => 'rational32s', Unknown => 1, Hidden => 1, PrintConv => 'sprintf("%+.2f",$val)' },
1606
+ # 0x2004 - (same value as 3 in all my samples)
1607
+ 0x2004 => { Name => 'ExposureCompensation2', Format => 'rational32s', Unknown => 1, Hidden => 1, PrintConv => 'sprintf("%+.2f",$val)' },
1608
+ # 0x2005 - seen "10 1600", "10 6800", "10 200", "10 35000" etc
1609
+ 0x2005 => { Name => 'ExposureTime', Format => 'rational64u', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)' },
1610
+ # 0x2006 - seen "450 100", "400 100" (all images in RAF have same value)
1611
+ 0x2006 => { Name => 'FNumber', Format => 'rational64u', PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)' },
1612
+ # 0x2007 - seen 200, 125, 250, 2000
1613
+ 0x2007 => 'ISO',
1614
+ # 0x2008 - seen 0, 65536
1575
1615
  );
1576
1616
 
1577
1617
  #------------------------------------------------------------------------------
@@ -1684,6 +1724,7 @@ sub ProcessFujiDir($$$)
1684
1724
  sub ProcessMRAW($$$)
1685
1725
  {
1686
1726
  my ($et, $dirInfo, $tagTablePtr) = @_;
1727
+ return 1 if $$et{DOC_NUM};
1687
1728
  my $dataPt = $$dirInfo{DataPt};
1688
1729
  my $dataPos = $$dirInfo{DataPos};
1689
1730
  my $dataLen = length $$dataPt;
@@ -1697,15 +1738,16 @@ sub ProcessMRAW($$$)
1697
1738
  my $pos = 44;
1698
1739
  my ($i, $n);
1699
1740
  for ($n=0; ; ++$n) {
1700
- $pos += 16; # skip offset/size fields
1701
- my $end = $pos + $size;
1741
+ my $end = $pos + 16 + $size;
1702
1742
  last if $end > $dataLen;
1743
+ my $rafStart = Get64u($dataPt, $pos);
1744
+ my $rafLen = Get64u($dataPt, $pos+8);
1745
+ $pos += 16; # skip offset/size fields
1703
1746
  $$et{DOC_NUM} = ++$$et{DOC_COUNT} if $pos > 60;
1704
1747
  $et->VPrint(0, "$$et{INDENT}(Raw image $n parameters: $size bytes, $num entries)\n");
1705
1748
  for ($i=0; $i<$num; ++$i) {
1706
1749
  last if $pos + 4 > $end;
1707
- # (don't know what the byte at the current $pos is for, value = 0x20)
1708
- my $tag = Get8u($dataPt, $pos+1);
1750
+ my $tag = Get16u($dataPt, $pos);
1709
1751
  my $size = Get16u($dataPt, $pos+2);
1710
1752
  $pos += 4;
1711
1753
  last if $pos + $size > $end;
@@ -1717,6 +1759,21 @@ sub ProcessMRAW($$$)
1717
1759
  );
1718
1760
  $pos += $size;
1719
1761
  }
1762
+ if ($rafStart and $et->Options('ExtractEmbedded')) {
1763
+ if ($et->Options('Verbose')) {
1764
+ my $msg = sprintf("$$et{INDENT}(RAW image $n data: Start=0x%x, Length=0x%x)\n",$rafStart,$rafLen);
1765
+ $et->VPrint(0, $msg);
1766
+ }
1767
+ my $raf = $$et{RAF};
1768
+ my $tell = $raf->Tell();
1769
+ my $order = GetByteOrder();
1770
+ my $fujiWidth = $$et{FujiWidth};
1771
+ $raf->Seek($rafStart, 0) or next;
1772
+ ProcessRAF($et, { RAF => $raf, Base => $rafStart });
1773
+ $$et{FujiWidth} = $fujiWidth;
1774
+ SetByteOrder($order);
1775
+ $raf->Seek($tell, 0);
1776
+ }
1720
1777
  }
1721
1778
  delete $$et{DOC_NUM};
1722
1779
  return 1;
@@ -1816,7 +1873,6 @@ sub WriteRAF($$)
1816
1873
  # make sure padding is only zero bytes (can be >100k for HS10)
1817
1874
  # (have seen non-null padding in X-Pro1)
1818
1875
  if ($buff =~ /[^\0]/) {
1819
- HexDump(\$buff);
1820
1876
  return 1 if $et->Error('Non-null bytes found in padding', 2);
1821
1877
  }
1822
1878
  }
@@ -1871,6 +1927,7 @@ sub ProcessRAF($$)
1871
1927
  my ($buff, $jpeg, $warn, $offset);
1872
1928
 
1873
1929
  my $raf = $$dirInfo{RAF};
1930
+ my $base = $$dirInfo{Base} || 0;
1874
1931
  $raf->Read($buff,0x70) == 0x70 or return 0;
1875
1932
  $buff =~ /^FUJIFILM/ or return 0;
1876
1933
  # get position and size of M-RAW header and jpeg preview
@@ -1878,13 +1935,13 @@ sub ProcessRAF($$)
1878
1935
  my ($jpos, $jlen) = unpack('x84NN', $buff);
1879
1936
  $jpos & 0x8000 and return 0;
1880
1937
  if ($jpos) {
1881
- $raf->Seek($jpos, 0) or return 0;
1938
+ $raf->Seek($jpos+$base, 0) or return 0;
1882
1939
  $raf->Read($jpeg, $jlen) == $jlen or return 0;
1883
1940
  }
1884
1941
  SetByteOrder('MM');
1885
- $et->SetFileType();
1942
+ $et->SetFileType() unless $$et{DOC_NUM};
1886
1943
  my $tbl = GetTagTable('Image::ExifTool::FujiFilm::RAFHeader');
1887
- $et->ProcessDirectory({ DataPt => \$buff, DirName => 'RAFHeader' }, $tbl);
1944
+ $et->ProcessDirectory({ DataPt => \$buff, DirName => 'RAFHeader', Base => $base }, $tbl);
1888
1945
 
1889
1946
  # extract information from embedded JPEG
1890
1947
  my %dirInfo = (
@@ -1892,21 +1949,22 @@ sub ProcessRAF($$)
1892
1949
  RAF => File::RandomAccess->new(\$jpeg),
1893
1950
  );
1894
1951
  if ($jpos) {
1895
- $$et{BASE} += $jpos;
1952
+ $$et{BASE} += $jpos + $base;
1896
1953
  my $ok = $et->ProcessJPEG(\%dirInfo);
1897
- $$et{BASE} -= $jpos;
1954
+ $$et{BASE} -= $jpos + $base;
1898
1955
  $et->FoundTag('PreviewImage', \$jpeg) if $ok;
1899
1956
  }
1900
1957
  # extract information from Fuji RAF and TIFF directories
1901
1958
  my ($rafNum, $ifdNum) = ('','');
1902
1959
  foreach $offset (0x48, 0x5c, 0x64, 0x78, 0x80) {
1903
1960
  last if $jpos and $offset >= $jpos;
1904
- unless ($raf->Seek($offset, 0) and $raf->Read($buff, 8)) {
1961
+ unless ($raf->Seek($offset+$base, 0) and $raf->Read($buff, 8)) {
1905
1962
  $warn = 1;
1906
1963
  last;
1907
1964
  }
1908
1965
  my ($start, $len) = unpack('N2',$buff);
1909
1966
  next unless $start;
1967
+ $start += $base;
1910
1968
  if ($offset == 0x64 or $offset == 0x80) {
1911
1969
  # parse FujiIFD directory
1912
1970
  %dirInfo = (
@@ -33,7 +33,7 @@ my @appExtensions = ( 'XMP Data/XMP', 'ICCRGBG1/012' );
33
33
 
34
34
  %Image::ExifTool::GIF::Main = (
35
35
  GROUPS => { 2 => 'Image' },
36
- VARS => { NO_ID => 1 },
36
+ VARS => { ID_FMT => 'none' },
37
37
  NOTES => q{
38
38
  This table lists information extracted from GIF images. See
39
39
  L<http://www.w3.org/Graphics/GIF/spec-gif89a.txt> for the official GIF89a
@@ -136,7 +136,7 @@ my %channelStruct = (
136
136
  %Image::ExifTool::GM::marl = (
137
137
  PROCESS_PROC => \&Process_marl,
138
138
  GROUPS => { 2 => 'Other' },
139
- VARS => { NO_ID => 1, NO_LOOKUP => 1 },
139
+ VARS => { ID_FMT => 'none', NO_LOOKUP => 1 },
140
140
  NOTES => q{
141
141
  Tags extracted from the 'ctbx' 'marl' (Marlin) box of timed PDR metadata
142
142
  from GM cars. Use the -ee (L<API ExtractEmbedded|../ExifTool.html#ExtractEmbedded>) option to extract this
Binary file
@@ -401,11 +401,13 @@ sub GetEntry($;$$)
401
401
  my $xlat = $langLookup{$lang};
402
402
  # load language lookups if not done already
403
403
  if (not defined $xlat) {
404
- if (eval "require '$geoDir/GeoLang/$lang.pm'") {
404
+ unshift @INC, $geoDir; # make sure $geoDir is first in path
405
+ if (eval "require 'GeoLang/$lang.pm'") {
405
406
  my $trans = "Image::ExifTool::GeoLang::${lang}::Translate";
406
407
  no strict 'refs';
407
408
  $xlat = \%$trans if %$trans;
408
409
  }
410
+ shift @INC;
409
411
  # read user-defined language translations
410
412
  if (%Image::ExifTool::Geolocation::geoLang) {
411
413
  my $userLang = $Image::ExifTool::Geolocation::geoLang{$lang};
@@ -34,7 +34,7 @@ use vars qw($VERSION);
34
34
  use Image::ExifTool qw(:Public);
35
35
  use Image::ExifTool::GPS;
36
36
 
37
- $VERSION = '1.81';
37
+ $VERSION = '1.82';
38
38
 
39
39
  sub JITTER() { return 2 } # maximum time jitter
40
40
 
@@ -275,6 +275,7 @@ sub LoadTrackLog($$;$)
275
275
  } elsif (((/\b(GPS)?Date/i and /\b(GPS)?(Date)?Time/i) or /\bTime\(seconds\)/i) and /\Q$csvDelim/) {
276
276
  chomp;
277
277
  @csvHeadings = split /\Q$csvDelim/;
278
+ my $isColumbus = ($csvHeadings[0] and $csvHeadings[0] eq 'INDEX'); # (Columbus GPS logger)
278
279
  $format = 'CSV';
279
280
  # convert recognized headings to our parameter names
280
281
  foreach (@csvHeadings) {
@@ -306,7 +307,7 @@ sub LoadTrackLog($$;$)
306
307
  } elsif (/^(Pos)?Lon/i) {
307
308
  $param = 'lon';
308
309
  /ref$/i and $param .= 'ref';
309
- } elsif (/^(Pos)?Alt/i) {
310
+ } elsif (/^(Pos)?(Alt|Height)/i) {
310
311
  $param = 'alt';
311
312
  } elsif (/^Speed/i) {
312
313
  $param = 'speed';
@@ -314,6 +315,9 @@ sub LoadTrackLog($$;$)
314
315
  if (m{\((mph|km/h|m/s)\)}) {
315
316
  $scaleSpeed = $otherConv{$1};
316
317
  $xtra = " in $1";
318
+ } elsif ($isColumbus) { # (Columbus GPS logger)
319
+ $scaleSpeed = $otherConv{'km/h'};
320
+ $xtra = " in km/h";
317
321
  } else {
318
322
  $xtra = ' in knots';
319
323
  }
@@ -541,12 +545,16 @@ DoneFix: $isDate = 1;
541
545
  $date = Time::Local::timegm(0,0,0,$1,$2-1,$3);
542
546
  } elsif ($val =~ /(\d{4}).*?(\d{2}).*?(\d{2})/) {
543
547
  $date = Time::Local::timegm(0,0,0,$3,$2-1,$1);
548
+ } elsif ($val =~ /^(\d{2})(\d{2})(\d{2})$/) { # (Columbus GPS logger)
549
+ $date = Time::Local::timegm(0,0,0,$3,$2-1,$1+2000);
544
550
  }
545
551
  } elsif ($param eq 'time') {
546
552
  if ($val =~ /^(\d{1,2}):(\d{2}):(\d{2}(\.\d+)?).*?(([-+])(\d{1,2}):?(\d{2}))?/) {
547
553
  $secs = (($1 * 60) + $2) * 60 + $3;
548
554
  # adjust for time zone if specified
549
555
  $secs += ($7 * 60 + $8) * ($6 eq '-' ? 60 : -60) if $5;
556
+ } elsif ($val =~ /^(\d{2})(\d{2})(\d{2})$/) { # (Columbus GPS logger)
557
+ $secs = (($1 * 60) + $2) * 60 + $3;
550
558
  }
551
559
  } elsif ($param eq 'lat' or $param eq 'lon') {
552
560
  $$fix{$param} = Image::ExifTool::GPS::ToDegrees($val, 1);
@@ -485,7 +485,7 @@ my %noYes = ( N => 'No', Y => 'Yes' );
485
485
  %Image::ExifTool::GoPro::GPS5 = (
486
486
  PROCESS_PROC => \&ProcessString,
487
487
  GROUPS => { 1 => 'GoPro', 2 => 'Location' },
488
- VARS => { HEX_ID => 0, ID_LABEL => 'Index' },
488
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Index' },
489
489
  0 => { # (unit='deg')
490
490
  Name => 'GPSLatitude',
491
491
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
@@ -514,7 +514,7 @@ my %noYes = ( N => 'No', Y => 'Yes' );
514
514
  %Image::ExifTool::GoPro::GPS9 = (
515
515
  PROCESS_PROC => \&ProcessString,
516
516
  GROUPS => { 1 => 'GoPro', 2 => 'Location' },
517
- VARS => { HEX_ID => 0, ID_LABEL => 'Index' },
517
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Index' },
518
518
  0 => { # (unit='deg')
519
519
  Name => 'GPSLatitude',
520
520
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
@@ -563,7 +563,7 @@ my %noYes = ( N => 'No', Y => 'Yes' );
563
563
  %Image::ExifTool::GoPro::GPRI = (
564
564
  PROCESS_PROC => \&ProcessString,
565
565
  GROUPS => { 1 => 'GoPro', 2 => 'Location' },
566
- VARS => { HEX_ID => 0, ID_LABEL => 'Index' },
566
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Index' },
567
567
  0 => { # (unit='s')
568
568
  Name => 'GPSDateTimeRaw',
569
569
  Groups => { 2 => 'Time' },
@@ -595,7 +595,7 @@ my %noYes = ( N => 'No', Y => 'Yes' );
595
595
  %Image::ExifTool::GoPro::GLPI = (
596
596
  PROCESS_PROC => \&ProcessString,
597
597
  GROUPS => { 1 => 'GoPro', 2 => 'Location' },
598
- VARS => { HEX_ID => 0, ID_LABEL => 'Index' },
598
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Index' },
599
599
  0 => { # (unit='s')
600
600
  Name => 'GPSDateTime',
601
601
  Groups => { 2 => 'Time' },
@@ -626,7 +626,7 @@ my %noYes = ( N => 'No', Y => 'Yes' );
626
626
  %Image::ExifTool::GoPro::KBAT = (
627
627
  PROCESS_PROC => \&ProcessString,
628
628
  GROUPS => { 1 => 'GoPro', 2 => 'Camera' },
629
- VARS => { HEX_ID => 0, ID_LABEL => 'Index' },
629
+ VARS => { ID_FMT => 'dec', ID_LABEL => 'Index' },
630
630
  NOTES => 'Battery status information found in GoPro Karma videos.',
631
631
  0 => { Name => 'BatteryCurrent', PrintConv => '"$val A"' },
632
632
  1 => { Name => 'BatteryCapacity', PrintConv => '"$val Ah"' },