exiftool_vendored 12.41.0 → 12.50.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +209 -6
  3. data/bin/MANIFEST +12 -0
  4. data/bin/META.json +1 -1
  5. data/bin/META.yml +1 -1
  6. data/bin/README +45 -44
  7. data/bin/config_files/acdsee.config +2 -1
  8. data/bin/config_files/frameCount.config +56 -0
  9. data/bin/config_files/tiff_version.config +1 -1
  10. data/bin/exiftool +115 -96
  11. data/bin/fmt_files/gpx.fmt +3 -0
  12. data/bin/fmt_files/gpx_wpt.fmt +3 -0
  13. data/bin/lib/Image/ExifTool/Apple.pm +16 -3
  14. data/bin/lib/Image/ExifTool/BuildTagLookup.pm +23 -12
  15. data/bin/lib/Image/ExifTool/Canon.pm +71 -33
  16. data/bin/lib/Image/ExifTool/CanonRaw.pm +8 -1
  17. data/bin/lib/Image/ExifTool/CanonVRD.pm +7 -8
  18. data/bin/lib/Image/ExifTool/DJI.pm +60 -1
  19. data/bin/lib/Image/ExifTool/DNG.pm +8 -2
  20. data/bin/lib/Image/ExifTool/DarwinCore.pm +13 -1
  21. data/bin/lib/Image/ExifTool/EXE.pm +9 -1
  22. data/bin/lib/Image/ExifTool/Exif.pm +26 -12
  23. data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
  24. data/bin/lib/Image/ExifTool/FLIR.pm +4 -3
  25. data/bin/lib/Image/ExifTool/FlashPix.pm +26 -3
  26. data/bin/lib/Image/ExifTool/FujiFilm.pm +51 -4
  27. data/bin/lib/Image/ExifTool/GPS.pm +21 -1
  28. data/bin/lib/Image/ExifTool/Geotag.pm +25 -5
  29. data/bin/lib/Image/ExifTool/ICC_Profile.pm +12 -9
  30. data/bin/lib/Image/ExifTool/ICO.pm +143 -0
  31. data/bin/lib/Image/ExifTool/ID3.pm +11 -11
  32. data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
  33. data/bin/lib/Image/ExifTool/LNK.pm +5 -2
  34. data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
  35. data/bin/lib/Image/ExifTool/MIE.pm +9 -3
  36. data/bin/lib/Image/ExifTool/MISB.pm +494 -0
  37. data/bin/lib/Image/ExifTool/MakerNotes.pm +8 -1
  38. data/bin/lib/Image/ExifTool/Matroska.pm +24 -16
  39. data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
  40. data/bin/lib/Image/ExifTool/Nikon.pm +293 -122
  41. data/bin/lib/Image/ExifTool/NikonCustom.pm +4 -1
  42. data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  43. data/bin/lib/Image/ExifTool/Olympus.pm +22 -2
  44. data/bin/lib/Image/ExifTool/PDF.pm +2 -1
  45. data/bin/lib/Image/ExifTool/Panasonic.pm +30 -4
  46. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
  47. data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
  48. data/bin/lib/Image/ExifTool/Pentax.pm +8 -3
  49. data/bin/lib/Image/ExifTool/Photoshop.pm +35 -8
  50. data/bin/lib/Image/ExifTool/QuickTime.pm +163 -13
  51. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +119 -13
  52. data/bin/lib/Image/ExifTool/README +13 -3
  53. data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  54. data/bin/lib/Image/ExifTool/Samsung.pm +234 -3
  55. data/bin/lib/Image/ExifTool/Shortcuts.pm +2 -1
  56. data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  57. data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  58. data/bin/lib/Image/ExifTool/Sony.pm +71 -43
  59. data/bin/lib/Image/ExifTool/TagInfoXML.pm +3 -1
  60. data/bin/lib/Image/ExifTool/TagLookup.pm +4752 -4516
  61. data/bin/lib/Image/ExifTool/TagNames.pod +1885 -1434
  62. data/bin/lib/Image/ExifTool/Text.pm +3 -4
  63. data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  64. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  65. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  66. data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
  67. data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
  68. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
  69. data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  70. data/bin/lib/Image/ExifTool/Writer.pl +14 -6
  71. data/bin/lib/Image/ExifTool/XMP.pm +78 -59
  72. data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
  73. data/bin/lib/Image/ExifTool.pm +120 -33
  74. data/bin/lib/Image/ExifTool.pod +83 -69
  75. data/bin/perl-Image-ExifTool.spec +43 -43
  76. data/lib/exiftool_vendored/version.rb +1 -1
  77. metadata +9 -4
@@ -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.39';
24
+ $VERSION = '1.41';
25
25
 
26
26
  sub ProcessFPX($$);
27
27
  sub ProcessFPXR($$$);
@@ -298,6 +298,7 @@ my %fpxFileType = (
298
298
  %Image::ExifTool::FlashPix::Main = (
299
299
  PROCESS_PROC => \&ProcessFPXR,
300
300
  GROUPS => { 2 => 'Image' },
301
+ VARS => { LONG_TAGS => 0 },
301
302
  NOTES => q{
302
303
  The FlashPix file format, introduced in 1996, was developed by Kodak,
303
304
  Hewlett-Packard and Microsoft. Internally the FPX file structure mimics
@@ -467,6 +468,25 @@ my %fpxFileType = (
467
468
  ByteOrder => 'BigEndian',
468
469
  },
469
470
  },
471
+ # recognize Autodesk Revit files by looking at BasicFileInfo
472
+ # (but don't yet support reading their metatdata)
473
+ BasicFileInfo => {
474
+ Name => 'BasicFileInfo',
475
+ Binary => 1,
476
+ RawConv => q{
477
+ $val =~ tr/\0//d; # brute force conversion to ASCII
478
+ if ($val =~ /\.(rfa|rft|rte|rvt)/) {
479
+ $self->OverrideFileType(uc($1), "application/$1", $1);
480
+ }
481
+ return $val;
482
+ },
483
+ },
484
+ IeImg => {
485
+ Name => 'EmbeddedImage',
486
+ Notes => 'embedded images in Scene7 vignette VNT files',
487
+ Groups => { 2 => 'Preview' },
488
+ Binary => 1,
489
+ },
470
490
  );
471
491
 
472
492
  # Summary Information properties
@@ -1318,7 +1338,9 @@ sub ConvertDTTM($)
1318
1338
  my $hr = ($val >> 6) & 0x1f;
1319
1339
  my $min = ($val & 0x3f);
1320
1340
  $yr += 1900 if $val;
1321
- return sprintf("%.4d:%.2d:%.2d %.2d:%.2d:00%s",$yr,$mon,$day,$hr,$min,$val ? 'Z' : '');
1341
+ # ExifTool 12.48 dropped the "Z" on the time here because a test .doc
1342
+ # file written by Word 2011 on Mac certainly used local time here
1343
+ return sprintf("%.4d:%.2d:%.2d %.2d:%.2d:00",$yr,$mon,$day,$hr,$min);
1322
1344
  }
1323
1345
 
1324
1346
  #------------------------------------------------------------------------------
@@ -2242,7 +2264,8 @@ sub ProcessFPX($$)
2242
2264
  # remove instance number or class ID from tag if necessary
2243
2265
  $tagInfo = $et->GetTagInfo($tagTablePtr, $1) if
2244
2266
  ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
2245
- ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
2267
+ ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1}) or
2268
+ ($tag =~ /(.*)_[0-9]{4}$/s and $$tagTablePtr{$1}); # IeImg instances
2246
2269
  }
2247
2270
 
2248
2271
  my $lSib = Get32u(\$dir, $pos + 0x44); # left sibling
@@ -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.80';
34
+ $VERSION = '1.84';
35
35
 
36
36
  sub ProcessFujiDir($$$);
37
37
  sub ProcessFaceRec($$$);
@@ -254,6 +254,23 @@ my %faceCategories = (
254
254
  0x2e0 => '-4 (weakest)', #10 (-4)
255
255
  },
256
256
  },
257
+ 0x100f => { #PR158
258
+ Name => 'Clarity',
259
+ Writable => 'int32s', #PH
260
+ PrintConv => {
261
+ -5000 => '-5',
262
+ -4000 => '-4',
263
+ -3000 => '-3',
264
+ -2000 => '-2',
265
+ -1000 => '-1',
266
+ 0 => '0',
267
+ 1000 => '1',
268
+ 2000 => '2',
269
+ 3000 => '3',
270
+ 4000 => '4',
271
+ 5000 => '5',
272
+ },
273
+ },
257
274
  0x1010 => {
258
275
  Name => 'FujiFlashMode',
259
276
  Writable => 'int16u',
@@ -444,7 +461,7 @@ my %faceCategories = (
444
461
  PrintConv => { 0 => 'Off', 1 => 'On' },
445
462
  },
446
463
  0x1047 => { #12
447
- Name => 'GrainEffect',
464
+ Name => 'GrainEffectRoughness',
448
465
  Writable => 'int32s',
449
466
  PrintConv => {
450
467
  0 => 'Off',
@@ -469,6 +486,15 @@ my %faceCategories = (
469
486
  PrintConvInv => '$val + 0',
470
487
  },
471
488
  # 0x104b - BWAdjustment for Green->Magenta (forum10800)
489
+ 0x104c => { #PR158
490
+ Name => "GrainEffectSize",
491
+ Writable => 'int16u', #PH
492
+ PrintConv => {
493
+ 0 => 'Off',
494
+ 16 => 'Small',
495
+ 32 => 'Large',
496
+ },
497
+ },
472
498
  0x104d => { #forum9634
473
499
  Name => 'CropMode',
474
500
  Writable => 'int16u',
@@ -689,8 +715,9 @@ my %faceCategories = (
689
715
  PrintConv => [{
690
716
  0 => 'None',
691
717
  1 => 'Optical', #PH
692
- 2 => 'Sensor-shift', #PH
718
+ 2 => 'Sensor-shift', #PH (now IBIS/OIS, ref forum13708)
693
719
  3 => 'OIS Lens', #forum9815 (optical+sensor?)
720
+ 258 => 'IBIS/OIS + DIS', #forum13708 (digital on top of IBIS/OIS)
694
721
  512 => 'Digital', #PH
695
722
  },{
696
723
  0 => 'Off',
@@ -762,6 +789,8 @@ my %faceCategories = (
762
789
  },
763
790
  PrintConvInv => '$val=~/(0x[0-9a-f]+)/i; hex $1',
764
791
  },
792
+ 0x1447 => { Name => 'FujiModel', Writable => 'string' },
793
+ 0x1448 => { Name => 'FujiModel2', Writable => 'string' },
765
794
  0x3803 => { #forum10037
766
795
  Name => 'VideoRecordingMode',
767
796
  Groups => { 2 => 'Video' },
@@ -841,6 +870,24 @@ my %faceCategories = (
841
870
  1 => 'Face',
842
871
  2 => 'Left Eye',
843
872
  3 => 'Right Eye',
873
+ 7 => 'Body',
874
+ 8 => 'Head',
875
+ 11 => 'Bike',
876
+ 12 => 'Body of Car',
877
+ 13 => 'Front of Car',
878
+ 14 => 'Animal Body',
879
+ 15 => 'Animal Head',
880
+ 16 => 'Animal Face',
881
+ 17 => 'Animal Left Eye',
882
+ 18 => 'Animal Right Eye',
883
+ 19 => 'Bird Body',
884
+ 20 => 'Bird Head',
885
+ 21 => 'Bird Left Eye',
886
+ 22 => 'Bird Right Eye',
887
+ 23 => 'Aircraft Body',
888
+ 25 => 'Aircraft Cockpit',
889
+ 26 => 'Train Front',
890
+ 27 => 'Train Cockpit',
844
891
  },'REPEAT'],
845
892
  },
846
893
  # 0x4202 int8u[-1] - number of cooredinates in each rectangle? (ref 11)
@@ -1025,7 +1072,7 @@ my %faceCategories = (
1025
1072
  Mask => 0x000000ff,
1026
1073
  PrintConv => {
1027
1074
  0 => 'Single',
1028
- 1 => 'Continuous Low',
1075
+ 1 => 'Continuous Low', # not used by X-H2S? (see forum13777)
1029
1076
  2 => 'Continuous High',
1030
1077
  },
1031
1078
  },
@@ -12,7 +12,7 @@ use strict;
12
12
  use vars qw($VERSION);
13
13
  use Image::ExifTool::Exif;
14
14
 
15
- $VERSION = '1.53';
15
+ $VERSION = '1.54';
16
16
 
17
17
  my %coordConv = (
18
18
  ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)',
@@ -360,21 +360,41 @@ my %coordConv = (
360
360
  # which must therefore require this module as necessary
361
361
  GPSLatitude => {
362
362
  SubDoc => 1, # generate for all sub-documents
363
+ Writable => 1,
364
+ Avoid => 1,
365
+ Priority => 1, # (necessary because Avoid sets default Priority to 0)
363
366
  Require => {
364
367
  0 => 'GPS:GPSLatitude',
365
368
  1 => 'GPS:GPSLatitudeRef',
366
369
  },
370
+ WriteAlso => {
371
+ 'GPS:GPSLatitude' => '$val',
372
+ 'GPS:GPSLatitudeRef' => '(defined $val and $val < 0) ? "S" : "N"',
373
+ },
367
374
  ValueConv => '$val[1] =~ /^S/i ? -$val[0] : $val[0]',
368
375
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
376
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lat")',
369
377
  },
370
378
  GPSLongitude => {
371
379
  SubDoc => 1, # generate for all sub-documents
380
+ Writable => 1,
381
+ Avoid => 1,
382
+ Priority => 1,
383
+ Require => {
384
+ 0 => 'GPS:GPSLongitude',
385
+ 1 => 'GPS:GPSLongitudeRef',
386
+ },
387
+ WriteAlso => {
388
+ 'GPS:GPSLongitude' => '$val',
389
+ 'GPS:GPSLongitudeRef' => '(defined $val and $val < 0) ? "W" : "E"',
390
+ },
372
391
  Require => {
373
392
  0 => 'GPS:GPSLongitude',
374
393
  1 => 'GPS:GPSLongitudeRef',
375
394
  },
376
395
  ValueConv => '$val[1] =~ /^W/i ? -$val[0] : $val[0]',
377
396
  PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
397
+ PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1, "lon")',
378
398
  },
379
399
  GPSAltitude => {
380
400
  SubDoc => [1,3], # generate for sub-documents if Desire 1 or 3 has a chance to exist
@@ -14,6 +14,7 @@
14
14
  # 2019/07/02 - PH Added ability to read IMU CSV files
15
15
  # 2019/11/10 - PH Also write pitch to CameraElevationAngle
16
16
  # 2020/12/01 - PH Added ability to read DJI CSV log files
17
+ # 2022/06/21 - PH Added ability to read Google Takeout JSON files
17
18
  #
18
19
  # References: 1) http://www.topografix.com/GPX/1/1/
19
20
  # 2) http://www.gpsinformation.org/dale/nmea.htm#GSA
@@ -28,7 +29,7 @@ use vars qw($VERSION);
28
29
  use Image::ExifTool qw(:Public);
29
30
  use Image::ExifTool::GPS;
30
31
 
31
- $VERSION = '1.66';
32
+ $VERSION = '1.68';
32
33
 
33
34
  sub JITTER() { return 2 } # maximum time jitter
34
35
 
@@ -133,7 +134,7 @@ sub LoadTrackLog($$;$)
133
134
  local ($_, $/, *EXIFTOOL_TRKFILE);
134
135
  my ($et, $val) = @_;
135
136
  my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
136
- my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings);
137
+ my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
137
138
  my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
138
139
 
139
140
  unless (eval { require Time::Local }) {
@@ -285,6 +286,10 @@ sub LoadTrackLog($$;$)
285
286
  }
286
287
  }
287
288
  next;
289
+ } elsif (/"(timelineObjects|placeVisit|activitySegment|latitudeE7)":/) {
290
+ # Google Takeout JSON format
291
+ $format = 'JSON';
292
+ $sortFixes = 1; # (fixes are not all in order for this format)
288
293
  } else {
289
294
  # search only first 50 lines of file for a valid fix
290
295
  last if ++$skipped > 50;
@@ -506,6 +511,19 @@ DoneFix: $isDate = 1;
506
511
  goto DoneFix;
507
512
  }
508
513
  next;
514
+ } elsif ($format eq 'JSON') {
515
+ # Google Takeout JSON format
516
+ if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp)":\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
517
+ if ($1 eq 'timestamp') {
518
+ $time = GetTime($2);
519
+ goto DoneFix if $time and $$fix{lat} and $$fix{lon};
520
+ } elsif ($1 eq 'latitudeE7' or $1 eq 'latE7') {
521
+ $$fix{lat} = $2 * 1e-7;
522
+ } else {
523
+ $$fix{lon} = $2 * 1e-7;
524
+ }
525
+ }
526
+ next;
509
527
  }
510
528
  my (%fix, $secs, $date, $nmea);
511
529
  if ($format eq 'NMEA') {
@@ -540,7 +558,7 @@ DoneFix: $isDate = 1;
540
558
  } elsif ($nmea eq 'RMC') {
541
559
  # $GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25
542
560
  # $GPRMC,093657.007,,3652.835020,N,01053.104094,E,1.642,,290913,,,A*0F
543
- # $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,ddmmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
561
+ # $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,dddmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
544
562
  /^\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ or next;
545
563
  next if $13 > 31 or $14 > 12 or $15 > 99; # validate day/month/year
546
564
  $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
@@ -751,6 +769,8 @@ DoneFix: $isDate = 1;
751
769
  $numPoints -= $cutHDOP;
752
770
  $numPoints -= $cutSats;
753
771
  }
772
+ # sort fixes if necessary
773
+ @fixTimes = sort { $a <=> $b } @fixTimes if $sortFixes;
754
774
  # mark first fix of the track
755
775
  while (@fixTimes) {
756
776
  $fix = $$points{$fixTimes[0]} or shift(@fixTimes), next;
@@ -1409,8 +1429,8 @@ This module is used by Image::ExifTool
1409
1429
  This module loads GPS track logs, interpolates to determine position based
1410
1430
  on time, and sets new GPS values for geotagging images. Currently supported
1411
1431
  formats are GPX, NMEA RMC/GGA/GLL, KML, IGC, Garmin XML and TCX, Magellan
1412
- PMGNTRK, Honeywell PTNTHPR, Winplus Beacon text, IMU CSV, DJI CSV, and
1413
- Bramor gEO log files.
1432
+ PMGNTRK, Honeywell PTNTHPR, Bramor gEO, Winplus Beacon text, Google Takeout
1433
+ JSON, GPS/IMU CSV, DJI CSV, ExifTool CSV log files.
1414
1434
 
1415
1435
  Methods in this module should not be called directly. Instead, the Geotag
1416
1436
  feature is accessed by writing the values of the ExifTool Geotag, Geosync
@@ -25,7 +25,7 @@ use strict;
25
25
  use vars qw($VERSION);
26
26
  use Image::ExifTool qw(:DataAccess :Utils);
27
27
 
28
- $VERSION = '1.38';
28
+ $VERSION = '1.40';
29
29
 
30
30
  sub ProcessICC($$);
31
31
  sub ProcessICC_Profile($$$);
@@ -522,11 +522,11 @@ my %manuSig = ( #6
522
522
  prmg => 'Perceptual Reference Medium Gamut',
523
523
  },
524
524
  },
525
- meta => { #5 (EVENTUALLY DECODE THIS ONCE WE HAVE A SAMPLE!!)
525
+ meta => { #5
526
526
  Name => 'Metadata',
527
527
  SubDirectory => {
528
528
  TagTable => 'Image::ExifTool::ICC_Profile::Metadata',
529
- Validate => '$type eq "meta"',
529
+ Validate => '$type eq "dict"',
530
530
  },
531
531
  },
532
532
 
@@ -627,7 +627,7 @@ my %manuSig = ( #6
627
627
  swpt => 'SpectralWhitePoint',
628
628
  s2cp => 'StandardToCustomPcc',
629
629
  smap => 'SurfaceMap',
630
- # smwp ? (seen in some v5 samples)
630
+ # smwp ? (seen in some v5 samples [was a mistake in sample production])
631
631
 
632
632
  # the following entry represents the ICC profile header, and doesn't
633
633
  # exist as a tag in the directory. It is only in this table to provide
@@ -815,6 +815,7 @@ my %manuSig = ( #6
815
815
  Name => 'ChromaticityColorant',
816
816
  Format => 'int16u',
817
817
  PrintConv => {
818
+ 0 => 'Unknown',
818
819
  1 => 'ITU-R BT.709',
819
820
  2 => 'SMPTE RP145-1994',
820
821
  3 => 'EBU Tech.3213-E',
@@ -891,6 +892,7 @@ my %manuSig = ( #6
891
892
  ManufacturerName => { },
892
893
  MediaColor => { },
893
894
  MediaWeight => { },
895
+ CreatorApp => { },
894
896
  );
895
897
 
896
898
  #------------------------------------------------------------------------------
@@ -1000,7 +1002,7 @@ sub FormatICCTag($$$)
1000
1002
  }
1001
1003
 
1002
1004
  #------------------------------------------------------------------------------
1003
- # Process ICC metadata record (ref 5) (UNTESTED!)
1005
+ # Process ICC metadata record (ref 5)
1004
1006
  # Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
1005
1007
  # Returns: 1 on success
1006
1008
  sub ProcessMetadata($$$)
@@ -1032,7 +1034,7 @@ sub ProcessMetadata($$$)
1032
1034
  my $namePtr = Get32u($dataPt, $entry);
1033
1035
  my $nameLen = Get32u($dataPt, $entry + 4);
1034
1036
  my $valuePtr = Get32u($dataPt, $entry + 8);
1035
- my $valueLen = Get32u($dataPt, $entry + 16);
1037
+ my $valueLen = Get32u($dataPt, $entry + 12);
1036
1038
  next unless $namePtr and $valuePtr; # ignore if offsets are zero
1037
1039
  if ($namePtr < $minPtr or $namePtr + $nameLen > $dirLen or
1038
1040
  $valuePtr < $minPtr or $valuePtr + $valueLen > $dirLen)
@@ -1040,8 +1042,8 @@ sub ProcessMetadata($$$)
1040
1042
  $et->Warn('Corrupted ICC meta dictionary');
1041
1043
  last;
1042
1044
  }
1043
- my $tag = substr($dataPt, $dirStart + $namePtr, $nameLen);
1044
- my $val = substr($dataPt, $dirStart + $valuePtr, $valueLen);
1045
+ my $tag = substr($$dataPt, $dirStart + $namePtr, $nameLen);
1046
+ my $val = substr($$dataPt, $dirStart + $valuePtr, $valueLen);
1045
1047
  $tag = $et->Decode($tag, 'UTF16', 'MM', 'UTF8');
1046
1048
  $val = $et->Decode($val, 'UTF16', 'MM');
1047
1049
  # generate tagInfo if it doesn't exist
@@ -1050,6 +1052,7 @@ sub ProcessMetadata($$$)
1050
1052
  $name =~ s/\s+(.)/\u$1/g;
1051
1053
  $name =~ tr/-_a-zA-Z0-9//dc;
1052
1054
  next unless length $name;
1055
+ $et->VPrint(0, $$et{INDENT}, "[adding $tag]\n");
1053
1056
  AddTagToTable($tagTablePtr, $tag, { Name => $name });
1054
1057
  }
1055
1058
  $et->HandleTag($tagTablePtr, $tag, $val);
@@ -1312,7 +1315,7 @@ sub ProcessICC_Profile($$$)
1312
1315
  DirName => $name,
1313
1316
  Parent => $$dirInfo{DirName},
1314
1317
  );
1315
- my $type = substr($$dataPt, $valuePtr, 4);
1318
+ my $type = $fmt;
1316
1319
  #### eval Validate ($type)
1317
1320
  if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
1318
1321
  $et->Warn("Invalid ICC $name data");
@@ -0,0 +1,143 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: ICO.pm
3
+ #
4
+ # Description: Read Windows ICO and CUR files
5
+ #
6
+ # Revisions: 2020-10-18 - P. Harvey Created
7
+ #
8
+ # References: 1) https://docs.fileformat.com/image/ico/
9
+ #------------------------------------------------------------------------------
10
+
11
+ package Image::ExifTool::ICO;
12
+
13
+ use strict;
14
+ use vars qw($VERSION);
15
+ use Image::ExifTool qw(:DataAccess :Utils);
16
+
17
+ $VERSION = '1.00';
18
+
19
+ %Image::ExifTool::ICO::Main = (
20
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
21
+ GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
22
+ NOTES => 'Information extracted from Windows ICO (icon) and CUR (cursor) files.',
23
+ 2 => {
24
+ Name => 'ImageType',
25
+ Format => 'int16u',
26
+ PrintConv => { 1 => 'Icon', 2 => 'Cursor' },
27
+ },
28
+ 4 => {
29
+ Name => 'ImageCount',
30
+ Format => 'int16u',
31
+ RawConv => '$$self{ImageCount} = $val',
32
+ },
33
+ 6 => {
34
+ Name => 'IconDir',
35
+ SubDirectory => { TagTable => 'Image::ExifTool::ICO::IconDir' },
36
+ },
37
+ );
38
+
39
+ %Image::ExifTool::ICO::IconDir = (
40
+ PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
41
+ GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
42
+ 0 => {
43
+ Name => 'ImageWidth',
44
+ ValueConv => '$val or $val + 256',
45
+ },
46
+ 1 => {
47
+ Name => 'ImageHeight',
48
+ ValueConv => '$val or $val + 256',
49
+ },
50
+ 2 => 'NumColors',
51
+ 4 => [{
52
+ Name => 'ColorPlanes',
53
+ Condition => '$$self{FileType} eq "ICO"',
54
+ Format => 'int16u',
55
+ Notes => 'ICO files',
56
+ },{
57
+ Name => 'HotspotX',
58
+ Format => 'int16u',
59
+ Notes => 'CUR files',
60
+ }],
61
+ 6 => [{
62
+ Name => 'BitsPerPixel',
63
+ Condition => '$$self{FileType} eq "ICO"',
64
+ Format => 'int16u',
65
+ Notes => 'ICO files',
66
+ },{
67
+ Name => 'HotspotY',
68
+ Format => 'int16u',
69
+ Notes => 'CUR files',
70
+ }],
71
+ 8 => {
72
+ Name => 'ImageLength',
73
+ Format => 'int32u',
74
+ },
75
+ );
76
+
77
+ #------------------------------------------------------------------------------
78
+ # Process ICO/CUR file
79
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref
80
+ # Returns: 1 on success, 0 if this wasn't a valid ICO/CUR file
81
+ sub ProcessICO($$$)
82
+ {
83
+ my ($et, $dirInfo) = @_;
84
+ my $raf = $$dirInfo{RAF};
85
+ my ($i, $buff);
86
+ # verify this is a valid ICO/CUR file
87
+ return 0 unless $raf->Read($buff, 6) == 6;
88
+ return 0 unless $buff =~ /^\0\0([\x01\x02])\0[^0]\0/s;
89
+ # (note: have seen cursor files in the wild with an 0x01 here,
90
+ # but SetFileType will use the .cur extension to identify these)
91
+ $et->SetFileType($1 eq "\x01" ? 'ICO' : 'CUR');
92
+ SetByteOrder('II');
93
+ my $tagTbl = GetTagTable('Image::ExifTool::ICO::Main');
94
+ my $num = Get16u(\$buff, 4);
95
+ $et->HandleTag($tagTbl, 4, $num);
96
+ for ($i=0; $i<$num; ++$i) {
97
+ $raf->Read($buff, 16) == 16 or $et->Warn('Truncated file'), last;
98
+ $$et{DOC_NUM} = ++$$et{DOC_COUNT} if $i;
99
+ $et->HandleTag($tagTbl, 6, $buff);
100
+ }
101
+ delete $$et{DOC_NUM};
102
+ return 1;
103
+ }
104
+
105
+ 1; # end
106
+
107
+ __END__
108
+
109
+ =head1 NAME
110
+
111
+ Image::ExifTool::ICO - Read ICO meta information
112
+
113
+ =head1 SYNOPSIS
114
+
115
+ This module is used by Image::ExifTool
116
+
117
+ =head1 DESCRIPTION
118
+
119
+ This module contains definitions required by Image::ExifTool to read
120
+ information from Windows ICO (icon) and CUR (cursor) files.
121
+
122
+ =head1 AUTHOR
123
+
124
+ Copyright 2003-2022, Phil Harvey (philharvey66 at gmail.com)
125
+
126
+ This library is free software; you can redistribute it and/or modify it
127
+ under the same terms as Perl itself.
128
+
129
+ =head1 REFERENCES
130
+
131
+ =over 4
132
+
133
+ =item L<https://docs.fileformat.com/image/ico/>
134
+
135
+ =back
136
+
137
+ =head1 SEE ALSO
138
+
139
+ L<Image::ExifTool::TagNames/ICO Tags>,
140
+ L<Image::ExifTool(3pm)|Image::ExifTool>
141
+
142
+ =cut
143
+
@@ -6,7 +6,7 @@
6
6
  # Revisions: 09/12/2005 - P. Harvey Created
7
7
  # 09/08/2020 - PH Added Lyrics3 support
8
8
  #
9
- # References: 1) http://www.id3.org/
9
+ # References: 1) http://www.id3.org/ (now https://id3.org)
10
10
  # 2) http://www.mp3-tech.org/
11
11
  # 3) http://www.fortunecity.com/underworld/sonic/3/id3tag.html
12
12
  # 4) https://id3.org/Lyrics3
@@ -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.57';
21
+ $VERSION = '1.58';
22
22
 
23
23
  sub ProcessID3v2($$$);
24
24
  sub ProcessPrivate($$$);
@@ -76,9 +76,9 @@ my %dateTimeConv = (
76
76
  OGG, FLAC, APE, MPC and RealAudio files. ID3v2 tags which support multiple
77
77
  languages (eg. Comment and Lyrics) are extracted by specifying the tag name,
78
78
  followed by a dash ('-'), then a 3-character ISO 639-2 language code (eg.
79
- "Comment-spa"). See L<http://www.id3.org/> for the official ID3
80
- specification and L<http://www.loc.gov/standards/iso639-2/php/code_list.php>
81
- for a list of ISO 639-2 language codes.
79
+ "Comment-spa"). See L<https://id3.org/> for the official ID3 specification
80
+ and L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of
81
+ ISO 639-2 language codes.
82
82
  },
83
83
  ID3v1 => {
84
84
  Name => 'ID3v1',
@@ -1414,13 +1414,13 @@ sub ProcessID3($$)
1414
1414
  if ($flags & 0x40) {
1415
1415
  # skip the extended header
1416
1416
  $size >= 4 or $et->Warn('Bad ID3 extended header'), last;
1417
- my $len = unpack('N', $hBuff);
1418
- if ($len > length($hBuff) - 4) {
1417
+ my $len = UnSyncSafe(unpack('N', $hBuff));
1418
+ if ($len > length($hBuff)) {
1419
1419
  $et->Warn('Truncated ID3 extended header');
1420
1420
  last;
1421
1421
  }
1422
- $hBuff = substr($hBuff, $len + 4);
1423
- $pos += $len + 4;
1422
+ $hBuff = substr($hBuff, $len);
1423
+ $pos += $len;
1424
1424
  }
1425
1425
  if ($flags & 0x10) {
1426
1426
  # ignore v2.4 footer (10 bytes long)
@@ -1516,7 +1516,7 @@ sub ProcessID3($$)
1516
1516
  }
1517
1517
  }
1518
1518
  #
1519
- # process the the information
1519
+ # process the information
1520
1520
  #
1521
1521
  if ($rtnVal) {
1522
1522
  # first process audio data if it exists
@@ -1661,7 +1661,7 @@ under the same terms as Perl itself.
1661
1661
 
1662
1662
  =over 4
1663
1663
 
1664
- =item L<http://www.id3.org/>
1664
+ =item L<https://id3.org/>
1665
1665
 
1666
1666
  =item L<http://www.mp3-tech.org/>
1667
1667
 
@@ -15,7 +15,7 @@ use strict;
15
15
  use vars qw($VERSION $AUTOLOAD %iptcCharset);
16
16
  use Image::ExifTool qw(:DataAccess :Utils);
17
17
 
18
- $VERSION = '1.57';
18
+ $VERSION = '1.58';
19
19
 
20
20
  %iptcCharset = (
21
21
  "\x1b%G" => 'UTF8',
@@ -411,6 +411,7 @@ my %fileFormat = (
411
411
  Shift => 'Time',
412
412
  ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
413
413
  ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
414
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("$val 00:00:00") : $val',
414
415
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
415
416
  },
416
417
  60 => {
@@ -420,6 +421,7 @@ my %fileFormat = (
420
421
  Shift => 'Time',
421
422
  ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
422
423
  ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
424
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("1970:01:01 $val") : $val',
423
425
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
424
426
  },
425
427
  62 => {
@@ -429,6 +431,7 @@ my %fileFormat = (
429
431
  Shift => 'Time',
430
432
  ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
431
433
  ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
434
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("$val 00:00:00") : $val',
432
435
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
433
436
  },
434
437
  63 => {
@@ -438,6 +441,7 @@ my %fileFormat = (
438
441
  Shift => 'Time',
439
442
  ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
440
443
  ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
444
+ PrintConv => '$self->Options("DateFormat") ? $self->ConvertDateTime("1970:01:01 $val") : $val',
441
445
  PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
442
446
  },
443
447
  65 => {
@@ -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.07';
18
+ $VERSION = '1.08';
19
19
 
20
20
  sub ProcessItemID($$$);
21
21
  sub ProcessLinkInfo($$$);
@@ -273,7 +273,9 @@ sub ProcessLinkInfo($$$);
273
273
  6 => 'Ram Disk',
274
274
  },
275
275
  },
276
- DriveSerialNumber => { },
276
+ DriveSerialNumber => {
277
+ PrintConv => 'join("-", unpack("A4 A4", sprintf("%08X", $val)))',
278
+ },
277
279
  VolumeLabel => { },
278
280
  LocalBasePath => { },
279
281
  CommonNetworkRelLink => { },
@@ -508,6 +510,7 @@ sub ProcessLinkInfo($$$)
508
510
  if ($off + 0x20 <= $dataLen) {
509
511
  # my $len = Get32u($dataPt, $off);
510
512
  $et->HandleTag($tagTablePtr, 'DriveType', undef, %opts, Start=>$off+4);
513
+ $et->HandleTag($tagTablePtr, 'DriveSerialNumber', undef, %opts, Start=>$off+8);
511
514
  $pos = Get32u($dataPt, $off + 0x0c);
512
515
  if ($pos == 0x14) {
513
516
  # use VolumeLabelOffsetUnicode instead