exiftool_vendored 12.42.0 → 12.52.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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/bin/Changes +226 -6
  3. data/bin/MANIFEST +14 -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 +116 -97
  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 +66 -37
  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/Casio.pm +3 -3
  19. data/bin/lib/Image/ExifTool/DJI.pm +2 -1
  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 +17 -12
  23. data/bin/lib/Image/ExifTool/FLAC.pm +17 -3
  24. data/bin/lib/Image/ExifTool/FLIR.pm +9 -7
  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 +31 -5
  28. data/bin/lib/Image/ExifTool/Geotag.pm +36 -8
  29. data/bin/lib/Image/ExifTool/ICC_Profile.pm +3 -2
  30. data/bin/lib/Image/ExifTool/ICO.pm +143 -0
  31. data/bin/lib/Image/ExifTool/ID3.pm +6 -6
  32. data/bin/lib/Image/ExifTool/IPTC.pm +5 -1
  33. data/bin/lib/Image/ExifTool/JPEG.pm +1 -0
  34. data/bin/lib/Image/ExifTool/Jpeg2000.pm +24 -3
  35. data/bin/lib/Image/ExifTool/LNK.pm +5 -2
  36. data/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
  37. data/bin/lib/Image/ExifTool/Lang/fr.pm +6015 -759
  38. data/bin/lib/Image/ExifTool/Lang/sk.pm +1927 -0
  39. data/bin/lib/Image/ExifTool/M2TS.pm +98 -8
  40. data/bin/lib/Image/ExifTool/MIE.pm +9 -3
  41. data/bin/lib/Image/ExifTool/MISB.pm +494 -0
  42. data/bin/lib/Image/ExifTool/MakerNotes.pm +3 -1
  43. data/bin/lib/Image/ExifTool/Matroska.pm +272 -48
  44. data/bin/lib/Image/ExifTool/Motorola.pm +8 -2
  45. data/bin/lib/Image/ExifTool/Nikon.pm +746 -382
  46. data/bin/lib/Image/ExifTool/NikonCustom.pm +139 -106
  47. data/bin/lib/Image/ExifTool/NikonSettings.pm +5 -3
  48. data/bin/lib/Image/ExifTool/Olympus.pm +6 -4
  49. data/bin/lib/Image/ExifTool/PNG.pm +8 -1
  50. data/bin/lib/Image/ExifTool/Panasonic.pm +21 -4
  51. data/bin/lib/Image/ExifTool/PanasonicRaw.pm +25 -5
  52. data/bin/lib/Image/ExifTool/Parrot.pm +96 -2
  53. data/bin/lib/Image/ExifTool/Pentax.pm +7 -2
  54. data/bin/lib/Image/ExifTool/Photoshop.pm +29 -3
  55. data/bin/lib/Image/ExifTool/QuickTime.pm +166 -13
  56. data/bin/lib/Image/ExifTool/QuickTimeStream.pl +161 -22
  57. data/bin/lib/Image/ExifTool/README +15 -4
  58. data/bin/lib/Image/ExifTool/RIFF.pm +106 -9
  59. data/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  60. data/bin/lib/Image/ExifTool/Sigma.pm +27 -1
  61. data/bin/lib/Image/ExifTool/SigmaRaw.pm +37 -13
  62. data/bin/lib/Image/ExifTool/Sony.pm +75 -47
  63. data/bin/lib/Image/ExifTool/TagInfoXML.pm +13 -6
  64. data/bin/lib/Image/ExifTool/TagLookup.pm +4791 -4519
  65. data/bin/lib/Image/ExifTool/TagNames.pod +2056 -1446
  66. data/bin/lib/Image/ExifTool/Text.pm +3 -4
  67. data/bin/lib/Image/ExifTool/Torrent.pm +2 -3
  68. data/bin/lib/Image/ExifTool/Validate.pm +3 -3
  69. data/bin/lib/Image/ExifTool/WriteCanonRaw.pl +7 -0
  70. data/bin/lib/Image/ExifTool/WriteExif.pl +100 -23
  71. data/bin/lib/Image/ExifTool/WriteIPTC.pl +2 -6
  72. data/bin/lib/Image/ExifTool/WritePhotoshop.pl +5 -5
  73. data/bin/lib/Image/ExifTool/WriteQuickTime.pl +12 -7
  74. data/bin/lib/Image/ExifTool/WriteRIFF.pl +359 -0
  75. data/bin/lib/Image/ExifTool/WriteXMP.pl +15 -1
  76. data/bin/lib/Image/ExifTool/Writer.pl +46 -18
  77. data/bin/lib/Image/ExifTool/XMP.pm +78 -59
  78. data/bin/lib/Image/ExifTool/XMP2.pl +19 -4
  79. data/bin/lib/Image/ExifTool/ZIP.pm +19 -7
  80. data/bin/lib/Image/ExifTool.pm +146 -38
  81. data/bin/lib/Image/ExifTool.pod +83 -69
  82. data/bin/perl-Image-ExifTool.spec +43 -43
  83. data/lib/exiftool_vendored/version.rb +1 -1
  84. metadata +10 -4
@@ -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.55';
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
@@ -387,12 +407,18 @@ my %coordConv = (
387
407
  # Require either GPS:GPSAltitudeRef or XMP:GPSAltitudeRef
388
408
  RawConv => '(defined $val[1] or defined $val[3]) ? $val : undef',
389
409
  ValueConv => q{
390
- my $alt = $val[0];
391
- $alt = $val[2] unless defined $alt;
392
- return undef unless defined $alt and IsFloat($alt);
393
- return(($val[1] || $val[3]) ? -$alt : $alt);
410
+ foreach (0,2) {
411
+ next unless defined $val[$_] and IsFloat($val[$_]) and defined $val[$_+1];
412
+ return $val[$_+1] ? -abs($val[$_]) : $val[$_];
413
+ }
414
+ return undef;
394
415
  },
395
416
  PrintConv => q{
417
+ foreach (0,2) {
418
+ next unless defined $val[$_] and IsFloat($val[$_]);
419
+ next unless defined $prt[$_+1] and $prt[$_+1] =~ /Sea/;
420
+ return((int($val[$_]*10)/10) . ' m ' . $prt[$_+1]);
421
+ }
396
422
  $val = int($val * 10) / 10;
397
423
  return(($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level");
398
424
  },
@@ -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.69';
32
33
 
33
34
  sub JITTER() { return 2 } # maximum time jitter
34
35
 
@@ -74,7 +75,8 @@ my %xmlTag = (
74
75
  );
75
76
 
76
77
  # fix information keys which must be interpolated around a circle
77
- my %cyclical = (lon => 1, track => 1, dir => 1, roll => 1);
78
+ my %cyclical = (lon => 1, track => 1, dir => 1, pitch => 1, roll => 1);
79
+ my %cyc180 = (lon => 1, pitch => 1, roll => 1); # wraps from 180 to -180
78
80
 
79
81
  # fix information keys for each of our general categories
80
82
  my %fixInfoKeys = (
@@ -87,6 +89,9 @@ my %fixInfoKeys = (
87
89
 
88
90
  my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
89
91
 
92
+ # tags which may exist separately in some formats (eg. CSV)
93
+ my %sepTags = ( dir => 1, pitch => 1, roll => 1, track => 1, speed => 1 );
94
+
90
95
  # conversion factors for GPSSpeed
91
96
  my %speedConv = (
92
97
  'K' => 1.852, # km/h per knot
@@ -133,7 +138,7 @@ sub LoadTrackLog($$;$)
133
138
  local ($_, $/, *EXIFTOOL_TRKFILE);
134
139
  my ($et, $val) = @_;
135
140
  my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
136
- my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings);
141
+ my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings, $sortFixes);
137
142
  my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
138
143
 
139
144
  unless (eval { require Time::Local }) {
@@ -275,6 +280,8 @@ sub LoadTrackLog($$;$)
275
280
  $param = 'pitch';
276
281
  } elsif (/^(Angle)?Roll/i) {
277
282
  $param = 'roll';
283
+ } elsif (/^Img ?Dir/i) {
284
+ $param = 'dir';
278
285
  }
279
286
  if ($param) {
280
287
  $et->VPrint(2, "CSV column '${_}' is $param\n");
@@ -285,6 +292,10 @@ sub LoadTrackLog($$;$)
285
292
  }
286
293
  }
287
294
  next;
295
+ } elsif (/"(timelineObjects|placeVisit|activitySegment|latitudeE7)":/) {
296
+ # Google Takeout JSON format
297
+ $format = 'JSON';
298
+ $sortFixes = 1; # (fixes are not all in order for this format)
288
299
  } else {
289
300
  # search only first 50 lines of file for a valid fix
290
301
  last if ++$skipped > 50;
@@ -491,6 +502,7 @@ DoneFix: $isDate = 1;
491
502
  $secs = $val;
492
503
  } else {
493
504
  $$fix{$param} = $val;
505
+ $$has{$param} = 1 if $sepTags{$param};
494
506
  }
495
507
  }
496
508
  # make coordinate negative according to reference direction if necessary
@@ -506,6 +518,19 @@ DoneFix: $isDate = 1;
506
518
  goto DoneFix;
507
519
  }
508
520
  next;
521
+ } elsif ($format eq 'JSON') {
522
+ # Google Takeout JSON format
523
+ if (/"(latitudeE7|longitudeE7|latE7|lngE7|timestamp)":\s*"?(.*?)"?,?\s*[\x0d\x0a]/) {
524
+ if ($1 eq 'timestamp') {
525
+ $time = GetTime($2);
526
+ goto DoneFix if $time and $$fix{lat} and $$fix{lon};
527
+ } elsif ($1 eq 'latitudeE7' or $1 eq 'latE7') {
528
+ $$fix{lat} = $2 * 1e-7;
529
+ } else {
530
+ $$fix{lon} = $2 * 1e-7;
531
+ }
532
+ }
533
+ next;
509
534
  }
510
535
  my (%fix, $secs, $date, $nmea);
511
536
  if ($format eq 'NMEA') {
@@ -540,7 +565,7 @@ DoneFix: $isDate = 1;
540
565
  } elsif ($nmea eq 'RMC') {
541
566
  # $GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25
542
567
  # $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
568
+ # $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,dddmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
544
569
  /^\$[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
570
  next if $13 > 31 or $14 > 12 or $15 > 99; # validate day/month/year
546
571
  $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
@@ -751,6 +776,8 @@ DoneFix: $isDate = 1;
751
776
  $numPoints -= $cutHDOP;
752
777
  $numPoints -= $cutSats;
753
778
  }
779
+ # sort fixes if necessary
780
+ @fixTimes = sort { $a <=> $b } @fixTimes if $sortFixes;
754
781
  # mark first fix of the track
755
782
  while (@fixTimes) {
756
783
  $fix = $$points{$fixTimes[0]} or shift(@fixTimes), next;
@@ -1081,6 +1108,7 @@ Category: foreach $category (qw{pos track alt orient atemp}) {
1081
1108
  next unless defined $v0 and defined $v1;
1082
1109
  $f = $f0b;
1083
1110
  } else {
1111
+ next if $sepTags{$key}; # (don't scan outwards for some formats, eg. CSV)
1084
1112
  # scan outwards looking for fixes with the required information
1085
1113
  # (NOTE: SHOULD EVENTUALLY DO THIS FOR EXTRAPOLATION TOO!)
1086
1114
  my ($t0b, $t1b);
@@ -1107,8 +1135,8 @@ Category: foreach $category (qw{pos track alt orient atemp}) {
1107
1135
  # 360 degrees to the smaller angle before interpolating
1108
1136
  $v0 < $v1 ? $v0 += 360 : $v1 += 360;
1109
1137
  $$fix{$key} = $v1 * $f + $v0 * (1 - $f);
1110
- # longitude and roll ranges are -180 to 180, others are 0 to 360
1111
- my $max = ($key eq 'lon' or $key eq 'roll') ? 180 : 360;
1138
+ # some ranges are -180 to 180, others are 0 to 360
1139
+ my $max = $cyc180{$key} ? 180 : 360;
1112
1140
  $$fix{$key} -= 360 if $$fix{$key} >= $max;
1113
1141
  } else {
1114
1142
  # simple linear interpolation
@@ -1409,8 +1437,8 @@ This module is used by Image::ExifTool
1409
1437
  This module loads GPS track logs, interpolates to determine position based
1410
1438
  on time, and sets new GPS values for geotagging images. Currently supported
1411
1439
  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.
1440
+ PMGNTRK, Honeywell PTNTHPR, Bramor gEO, Winplus Beacon text, Google Takeout
1441
+ JSON, GPS/IMU CSV, DJI CSV, ExifTool CSV log files.
1414
1442
 
1415
1443
  Methods in this module should not be called directly. Instead, the Geotag
1416
1444
  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.39';
28
+ $VERSION = '1.40';
29
29
 
30
30
  sub ProcessICC($$);
31
31
  sub ProcessICC_Profile($$$);
@@ -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',
@@ -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
+
@@ -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($$$);
@@ -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
@@ -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 => {
@@ -205,6 +205,7 @@ sub ProcessJPEG_HDR($$$);
205
205
  Name => 'JUMBF',
206
206
  Condition => '$$valPt =~ /^JP/',
207
207
  SubDirectory => { TagTable => 'Image::ExifTool::Jpeg2000::Main' },
208
+ # Note: The recommended options for reading C2PA JUMBF metadata are "-G3 -b -j -u"
208
209
  }],
209
210
  APP12 => [{
210
211
  Name => 'PictureInfo',
@@ -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.32';
19
+ $VERSION = '1.33';
20
20
 
21
21
  sub ProcessJpeg2000Box($$$);
22
22
  sub ProcessJUMD($$$);
@@ -418,6 +418,12 @@ my %j2cMarker = (
418
418
  Binary => 1,
419
419
  JUMBF_Suffix => 'Data', # (used when tag is renamed according to JUMDLabel)
420
420
  },
421
+ c2sh => { # used in JUMBF
422
+ Name => 'C2PASaltHash',
423
+ Format => 'undef',
424
+ ValueConv => 'unpack("H*",$val)',
425
+ JUMBF_Suffix => 'Salt', # (used when tag is renamed according to JUMDLabel)
426
+ },
421
427
  #
422
428
  # stuff seen in JPEG XL images:
423
429
  #
@@ -770,7 +776,22 @@ sub ProcessJUMD($$$)
770
776
  $et->HandleTag($tagTablePtr, 'sig', substr($$dataPt, $pos, 32));
771
777
  $pos += 32;
772
778
  }
773
- $pos == $end or $et->Warn('Extra data in JUMD box'." $pos $end", 1);
779
+ my $more = $end - $pos;
780
+ if ($more) {
781
+ # (may find c2sh box hiding after JUMD record)
782
+ if ($more >= 8) {
783
+ my %dirInfo = (
784
+ DataPt => $dataPt,
785
+ DataLen => $$dirInfo{DataLen},
786
+ DirStart => $pos,
787
+ DirLen => $more,
788
+ DirName => 'JUMDPrivate',
789
+ );
790
+ $et->ProcessDirectory(\%dirInfo, GetTagTable('Image::ExifTool::Jpeg2000::Main'));
791
+ } else {
792
+ $et->Warn("Extra data in JUMD box $more bytes)", 1);
793
+ }
794
+ }
774
795
  return 1;
775
796
  }
776
797
 
@@ -902,7 +923,7 @@ sub ProcessJpeg2000Box($$$)
902
923
  my ($et, $dirInfo, $tagTablePtr) = @_;
903
924
  my $dataPt = $$dirInfo{DataPt};
904
925
  my $dataLen = $$dirInfo{DataLen};
905
- my $dataPos = $$dirInfo{DataPos};
926
+ my $dataPos = $$dirInfo{DataPos} || 0;
906
927
  my $dirLen = $$dirInfo{DirLen} || 0;
907
928
  my $dirStart = $$dirInfo{DirStart} || 0;
908
929
  my $base = $$dirInfo{Base} || 0;
@@ -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
@@ -4149,7 +4149,7 @@ $VERSION = '1.36';
4149
4149
  'Auto' => 'Automatisch',
4150
4150
  'Continuous' => 'Serienaufnahme',
4151
4151
  'Custom' => 'Benutzerdefiniert',
4152
- 'Face detect' => 'Gesichtserkennung AF',
4152
+ 'Face Detect' => 'Gesichtserkennung AF',
4153
4153
  'Infinity' => 'Unendlich',
4154
4154
  'Macro' => 'Makro',
4155
4155
  'Macro (1)' => 'Makro (1)',