exiftool_vendored 12.57.0 → 12.59.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +39 -0
  3. data/bin/MANIFEST +3 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +2 -2
  7. data/bin/config_files/example.config +1 -0
  8. data/bin/config_files/rotate_regions.config +1 -1
  9. data/bin/exiftool +76 -57
  10. data/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  11. data/bin/lib/Image/ExifTool/APE.pm +2 -2
  12. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +13 -14
  13. data/bin/lib/Image/ExifTool/Canon.pm +26 -6
  14. data/bin/lib/Image/ExifTool/DJI.pm +28 -2
  15. data/bin/lib/Image/ExifTool/Exif.pm +24 -5
  16. data/bin/lib/Image/ExifTool/FlashPix.pm +28 -10
  17. data/bin/lib/Image/ExifTool/FujiFilm.pm +1 -0
  18. data/bin/lib/Image/ExifTool/JPEG.pm +14 -2
  19. data/bin/lib/Image/ExifTool/LIF.pm +10 -2
  20. data/bin/lib/Image/ExifTool/LNK.pm +5 -4
  21. data/bin/lib/Image/ExifTool/MPEG.pm +2 -2
  22. data/bin/lib/Image/ExifTool/MakerNotes.pm +2 -2
  23. data/bin/lib/Image/ExifTool/Minolta.pm +6 -7
  24. data/bin/lib/Image/ExifTool/MinoltaRaw.pm +9 -1
  25. data/bin/lib/Image/ExifTool/Nikon.pm +390 -114
  26. data/bin/lib/Image/ExifTool/Olympus.pm +87 -7
  27. data/bin/lib/Image/ExifTool/PNG.pm +15 -2
  28. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +27 -1
  29. data/bin/lib/Image/ExifTool/Pentax.pm +8 -5
  30. data/bin/lib/Image/ExifTool/PhaseOne.pm +14 -1
  31. data/bin/lib/Image/ExifTool/Photoshop.pm +3 -3
  32. data/bin/lib/Image/ExifTool/QuickTime.pm +16 -11
  33. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +38 -6
  34. data/bin/lib/Image/ExifTool/README +8 -0
  35. data/bin/lib/Image/ExifTool/RIFF.pm +41 -13
  36. data/bin/lib/Image/ExifTool/Rawzor.pm +2 -2
  37. data/bin/lib/Image/ExifTool/Sigma.pm +4 -4
  38. data/bin/lib/Image/ExifTool/Sony.pm +23 -1
  39. data/bin/lib/Image/ExifTool/TagLookup.pm +4464 -4441
  40. data/bin/lib/Image/ExifTool/TagNames.pod +117 -36
  41. data/bin/lib/Image/ExifTool/Validate.pm +5 -5
  42. data/bin/lib/Image/ExifTool/WriteExif.pl +49 -0
  43. data/bin/lib/Image/ExifTool/WriteXMP.pl +1 -1
  44. data/bin/lib/Image/ExifTool/Writer.pl +74 -14
  45. data/bin/lib/Image/ExifTool/XMP.pm +19 -4
  46. data/bin/lib/Image/ExifTool/XMP2.pl +2 -1
  47. data/bin/lib/Image/ExifTool.pm +131 -17
  48. data/bin/lib/Image/ExifTool.pod +40 -5
  49. data/bin/perl-Image-ExifTool.spec +1 -1
  50. data/lib/exiftool_vendored/version.rb +1 -1
  51. metadata +2 -2
@@ -88,18 +88,13 @@ sub ProcessCTMD($$$);
88
88
  sub ProcessExifInfo($$$);
89
89
  sub SwapWords($);
90
90
 
91
- $VERSION = '4.65';
91
+ $VERSION = '4.66';
92
92
 
93
93
  # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
94
94
  # (or is it? Ref 32 shows 5 non-USM L-type lenses)
95
95
  # --> have relaxed this for new lenses because Canon has been
96
96
  # consistent about keeping "USM" in the model name
97
97
  %canonLensTypes = ( #4
98
- Notes => q{
99
- Decimal values have been added to differentiate lenses which would otherwise
100
- have the same LensType, and are used by the Composite LensID tag when
101
- attempting to identify the specific lens model.
102
- },
103
98
  -1 => 'n/a',
104
99
  1 => 'Canon EF 50mm f/1.8',
105
100
  2 => 'Canon EF 28mm f/2.8 or Sigma Lens',
@@ -2402,6 +2397,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' );
2402
2397
  DataMember => 'LensType',
2403
2398
  ValueConvInv => 'int($val)', # (must truncate decimal part)
2404
2399
  PrintConv => \%canonLensTypes,
2400
+ PrintInt => 1,
2405
2401
  },
2406
2402
  23 => {
2407
2403
  Name => 'MaxFocalLength',
@@ -3060,6 +3056,7 @@ my %ciMaxFocal = (
3060
3056
  RawConv => '$val ? $val : undef', # don't use if value is zero
3061
3057
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3062
3058
  PrintConv => \%canonLensTypes,
3059
+ PrintInt => 1,
3063
3060
  },
3064
3061
  0x0e => {
3065
3062
  Name => 'MinFocalLength',
@@ -3175,6 +3172,7 @@ my %ciMaxFocal = (
3175
3172
  RawConv => '$val ? $val : undef', # don't use if value is zero
3176
3173
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3177
3174
  PrintConv => \%canonLensTypes,
3175
+ PrintInt => 1,
3178
3176
  },
3179
3177
  0x11 => { %ciMinFocal }, #9
3180
3178
  0x13 => { %ciMaxFocal }, #9
@@ -3252,6 +3250,7 @@ my %ciMaxFocal = (
3252
3250
  RawConv => '$val ? $val : undef', # don't use if value is zero
3253
3251
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3254
3252
  PrintConv => \%canonLensTypes,
3253
+ PrintInt => 1,
3255
3254
  },
3256
3255
  0x11 => { %ciMinFocal },
3257
3256
  0x13 => { %ciMaxFocal },
@@ -3347,6 +3346,7 @@ my %ciMaxFocal = (
3347
3346
  SeparateTable => 1,
3348
3347
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3349
3348
  PrintConv => \%canonLensTypes,
3349
+ PrintInt => 1,
3350
3350
  },
3351
3351
  0x113 => { %ciMinFocal },
3352
3352
  0x115 => { %ciMaxFocal },
@@ -3502,6 +3502,7 @@ my %ciMaxFocal = (
3502
3502
  SeparateTable => 1,
3503
3503
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3504
3504
  PrintConv => \%canonLensTypes,
3505
+ PrintInt => 1,
3505
3506
  },
3506
3507
  0x151 => { %ciMinFocal },
3507
3508
  0x153 => { %ciMaxFocal,
@@ -3610,6 +3611,7 @@ my %ciMaxFocal = (
3610
3611
  SeparateTable => 1,
3611
3612
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3612
3613
  PrintConv => \%canonLensTypes,
3614
+ PrintInt => 1,
3613
3615
  },
3614
3616
  0x1a9 => { %ciMinFocal },
3615
3617
  0x1ab => { %ciMaxFocal,
@@ -3661,6 +3663,7 @@ my %ciMaxFocal = (
3661
3663
  RawConv => '$val ? $val : undef', # don't use if value is zero
3662
3664
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3663
3665
  PrintConv => \%canonLensTypes,
3666
+ PrintInt => 1,
3664
3667
  },
3665
3668
  0x17 => { %ciCameraTemperature }, #PH
3666
3669
  0x1b => { %ciMacroMagnification }, #PH
@@ -3721,6 +3724,7 @@ my %ciMaxFocal = (
3721
3724
  SeparateTable => 1,
3722
3725
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3723
3726
  PrintConv => \%canonLensTypes,
3727
+ PrintInt => 1,
3724
3728
  },
3725
3729
  0xa4 => { #PH
3726
3730
  Name => 'FirmwareRevision',
@@ -3936,6 +3940,7 @@ my %ciMaxFocal = (
3936
3940
  SeparateTable => 1,
3937
3941
  ValueConvInv => 'int($val)', # (must truncate decimal part)
3938
3942
  PrintConv => \%canonLensTypes,
3943
+ PrintInt => 1,
3939
3944
  },
3940
3945
  0xe8 => { %ciMinFocal },
3941
3946
  0xea => { %ciMaxFocal,
@@ -4060,6 +4065,7 @@ my %ciMaxFocal = (
4060
4065
  SeparateTable => 1,
4061
4066
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4062
4067
  PrintConv => \%canonLensTypes,
4068
+ PrintInt => 1,
4063
4069
  },
4064
4070
  0x155 => { %ciMinFocal },
4065
4071
  0x157 => { %ciMaxFocal,
@@ -4169,6 +4175,7 @@ my %ciMaxFocal = (
4169
4175
  SeparateTable => 1,
4170
4176
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4171
4177
  PrintConv => \%canonLensTypes,
4178
+ PrintInt => 1,
4172
4179
  },
4173
4180
  0x163 => { %ciMinFocal }, # (5DmkIII + 0x0e)
4174
4181
  0x165 => { %ciMaxFocal }, # (5DmkIII + 0x0e)
@@ -4316,6 +4323,7 @@ my %ciMaxFocal = (
4316
4323
  SeparateTable => 1,
4317
4324
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4318
4325
  PrintConv => \%canonLensTypes,
4326
+ PrintInt => 1,
4319
4327
  },
4320
4328
  0x114 => { %ciMinFocal },
4321
4329
  0x116 => { %ciMaxFocal },
@@ -4405,6 +4413,7 @@ my %ciMaxFocal = (
4405
4413
  SeparateTable => 1,
4406
4414
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4407
4415
  PrintConv => \%canonLensTypes,
4416
+ PrintInt => 1,
4408
4417
  },
4409
4418
  0xd8 => { %ciMinFocal }, #15
4410
4419
  0xda => { %ciMaxFocal }, #15
@@ -4540,6 +4549,7 @@ my %ciMaxFocal = (
4540
4549
  SeparateTable => 1,
4541
4550
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4542
4551
  PrintConv => \%canonLensTypes,
4552
+ PrintInt => 1,
4543
4553
  },
4544
4554
  0xec => { %ciMinFocal },
4545
4555
  0xee => { %ciMaxFocal,
@@ -4629,6 +4639,7 @@ my %ciMaxFocal = (
4629
4639
  SeparateTable => 1,
4630
4640
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4631
4641
  PrintConv => \%canonLensTypes,
4642
+ PrintInt => 1,
4632
4643
  },
4633
4644
  0xea => { %ciMinFocal },
4634
4645
  0xec => { %ciMaxFocal },
@@ -4710,6 +4721,7 @@ my %ciMaxFocal = (
4710
4721
  SeparateTable => 1,
4711
4722
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4712
4723
  PrintConv => \%canonLensTypes,
4724
+ PrintInt => 1,
4713
4725
  },
4714
4726
  0x168 => { %ciMinFocal },
4715
4727
  0x16a => { %ciMaxFocal },
@@ -4777,6 +4789,7 @@ my %ciMaxFocal = (
4777
4789
  SeparateTable => 1,
4778
4790
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4779
4791
  PrintConv => \%canonLensTypes,
4792
+ PrintInt => 1,
4780
4793
  },
4781
4794
  0x18b => { %ciMinFocal },
4782
4795
  0x18d => { %ciMaxFocal },
@@ -4860,6 +4873,7 @@ my %ciMaxFocal = (
4860
4873
  SeparateTable => 1,
4861
4874
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4862
4875
  PrintConv => \%canonLensTypes,
4876
+ PrintInt => 1,
4863
4877
  },
4864
4878
  0x107 => { #PH
4865
4879
  Name => 'FirmwareVersion',
@@ -4975,6 +4989,7 @@ my %ciMaxFocal = (
4975
4989
  SeparateTable => 1,
4976
4990
  ValueConvInv => 'int($val)', # (must truncate decimal part)
4977
4991
  PrintConv => \%canonLensTypes,
4992
+ PrintInt => 1,
4978
4993
  },
4979
4994
  0xf8 => { %ciMinFocal },
4980
4995
  0xfa => { %ciMaxFocal },
@@ -5070,6 +5085,7 @@ my %ciMaxFocal = (
5070
5085
  SeparateTable => 1,
5071
5086
  ValueConvInv => 'int($val)', # (must truncate decimal part)
5072
5087
  PrintConv => \%canonLensTypes,
5088
+ PrintInt => 1,
5073
5089
  },
5074
5090
  0x101 => { %ciMinFocal }, # (500D + 9)
5075
5091
  0x103 => { %ciMaxFocal }, # (500D + 9)
@@ -5165,6 +5181,7 @@ my %ciMaxFocal = (
5165
5181
  SeparateTable => 1,
5166
5182
  ValueConvInv => 'int($val)', # (must truncate decimal part)
5167
5183
  PrintConv => \%canonLensTypes,
5184
+ PrintInt => 1,
5168
5185
  },
5169
5186
  0xec => { %ciMinFocal }, # (60D + 2)
5170
5187
  0xee => { %ciMaxFocal }, # (60D + 2)
@@ -5247,6 +5264,7 @@ my %ciMaxFocal = (
5247
5264
  SeparateTable => 1,
5248
5265
  ValueConvInv => 'int($val)', # (must truncate decimal part)
5249
5266
  PrintConv => \%canonLensTypes,
5267
+ PrintInt => 1,
5250
5268
  },
5251
5269
  0x129 => { %ciMinFocal },
5252
5270
  0x12b => { %ciMaxFocal },
@@ -5359,6 +5377,7 @@ my %ciMaxFocal = (
5359
5377
  SeparateTable => 1,
5360
5378
  ValueConvInv => 'int($val)', # (must truncate decimal part)
5361
5379
  PrintConv => \%canonLensTypes,
5380
+ PrintInt => 1,
5362
5381
  },
5363
5382
  0x186 => { %ciMinFocal },
5364
5383
  0x188 => { %ciMaxFocal },
@@ -5433,6 +5452,7 @@ my %ciMaxFocal = (
5433
5452
  SeparateTable => 1,
5434
5453
  ValueConvInv => 'int($val)', # (must truncate decimal part)
5435
5454
  PrintConv => \%canonLensTypes,
5455
+ PrintInt => 1,
5436
5456
  },
5437
5457
  0xe4 => { %ciMinFocal }, #PH
5438
5458
  0xe6 => { %ciMaxFocal }, #PH
@@ -16,7 +16,7 @@ use Image::ExifTool::Exif;
16
16
  use Image::ExifTool::XMP;
17
17
  use Image::ExifTool::GPS;
18
18
 
19
- $VERSION = '1.06';
19
+ $VERSION = '1.08';
20
20
 
21
21
  sub ProcessDJIInfo($$$);
22
22
 
@@ -96,6 +96,31 @@ my %convFloat2 = (
96
96
  # (nothing yet decoded from device header)
97
97
  );
98
98
 
99
+ # thermal parameters in APP4 of DJI M3T, H20N, M2EA and some M30T images (ref PH/forum11401)
100
+ %Image::ExifTool::DJI::ThermalParams2 = (
101
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
102
+ GROUPS => { 0 => 'APP4', 2 => 'Image' },
103
+ NOTES => 'Thermal parameters extracted from APP4 of DJI M3T RJPEG files.',
104
+ 0x00 => { Name => 'AmbientTemperature', Format => 'float', PrintConv => 'sprintf("%.1f C",$val)' }, # (NC)
105
+ 0x04 => { Name => 'ObjectDistance', Format => 'float', PrintConv => 'sprintf("%.1f m",$val)' },
106
+ 0x08 => { Name => 'Emissivity', Format => 'float', PrintConv => 'sprintf("%.2f",$val)' },
107
+ 0x0c => { Name => 'RelativeHumidity', Format => 'float', PrintConv => 'sprintf("%g %%",$val*100)' },
108
+ 0x10 => { Name => 'ReflectedTemperature',Format => 'float', PrintConv => 'sprintf("%.1f C",$val)' },
109
+ 0x65 => { Name => 'IDString', Format => 'string[16]' }, # (NC)
110
+ );
111
+
112
+ # thermal parameters in APP4 of some DJI M30T images (ref PH)
113
+ %Image::ExifTool::DJI::ThermalParams3 = (
114
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
115
+ GROUPS => { 0 => 'APP4', 2 => 'Image' },
116
+ NOTES => 'Thermal parameters extracted from APP4 of some DJI RJPEG files.',
117
+ # 0x00 - 0xaa553800 - params3 magic number
118
+ 0x04 => { Name => 'RelativeHumidity', Format => 'int16u' },
119
+ 0x06 => { Name => 'ObjectDistance', Format => 'int16u', ValueConv => '$val / 10' },
120
+ 0x08 => { Name => 'Emissivity', Format => 'int16u', ValueConv => '$val / 100' },
121
+ 0x0a => { Name => 'ReflectedTemperature',Format => 'int16u', ValueConv => '$val / 10' },
122
+ );
123
+
99
124
  %Image::ExifTool::DJI::XMP = (
100
125
  %Image::ExifTool::XMP::xmpTableDefaults,
101
126
  GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'Location' },
@@ -161,7 +186,7 @@ my %convFloat2 = (
161
186
  );
162
187
 
163
188
  #------------------------------------------------------------------------------
164
- # Process DJI infor (ref PH)
189
+ # Process DJI info (ref PH)
165
190
  # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
166
191
  # Returns: 1 on success
167
192
  sub ProcessDJIInfo($$$)
@@ -174,6 +199,7 @@ sub ProcessDJIInfo($$$)
174
199
  my $buff = substr($$dataPt, $dirStart, $dirLen);
175
200
  $dataPt = \$buff;
176
201
  }
202
+ $et->VerboseDir('DJIInfo', undef, length $$dataPt);
177
203
  while ($$dataPt =~ /\G\[(.*?)\](?=(\[|$))/sg) {
178
204
  my ($tag, $val) = split /:/, $1, 2;
179
205
  next unless defined $tag and defined $val;
@@ -65,6 +65,7 @@ sub RebuildMakerNotes($$$);
65
65
  sub EncodeExifText($$);
66
66
  sub ValidateIFD($;$);
67
67
  sub ValidateImageData($$$;$);
68
+ sub AddImageDataMD5($$$);
68
69
  sub ProcessTiffIFD($$$);
69
70
  sub PrintParameter($$$);
70
71
  sub GetOffList($$$$$);
@@ -573,6 +574,7 @@ my %opcodeInfo = (
573
574
  ],
574
575
  Name => 'StripOffsets',
575
576
  IsOffset => 1,
577
+ IsImageData => 1,
576
578
  OffsetPair => 0x117, # point to associated byte counts
577
579
  # A200 stores this information in the wrong byte order!!
578
580
  ValueConv => '$val=join(" ",unpack("N*",pack("V*",split(" ",$val))));\$val',
@@ -582,6 +584,7 @@ my %opcodeInfo = (
582
584
  Condition => '$$self{Compression} and $$self{Compression} eq "34892"', # DNG Lossy JPEG
583
585
  Name => 'OtherImageStart',
584
586
  IsOffset => 1,
587
+ IsImageData => 1,
585
588
  OffsetPair => 0x117, # point to associated byte counts
586
589
  DataTag => 'OtherImage',
587
590
  },
@@ -594,6 +597,7 @@ my %opcodeInfo = (
594
597
  ],
595
598
  Name => 'StripOffsets',
596
599
  IsOffset => 1,
600
+ IsImageData => 1,
597
601
  OffsetPair => 0x117, # point to associated byte counts
598
602
  ValueConv => 'length($val) > 32 ? \$val : $val',
599
603
  },
@@ -630,6 +634,7 @@ my %opcodeInfo = (
630
634
  # JpgFromRawStart in various IFD's of DNG images except SubIFD2
631
635
  Name => 'JpgFromRawStart',
632
636
  IsOffset => 1,
637
+ IsImageData => 1,
633
638
  OffsetPair => 0x117,
634
639
  DataTag => 'JpgFromRaw',
635
640
  Writable => 'int32u',
@@ -933,6 +938,7 @@ my %opcodeInfo = (
933
938
  0x144 => {
934
939
  Name => 'TileOffsets',
935
940
  IsOffset => 1,
941
+ IsImageData => 1,
936
942
  OffsetPair => 0x145,
937
943
  ValueConv => 'length($val) > 32 ? \$val : $val',
938
944
  },
@@ -1187,6 +1193,7 @@ my %opcodeInfo = (
1187
1193
  Name => 'JpgFromRawStart',
1188
1194
  Condition => '$$self{DIR_NAME} eq "SubIFD"',
1189
1195
  IsOffset => 1,
1196
+ IsImageData => 1,
1190
1197
  OffsetPair => 0x202,
1191
1198
  DataTag => 'JpgFromRaw',
1192
1199
  Writable => 'int32u',
@@ -1199,6 +1206,7 @@ my %opcodeInfo = (
1199
1206
  Name => 'JpgFromRawStart',
1200
1207
  Condition => '$$self{DIR_NAME} eq "IFD2"',
1201
1208
  IsOffset => 1,
1209
+ IsImageData => 1,
1202
1210
  OffsetPair => 0x202,
1203
1211
  DataTag => 'JpgFromRaw',
1204
1212
  Writable => 'int32u',
@@ -1210,6 +1218,7 @@ my %opcodeInfo = (
1210
1218
  {
1211
1219
  Name => 'OtherImageStart',
1212
1220
  Condition => '$$self{DIR_NAME} eq "SubIFD1"',
1221
+ IsImageData => 1,
1213
1222
  IsOffset => 1,
1214
1223
  OffsetPair => 0x202,
1215
1224
  DataTag => 'OtherImage',
@@ -1222,6 +1231,7 @@ my %opcodeInfo = (
1222
1231
  Name => 'OtherImageStart',
1223
1232
  Condition => '$$self{DIR_NAME} eq "SubIFD2"',
1224
1233
  IsOffset => 1,
1234
+ IsImageData => 1,
1225
1235
  OffsetPair => 0x202,
1226
1236
  DataTag => 'OtherImage',
1227
1237
  Writable => 'int32u',
@@ -1232,6 +1242,7 @@ my %opcodeInfo = (
1232
1242
  {
1233
1243
  Name => 'OtherImageStart',
1234
1244
  IsOffset => 1,
1245
+ IsImageData => 1,
1235
1246
  OffsetPair => 0x202,
1236
1247
  },
1237
1248
  ],
@@ -2968,6 +2979,7 @@ my %opcodeInfo = (
2968
2979
  0xbcc0 => { #13
2969
2980
  Name => 'ImageOffset',
2970
2981
  IsOffset => 1,
2982
+ IsImageData => 1,
2971
2983
  OffsetPair => 0xbcc1, # point to associated byte count
2972
2984
  },
2973
2985
  0xbcc1 => { #13
@@ -2977,6 +2989,7 @@ my %opcodeInfo = (
2977
2989
  0xbcc2 => { #13
2978
2990
  Name => 'AlphaOffset',
2979
2991
  IsOffset => 1,
2992
+ IsImageData => 1,
2980
2993
  OffsetPair => 0xbcc3, # point to associated byte count
2981
2994
  },
2982
2995
  0xbcc3 => { #13
@@ -5885,10 +5898,14 @@ sub ProcessExif($$$)
5885
5898
  my $saveFormat = $et->Options('SaveFormat');
5886
5899
  my $htmlDump = $$et{HTML_DUMP};
5887
5900
  my $success = 1;
5888
- my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName);
5901
+ my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName, $doMD5);
5889
5902
  my $inMakerNotes = $$tagTablePtr{GROUPS}{0} eq 'MakerNotes';
5890
5903
  my $isExif = ($tagTablePtr eq \%Image::ExifTool::Exif::Main);
5891
5904
 
5905
+ # set flag to calculate image data MD5 if requested
5906
+ $doMD5 = 1 if $$et{ImageDataMD5} and (($$et{FILE_TYPE} eq 'TIFF' and not $base and not $inMakerNotes) or
5907
+ ($$et{FILE_TYPE} eq 'RAF' and $dirName eq 'FujiIFD'));
5908
+
5892
5909
  # set encoding to assume for strings
5893
5910
  $strEnc = $et->Options('CharsetEXIF') if $$tagTablePtr{GROUPS}{0} eq 'EXIF';
5894
5911
 
@@ -6725,7 +6742,7 @@ sub ProcessExif($$$)
6725
6742
  }
6726
6743
  $val = join(' ', @vals);
6727
6744
  }
6728
- if ($validate) {
6745
+ if ($validate or $doMD5) {
6729
6746
  if ($$tagInfo{OffsetPair}) {
6730
6747
  $offsetInfo{$tagID} = [ $tagInfo, $val ];
6731
6748
  } elsif ($saveForValidate{$tagID} and $isExif) {
@@ -6743,9 +6760,11 @@ sub ProcessExif($$$)
6743
6760
  }
6744
6761
  }
6745
6762
 
6746
- # validate image data offsets for this IFD
6747
- if ($validate and %offsetInfo) {
6748
- Image::ExifTool::Validate::ValidateOffsetInfo($et, \%offsetInfo, $$dirInfo{DirName}, $inMakerNotes)
6763
+ if (%offsetInfo) {
6764
+ # calculate image data MD5 if requested
6765
+ AddImageDataMD5($et, $dirInfo, \%offsetInfo) if $doMD5;
6766
+ # validate image data offsets for this IFD (note: modifies %offsetInfo)
6767
+ Image::ExifTool::Validate::ValidateOffsetInfo($et, \%offsetInfo, $dirName, $inMakerNotes) if $validate;
6749
6768
  }
6750
6769
 
6751
6770
  # scan for subsequent IFD's if specified
@@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils);
21
21
  use Image::ExifTool::Exif;
22
22
  use Image::ExifTool::ASF; # for GetGUID()
23
23
 
24
- $VERSION = '1.42';
24
+ $VERSION = '1.44';
25
25
 
26
26
  sub ProcessFPX($$);
27
27
  sub ProcessFPXR($$$);
@@ -488,16 +488,27 @@ my %fpxFileType = (
488
488
  IeImg => {
489
489
  Name => 'EmbeddedImage',
490
490
  Notes => q{
491
- embedded images in Scene7 vignette VNT files. EmbeddedImageRectangle is
492
- generated for applicable images, and may be associated with the
493
- corresponding EmbeddedImage via the family 3 group name
491
+ embedded images in Scene7 vignette VNT files. The EmbeddedImage Class and
492
+ Rectangle are also extracted for applicable images, and may be associated
493
+ with the corresponding EmbeddedImage via the family 3 group name
494
494
  },
495
495
  Groups => { 2 => 'Preview' },
496
496
  Binary => 1,
497
497
  },
498
- IeImg_rect => { # (not a real tag -- extracted from Contents of VNT file)
498
+ IeImg_class => {
499
+ Name => 'EmbeddedImageClass',
500
+ Notes => q{
501
+ not a real tag. This information is extracted if available for the
502
+ corresponding EmbeddedImage from the Contents of a VNT file
503
+ },
504
+ # eg. "Cache", "Mask"
505
+ },
506
+ IeImg_rect => { #
499
507
  Name => 'EmbeddedImageRectangle',
500
- Hidden => 1,
508
+ Notes => q{
509
+ not a real tag. This information is extracted if available for the
510
+ corresponding EmbeddedImage from the Contents of a VNT file
511
+ },
501
512
  },
502
513
  );
503
514
 
@@ -1577,13 +1588,16 @@ sub ProcessContents($$$)
1577
1588
  pos($$dataPt) += $size;
1578
1589
  }
1579
1590
  $$et{IeImg_lkup} = { };
1580
- # - the byte after TargetRole1 is 0x0d or 0x11 for separate images in my samples,
1591
+ $$et{IeImg_class} = { };
1592
+ # - the byte before \x80 is 0x0d, 0x11 or 0x1f for separate images in my samples,
1581
1593
  # and 0x1c or 0x23 for inline masks
1582
- while ($$dataPt =~ /\x0bTargetRole1.\x80\0\0\x01.{4}(.{24})/sg) {
1583
- my ($index, @coords) = unpack('Vx4V4', $1);
1594
+ # - the byte after \xff\xff is 0x3b in my samples for $1 containing 'VnMask' or 'VnCache'
1595
+ while ($$dataPt =~ /\x0bTargetRole1(?:.\x80|\xff\xff.\0.\0Vn(\w+))\0\0\x01.{4}(.{24})/sg) {
1596
+ my ($index, @coords) = unpack('Vx4V4', $2);
1584
1597
  next if $index == 0xffffffff;
1585
1598
  $$et{IeImg_lkup}{$index} and $et->WarnOnce('Duplicate image index');
1586
1599
  $$et{IeImg_lkup}{$index} = "@coords";
1600
+ $$et{IeImg_class}{$index} = $1 if $1;
1587
1601
  }
1588
1602
  }
1589
1603
  }
@@ -2395,6 +2409,10 @@ sub ProcessFPX($$)
2395
2409
  # save position of this image
2396
2410
  $et->HandleTag($tagTablePtr, IeImg_rect => $$et{IeImg_lkup}{$num});
2397
2411
  delete $$et{IeImg_lkup}{$num};
2412
+ if ($$et{IeImg_class} and $$et{IeImg_class}{$num}) {
2413
+ $et->HandleTag($tagTablePtr, IeImg_class => $$et{IeImg_class}{$num});
2414
+ delete $$et{IeImg_class}{$num};
2415
+ }
2398
2416
  }
2399
2417
  delete $$et{DOC_NUM};
2400
2418
  } else {
@@ -2441,7 +2459,7 @@ sub ProcessFPX($$)
2441
2459
  }
2442
2460
  $$et{INDENT} = $oldIndent if $verbose;
2443
2461
  # try to better identify the file type
2444
- if ($$et{VALUE}{FileType} eq 'FPX') {
2462
+ if ($$et{FileType} eq 'FPX') {
2445
2463
  my $val = $$et{CompObjUserType} || $$et{Software};
2446
2464
  if ($val) {
2447
2465
  my %type = ( '^3ds Max' => 'MAX', Word => 'DOC', PowerPoint => 'PPT', Excel => 'XLS' );
@@ -1372,6 +1372,7 @@ my %faceCategories = (
1372
1372
  0xf007 => {
1373
1373
  Name => 'StripOffsets',
1374
1374
  IsOffset => 1,
1375
+ IsImageData => 1,
1375
1376
  OffsetPair => 0xf008, # point to associated byte counts
1376
1377
  },
1377
1378
  0xf008 => {
@@ -11,7 +11,7 @@ use strict;
11
11
  use vars qw($VERSION);
12
12
  use Image::ExifTool qw(:DataAccess :Utils);
13
13
 
14
- $VERSION = '1.34';
14
+ $VERSION = '1.35';
15
15
 
16
16
  sub ProcessOcad($$$);
17
17
  sub ProcessJPEG_HDR($$$);
@@ -134,9 +134,17 @@ sub ProcessJPEG_HDR($$$);
134
134
  Condition => '$$self{HasIJPEG}"',
135
135
  SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::Factory' },
136
136
  }, {
137
- Name => 'ThermalParams', # (written by DJI FLIR models)
137
+ Name => 'ThermalParams', # (written by some DJI FLIR models)
138
138
  Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^\xaa\x55\x12\x06/',
139
139
  SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams' },
140
+ }, {
141
+ Name => 'ThermalParams2', # (written by M3T)
142
+ Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^(.{32})?.{32}\x2c\x01\x20\0/s',
143
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams2' },
144
+ }, {
145
+ Name => 'ThermalParams3', # (written by M30T)
146
+ Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^.{32}\xaa\x55\x38\0/s',
147
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams3' },
140
148
  }, {
141
149
  Name => 'PreviewImage', # (eg. Samsung S1060)
142
150
  Notes => 'continued from APP3',
@@ -207,6 +215,10 @@ sub ProcessJPEG_HDR($$$);
207
215
  Name => 'InfiRayOpMode',
208
216
  Condition => '$$self{HasIJPEG}',
209
217
  SubDirectory => { TagTable => 'Image::ExifTool::InfiRay::OpMode' },
218
+ }, {
219
+ Name => 'DJI-DBG',
220
+ Condition => '$$valPt =~ /^DJI-DBG\0/',
221
+ SubDirectory => { TagTable => 'Image::ExifTool::DJI::Info' },
210
222
  }],
211
223
  APP8 => [{
212
224
  Name => 'SPIFF',
@@ -13,7 +13,7 @@ use vars qw($VERSION);
13
13
  use Image::ExifTool qw(:DataAccess :Utils);
14
14
  use Image::ExifTool::XMP;
15
15
 
16
- $VERSION = '1.00';
16
+ $VERSION = '1.01';
17
17
 
18
18
  %Image::ExifTool::LIF::Main = (
19
19
  GROUPS => { 0 => 'XML', 1 => 'XML', 2 => 'Image' },
@@ -30,7 +30,15 @@ $VERSION = '1.00';
30
30
  my $unixTimeZero = 134774 * 24 * 3600;
31
31
  my @vals = split ' ', $val;
32
32
  foreach (@vals) {
33
- $_ = 1e-7 * hex($_);
33
+ if (/[^0-9a-f]/i) {
34
+ $_ = '0000:00:00 00:00:00';
35
+ } elsif (length $_ > 8) {
36
+ my $lo = hex substr($_, -8);
37
+ my $hi = hex substr($_, 0, -8);
38
+ $_ = 1e-7 * ($hi * 4294967296 + $lo);
39
+ } else {
40
+ $_ = 1e-7 * hex($_);
41
+ }
34
42
  # shift from Jan 1, 1601 to Jan 1, 1970
35
43
  $_ = Image::ExifTool::ConvertUnixTime($_ - $unixTimeZero);
36
44
  }
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.08';
18
+ $VERSION = '1.09';
19
19
 
20
20
  sub ProcessItemID($$$);
21
21
  sub ProcessLinkInfo($$$);
@@ -507,7 +507,7 @@ sub ProcessLinkInfo($$$)
507
507
  if ($lif & 0x01) {
508
508
  # read Volume ID
509
509
  $off = Get32u($dataPt, 0x0c);
510
- if ($off + 0x20 <= $dataLen) {
510
+ if ($off and $off + 0x20 <= $dataLen) {
511
511
  # my $len = Get32u($dataPt, $off);
512
512
  $et->HandleTag($tagTablePtr, 'DriveType', undef, %opts, Start=>$off+4);
513
513
  $et->HandleTag($tagTablePtr, 'DriveSerialNumber', undef, %opts, Start=>$off+8);
@@ -545,6 +545,7 @@ sub ProcessLinkInfo($$$)
545
545
  $off = Get32u($dataPt, 0x14);
546
546
  if ($off and $off + 0x14 <= $dataLen) {
547
547
  my $siz = Get32u($dataPt, $off);
548
+ return 0 if $off + $siz > $dataLen;
548
549
  $pos = Get32u($dataPt, $off + 0x08);
549
550
  if ($pos > 0x14 and $siz >= 0x18) {
550
551
  $pos = Get32u($dataPt, $off + 0x14);
@@ -552,7 +553,7 @@ sub ProcessLinkInfo($$$)
552
553
  } else {
553
554
  undef $unicode;
554
555
  }
555
- $val = GetString($dataPt, $pos, $unicode);
556
+ $val = GetString($dataPt, $off + $pos, $unicode);
556
557
  if (defined $val) {
557
558
  $size = length $val;
558
559
  $val = $et->Decode($val, 'UCS2') if $unicode;
@@ -567,7 +568,7 @@ sub ProcessLinkInfo($$$)
567
568
  } else {
568
569
  undef $unicode;
569
570
  }
570
- $val = GetString($dataPt, $pos, $unicode);
571
+ $val = GetString($dataPt, $off + $pos, $unicode);
571
572
  if (defined $val) {
572
573
  $size = length $val;
573
574
  $val = $et->Decode($val, 'UCS2') if $unicode;
@@ -18,7 +18,7 @@ use strict;
18
18
  use vars qw($VERSION);
19
19
  use Image::ExifTool qw(:DataAccess :Utils);
20
20
 
21
- $VERSION = '1.16';
21
+ $VERSION = '1.17';
22
22
 
23
23
  %Image::ExifTool::MPEG::Audio = (
24
24
  GROUPS => { 2 => 'Audio' },
@@ -599,7 +599,7 @@ sub ProcessMPEGVideo($$)
599
599
  return 0;
600
600
  }
601
601
  # set file type if not done already
602
- $et->SetFileType('MPEG') unless $$et{VALUE}{FileType};
602
+ $et->SetFileType('MPEG') unless $$et{FileType};
603
603
 
604
604
  my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Video');
605
605
  ProcessFrameHeader($et, $tagTablePtr, $w1, $w2);
@@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$);
21
21
  sub WriteUnknownOrPreview($$$);
22
22
  sub FixLeicaBase($$;$);
23
23
 
24
- $VERSION = '2.12';
24
+ $VERSION = '2.13';
25
25
 
26
26
  my $debug; # set to 1 to enable debugging code
27
27
 
@@ -96,7 +96,7 @@ my $debug; # set to 1 to enable debugging code
96
96
  },
97
97
  {
98
98
  Name => 'MakerNoteDJI',
99
- Condition => '$$self{Make} eq "DJI" and $$valPt !~ /^...\@AMBA/s',
99
+ Condition => '$$self{Make} eq "DJI" and $$valPt !~ /^(...\@AMBA|DJI)/s',
100
100
  SubDirectory => {
101
101
  TagTable => 'Image::ExifTool::DJI::Main',
102
102
  Start => '$valuePtr',