exiftool-vendored.exe 12.30.0 → 12.38.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 (52) hide show
  1. package/bin/exiftool_files/Changes +129 -3
  2. package/bin/exiftool_files/README +2 -2
  3. package/bin/exiftool_files/arg_files/xmp2exif.args +2 -1
  4. package/bin/exiftool_files/config_files/example.config +1 -1
  5. package/bin/exiftool_files/exiftool.pl +100 -58
  6. package/bin/exiftool_files/fmt_files/gpx.fmt +1 -1
  7. package/bin/exiftool_files/fmt_files/gpx_wpt.fmt +1 -1
  8. package/bin/exiftool_files/lib/Image/ExifTool/BuildTagLookup.pm +13 -3
  9. package/bin/exiftool_files/lib/Image/ExifTool/CBOR.pm +331 -0
  10. package/bin/exiftool_files/lib/Image/ExifTool/Canon.pm +175 -12
  11. package/bin/exiftool_files/lib/Image/ExifTool/CanonCustom.pm +12 -2
  12. package/bin/exiftool_files/lib/Image/ExifTool/Charset.pm +2 -0
  13. package/bin/exiftool_files/lib/Image/ExifTool/DPX.pm +13 -2
  14. package/bin/exiftool_files/lib/Image/ExifTool/DarwinCore.pm +2 -2
  15. package/bin/exiftool_files/lib/Image/ExifTool/Exif.pm +109 -3
  16. package/bin/exiftool_files/lib/Image/ExifTool/FLIR.pm +33 -8
  17. package/bin/exiftool_files/lib/Image/ExifTool/GIF.pm +5 -1
  18. package/bin/exiftool_files/lib/Image/ExifTool/GPS.pm +14 -10
  19. package/bin/exiftool_files/lib/Image/ExifTool/Geotag.pm +13 -2
  20. package/bin/exiftool_files/lib/Image/ExifTool/GoPro.pm +16 -1
  21. package/bin/exiftool_files/lib/Image/ExifTool/ICC_Profile.pm +96 -4
  22. package/bin/exiftool_files/lib/Image/ExifTool/JSON.pm +7 -3
  23. package/bin/exiftool_files/lib/Image/ExifTool/Jpeg2000.pm +154 -24
  24. package/bin/exiftool_files/lib/Image/ExifTool/M2TS.pm +27 -12
  25. package/bin/exiftool_files/lib/Image/ExifTool/MacOS.pm +2 -2
  26. package/bin/exiftool_files/lib/Image/ExifTool/Nikon.pm +1204 -96
  27. package/bin/exiftool_files/lib/Image/ExifTool/NikonCustom.pm +5 -1
  28. package/bin/exiftool_files/lib/Image/ExifTool/NikonSettings.pm +135 -71
  29. package/bin/exiftool_files/lib/Image/ExifTool/Olympus.pm +5 -1
  30. package/bin/exiftool_files/lib/Image/ExifTool/OpenEXR.pm +4 -2
  31. package/bin/exiftool_files/lib/Image/ExifTool/PDF.pm +11 -12
  32. package/bin/exiftool_files/lib/Image/ExifTool/PNG.pm +4 -1
  33. package/bin/exiftool_files/lib/Image/ExifTool/Panasonic.pm +2 -2
  34. package/bin/exiftool_files/lib/Image/ExifTool/Pentax.pm +2 -1
  35. package/bin/exiftool_files/lib/Image/ExifTool/QuickTime.pm +69 -10
  36. package/bin/exiftool_files/lib/Image/ExifTool/QuickTimeStream.pl +141 -111
  37. package/bin/exiftool_files/lib/Image/ExifTool/README +9 -2
  38. package/bin/exiftool_files/lib/Image/ExifTool/Sony.pm +56 -13
  39. package/bin/exiftool_files/lib/Image/ExifTool/TagInfoXML.pm +9 -4
  40. package/bin/exiftool_files/lib/Image/ExifTool/TagLookup.pm +6473 -5827
  41. package/bin/exiftool_files/lib/Image/ExifTool/TagNames.pod +1401 -54
  42. package/bin/exiftool_files/lib/Image/ExifTool/WritePDF.pl +1 -0
  43. package/bin/exiftool_files/lib/Image/ExifTool/WritePNG.pl +2 -0
  44. package/bin/exiftool_files/lib/Image/ExifTool/WriteQuickTime.pl +10 -0
  45. package/bin/exiftool_files/lib/Image/ExifTool/WriteXMP.pl +10 -11
  46. package/bin/exiftool_files/lib/Image/ExifTool/Writer.pl +50 -5
  47. package/bin/exiftool_files/lib/Image/ExifTool/XMP.pm +125 -31
  48. package/bin/exiftool_files/lib/Image/ExifTool/XMP2.pl +3 -1
  49. package/bin/exiftool_files/lib/Image/ExifTool/XMPStruct.pl +3 -1
  50. package/bin/exiftool_files/lib/Image/ExifTool.pm +8931 -8864
  51. package/bin/exiftool_files/lib/Image/ExifTool.pod +21 -13
  52. package/package.json +3 -3
@@ -16,7 +16,7 @@ use strict;
16
16
  use vars qw($VERSION);
17
17
  use Image::ExifTool qw(:DataAccess :Utils);
18
18
 
19
- $VERSION = '1.30';
19
+ $VERSION = '1.32';
20
20
 
21
21
  sub ProcessJpeg2000Box($$$);
22
22
  sub ProcessJUMD($$$);
@@ -42,8 +42,9 @@ my %jp2Map = (
42
42
  'UUID-IPTC' => 'JP2',
43
43
  'UUID-EXIF' => 'JP2',
44
44
  'UUID-XMP' => 'JP2',
45
- # jp2h => 'JP2', (not yet functional)
46
- # ICC_Profile => 'jp2h', (not yet functional)
45
+ jp2h => 'JP2',
46
+ colr => 'jp2h',
47
+ ICC_Profile => 'colr',
47
48
  IFD1 => 'IFD0',
48
49
  EXIF => 'IFD0', # to write EXIF as a block
49
50
  ExifIFD => 'IFD0',
@@ -116,9 +117,6 @@ my %j2cMarker = (
116
117
  0x76 => 'NLT', # non-linearity point transformation
117
118
  );
118
119
 
119
- my %jumbfTypes = (
120
- );
121
-
122
120
  # JPEG 2000 "box" (ie. atom) names
123
121
  # Note: only tags with a defined "Format" are extracted
124
122
  %Image::ExifTool::Jpeg2000::Main = (
@@ -127,10 +125,13 @@ my %jumbfTypes = (
127
125
  WRITE_PROC => \&ProcessJpeg2000Box,
128
126
  PREFERRED => 1, # always add these tags when writing
129
127
  NOTES => q{
130
- The tags below are extracted from JPEG 2000 images and the JUMBF metadata in
131
- JPEG images. Note that ExifTool currently writes only EXIF, IPTC and XMP
132
- tags in Jpeg2000 images.
128
+ The tags below are found in JPEG 2000 images and the JUMBF metadata in JPEG
129
+ images, but not all of these are extracted. Note that ExifTool currently
130
+ writes only EXIF, IPTC and XMP tags in Jpeg2000 images.
133
131
  },
132
+ #
133
+ # NOTE: ONLY TAGS WITH "Format" DEFINED ARE EXTRACTED!
134
+ #
134
135
  'jP ' => 'JP2Signature', # (ref 1)
135
136
  "jP\x1a\x1a" => 'JP2Signature', # (ref 2)
136
137
  prfl => 'Profile',
@@ -340,10 +341,20 @@ my %jumbfTypes = (
340
341
  },
341
342
  {
342
343
  Name => 'UUID-Signature', # (seen in JUMB data of JPEG images)
344
+ # (may be able to remove this when JUMBF specification is finalized)
343
345
  Condition => '$$valPt=~/^casg\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
344
346
  Format => 'undef',
345
347
  ValueConv => 'substr($val,16)',
346
348
  },
349
+ {
350
+ Name => 'UUID-C2PAClaimSignature', # (seen in incorrectly-formatted JUMB data of JPEG images)
351
+ # (may be able to remove this when JUMBF specification is finalized)
352
+ Condition => '$$valPt=~/^c2cs\x00\x11\x00\x10\x80\x00\x00\xaa\x00\x38\x9b\x71/',
353
+ SubDirectory => {
354
+ TagTable => 'Image::ExifTool::CBOR::Main',
355
+ Start => '$valuePtr + 16',
356
+ },
357
+ },
347
358
  {
348
359
  Name => 'UUID-Unknown',
349
360
  },
@@ -386,6 +397,27 @@ my %jumbfTypes = (
386
397
  },
387
398
  SubDirectory => { TagTable => 'Image::ExifTool::JSON::Main' },
388
399
  },
400
+ cbor => {
401
+ Name => 'CBORData',
402
+ Flags => [ 'Binary', 'Protected' ],
403
+ SubDirectory => { TagTable => 'Image::ExifTool::CBOR::Main' },
404
+ },
405
+ bfdb => { # used in JUMBF (see # (used when tag is renamed according to JUMDLabel)
406
+ Name => 'BinaryDataType',
407
+ Notes => 'JUMBF, MIME type and optional file name',
408
+ Format => 'undef',
409
+ # (ignore "toggles" byte and just extract MIME type and file name)
410
+ ValueConv => '$_=substr($val,1); s/\0+$//; s/\0/, /; $_',
411
+ JUMBF_Suffix => 'Type', # (used when tag is renamed according to JUMDLabel)
412
+ },
413
+ bidb => { # used in JUMBF
414
+ Name => 'BinaryData',
415
+ Notes => 'JUMBF',
416
+ Groups => { 2 => 'Preview' },
417
+ Format => 'undef',
418
+ Binary => 1,
419
+ JUMBF_Suffix => 'Data', # (used when tag is renamed according to JUMDLabel)
420
+ },
389
421
  #
390
422
  # stuff seen in JPEG XL images:
391
423
  #
@@ -529,11 +561,34 @@ my %jumbfTypes = (
529
561
 
530
562
  %Image::ExifTool::Jpeg2000::ColorSpec = (
531
563
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
564
+ WRITE_PROC => \&Image::ExifTool::WriteBinaryData, # (we don't actually call this)
532
565
  GROUPS => { 2 => 'Image' },
533
566
  FORMAT => 'int8s',
567
+ WRITABLE => 1,
568
+ # (Note: 'colr' is not a real group, but is used as a hack to write the
569
+ # necessary colr box. This hack necessitated another hack in TagInfoXML.pm
570
+ # to avoid reporting this fake group in the XML output)
571
+ WRITE_GROUP => 'colr',
572
+ DATAMEMBER => [ 0 ],
573
+ IS_SUBDIR => [ 3 ],
574
+ NOTES => q{
575
+ The table below contains tags in the color specification (colr) box. This
576
+ box may be rewritten by writing either ICC_Profile, ColorSpace or
577
+ ColorSpecData. When writing, any existing colr boxes are replaced with the
578
+ newly created colr box.
579
+
580
+ B<NOTE>: Care must be taken when writing this color specification because
581
+ writing a specification that is incompatible with the image data may make
582
+ the image undisplayable.
583
+ },
534
584
  0 => {
535
585
  Name => 'ColorSpecMethod',
536
586
  RawConv => '$$self{ColorSpecMethod} = $val',
587
+ Protected => 1,
588
+ Notes => q{
589
+ default for writing is 2 when writing ICC_Profile, 1 when writing
590
+ ColorSpace, or 4 when writing ColorSpecData
591
+ },
537
592
  PrintConv => {
538
593
  1 => 'Enumerated',
539
594
  2 => 'Restricted ICC',
@@ -541,9 +596,15 @@ my %jumbfTypes = (
541
596
  4 => 'Vendor Color',
542
597
  },
543
598
  },
544
- 1 => 'ColorSpecPrecedence',
599
+ 1 => {
600
+ Name => 'ColorSpecPrecedence',
601
+ Notes => 'default for writing is 0',
602
+ Protected => 1,
603
+ },
545
604
  2 => {
546
605
  Name => 'ColorSpecApproximation',
606
+ Notes => 'default for writing is 0',
607
+ Protected => 1,
547
608
  PrintConv => {
548
609
  0 => 'Not Specified',
549
610
  1 => 'Accurate',
@@ -568,6 +629,7 @@ my %jumbfTypes = (
568
629
  Name => 'ColorSpace',
569
630
  Condition => '$$self{ColorSpecMethod} == 1',
570
631
  Format => 'int32u',
632
+ Protected => 1,
571
633
  PrintConv => { # ref 15444-2 2002-05-15
572
634
  0 => 'Bi-level',
573
635
  1 => 'YCbCr(1)',
@@ -597,6 +659,8 @@ my %jumbfTypes = (
597
659
  {
598
660
  Name => 'ColorSpecData',
599
661
  Format => 'undef[$size-3]',
662
+ Writable => 'undef',
663
+ Protected => 1,
600
664
  Binary => 1,
601
665
  },
602
666
  ],
@@ -690,6 +754,7 @@ sub ProcessJUMD($$$)
690
754
  if ($len) {
691
755
  $name =~ s/[^-_a-zA-Z0-9]([a-z])/\U$1/g; # capitalize characters after illegal characters
692
756
  $name =~ tr/-_a-zA-Z0-9//dc; # remove other illegal characters
757
+ $name =~ s/__/_/; # collapse double underlines
693
758
  $name = ucfirst $name; # capitalize first letter
694
759
  $name = "Tag$name" if length($name) < 2; # must at least 2 characters long
695
760
  $$et{JUMBFLabel} = $name;
@@ -785,6 +850,48 @@ sub CreateNewBoxes($$)
785
850
  return 1;
786
851
  }
787
852
 
853
+ #------------------------------------------------------------------------------
854
+ # Create Color Specification Box
855
+ # Inputs: 0) ExifTool object ref, 1) Output file or scalar ref
856
+ # Returns: 1 on success
857
+ sub CreateColorSpec($$)
858
+ {
859
+ my ($et, $outfile) = @_;
860
+ my $meth = $et->GetNewValue('Jpeg2000:ColorSpecMethod');
861
+ my $prec = $et->GetNewValue('Jpeg2000:ColorSpecPrecedence') || 0;
862
+ my $approx = $et->GetNewValue('Jpeg2000:ColorSpecApproximation') || 0;
863
+ my $icc = $et->GetNewValue('ICC_Profile');
864
+ my $space = $et->GetNewValue('Jpeg2000:ColorSpace');
865
+ my $cdata = $et->GetNewValue('Jpeg2000:ColorSpecData');
866
+ unless ($meth) {
867
+ if ($icc) {
868
+ $meth = 2;
869
+ } elsif (defined $space) {
870
+ $meth = 1;
871
+ } elsif (defined $cdata) {
872
+ $meth = 4;
873
+ } else {
874
+ $et->Warn('Color space not defined'), return 0;
875
+ }
876
+ }
877
+ if ($meth eq '1') {
878
+ defined $space or $et->Warn('Must specify ColorSpace'), return 0;
879
+ $cdata = pack('N', $space);
880
+ } elsif ($meth eq '2' or $meth eq '3') {
881
+ defined $icc or $et->Warn('Must specify ICC_Profile'), return 0;
882
+ $cdata = $icc;
883
+ } elsif ($meth eq '4') {
884
+ defined $cdata or $et->Warn('Must specify ColorSpecData'), return 0;
885
+ } else {
886
+ $et->Warn('Unknown ColorSpecMethod'), return 0;
887
+ }
888
+ my $boxhdr = pack('N', length($cdata) + 11) . 'colr';
889
+ Write($outfile, $boxhdr, pack('CCC',$meth,$prec,$approx), $cdata) or return 0;
890
+ ++$$et{CHANGED};
891
+ $et->VPrint(1, " + Jpeg2000:ColorSpec\n");
892
+ return 1;
893
+ }
894
+
788
895
  #------------------------------------------------------------------------------
789
896
  # Process JPEG 2000 box
790
897
  # Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) Pointer to tag table
@@ -802,7 +909,7 @@ sub ProcessJpeg2000Box($$$)
802
909
  my $raf = $$dirInfo{RAF};
803
910
  my $outfile = $$dirInfo{OutFile};
804
911
  my $dirEnd = $dirStart + $dirLen;
805
- my ($err, $outBuff, $verbose);
912
+ my ($err, $outBuff, $verbose, $doColour);
806
913
 
807
914
  if ($outfile) {
808
915
  unless ($raf) {
@@ -810,13 +917,19 @@ sub ProcessJpeg2000Box($$$)
810
917
  $outBuff = '';
811
918
  $outfile = \$outBuff;
812
919
  }
920
+ # determine if we will be writing colr box
921
+ if ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'JP2Header') {
922
+ $doColour = 2 if defined $et->GetNewValue('ColorSpecMethod') or $et->GetNewValue('ICC_Profile') or
923
+ defined $et->GetNewValue('ColorSpecPrecedence') or defined $et->GetNewValue('ColorSpace') or
924
+ defined $et->GetNewValue('ColorSpecApproximation') or defined $et->GetNewValue('ColorSpecData');
925
+ }
813
926
  } else {
814
927
  # (must not set verbose flag when writing!)
815
928
  $verbose = $$et{OPTIONS}{Verbose};
816
929
  $et->VerboseDir($$dirInfo{DirName}) if $verbose;
817
930
  }
818
931
  # loop through all contained boxes
819
- my ($pos, $boxLen);
932
+ my ($pos, $boxLen, $lastBox);
820
933
  for ($pos=$dirStart; ; $pos+=$boxLen) {
821
934
  my ($boxID, $buff, $valuePtr);
822
935
  my $hdrLen = 8; # the box header length
@@ -825,9 +938,7 @@ sub ProcessJpeg2000Box($$$)
825
938
  my $n = $raf->Read($buff,$hdrLen);
826
939
  unless ($n == $hdrLen) {
827
940
  $n and $err = '', last;
828
- if ($outfile) {
829
- CreateNewBoxes($et, $outfile) or $err = 1;
830
- }
941
+ CreateNewBoxes($et, $outfile) or $err = 1 if $outfile;
831
942
  last;
832
943
  }
833
944
  $dataPt = \$buff;
@@ -839,6 +950,17 @@ sub ProcessJpeg2000Box($$$)
839
950
  }
840
951
  $boxLen = unpack("x$pos N",$$dataPt); # (length includes header and data)
841
952
  $boxID = substr($$dataPt, $pos+4, 4);
953
+ # remove old colr boxes if necessary
954
+ if ($doColour and $boxID eq 'colr') {
955
+ if ($doColour == 1) { # did we successfully write the new colr box?
956
+ $et->VPrint(1," - Jpeg2000:ColorSpec\n");
957
+ ++$$et{CHANGED};
958
+ next;
959
+ }
960
+ $et->Warn('Out-of-order colr box encountered');
961
+ undef $doColour;
962
+ }
963
+ $lastBox = $boxID;
842
964
  $pos += $hdrLen; # move to end of box header
843
965
  if ($boxLen == 1) {
844
966
  # box header contains an additional 8-byte integer for length
@@ -932,6 +1054,14 @@ sub ProcessJpeg2000Box($$$)
932
1054
  }
933
1055
  }
934
1056
  }
1057
+ # create new tag for JUMBF data values with name corresponding to JUMBFLabel
1058
+ if ($tagInfo and $$et{JUMBFLabel} and (not $$tagInfo{SubDirectory} or $$tagInfo{BlockExtract})) {
1059
+ $tagInfo = { %$tagInfo, Name => $$et{JUMBFLabel} . ($$tagInfo{JUMBF_Suffix} || '') };
1060
+ delete $$tagInfo{Description};
1061
+ AddTagToTable($tagTablePtr, '_JUMBF_' . $$et{JUMBFLabel}, $tagInfo);
1062
+ delete $$tagInfo{Protected}; # (must do this so -j -b returns JUMBF binary data)
1063
+ $$tagInfo{TagID} = $boxID;
1064
+ }
935
1065
  if ($verbose) {
936
1066
  $et->VerboseInfo($boxID, $tagInfo,
937
1067
  Table => $tagTablePtr,
@@ -942,13 +1072,6 @@ sub ProcessJpeg2000Box($$$)
942
1072
  );
943
1073
  next unless $tagInfo;
944
1074
  }
945
- # create new tag for JUMBF data values with name corresponding to JUMBFLabel
946
- if ($$et{JUMBFLabel} and (not $$tagInfo{SubDirectory} or $$tagInfo{BlockExtract})) {
947
- $tagInfo = { %$tagInfo, Name => $$et{JUMBFLabel} };
948
- AddTagToTable($tagTablePtr, '_JUMBF_' . $$et{JUMBFLabel}, $tagInfo);
949
- delete $$tagInfo{Protected}; # (must do this so -j -b returns JUMBF binary data)
950
- $$tagInfo{TagID} = $boxID;
951
- }
952
1075
  if ($$tagInfo{SubDirectory}) {
953
1076
  my $subdir = $$tagInfo{SubDirectory};
954
1077
  my $subdirStart = $valuePtr;
@@ -976,8 +1099,10 @@ sub ProcessJpeg2000Box($$$)
976
1099
  # remove this directory from our create list
977
1100
  delete $$et{AddJp2Dirs}{$$tagInfo{Name}};
978
1101
  my $newdir;
979
- # only edit writable UUID and Exif boxes
980
- if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL})) {
1102
+ # only edit writable UUID, Exif and jp2h boxes
1103
+ if ($uuid or $boxID eq 'Exif' or ($boxID eq 'xml ' and $$et{IsJXL}) or
1104
+ ($boxID eq 'jp2h' and $$et{EDIT_DIRS}{jp2h}))
1105
+ {
981
1106
  $newdir = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
982
1107
  next if defined $newdir and not length $newdir; # next if deleting the box
983
1108
  } elsif (defined $uuid) {
@@ -989,6 +1114,11 @@ sub ProcessJpeg2000Box($$$)
989
1114
  my $boxhdr = pack('N', length($newdir) + 8 + $prefixLen) . $boxID;
990
1115
  $boxhdr .= substr($$dataPt, $valuePtr, $prefixLen) if $prefixLen;
991
1116
  Write($outfile, $boxhdr, $newdir) or $err = 1;
1117
+ # write new colr box immediately after ihdr
1118
+ if ($doColour and $boxID eq 'ihdr') {
1119
+ # (shouldn't be multiple ihdr boxes, but just in case, write only 1)
1120
+ $doColour = $doColour==2 ? CreateColorSpec($et, $outfile) : 0;
1121
+ }
992
1122
  } else {
993
1123
  # extract as a block if specified
994
1124
  $subdirInfo{BlockInfo} = $tagInfo if $$tagInfo{BlockExtract};
@@ -31,7 +31,7 @@ use strict;
31
31
  use vars qw($VERSION);
32
32
  use Image::ExifTool qw(:DataAccess :Utils);
33
33
 
34
- $VERSION = '1.20';
34
+ $VERSION = '1.21';
35
35
 
36
36
  # program map table "stream_type" lookup (ref 6/1)
37
37
  my %streamType = (
@@ -332,6 +332,7 @@ sub ParsePID($$$$$)
332
332
  } elsif ($$dataPt =~ /^A([NS])([EW])\0/s) {
333
333
  # INNOVV TS video (same format is INNOVV MP4)
334
334
  SetByteOrder('II');
335
+ my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
335
336
  while ($$dataPt =~ /(A[NS][EW]\0.{28})/g) {
336
337
  my $dat = $1;
337
338
  my $lat = abs(GetFloat(\$dat, 4)); # (abs just to be safe)
@@ -340,14 +341,10 @@ sub ParsePID($$$$$)
340
341
  my $trk = GetFloat(\$dat, 16);
341
342
  my @acc = unpack('x20V3', $dat);
342
343
  map { $_ = $_ - 4294967296 if $_ >= 0x80000000 } @acc;
343
- my $deg = int($lat / 100);
344
- $lat = $deg + ($lat - $deg * 100) / 60;
345
- $deg = int($lon / 100);
346
- $lon = $deg + ($lon - $deg * 100) / 60;
344
+ Image::ExifTool::QuickTime::ConvertLatLon($lat, $lon);
347
345
  $$et{DOC_NUM} = ++$$et{DOC_COUNT};
348
- my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
349
- $et->HandleTag($tagTbl, GPSLatitude => $lat * (substr($dat,1,1) eq 'S' ? -1 : 1));
350
- $et->HandleTag($tagTbl, GPSLongitude => $lon * (substr($dat,2,1) eq 'W' ? -1 : 1));
346
+ $et->HandleTag($tagTbl, GPSLatitude => abs($lat) * (substr($dat,1,1) eq 'S' ? -1 : 1));
347
+ $et->HandleTag($tagTbl, GPSLongitude => abs($lon) * (substr($dat,2,1) eq 'W' ? -1 : 1));
351
348
  $et->HandleTag($tagTbl, GPSSpeed => $spd);
352
349
  $et->HandleTag($tagTbl, GPSSpeedRef => 'K');
353
350
  $et->HandleTag($tagTbl, GPSTrack => $trk);
@@ -375,10 +372,7 @@ sub ParsePID($$$$$)
375
372
  $a[2] =~ tr/./:/;
376
373
  # (untested, and probably doesn't work for S/W hemispheres)
377
374
  my ($lat, $lon) = @a[3,4];
378
- my $deg = int($lat / 100);
379
- $lat = $deg + ($lat - $deg * 100) / 60;
380
- $deg = int($lon / 100);
381
- $lon = $deg + ($lon - $deg * 100) / 60;
375
+ Image::ExifTool::QuickTime::ConvertLatLon($lat, $lon);
382
376
  # $a[0] - flags? values: '0x0001','0x0004','0x0008','0x0010'
383
377
  $et->HandleTag($tagTbl, GPSDateTime => $a[2]);
384
378
  $et->HandleTag($tagTbl, GPSLatitude => $lat);
@@ -396,6 +390,27 @@ sub ParsePID($$$$$)
396
390
  }
397
391
  }
398
392
  $more = 1;
393
+ } elsif ($$dataPt =~ /^.{44}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s and length($$dataPt) >= 84) {
394
+ #forum11320
395
+ SetByteOrder('II');
396
+ my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
397
+ my $lat = abs(GetFloat($dataPt, 48)); # (abs just to be safe)
398
+ my $lon = abs(GetFloat($dataPt, 56)); # (abs just to be safe)
399
+ my $spd = GetFloat($dataPt, 64);
400
+ my $trk = GetFloat($dataPt, 68);
401
+ $et->WarnOnce('GPSLatitude/Longitude encryption is not yet known, so these will be wrong');
402
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT};
403
+ my @date = unpack('x32V3x28V3', $$dataPt);
404
+ $date[3] += 2000;
405
+ $et->HandleTag($tagTbl, GPSDateTime => sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @date[3..5,0..2]));
406
+ $et->HandleTag($tagTbl, GPSLatitude => abs($lat) * ($1 eq 'S' ? -1 : 1));
407
+ $et->HandleTag($tagTbl, GPSLongitude => abs($lon) * ($2 eq 'W' ? -1 : 1));
408
+ $et->HandleTag($tagTbl, GPSSpeed => $spd);
409
+ $et->HandleTag($tagTbl, GPSSpeedRef => 'K');
410
+ $et->HandleTag($tagTbl, GPSTrack => $trk);
411
+ $et->HandleTag($tagTbl, GPSTrackRef => 'T');
412
+ SetByteOrder('MM');
413
+ $more = 1;
399
414
  }
400
415
  delete $$et{DOC_NUM};
401
416
  }
@@ -52,7 +52,7 @@ my %mdDateInfo = (
52
52
  NOTES => q{
53
53
  MDItem tags are extracted using the "mdls" utility. They are extracted if
54
54
  any "MDItem*" tag or the MacOS group is specifically requested, or by
55
- setting the L<MDItemTags|../ExifTool.html#MDItemTags> API option to 1 or the L<RequestAll|../ExifTool.html#RequestAll> API option to 2 or
55
+ setting the API L<MDItemTags|../ExifTool.html#MDItemTags> option to 1 or the API L<RequestAll|../ExifTool.html#RequestAll> option to 2 or
56
56
  higher. Note that these tags do not necessarily reflect the current
57
57
  metadata of a file -- it may take some time for the MacOS mdworker daemon to
58
58
  index the file after a metadata change.
@@ -244,7 +244,7 @@ my %mdDateInfo = (
244
244
  NOTES => q{
245
245
  XAttr tags are extracted using the "xattr" utility. They are extracted if
246
246
  any "XAttr*" tag or the MacOS group is specifically requested, or by setting
247
- the L<XAttrTags|../ExifTool.html#XAttrTags> API option to 1 or the L<RequestAll|../ExifTool.html#RequestAll> API option to 2 or higher.
247
+ the API L<XAttrTags|../ExifTool.html#XAttrTags> option to 1 or the API L<RequestAll|../ExifTool.html#RequestAll> option to 2 or higher.
248
248
  And they are extracted by default from MacOS "._" files when reading
249
249
  these files directly.
250
250
  },