exiftool-vendored.pl 13.0.0 → 13.16.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 (216) hide show
  1. package/bin/Changes +254 -20
  2. package/bin/MANIFEST +10 -0
  3. package/bin/META.json +1 -1
  4. package/bin/META.yml +1 -1
  5. package/bin/README +3 -3
  6. package/bin/arg_files/exif2xmp.args +4 -0
  7. package/bin/arg_files/xmp2exif.args +2 -1
  8. package/bin/build_geolocation +1 -1
  9. package/bin/exiftool +356 -213
  10. package/bin/lib/File/RandomAccess.pm +1 -1
  11. package/bin/lib/File/RandomAccess.pod +2 -2
  12. package/bin/lib/Image/ExifTool/AAC.pm +1 -1
  13. package/bin/lib/Image/ExifTool/AES.pm +1 -1
  14. package/bin/lib/Image/ExifTool/AFCP.pm +6 -6
  15. package/bin/lib/Image/ExifTool/AIFF.pm +2 -2
  16. package/bin/lib/Image/ExifTool/APE.pm +2 -2
  17. package/bin/lib/Image/ExifTool/APP12.pm +1 -1
  18. package/bin/lib/Image/ExifTool/ASF.pm +2 -2
  19. package/bin/lib/Image/ExifTool/Apple.pm +11 -9
  20. package/bin/lib/Image/ExifTool/Audible.pm +1 -1
  21. package/bin/lib/Image/ExifTool/BMP.pm +1 -1
  22. package/bin/lib/Image/ExifTool/BPG.pm +1 -1
  23. package/bin/lib/Image/ExifTool/BZZ.pm +1 -1
  24. package/bin/lib/Image/ExifTool/BigTIFF.pm +1 -1
  25. package/bin/lib/Image/ExifTool/BuildTagLookup.pm +36 -22
  26. package/bin/lib/Image/ExifTool/CBOR.pm +5 -2
  27. package/bin/lib/Image/ExifTool/Canon.pm +66 -27
  28. package/bin/lib/Image/ExifTool/CanonCustom.pm +1 -1
  29. package/bin/lib/Image/ExifTool/CanonRaw.pm +1 -1
  30. package/bin/lib/Image/ExifTool/CanonVRD.pm +1 -1
  31. package/bin/lib/Image/ExifTool/CaptureOne.pm +1 -1
  32. package/bin/lib/Image/ExifTool/Casio.pm +1 -1
  33. package/bin/lib/Image/ExifTool/Charset.pm +1 -1
  34. package/bin/lib/Image/ExifTool/DICOM.pm +1 -1
  35. package/bin/lib/Image/ExifTool/DJI.pm +196 -30
  36. package/bin/lib/Image/ExifTool/DNG.pm +1 -1
  37. package/bin/lib/Image/ExifTool/DPX.pm +1 -1
  38. package/bin/lib/Image/ExifTool/DV.pm +1 -1
  39. package/bin/lib/Image/ExifTool/DarwinCore.pm +1 -1
  40. package/bin/lib/Image/ExifTool/DjVu.pm +1 -1
  41. package/bin/lib/Image/ExifTool/EXE.pm +138 -33
  42. package/bin/lib/Image/ExifTool/Exif.pm +29 -16
  43. package/bin/lib/Image/ExifTool/FITS.pm +3 -3
  44. package/bin/lib/Image/ExifTool/FLAC.pm +1 -1
  45. package/bin/lib/Image/ExifTool/FLIF.pm +3 -3
  46. package/bin/lib/Image/ExifTool/FLIR.pm +1 -1
  47. package/bin/lib/Image/ExifTool/Fixup.pm +1 -1
  48. package/bin/lib/Image/ExifTool/Flash.pm +1 -1
  49. package/bin/lib/Image/ExifTool/FlashPix.pm +17 -21
  50. package/bin/lib/Image/ExifTool/Font.pm +2 -2
  51. package/bin/lib/Image/ExifTool/FotoStation.pm +1 -1
  52. package/bin/lib/Image/ExifTool/FujiFilm.pm +1 -1
  53. package/bin/lib/Image/ExifTool/GE.pm +1 -1
  54. package/bin/lib/Image/ExifTool/GIF.pm +144 -93
  55. package/bin/lib/Image/ExifTool/GIMP.pm +1 -1
  56. package/bin/lib/Image/ExifTool/GM.pm +1 -1
  57. package/bin/lib/Image/ExifTool/GPS.pm +34 -30
  58. package/bin/lib/Image/ExifTool/GeoTiff.pm +1 -1
  59. package/bin/lib/Image/ExifTool/Geolocation.dat +0 -0
  60. package/bin/lib/Image/ExifTool/Geolocation.pm +19 -9
  61. package/bin/lib/Image/ExifTool/Geotag.pm +46 -12
  62. package/bin/lib/Image/ExifTool/GoPro.pm +120 -8
  63. package/bin/lib/Image/ExifTool/H264.pm +1 -1
  64. package/bin/lib/Image/ExifTool/HP.pm +2 -2
  65. package/bin/lib/Image/ExifTool/HTML.pm +1 -1
  66. package/bin/lib/Image/ExifTool/HtmlDump.pm +1 -1
  67. package/bin/lib/Image/ExifTool/ICC_Profile.pm +81 -2
  68. package/bin/lib/Image/ExifTool/ICO.pm +1 -1
  69. package/bin/lib/Image/ExifTool/ID3.pm +8 -8
  70. package/bin/lib/Image/ExifTool/IPTC.pm +10 -7
  71. package/bin/lib/Image/ExifTool/ISO.pm +1 -1
  72. package/bin/lib/Image/ExifTool/ITC.pm +1 -1
  73. package/bin/lib/Image/ExifTool/Import.pm +5 -4
  74. package/bin/lib/Image/ExifTool/InDesign.pm +2 -2
  75. package/bin/lib/Image/ExifTool/InfiRay.pm +1 -1
  76. package/bin/lib/Image/ExifTool/JPEG.pm +32 -5
  77. package/bin/lib/Image/ExifTool/JPEGDigest.pm +1 -1
  78. package/bin/lib/Image/ExifTool/JSON.pm +1 -1
  79. package/bin/lib/Image/ExifTool/JVC.pm +1 -1
  80. package/bin/lib/Image/ExifTool/Jpeg2000.pm +10 -9
  81. package/bin/lib/Image/ExifTool/Kodak.pm +1 -1
  82. package/bin/lib/Image/ExifTool/KyoceraRaw.pm +1 -1
  83. package/bin/lib/Image/ExifTool/LIF.pm +1 -1
  84. package/bin/lib/Image/ExifTool/LNK.pm +2 -2
  85. package/bin/lib/Image/ExifTool/Lang/cs.pm +1 -1
  86. package/bin/lib/Image/ExifTool/Lang/de.pm +1 -1
  87. package/bin/lib/Image/ExifTool/Lang/en_ca.pm +1 -1
  88. package/bin/lib/Image/ExifTool/Lang/en_gb.pm +1 -1
  89. package/bin/lib/Image/ExifTool/Lang/es.pm +1 -1
  90. package/bin/lib/Image/ExifTool/Lang/fi.pm +1 -1
  91. package/bin/lib/Image/ExifTool/Lang/fr.pm +1 -1
  92. package/bin/lib/Image/ExifTool/Lang/it.pm +1 -1
  93. package/bin/lib/Image/ExifTool/Lang/ja.pm +1 -1
  94. package/bin/lib/Image/ExifTool/Lang/ko.pm +1 -1
  95. package/bin/lib/Image/ExifTool/Lang/nl.pm +1 -1
  96. package/bin/lib/Image/ExifTool/Lang/pl.pm +1 -1
  97. package/bin/lib/Image/ExifTool/Lang/ru.pm +1 -1
  98. package/bin/lib/Image/ExifTool/Lang/sk.pm +1 -1
  99. package/bin/lib/Image/ExifTool/Lang/sv.pm +1 -1
  100. package/bin/lib/Image/ExifTool/Lang/tr.pm +1 -1
  101. package/bin/lib/Image/ExifTool/Lang/zh_cn.pm +1 -1
  102. package/bin/lib/Image/ExifTool/Lang/zh_tw.pm +1 -1
  103. package/bin/lib/Image/ExifTool/Leaf.pm +1 -1
  104. package/bin/lib/Image/ExifTool/LigoGPS.pm +409 -0
  105. package/bin/lib/Image/ExifTool/Lytro.pm +1 -1
  106. package/bin/lib/Image/ExifTool/M2TS.pm +57 -18
  107. package/bin/lib/Image/ExifTool/MIE.pm +15 -6
  108. package/bin/lib/Image/ExifTool/MIEUnits.pod +1 -1
  109. package/bin/lib/Image/ExifTool/MIFF.pm +1 -1
  110. package/bin/lib/Image/ExifTool/MISB.pm +1 -1
  111. package/bin/lib/Image/ExifTool/MNG.pm +1 -1
  112. package/bin/lib/Image/ExifTool/MOI.pm +1 -1
  113. package/bin/lib/Image/ExifTool/MPC.pm +1 -1
  114. package/bin/lib/Image/ExifTool/MPEG.pm +1 -1
  115. package/bin/lib/Image/ExifTool/MPF.pm +1 -1
  116. package/bin/lib/Image/ExifTool/MRC.pm +1 -1
  117. package/bin/lib/Image/ExifTool/MWG.pm +1 -1
  118. package/bin/lib/Image/ExifTool/MXF.pm +3 -3
  119. package/bin/lib/Image/ExifTool/MacOS.pm +3 -2
  120. package/bin/lib/Image/ExifTool/MakerNotes.pm +1 -1
  121. package/bin/lib/Image/ExifTool/Matroska.pm +22 -6
  122. package/bin/lib/Image/ExifTool/Microsoft.pm +2 -2
  123. package/bin/lib/Image/ExifTool/Minolta.pm +1 -1
  124. package/bin/lib/Image/ExifTool/MinoltaRaw.pm +1 -1
  125. package/bin/lib/Image/ExifTool/Motorola.pm +1 -1
  126. package/bin/lib/Image/ExifTool/Nikon.pm +495 -39
  127. package/bin/lib/Image/ExifTool/NikonCapture.pm +1 -1
  128. package/bin/lib/Image/ExifTool/NikonCustom.pm +2 -2
  129. package/bin/lib/Image/ExifTool/NikonSettings.pm +1 -1
  130. package/bin/lib/Image/ExifTool/Nintendo.pm +1 -1
  131. package/bin/lib/Image/ExifTool/OOXML.pm +8 -8
  132. package/bin/lib/Image/ExifTool/Ogg.pm +1 -1
  133. package/bin/lib/Image/ExifTool/Olympus.pm +1 -1
  134. package/bin/lib/Image/ExifTool/OpenEXR.pm +1 -1
  135. package/bin/lib/Image/ExifTool/Opus.pm +1 -1
  136. package/bin/lib/Image/ExifTool/Other.pm +1 -1
  137. package/bin/lib/Image/ExifTool/PCX.pm +1 -1
  138. package/bin/lib/Image/ExifTool/PDF.pm +49 -18
  139. package/bin/lib/Image/ExifTool/PGF.pm +1 -1
  140. package/bin/lib/Image/ExifTool/PICT.pm +1 -1
  141. package/bin/lib/Image/ExifTool/PLIST.pm +4 -4
  142. package/bin/lib/Image/ExifTool/PLUS.pm +1 -1
  143. package/bin/lib/Image/ExifTool/PNG.pm +20 -8
  144. package/bin/lib/Image/ExifTool/PPM.pm +12 -3
  145. package/bin/lib/Image/ExifTool/PSP.pm +1 -1
  146. package/bin/lib/Image/ExifTool/Palm.pm +1 -1
  147. package/bin/lib/Image/ExifTool/Panasonic.pm +27 -3
  148. package/bin/lib/Image/ExifTool/PanasonicRaw.pm +1 -1
  149. package/bin/lib/Image/ExifTool/Parrot.pm +1 -1
  150. package/bin/lib/Image/ExifTool/Pentax.pm +1 -1
  151. package/bin/lib/Image/ExifTool/PhaseOne.pm +4 -4
  152. package/bin/lib/Image/ExifTool/PhotoCD.pm +1 -1
  153. package/bin/lib/Image/ExifTool/PhotoMechanic.pm +1 -1
  154. package/bin/lib/Image/ExifTool/Photoshop.pm +65 -4
  155. package/bin/lib/Image/ExifTool/PostScript.pm +1 -1
  156. package/bin/lib/Image/ExifTool/PrintIM.pm +1 -1
  157. package/bin/lib/Image/ExifTool/Protobuf.pm +270 -0
  158. package/bin/lib/Image/ExifTool/Qualcomm.pm +1 -1
  159. package/bin/lib/Image/ExifTool/QuickTime.pm +326 -88
  160. package/bin/lib/Image/ExifTool/QuickTimeStream.pl +199 -195
  161. package/bin/lib/Image/ExifTool/README +12 -2
  162. package/bin/lib/Image/ExifTool/RIFF.pm +21 -6
  163. package/bin/lib/Image/ExifTool/RSRC.pm +1 -1
  164. package/bin/lib/Image/ExifTool/RTF.pm +2 -2
  165. package/bin/lib/Image/ExifTool/Radiance.pm +1 -1
  166. package/bin/lib/Image/ExifTool/Rawzor.pm +1 -1
  167. package/bin/lib/Image/ExifTool/Real.pm +1 -1
  168. package/bin/lib/Image/ExifTool/Reconyx.pm +1 -1
  169. package/bin/lib/Image/ExifTool/Red.pm +1 -1
  170. package/bin/lib/Image/ExifTool/Ricoh.pm +4 -4
  171. package/bin/lib/Image/ExifTool/Samsung.pm +2 -2
  172. package/bin/lib/Image/ExifTool/Sanyo.pm +1 -1
  173. package/bin/lib/Image/ExifTool/Scalado.pm +1 -1
  174. package/bin/lib/Image/ExifTool/Shift.pl +1 -1
  175. package/bin/lib/Image/ExifTool/Shortcuts.pm +1 -1
  176. package/bin/lib/Image/ExifTool/Sigma.pm +1 -1
  177. package/bin/lib/Image/ExifTool/SigmaRaw.pm +1 -1
  178. package/bin/lib/Image/ExifTool/Sony.pm +5 -4
  179. package/bin/lib/Image/ExifTool/SonyIDC.pm +1 -1
  180. package/bin/lib/Image/ExifTool/Stim.pm +1 -1
  181. package/bin/lib/Image/ExifTool/TagInfoXML.pm +6 -5
  182. package/bin/lib/Image/ExifTool/TagLookup.pm +7023 -6968
  183. package/bin/lib/Image/ExifTool/TagNames.pod +445 -29
  184. package/bin/lib/Image/ExifTool/Text.pm +4 -3
  185. package/bin/lib/Image/ExifTool/Theora.pm +1 -1
  186. package/bin/lib/Image/ExifTool/Torrent.pm +3 -3
  187. package/bin/lib/Image/ExifTool/Unknown.pm +1 -1
  188. package/bin/lib/Image/ExifTool/VCard.pm +3 -3
  189. package/bin/lib/Image/ExifTool/Validate.pm +6 -6
  190. package/bin/lib/Image/ExifTool/Vivo.pm +124 -0
  191. package/bin/lib/Image/ExifTool/Vorbis.pm +1 -1
  192. package/bin/lib/Image/ExifTool/WPG.pm +1 -1
  193. package/bin/lib/Image/ExifTool/WTV.pm +1 -1
  194. package/bin/lib/Image/ExifTool/WriteCanonRaw.pl +1 -1
  195. package/bin/lib/Image/ExifTool/WriteExif.pl +3 -3
  196. package/bin/lib/Image/ExifTool/WriteIPTC.pl +1 -1
  197. package/bin/lib/Image/ExifTool/WritePDF.pl +1 -1
  198. package/bin/lib/Image/ExifTool/WritePNG.pl +1 -1
  199. package/bin/lib/Image/ExifTool/WritePhotoshop.pl +1 -1
  200. package/bin/lib/Image/ExifTool/WritePostScript.pl +1 -1
  201. package/bin/lib/Image/ExifTool/WriteQuickTime.pl +166 -79
  202. package/bin/lib/Image/ExifTool/WriteRIFF.pl +17 -6
  203. package/bin/lib/Image/ExifTool/WriteXMP.pl +3 -3
  204. package/bin/lib/Image/ExifTool/Writer.pl +89 -96
  205. package/bin/lib/Image/ExifTool/XISF.pm +1 -1
  206. package/bin/lib/Image/ExifTool/XMP.pm +28 -13
  207. package/bin/lib/Image/ExifTool/XMP2.pl +103 -1
  208. package/bin/lib/Image/ExifTool/XMPStruct.pl +2 -3
  209. package/bin/lib/Image/ExifTool/ZIP.pm +2 -2
  210. package/bin/lib/Image/ExifTool/ZISRAW.pm +1 -1
  211. package/bin/lib/Image/ExifTool/iWork.pm +1 -1
  212. package/bin/lib/Image/ExifTool.pm +335 -163
  213. package/bin/lib/Image/ExifTool.pod +119 -73
  214. package/bin/perl-Image-ExifTool.spec +1 -1
  215. package/bin/windows_exiftool.txt +96 -51
  216. package/package.json +9 -9
@@ -825,7 +825,7 @@ timed metadata from the 'mett' frame found in Parrot drone MP4 videos.
825
825
 
826
826
  =head1 AUTHOR
827
827
 
828
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
828
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
829
829
 
830
830
  This library is free software; you can redistribute it and/or modify it
831
831
  under the same terms as Perl itself.
@@ -6477,7 +6477,7 @@ tags, and everyone who helped contribute to the LensType values.
6477
6477
 
6478
6478
  =head1 AUTHOR
6479
6479
 
6480
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
6480
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
6481
6481
 
6482
6482
  This library is free software; you can redistribute it and/or modify it
6483
6483
  under the same terms as Perl itself.
@@ -450,7 +450,7 @@ sub WritePhaseOne($$$)
450
450
 
451
451
  return undef if $dirLen < 12;
452
452
  unless ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{ENTRY_SIZE}) {
453
- $et->WarnOnce("No ENTRY_SIZE for $$tagTablePtr{TABLE_NAME}");
453
+ $et->Warn("No ENTRY_SIZE for $$tagTablePtr{TABLE_NAME}");
454
454
  return undef;
455
455
  }
456
456
  my $entrySize = $$tagTablePtr{VARS}{ENTRY_SIZE};
@@ -591,7 +591,7 @@ sub ProcessPhaseOne($$$)
591
591
 
592
592
  return 0 if $dirLen < 12;
593
593
  unless ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{ENTRY_SIZE}) {
594
- $et->WarnOnce("No ENTRY_SIZE for $$tagTablePtr{TABLE_NAME}");
594
+ $et->Warn("No ENTRY_SIZE for $$tagTablePtr{TABLE_NAME}");
595
595
  return undef;
596
596
  }
597
597
  my $entrySize = $$tagTablePtr{VARS}{ENTRY_SIZE};
@@ -632,7 +632,7 @@ sub ProcessPhaseOne($$$)
632
632
  $formatSize = Get32u($dataPt, $entry+4);
633
633
  $formatStr = $formatName[$formatSize];
634
634
  unless ($formatStr) {
635
- $et->WarnOnce("Unrecognized $ifdType format size $formatSize",1);
635
+ $et->Warn("Unrecognized $ifdType format size $formatSize",1);
636
636
  $formatSize = 1;
637
637
  $formatStr = 'undef';
638
638
  }
@@ -726,7 +726,7 @@ One maker notes.
726
726
 
727
727
  =head1 AUTHOR
728
728
 
729
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
729
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
730
730
 
731
731
  This library is free software; you can redistribute it and/or modify it
732
732
  under the same terms as Perl itself.
@@ -484,7 +484,7 @@ information from Kodak Photo CD Image Pac (PCD) files.
484
484
 
485
485
  =head1 AUTHOR
486
486
 
487
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
487
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
488
488
 
489
489
  This library is free software; you can redistribute it and/or modify it
490
490
  under the same terms as Perl itself.
@@ -237,7 +237,7 @@ write information written by the Camera Bits Photo Mechanic software.
237
237
 
238
238
  =head1 AUTHOR
239
239
 
240
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
240
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
241
241
 
242
242
  This library is free software; you can redistribute it and/or modify it
243
243
  under the same terms as Perl itself.
@@ -28,11 +28,12 @@ use strict;
28
28
  use vars qw($VERSION $AUTOLOAD $iptcDigestInfo %printFlags);
29
29
  use Image::ExifTool qw(:DataAccess :Utils);
30
30
 
31
- $VERSION = '1.70';
31
+ $VERSION = '1.72';
32
32
 
33
33
  sub ProcessPhotoshop($$$);
34
34
  sub WritePhotoshop($$$);
35
35
  sub ProcessLayers($$$);
36
+ sub ProcessChannelOptions($$$);
36
37
 
37
38
  # PrintFlags bit definitions (ref forum13785)
38
39
  %printFlags = (
@@ -322,7 +323,13 @@ my %unicodeString = (
322
323
  0x0432 => { Unknown => 1, Name => 'MeasurementScale' }, #7
323
324
  0x0433 => { Unknown => 1, Name => 'TimelineInfo' }, #7
324
325
  0x0434 => { Unknown => 1, Name => 'SheetDisclosure' }, #7
325
- 0x0435 => { Unknown => 1, Name => 'DisplayInfo' }, #7
326
+ 0x0435 => {
327
+ Name => 'ChannelOptions', #7/forum16762
328
+ SubDirectory => {
329
+ TagTable => 'Image::ExifTool::Photoshop::ChannelOptions',
330
+ Start => 4,
331
+ },
332
+ },
326
333
  0x0436 => { Unknown => 1, Name => 'OnionSkins' }, #7
327
334
  0x0438 => { Unknown => 1, Name => 'CountInfo' }, #7
328
335
  0x043a => { Unknown => 1, Name => 'PrintInfo2' }, #7
@@ -350,6 +357,41 @@ my %unicodeString = (
350
357
  0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' },
351
358
  );
352
359
 
360
+ # Photoshop channel options (ref forum16762)
361
+ %Image::ExifTool::Photoshop::ChannelOptions = (
362
+ PROCESS_PROC => \&ProcessChannelOptions,
363
+ VARS => { IS_BINARY => 1 },
364
+ GROUPS => { 2 => 'Image' },
365
+ NOTES => 'These tags relate only to the appearance of a channel.',
366
+ 0 => {
367
+ Name => 'ChannelColorSpace',
368
+ Format => 'int16u',
369
+ PrintConv => {
370
+ 0 => 'RGB',
371
+ 1 => 'HSB',
372
+ 2 => 'CMYK',
373
+ 7 => 'Lab',
374
+ 8 => 'Grayscale',
375
+ },
376
+ },
377
+ 2 => {
378
+ Name => 'ChannelColorData',
379
+ Format => 'int16u[4]',
380
+ },
381
+ 11 => {
382
+ Name => 'ChannelOpacity',
383
+ PrintConv => '"$val%"',
384
+ },
385
+ 12 => {
386
+ Name => 'ChannelColorIndicates',
387
+ PrintConv => {
388
+ 0 => 'Selected Areas',
389
+ 1 => 'Masked Areas',
390
+ 2 => 'Spot Color',
391
+ },
392
+ },
393
+ );
394
+
353
395
  # Photoshop JPEG quality record (ref 2)
354
396
  %Image::ExifTool::Photoshop::JPEG_Quality = (
355
397
  PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -755,6 +797,25 @@ sub ProcessLayersAndMask($$$)
755
797
  return $raf->Seek($end, 0) ? 1 : 0;
756
798
  }
757
799
 
800
+ #------------------------------------------------------------------------------
801
+ # Process Photoshop channel options (ref forum16762)
802
+ # Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
803
+ # Returns: 1 on success
804
+ sub ProcessChannelOptions($$$)
805
+ {
806
+ my ($et, $dirInfo, $tagTablePtr) = @_;
807
+ my $end = $$dirInfo{DirStart} + $$dirInfo{DirLen};
808
+ $$dirInfo{DirLen} = 13;
809
+ my $i;
810
+ for ($i=0; $$dirInfo{DirStart} + 13 <= $end; ++$i) {
811
+ $$et{SET_GROUP1} = "Channel$i";
812
+ $et->ProcessBinaryData($dirInfo, $tagTablePtr);
813
+ $$dirInfo{DirStart} += 13;
814
+ }
815
+ delete $$et{SET_GROUP1};
816
+ return 1;
817
+ }
818
+
758
819
  #------------------------------------------------------------------------------
759
820
  # Process Photoshop layers (beginning with layer count)
760
821
  # Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
@@ -1050,7 +1111,7 @@ sub ProcessPhotoshop($$$)
1050
1111
  if ($$et{VALUE}{IPTCDigest} and $$et{VALUE}{CurrentIPTCDigest} and
1051
1112
  $$et{VALUE}{IPTCDigest} ne $$et{VALUE}{CurrentIPTCDigest})
1052
1113
  {
1053
- $et->WarnOnce('IPTCDigest is not current. XMP may be out of sync');
1114
+ $et->Warn('IPTCDigest is not current. XMP may be out of sync');
1054
1115
  }
1055
1116
  delete $$et{LOW_PRIORITY_DIR}{'*'};
1056
1117
  return $success;
@@ -1201,7 +1262,7 @@ be preserved when copying Photoshop information via user-defined tags.
1201
1262
 
1202
1263
  =head1 AUTHOR
1203
1264
 
1204
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
1265
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
1205
1266
 
1206
1267
  This library is free software; you can redistribute it and/or modify it
1207
1268
  under the same terms as Perl itself.
@@ -768,7 +768,7 @@ This code reads meta information from EPS (Encapsulated PostScript), PS
768
768
 
769
769
  =head1 AUTHOR
770
770
 
771
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
771
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
772
772
 
773
773
  This library is free software; you can redistribute it and/or modify it
774
774
  under the same terms as Perl itself.
@@ -112,7 +112,7 @@ Print Image Matching meta information.
112
112
 
113
113
  =head1 AUTHOR
114
114
 
115
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
115
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
116
116
 
117
117
  This library is free software; you can redistribute it and/or modify it
118
118
  under the same terms as Perl itself.
@@ -0,0 +1,270 @@
1
+ #------------------------------------------------------------------------------
2
+ # File: Protobuf.pm
3
+ #
4
+ # Description: Decode protocol buffer data
5
+ #
6
+ # Revisions: 2024-12-04 - P. Harvey Created
7
+ #
8
+ # Notes: Tag definitions for Protobuf tags support additional 'signed',
9
+ # 'unsigned' and 'int64s' formats for varInt (type 0) values,
10
+ # and 'rational' for byte (type 2) values
11
+ #
12
+ # References: 1) https://protobuf.dev/programming-guides/encoding/
13
+ #------------------------------------------------------------------------------
14
+
15
+ package Image::ExifTool::Protobuf;
16
+
17
+ use strict;
18
+ use vars qw($VERSION);
19
+ use Image::ExifTool qw(:DataAccess :Utils);
20
+
21
+ $VERSION = '1.02';
22
+
23
+ sub ProcessProtobuf($$$;$);
24
+
25
+ #------------------------------------------------------------------------------
26
+ # Read bytes from dirInfo object
27
+ # Inputs: 0) dirInfo ref (with DataPt and Pos set), 1) number of bytes
28
+ # Returns: binary data or undef on error
29
+ sub GetBytes($$)
30
+ {
31
+ my ($dirInfo, $n) = @_;
32
+ my $dataPt = $$dirInfo{DataPt};
33
+ my $pos = $$dirInfo{Pos};
34
+ return undef if $pos + $n > length $$dataPt;
35
+ $$dirInfo{Pos} += $n;
36
+ return substr($$dataPt, $pos, $n);
37
+ }
38
+
39
+ #------------------------------------------------------------------------------
40
+ # Read variable-length integer
41
+ # Inputs: 0) dirInfo ref
42
+ # Returns: integer value
43
+ sub VarInt($)
44
+ {
45
+ my $dirInfo = shift;
46
+ my $val = 0;
47
+ my $shift = 0;
48
+ for (;;) {
49
+ my $buff = GetBytes($dirInfo, 1);
50
+ defined $buff or return undef;
51
+ $val += (ord($buff) & 0x7f) << $shift;
52
+ last unless ord($buff) & 0x80;
53
+ $shift += 7;
54
+ }
55
+ return $val;
56
+ }
57
+
58
+ #------------------------------------------------------------------------------
59
+ # Read protobuf record
60
+ # Inputs: 0) dirInfo ref
61
+ # Returns: 0) record payload (plus tag id and format type in list context)
62
+ # Notes: Updates dirInfo Pos to start of next record
63
+ sub ReadRecord($)
64
+ {
65
+ my $dirInfo = shift;
66
+ my $val = VarInt($dirInfo);
67
+ return undef unless defined $val;
68
+ my $id = $val >> 3;
69
+ my $type = $val & 0x07;
70
+ my $buff;
71
+
72
+ if ($type == 0) { # varInt
73
+ $buff = VarInt($dirInfo);
74
+ } elsif ($type == 1) { # 64-bit number
75
+ $buff = GetBytes($dirInfo, 8);
76
+ } elsif ($type == 2) { # string, bytes or protobuf
77
+ my $len = VarInt($dirInfo);
78
+ if ($len) {
79
+ $buff = GetBytes($dirInfo, $len);
80
+ } else {
81
+ $buff = '';
82
+ }
83
+ } elsif ($type == 3) { # (deprecated start group)
84
+ $buff = '';
85
+ } elsif ($type == 4) { # (deprecated end group)
86
+ $buff = '';
87
+ } elsif ($type == 5) { # 32-bit number
88
+ $buff = GetBytes($dirInfo, 4);
89
+ }
90
+ return wantarray ? ($buff, $id, $type) : $buff;
91
+ }
92
+
93
+ #------------------------------------------------------------------------------
94
+ # Check to see if this could be a protobuf object
95
+ # Inputs: 0) data reference
96
+ # Retursn: true if this looks like a protobuf
97
+ sub IsProtobuf($)
98
+ {
99
+ my $pt = shift;
100
+ my $dirInfo = { DataPt => $pt, Pos => 0 };
101
+ for (;;) {
102
+ return 0 unless defined ReadRecord($dirInfo);
103
+ return 1 if $$dirInfo{Pos} == length $$pt;
104
+ }
105
+ }
106
+
107
+ #------------------------------------------------------------------------------
108
+ # Process protobuf data (eg. DJI djmd timed data from Action4 videos) (ref 1)
109
+ # Inputs: 0) ExifTool ref, 1) dirInfo ref with DataPt, DataPos, DirName and Base,
110
+ # 2) tag table ptr, 3) prefix of parent protobuf ID's
111
+ # Returns: true on success
112
+ sub ProcessProtobuf($$$;$)
113
+ {
114
+ my ($et, $dirInfo, $tagTbl, $prefix) = @_;
115
+ my $dataPt = $$dirInfo{DataPt};
116
+ my $dirName = $$dirInfo{DirName};
117
+ my $dirStart = $$dirInfo{DirStart} || 0;
118
+ my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
119
+ my $dirEnd = $dirStart + $dirLen;
120
+ my $dataPos = ($$dirInfo{Base} || 0) + ($$dirInfo{DataPos} || 0);
121
+ my $unknown = $et->Options('Unknown') || $et->Options('Verbose');
122
+
123
+ $$dirInfo{Pos} = $$dirInfo{DirStart} || 0; # initialize buffer Pos
124
+ $et->VerboseDir('Protobuf', undef, $dirLen);
125
+
126
+ unless ($prefix) {
127
+ $prefix = '';
128
+ $$et{ProtoPrefix}{$dirName} = '' unless defined $$et{ProtoPrefix}{$dirName};
129
+ SetByteOrder('II');
130
+ }
131
+ # loop through protobuf records
132
+ for (;;) {
133
+ my $pos = $$dirInfo{Pos};
134
+ last if $pos >= $dirEnd;
135
+ my ($buff, $id, $type) = ReadRecord($dirInfo);
136
+ defined $buff or $et->Warn('Protobuf format error'), last;
137
+ if ($type == 2 and $buff =~ /\.proto$/) {
138
+ # save protocol name separately for directory type
139
+ $$et{ProtoPrefix}{$dirName} = substr($buff, 0, -6) . '_';
140
+ $et->HandleTag($tagTbl, Protocol => $buff);
141
+ }
142
+ my $tag = "$$et{ProtoPrefix}{$dirName}$prefix$id";
143
+ my $tagInfo = $$tagTbl{$tag};
144
+ if ($tagInfo) {
145
+ next if $type != 2 and $$tagInfo{Unknown} and not $unknown;
146
+ } else {
147
+ next unless $type == 2 or $unknown;
148
+ $tagInfo = AddTagToTable($tagTbl, $tag, { Unknown => 1 });
149
+ }
150
+ # set IsProtobuf flag (only for Unknown tags) if necessary
151
+ if ($type == 2 and $$tagInfo{Unknown}) {
152
+ if ($$tagInfo{IsProtobuf}) {
153
+ $$tagInfo{IsProtobuf} = 0 unless IsProtobuf(\$buff);
154
+ } elsif (not defined $$tagInfo{IsProtobuf} and $buff =~ /[^\x20-\x7e]/ and
155
+ IsProtobuf(\$buff))
156
+ {
157
+ $$tagInfo{IsProtobuf} = 1;
158
+ }
159
+ next unless $$tagInfo{IsProtobuf} or $unknown;
160
+ }
161
+ # format binary payload into a useful value
162
+ my $val;
163
+ if ($$tagInfo{Format}) {
164
+ if ($type == 0) {
165
+ $val = $buff;
166
+ if ($$tagInfo{Format} eq 'signed') {
167
+ $val = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
168
+ } elsif ($$tagInfo{Format} eq 'int64s' and $val > 0xffffffff) {
169
+ # hack for DJI drones which store 64-bit signed integers improperly
170
+ # (just toss upper 32 bits which should be all 1's anyway)
171
+ $val = ($val & 0xffffffff) - 4294967296;
172
+ }
173
+ } elsif ($type == 2 and $$tagInfo{Format} eq 'rational') {
174
+ my $dir = { DataPt => \$buff, Pos => 0 };
175
+ my $num = VarInt($dir);
176
+ my $den = VarInt($dir);
177
+ $val = (defined $num and $den) ? "$num/$den" : 'err';
178
+ } else {
179
+ $val = ReadValue(\$buff, 0, $$tagInfo{Format}, undef, length($buff));
180
+ }
181
+ } elsif ($type == 0) {
182
+ $val = $buff;
183
+ my $hex = sprintf('%x', $val);
184
+ if (length($hex) == 16 and $hex =~ /^ffffffff/) {
185
+ my $s64 = hex(substr($hex, 8)) - 4294967296;
186
+ $val .= " (0x$hex, int64s $s64)";
187
+ } else {
188
+ my $signed = ($val & 1) ? -($val >> 1)-1 : ($val >> 1);
189
+ $val .= " (0x$hex, signed $signed)";
190
+ }
191
+ } elsif ($type == 1) {
192
+ $val = '0x' . unpack('H*', $buff) . ' (double ' . GetDouble(\$buff,0) . ')';
193
+ } elsif ($type == 2) {
194
+ if ($$tagInfo{SubDirectory}) {
195
+ # (fall through to process known SubDirectory)
196
+ } elsif ($$tagInfo{IsProtobuf}) {
197
+ # process Unknown protobuf directories
198
+ $et->VPrint(1, "$$et{INDENT}Protobuf $tag (" . length($buff) . " bytes) -->\n");
199
+ my $addr = $dataPos + $$dirInfo{Pos} - length($buff);
200
+ $et->VerboseDump(\$buff, Addr => $addr, Prefix => $$et{INDENT});
201
+ my %subdir = ( DataPt => \$buff, DataPos => $addr, DirName => $dirName );
202
+ $$et{INDENT} .= '| ';
203
+ ProcessProtobuf($et, \%subdir, $tagTbl, "$prefix$id-");
204
+ $$et{INDENT} = substr($$et{INDENT}, 0, -2);
205
+ next;
206
+ } elsif ($buff !~ /[^\x20-\x7e]/) {
207
+ $val = $buff; # assume this is an ASCII string
208
+ } elsif (length($buff) % 4) {
209
+ $val = '0x' . unpack('H*', $buff);
210
+ } else {
211
+ $val = '0x' . join(' ', unpack('(H8)*', $buff)); # (group in 4-byte blocks)
212
+ }
213
+ } elsif ($type == 5) {
214
+ $val = '0x' . unpack('H*', $buff) . ' (int32u ' . Get32u(\$buff, 0);
215
+ $val .= ', int32s ' . Get32s(\$buff, 0) if ord(substr($buff,3,1)) & 0x80;
216
+ $val .= ', float ' . GetFloat(\$buff, 0) . ')';
217
+ } else {
218
+ $val = $buff;
219
+ }
220
+ # get length of data in the record
221
+ my $start = $type == 0 ? $pos + 1 : $$dirInfo{Pos} - length $buff;
222
+ $et->HandleTag($tagTbl, $tag, $val,
223
+ DataPt => $dataPt,
224
+ DataPos=> $dataPos,
225
+ Start => $start,
226
+ Size => $$dirInfo{Pos} - $start,
227
+ Extra => ", type=$type",
228
+ Format => $$tagInfo{Format},
229
+ );
230
+ }
231
+ # warn if we didn't finish exactly at the end of the buffer
232
+ $et->Warn('Truncated protobuf data') unless $prefix or $$dirInfo{Pos} == $dirEnd;
233
+ return 1;
234
+ }
235
+
236
+ __END__
237
+
238
+ =head1 NAME
239
+
240
+ Image::ExifTool::Protobuf - Decode protocol buffer information
241
+
242
+ =head1 SYNOPSIS
243
+
244
+ This module is loaded automatically by Image::ExifTool when required.
245
+
246
+ =head1 DESCRIPTION
247
+
248
+ This module contains definitions required by Image::ExifTool to decode
249
+ information in protocol buffer (protobuf) format.
250
+
251
+ =head1 AUTHOR
252
+
253
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
254
+
255
+ This library is free software; you can redistribute it and/or modify it
256
+ under the same terms as Perl itself.
257
+
258
+ =head1 REFERENCES
259
+
260
+ =over 4
261
+
262
+ =item L<https://protobuf.dev/programming-guides/encoding/>
263
+
264
+ =back
265
+
266
+ =head1 SEE ALSO
267
+
268
+ L<Image::ExifTool(3pm)|Image::ExifTool>
269
+
270
+ =cut
@@ -1331,7 +1331,7 @@ information from the APP7 Qualcomm segment in JPEG images.
1331
1331
 
1332
1332
  =head1 AUTHOR
1333
1333
 
1334
- Copyright 2003-2024, Phil Harvey (philharvey66 at gmail.com)
1334
+ Copyright 2003-2025, Phil Harvey (philharvey66 at gmail.com)
1335
1335
 
1336
1336
  This library is free software; you can redistribute it and/or modify it
1337
1337
  under the same terms as Perl itself.