exiftool_vendored 11.86.0 → 11.88.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of exiftool_vendored might be problematic. Click here for more details.

Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +38 -16
  3. data/bin/MANIFEST +3 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +34 -33
  7. data/bin/config_files/acdsee.config +1 -3
  8. data/bin/config_files/depthmap.config +56 -0
  9. data/bin/config_files/example.config +2 -0
  10. data/bin/config_files/gps2utm.config +1 -1
  11. data/bin/config_files/tiff_version.config +1 -1
  12. data/bin/exiftool +56 -39
  13. data/bin/fmt_files/gpx_wpt.fmt +1 -1
  14. data/bin/lib/Image/ExifTool.pm +32 -7
  15. data/bin/lib/Image/ExifTool.pod +53 -52
  16. data/bin/lib/Image/ExifTool/AIFF.pm +1 -1
  17. data/bin/lib/Image/ExifTool/Apple.pm +1 -1
  18. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +3 -3
  19. data/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
  20. data/bin/lib/Image/ExifTool/DNG.pm +1 -1
  21. data/bin/lib/Image/ExifTool/Exif.pm +3 -3
  22. data/bin/lib/Image/ExifTool/FITS.pm +1 -1
  23. data/bin/lib/Image/ExifTool/FLIR.pm +5 -5
  24. data/bin/lib/Image/ExifTool/Flash.pm +1 -1
  25. data/bin/lib/Image/ExifTool/FlashPix.pm +1 -1
  26. data/bin/lib/Image/ExifTool/Font.pm +2 -2
  27. data/bin/lib/Image/ExifTool/FujiFilm.pm +23 -7
  28. data/bin/lib/Image/ExifTool/GIF.pm +1 -1
  29. data/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
  30. data/bin/lib/Image/ExifTool/ICC_Profile.pm +1 -1
  31. data/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  32. data/bin/lib/Image/ExifTool/MIE.pm +1 -1
  33. data/bin/lib/Image/ExifTool/Minolta.pm +1 -1
  34. data/bin/lib/Image/ExifTool/Nikon.pm +1 -1
  35. data/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
  36. data/bin/lib/Image/ExifTool/Olympus.pm +4 -2
  37. data/bin/lib/Image/ExifTool/PDF.pm +2 -2
  38. data/bin/lib/Image/ExifTool/PNG.pm +10 -5
  39. data/bin/lib/Image/ExifTool/Panasonic.pm +1 -1
  40. data/bin/lib/Image/ExifTool/Pentax.pm +3 -3
  41. data/bin/lib/Image/ExifTool/Photoshop.pm +1 -1
  42. data/bin/lib/Image/ExifTool/QuickTime.pm +9 -4
  43. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +1 -1
  44. data/bin/lib/Image/ExifTool/README +51 -51
  45. data/bin/lib/Image/ExifTool/RIFF.pm +2 -2
  46. data/bin/lib/Image/ExifTool/RTF.pm +1 -1
  47. data/bin/lib/Image/ExifTool/Samsung.pm +1 -1
  48. data/bin/lib/Image/ExifTool/Sony.pm +1 -1
  49. data/bin/lib/Image/ExifTool/TagLookup.pm +1725 -1617
  50. data/bin/lib/Image/ExifTool/TagNames.pod +307 -9
  51. data/bin/lib/Image/ExifTool/Text.pm +59 -10
  52. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  53. data/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  54. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +27 -12
  55. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  56. data/bin/lib/Image/ExifTool/Writer.pl +25 -7
  57. data/bin/lib/Image/ExifTool/XMP.pm +6 -1
  58. data/bin/lib/Image/ExifTool/XMP2.pl +213 -1
  59. data/bin/lib/Image/ExifTool/ZIP.pm +1 -1
  60. data/bin/perl-Image-ExifTool.spec +30 -30
  61. data/lib/exiftool_vendored/version.rb +1 -1
  62. metadata +3 -2
@@ -454,7 +454,7 @@ sub WriteCanonRaw($$$)
454
454
  # pad with original garbage in case it contained something useful
455
455
  $value .= substr($buff, $pt+2+8-$len, 8-$len);
456
456
  } elsif ($len > 8) { # this shouldn't happen
457
- warn "Value too long! -- trucated\n";
457
+ warn "Value too long! -- truncated\n";
458
458
  $value = substr($value, 0, 8);
459
459
  }
460
460
  # create new directory entry
@@ -13,7 +13,7 @@ use strict;
13
13
 
14
14
  #------------------------------------------------------------------------------
15
15
  # Calculate CRC or update running CRC (ref 1)
16
- # Inputs: 0) data reference, 1) running crc to update (undef intially)
16
+ # Inputs: 0) data reference, 1) running crc to update (undef initially)
17
17
  # 2) data position (undef for 0), 3) data length (undef for all data),
18
18
  # Returns: updated CRC
19
19
  my @crcTable;
@@ -532,7 +532,7 @@ sub WriteItemInfo($$$)
532
532
  } elsif ($n <= 0xffffffff) {
533
533
  Set32u($n, $outfile, $$boxPos{iloc}[0] + 8 + $lenPt);
534
534
  } else {
535
- $et->Error("Can't yet promote iloc offset to 64 bits");
535
+ $et->Error("Can't yet promote iloc length to 64 bits");
536
536
  return ();
537
537
  }
538
538
  $n = 0;
@@ -621,18 +621,21 @@ sub WriteItemInfo($$$)
621
621
  my $nlen = ($siz >> 8) & 0x0f;
622
622
  my $nbas = ($siz >> 4) & 0x0f;
623
623
  my $nind = $siz & 0x0f;
624
- my $p;
624
+ my ($pbas, $poff);
625
625
  if ($ilocVer == 0) {
626
626
  # set offset to 0 as flag that this is a new idat chunk being added
627
- $p = length($add{iloc}) + 4 + $nbas + 2;
627
+ $pbas = length($add{iloc}) + 4;
628
+ $poff = $pbas + $nbas + 2;
628
629
  $add{iloc} .= pack('nn',$id,0) . SetVarInt(0,$nbas) . Set16u(1) .
629
630
  SetVarInt(0,$noff) . SetVarInt(length($newVal),$nlen);
630
631
  } elsif ($ilocVer == 1) {
631
- $p = length($add{iloc}) + 6 + $nbas + 2 + $nind;
632
+ $pbas = length($add{iloc}) + 6;
633
+ $poff = $pbas + $nbas + 2 + $nind;
632
634
  $add{iloc} .= pack('nnn',$id,0,0) . SetVarInt(0,$nbas) . Set16u(1) . SetVarInt(0,$nind) .
633
635
  SetVarInt(0,$noff) . SetVarInt(length($newVal),$nlen);
634
636
  } elsif ($ilocVer == 2) {
635
- $p = length($add{iloc}) + 8 + $nbas + 2 + $nind;
637
+ $pbas = length($add{iloc}) + 8;
638
+ $poff = $pbas + $nbas + 2 + $nind;
636
639
  $add{iloc} .= pack('Nnn',$id,0,0) . SetVarInt(0,$nbas) . Set16u(1) . SetVarInt(0,$nind) .
637
640
  SetVarInt(0,$noff) . SetVarInt(length($newVal),$nlen);
638
641
  } else {
@@ -643,9 +646,19 @@ sub WriteItemInfo($$$)
643
646
  my $off = $$dirInfo{ChunkOffset} or $et->Warn('Internal error. Missing ChunkOffset'), last;
644
647
  my $newOff;
645
648
  if ($noff == 4) {
646
- $newOff = [ 'stco_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $p, $noff, 0, $id ];
649
+ $newOff = [ 'stco_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $poff, $noff, 0, $id ];
647
650
  } elsif ($noff == 8) {
648
- $newOff = [ 'co64_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $p, $noff, 0, $id ];
651
+ $newOff = [ 'co64_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $poff, $noff, 0, $id ];
652
+ } elsif ($noff == 0) {
653
+ # offset_size is zero, so store the offset in base_offset instead
654
+ if ($nbas == 4) {
655
+ $newOff = [ 'stco_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $pbas, $nbas, 0, $id ];
656
+ } elsif ($nbas == 8) {
657
+ $newOff = [ 'co64_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $pbas, $nbas, 0, $id ];
658
+ } else {
659
+ $et->Warn("Can't create $name. Invalid iloc offset+base size");
660
+ last;
661
+ }
649
662
  } else {
650
663
  $et->Warn("Can't create $name. Invalid iloc offset size");
651
664
  last;
@@ -1093,7 +1106,7 @@ sub WriteQuickTime($$$)
1093
1106
  my $newVal = $et->GetNewValue($nvHash);
1094
1107
  next unless defined $newVal;
1095
1108
  my $prVal = $newVal;
1096
- my $flags = FormatQTValue($et, \$newVal, $$tagInfo{Format});
1109
+ my $flags = FormatQTValue($et, \$newVal, $format);
1097
1110
  next unless defined $newVal;
1098
1111
  my ($ctry, $lang) = (0, $undLang);
1099
1112
  if ($$ti{LangCode}) {
@@ -1149,7 +1162,6 @@ sub WriteQuickTime($$$)
1149
1162
  $val =~ s/\0$// unless $$tagInfo{Binary};
1150
1163
  $flags = 0x01; # write all strings as UTF-8
1151
1164
  } else {
1152
- $format = $$tagInfo{Format};
1153
1165
  if ($format) {
1154
1166
  # update flags for the format we are writing
1155
1167
  $flags = $qtFormat{$format} if $qtFormat{$format};
@@ -1171,7 +1183,7 @@ sub WriteQuickTime($$$)
1171
1183
  }
1172
1184
  my $prVal = $newVal;
1173
1185
  # format new value for writing (and get new flags)
1174
- $flags = FormatQTValue($et, \$newVal, $$tagInfo{Format});
1186
+ $flags = FormatQTValue($et, \$newVal, $format);
1175
1187
  my $grp = $et->GetGroup($langInfo, 1);
1176
1188
  $et->VerboseValue("- $grp:$$langInfo{Name}", $val);
1177
1189
  $et->VerboseValue("+ $grp:$$langInfo{Name}", $prVal);
@@ -1245,11 +1257,14 @@ sub WriteQuickTime($$$)
1245
1257
  } else {
1246
1258
  $newData = pack('nn', length($newData), $lang) . $newData;
1247
1259
  }
1248
- } elsif (not $$tagInfo{Format} or $$tagInfo{Format} =~ /^string/ and
1249
- not $$tagInfo{Binary} and not $$tagInfo{ValueConv})
1260
+ } elsif (not $format or $format =~ /^string/ and
1261
+ not $$tagInfo{Binary} and not $$tagInfo{ValueConv})
1250
1262
  {
1251
1263
  # write all strings as UTF-8
1252
1264
  $newData = $et->Encode($newData, 'UTF8');
1265
+ } elsif ($format and not $$tagInfo{Binary}) {
1266
+ # format new value for writing
1267
+ $newData = WriteValue($newData, $format);
1253
1268
  }
1254
1269
  }
1255
1270
  $$didTag{$nvHash} = 1; # set flag so we don't add this tag again
@@ -506,7 +506,7 @@ sub ConformPathToNamespace($$)
506
506
  next if $$nsUsed{$ns};
507
507
  my $uri = $nsURI{$ns};
508
508
  unless ($uri) {
509
- warn "No URI for namepace prefix $ns!\n";
509
+ warn "No URI for namespace prefix $ns!\n";
510
510
  next;
511
511
  }
512
512
  my $ns2;
@@ -745,7 +745,7 @@ TAG: foreach $tagInfo (@matchingTags) {
745
745
  }
746
746
  $writeGroup{$tagInfo} = $writeGroup;
747
747
  }
748
- # sort tag info list in reverse order of priority (higest number last)
748
+ # sort tag info list in reverse order of priority (highest number last)
749
749
  # so we get the highest priority error message in the end
750
750
  @tagInfoList = sort { $tagPriority{$a} <=> $tagPriority{$b} } @tagInfoList;
751
751
  # must write any tags which also write other tags first
@@ -857,7 +857,7 @@ TAG: foreach $tagInfo (@matchingTags) {
857
857
  # check to make sure this is a List or Shift tag if adding
858
858
  if ($addValue and not ($shift or $$tagInfo{List})) {
859
859
  if ($addValue eq '2') {
860
- undef $addValue; # quitely reset this option
860
+ undef $addValue; # quietly reset this option
861
861
  } else {
862
862
  $err = "Can't add $wgrp1:$tag (not a List type)";
863
863
  $verbose > 2 and print $out "$err\n";
@@ -1338,13 +1338,13 @@ sub SetNewValuesFromFile($$;@)
1338
1338
  foreach $tag (@tags) {
1339
1339
  # don't try to set errors or warnings
1340
1340
  next if $tag =~ /^(Error|Warning)\b/;
1341
- # get approprite value type if necessary
1341
+ # get appropriate value type if necessary
1342
1342
  if ($opts{SrcType} and $opts{SrcType} ne $srcType) {
1343
1343
  $$info{$tag} = $srcExifTool->GetValue($tag, $opts{SrcType});
1344
1344
  }
1345
1345
  # set value for this tag
1346
1346
  my ($n, $e) = $self->SetNewValue($tag, $$info{$tag}, %opts);
1347
- # delete this tag if we could't set it
1347
+ # delete this tag if we couldn't set it
1348
1348
  $n or delete $$info{$tag};
1349
1349
  }
1350
1350
  return $info;
@@ -2305,6 +2305,10 @@ sub WriteInfo($$;$$)
2305
2305
  $fileType = $tiffType;
2306
2306
  undef $rtnVal;
2307
2307
  } else {
2308
+ if ($tiffType eq 'FFF') {
2309
+ # (see https://exiftool.org/forum/index.php?topic=10848.0)
2310
+ $self->Error('Phocus may not properly update previews of edited FFF images', 1);
2311
+ }
2308
2312
  $dirInfo{Parent} = $tiffType;
2309
2313
  $rtnVal = $self->ProcessTIFF(\%dirInfo);
2310
2314
  }
@@ -5668,7 +5672,8 @@ sub WriteJPEG($$)
5668
5672
  my ($buff, $endPos, $trailInfo);
5669
5673
  my $delPreview = $$self{DEL_PREVIEW};
5670
5674
  $trailInfo = IdentifyTrailer($raf) unless $$delGroup{Trailer};
5671
- unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer}) {
5675
+ my $nvTrail = $self->GetNewValueHash($Image::ExifTool::Extra{Trailer});
5676
+ unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or $nvTrail) {
5672
5677
  # blindly copy the rest of the file
5673
5678
  while ($raf->Read($buff, 65536)) {
5674
5679
  Write($outfile, $buff) or $err = 1, last;
@@ -5699,7 +5704,20 @@ sub WriteJPEG($$)
5699
5704
  }
5700
5705
  # remember position of last data copied
5701
5706
  $endPos = $raf->Tell() - length($buff);
5702
- # rewrite trailers if they exist
5707
+ # write new trailer if specified
5708
+ if ($nvTrail) {
5709
+ # access new value directly to avoid copying a potentially very large data block
5710
+ if ($$nvTrail{Value} and $$nvTrail{Value}[0]) { # (note: "0" will also delete the trailer)
5711
+ $self->VPrint(0, ' Writing new trailer');
5712
+ Write($outfile, $$nvTrail{Value}[0]) or $err = 1;
5713
+ ++$$self{CHANGED};
5714
+ } elsif ($raf->Seek(0, 2) and $raf->Tell() != $endPos) {
5715
+ $self->VPrint(0, ' Deleting trailer (', $raf->Tell() - $endPos, ' bytes)');
5716
+ ++$$self{CHANGED}; # changed if there was previously a trailer
5717
+ }
5718
+ last; # all done
5719
+ }
5720
+ # rewrite existing trailers
5703
5721
  if ($trailInfo) {
5704
5722
  my $tbuf = '';
5705
5723
  $raf->Seek(-length($buff), 1); # seek back to just after EOI
@@ -5863,7 +5881,7 @@ sub WriteJPEG($$)
5863
5881
  HexDump($segDataPt, undef, %dumpParms);
5864
5882
  }
5865
5883
  }
5866
- # group delete of APP segements
5884
+ # group delete of APP segments
5867
5885
  if ($$delGroup{$dirName}) {
5868
5886
  $verbose and print $out " Deleting $dirName segment\n";
5869
5887
  ++$$self{CHANGED};
@@ -183,6 +183,7 @@ my %xmpNS = (
183
183
  dwc => 'http://rs.tdwg.org/dwc/index.htm',
184
184
  GettyImagesGIFT => 'http://xmp.gettyimages.com/gift/1.0/',
185
185
  LImage => 'http://ns.leiainc.com/photos/1.0/image/',
186
+ Profile => 'http://ns.google.com/photos/dd/1.0/profile/',
186
187
  );
187
188
 
188
189
  # build reverse namespace lookup
@@ -778,6 +779,10 @@ my %sRetouchArea = (
778
779
  Name => 'LImage',
779
780
  SubDirectory => { TagTable => 'Image::ExifTool::XMP::LImage' },
780
781
  },
782
+ Device => {
783
+ Name => 'Device',
784
+ SubDirectory => { TagTable => 'Image::ExifTool::XMP::Device' },
785
+ },
781
786
  );
782
787
 
783
788
  # hack to allow XML containing Dublin Core metadata to be handled like XMP (eg. EPUB - see ZIP.pm)
@@ -2244,7 +2249,7 @@ my %sPantryItem = (
2244
2249
 
2245
2250
  # Composite XMP tags
2246
2251
  %Image::ExifTool::XMP::Composite = (
2247
- # get latitude/logitude reference from XMP lat/long tags
2252
+ # get latitude/longitude reference from XMP lat/long tags
2248
2253
  # (used to set EXIF GPS position from XMP tags)
2249
2254
  GPSLatitudeRef => {
2250
2255
  Require => 'XMP-exif:GPSLatitude',
@@ -15,6 +15,7 @@
15
15
  # 9) http://www.w3.org/TR/SVG11/
16
16
  # 11) http://www.extensis.com/en/support/kb_article.jsp?articleNumber=6102211
17
17
  # 12) XMPSpecificationPart3_May2013, page 58
18
+ # 13) https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf
18
19
  #------------------------------------------------------------------------------
19
20
 
20
21
  package Image::ExifTool::XMP;
@@ -76,6 +77,65 @@ my %sTimecode = (
76
77
  timeValue => { },
77
78
  value => { Writable => 'integer', Notes => 'only in XMP 2008 spec; an error?' },
78
79
  );
80
+ my %sPose = (
81
+ STRUCT_NAME => 'Pose',
82
+ NAMESPACE => { Pose => 'http://ns.google.com/photos/dd/1.0/pose/' },
83
+ PositionX => { Writable => 'real', Groups => { 2 => 'Location' } },
84
+ PositionY => { Writable => 'real', Groups => { 2 => 'Location' } },
85
+ PositionZ => { Writable => 'real', Groups => { 2 => 'Location' } },
86
+ RotationX => { Writable => 'real', Groups => { 2 => 'Location' } },
87
+ RotationY => { Writable => 'real', Groups => { 2 => 'Location' } },
88
+ RotationZ => { Writable => 'real', Groups => { 2 => 'Location' } },
89
+ RotationW => { Writable => 'real', Groups => { 2 => 'Location' } },
90
+ Timestamp => {
91
+ Writable => 'integer',
92
+ Shift => 'Time',
93
+ Groups => { 2 => 'Time' },
94
+ ValueConv => 'ConvertUnixTime($val / 1000, 1, 3)',
95
+ ValueConvInv => 'int(GetUnixTime($val, 1) * 1000)',
96
+ PrintConv => '$self->ConvertDateTime($val)',
97
+ PrintConvInv => '$self->InverseDateTime($val,undef,1)',
98
+ },
99
+ );
100
+ my %sEarthPose = (
101
+ STRUCT_NAME => 'EarthPose',
102
+ NAMESPACE => { EarthPose => 'http://ns.google.com/photos/dd/1.0/earthpose/' },
103
+ Latitude => { Writable => 'real', Groups => { 2 => 'Location' }, %latConv },
104
+ Longitude => { Writable => 'real', Groups => { 2 => 'Location' }, %longConv },
105
+ Altitude => {
106
+ Writable => 'real',
107
+ Groups => { 2 => 'Location' },
108
+ PrintConv => '"$val m"',
109
+ PrintConvInv => '$val=~s/\s*m$//;$val',
110
+ },
111
+ RotationX => { Writable => 'real', Groups => { 2 => 'Location' } },
112
+ RotationY => { Writable => 'real', Groups => { 2 => 'Location' } },
113
+ RotationZ => { Writable => 'real', Groups => { 2 => 'Location' } },
114
+ RotationW => { Writable => 'real', Groups => { 2 => 'Location' } },
115
+ Timestamp => {
116
+ Writable => 'integer',
117
+ Shift => 'Time',
118
+ Groups => { 2 => 'Time' },
119
+ ValueConv => 'ConvertUnixTime($val / 1000, 1, 3)',
120
+ ValueConvInv => 'int(GetUnixTime($val, 1) * 1000)',
121
+ PrintConv => '$self->ConvertDateTime($val)',
122
+ PrintConvInv => '$self->InverseDateTime($val,undef,1)',
123
+ },
124
+ );
125
+ my %sVendorInfo = (
126
+ STRUCT_NAME => 'VendorInfo',
127
+ NAMESPACE => { VendorInfo => 'http://ns.google.com/photos/dd/1.0/vendorinfo/' },
128
+ Model => { },
129
+ Manufacturer => { },
130
+ Notes => { },
131
+ );
132
+ my %sAppInfo = (
133
+ STRUCT_NAME => 'AppInfo',
134
+ NAMESPACE => { AppInfo => 'http://ns.google.com/photos/dd/1.0/appinfo/' },
135
+ Application => { },
136
+ Version => { },
137
+ ItemURI => { },
138
+ );
79
139
 
80
140
  # camera-raw defaults
81
141
  %Image::ExifTool::XMP::crd = (
@@ -1167,7 +1227,7 @@ my %prismPublicationDate = (
1167
1227
  NAMESPACE => 'PixelLive',
1168
1228
  AVOID => 1,
1169
1229
  NOTES => q{
1170
- PixelLive namespace tags. These tags are not writable becase they are very
1230
+ PixelLive namespace tags. These tags are not writable because they are very
1171
1231
  uncommon and I haven't been able to locate a reference which gives the
1172
1232
  namespace URI.
1173
1233
  },
@@ -1789,6 +1849,158 @@ my %sSubVersion = (
1789
1849
  CameraBurstID => { },
1790
1850
  );
1791
1851
 
1852
+ # Google depth-map Device namespace (ref 13)
1853
+ %Image::ExifTool::XMP::Device = (
1854
+ %xmpTableDefaults,
1855
+ GROUPS => { 1 => 'XMP-Device', 2 => 'Camera' },
1856
+ NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1857
+ NOTES => q{
1858
+ Google depth-map Device tags. See
1859
+ L<https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf> for
1860
+ the specification.
1861
+ },
1862
+ Container => {
1863
+ Struct => {
1864
+ STRUCT_NAME => 'DeviceContainer',
1865
+ NAMESPACE => { Container => 'http://ns.google.com/photos/dd/1.0/container/' },
1866
+ Directory => {
1867
+ List => 'Seq',
1868
+ Struct => {
1869
+ STRUCT_NAME => 'DeviceDirectory',
1870
+ NAMESPACE => { Container => 'http://ns.google.com/photos/dd/1.0/container/' },
1871
+ Item => {
1872
+ Struct => {
1873
+ STRUCT_NAME => 'DeviceItem',
1874
+ NAMESPACE => { Item => 'http://ns.google.com/photos/dd/1.0/item/' },
1875
+ Mime => { },
1876
+ Length => { Writable => 'integer' },
1877
+ Padding => { Writable => 'integer' },
1878
+ DataURI => { },
1879
+ },
1880
+ },
1881
+ },
1882
+ }
1883
+ },
1884
+ },
1885
+ Profiles => {
1886
+ List => 'Seq',
1887
+ FlatName => '',
1888
+ Struct => {
1889
+ STRUCT_NAME => 'DeviceProfiles',
1890
+ NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1891
+ Profile => {
1892
+ Struct => {
1893
+ STRUCT_NAME => 'DeviceProfile',
1894
+ NAMESPACE => { Profile => 'http://ns.google.com/photos/dd/1.0/profile/' },
1895
+ CameraIndices => { List => 'Seq', Writable => 'integer' },
1896
+ Type => { },
1897
+ },
1898
+ },
1899
+ },
1900
+ },
1901
+ Cameras => {
1902
+ List => 'Seq',
1903
+ FlatName => '',
1904
+ Struct => {
1905
+ STRUCT_NAME => 'DeviceCameras',
1906
+ NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1907
+ Camera => {
1908
+ Struct => {
1909
+ STRUCT_NAME => 'DeviceCamera',
1910
+ NAMESPACE => { Camera => 'http://ns.google.com/photos/dd/1.0/camera/' },
1911
+ DepthMap => {
1912
+ Struct => {
1913
+ STRUCT_NAME => 'DeviceDepthMap',
1914
+ NAMESPACE => { DepthMap => 'http://ns.google.com/photos/dd/1.0/depthmap/' },
1915
+ ConfidenceURI => { },
1916
+ DepthURI => { },
1917
+ Far => { Writable => 'real' },
1918
+ Format => { },
1919
+ ItemSemantic=> { },
1920
+ MeasureType => { },
1921
+ Near => { Writable => 'real' },
1922
+ Units => { },
1923
+ Software => { },
1924
+ FocalTableEntryCount => { Writable => 'integer' },
1925
+ FocalTable => { }, # (base64)
1926
+ },
1927
+ },
1928
+ Image => {
1929
+ Struct => {
1930
+ STRUCT_NAME => 'DeviceImage',
1931
+ NAMESPACE => { Image => 'http://ns.google.com/photos/dd/1.0/image/' },
1932
+ ItemSemantic=> { },
1933
+ ItemURI => { },
1934
+ },
1935
+ },
1936
+ ImagingModel => {
1937
+ Struct => {
1938
+ STRUCT_NAME => 'DeviceImagingModel',
1939
+ NAMESPACE => { ImagingModel => 'http://ns.google.com/photos/dd/1.0/imagingmodel/' },
1940
+ Distortion => { }, # (base64)
1941
+ DistortionCount => { Writable => 'integer' },
1942
+ FocalLengthX => { Writable => 'real' },
1943
+ FocalLengthY => { Writable => 'real' },
1944
+ ImageHeight => { Writable => 'integer' },
1945
+ ImageWidth => { Writable => 'integer' },
1946
+ PixelAspectRatio=> { Writable => 'real' },
1947
+ PrincipalPointX => { Writable => 'real' },
1948
+ PrincipalPointY => { Writable => 'real' },
1949
+ Skew => { Writable => 'real' },
1950
+ },
1951
+ },
1952
+ PointCloud => {
1953
+ Struct => {
1954
+ STRUCT_NAME => 'DevicePointCloud',
1955
+ NAMESPACE => { PointCloud => 'http://ns.google.com/photos/dd/1.0/pointcloud/' },
1956
+ PointCloud => { Writable => 'integer' },
1957
+ Points => { },
1958
+ Metric => { Writable => 'boolean' },
1959
+ },
1960
+ },
1961
+ Pose => { Struct => \%sPose },
1962
+ LightEstimate => {
1963
+ Struct => {
1964
+ STRUCT_NAME => 'DeviceLightEstimate',
1965
+ NAMESPACE => { LightEstimate => 'http://ns.google.com/photos/dd/1.0/lightestimate/' },
1966
+ ColorCorrectionR => { Writable => 'real' },
1967
+ ColorCorrectionG => { Writable => 'real' },
1968
+ ColorCorrectionB => { Writable => 'real' },
1969
+ PixelIntensity => { Writable => 'real' },
1970
+ },
1971
+ },
1972
+ VendorInfo => { Struct => \%sVendorInfo },
1973
+ AppInfo => { Struct => \%sAppInfo },
1974
+ Trait => { },
1975
+ },
1976
+ },
1977
+ },
1978
+ },
1979
+ VendorInfo => { Struct => \%sVendorInfo },
1980
+ AppInfo => { Struct => \%sAppInfo },
1981
+ EarthPos => { Struct => \%sEarthPose },
1982
+ Pose => { Struct => \%sPose },
1983
+ Planes => {
1984
+ List => 'Seq',
1985
+ FlatName => '',
1986
+ Struct => {
1987
+ STRUCT_NAME => 'DevicePlanes',
1988
+ NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' },
1989
+ Plane => {
1990
+ Struct => {
1991
+ STRUCT_NAME => 'DevicePlane',
1992
+ NAMESPACE => { Plane => 'http://ns.google.com/photos/dd/1.0/plane/' },
1993
+ Pose => { Struct => \%sPose },
1994
+ ExtentX => { Writable => 'real' },
1995
+ ExtentZ => { Writable => 'real' },
1996
+ BoundaryVertexCount => { Writable => 'integer' },
1997
+ Boundary => { },
1998
+ },
1999
+ },
2000
+ },
2001
+ },
2002
+ );
2003
+
1792
2004
  # Getty Images namespace (ref PH)
1793
2005
  %Image::ExifTool::XMP::GettyImages = (
1794
2006
  %xmpTableDefaults,