From 893588697e190997db4996a9a45874a2df6390eb Mon Sep 17 00:00:00 2001 From: gl4ssiest Date: Tue, 31 Mar 2020 17:06:49 -0500 Subject: [PATCH] Exif-Tool updated to 11.92 version. Including .pm files required for master branch to work. --- src/Image-ExifTool/Changes | 922 +- src/Image-ExifTool/README | 102 +- src/Image-ExifTool/exiftool | 992 +- src/Image-ExifTool/lib/File/RandomAccess.pm | 2 +- src/Image-ExifTool/lib/File/RandomAccess.pod | 4 +- src/Image-ExifTool/lib/Image/ExifTool.pm | 825 +- src/Image-ExifTool/lib/Image/ExifTool.pod | 379 +- src/Image-ExifTool/lib/Image/ExifTool/AES.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/AFCP.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/AIFF.pm | 27 +- src/Image-ExifTool/lib/Image/ExifTool/APE.pm | 2 +- .../lib/Image/ExifTool/APP12.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/ASF.pm | 2 +- .../lib/Image/ExifTool/Apple.pm | 4 +- .../lib/Image/ExifTool/Audible.pm | 317 + src/Image-ExifTool/lib/Image/ExifTool/BMP.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/BPG.pm | 253 + src/Image-ExifTool/lib/Image/ExifTool/BZZ.pm | 2 +- .../lib/Image/ExifTool/BigTIFF.pm | 45 +- .../lib/Image/ExifTool/BuildTagLookup.pm | 230 +- .../lib/Image/ExifTool/Canon.pm | 314 +- .../lib/Image/ExifTool/CanonCustom.pm | 42 +- .../lib/Image/ExifTool/CanonRaw.pm | 6 +- .../lib/Image/ExifTool/CanonVRD.pm | 38 +- .../lib/Image/ExifTool/CaptureOne.pm | 2 +- .../lib/Image/ExifTool/Casio.pm | 4 +- .../lib/Image/ExifTool/Charset.pm | 2 +- .../lib/Image/ExifTool/Charset/DOSLatin1.pm | 49 + .../lib/Image/ExifTool/Charset/DOSLatinUS.pm | 49 + .../lib/Image/ExifTool/DICOM.pm | 17 +- src/Image-ExifTool/lib/Image/ExifTool/DJI.pm | 138 + src/Image-ExifTool/lib/Image/ExifTool/DNG.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/DPX.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/DV.pm | 26 +- .../lib/Image/ExifTool/DarwinCore.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/DjVu.pm | 5 +- src/Image-ExifTool/lib/Image/ExifTool/EXE.pm | 12 +- src/Image-ExifTool/lib/Image/ExifTool/Exif.pm | 563 +- src/Image-ExifTool/lib/Image/ExifTool/FITS.pm | 148 + src/Image-ExifTool/lib/Image/ExifTool/FLAC.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/FLIF.pm | 353 + src/Image-ExifTool/lib/Image/ExifTool/FLIR.pm | 31 +- .../lib/Image/ExifTool/Fixup.pm | 2 +- .../lib/Image/ExifTool/Flash.pm | 4 +- .../lib/Image/ExifTool/FlashPix.pm | 84 +- src/Image-ExifTool/lib/Image/ExifTool/Font.pm | 18 +- .../lib/Image/ExifTool/FotoStation.pm | 2 +- .../lib/Image/ExifTool/FujiFilm.pm | 182 +- src/Image-ExifTool/lib/Image/ExifTool/GE.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/GIF.pm | 12 +- src/Image-ExifTool/lib/Image/ExifTool/GIMP.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/GPS.pm | 17 +- .../lib/Image/ExifTool/GeoTiff.pm | 4 +- .../lib/Image/ExifTool/Geotag.pm | 108 +- .../lib/Image/ExifTool/GoPro.pm | 711 + src/Image-ExifTool/lib/Image/ExifTool/H264.pm | 6 +- src/Image-ExifTool/lib/Image/ExifTool/HP.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/HTML.pm | 27 +- .../lib/Image/ExifTool/HtmlDump.pm | 63 +- .../lib/Image/ExifTool/ICC_Profile.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/ID3.pm | 15 +- src/Image-ExifTool/lib/Image/ExifTool/IPTC.pm | 40 +- src/Image-ExifTool/lib/Image/ExifTool/ISO.pm | 206 + src/Image-ExifTool/lib/Image/ExifTool/ITC.pm | 2 +- .../lib/Image/ExifTool/Import.pm | 2 +- .../lib/Image/ExifTool/InDesign.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/JPEG.pm | 34 +- .../lib/Image/ExifTool/JPEGDigest.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/JSON.pm | 142 + src/Image-ExifTool/lib/Image/ExifTool/JVC.pm | 2 +- .../lib/Image/ExifTool/Jpeg2000.pm | 2 +- .../lib/Image/ExifTool/Kodak.pm | 13 +- .../lib/Image/ExifTool/KyoceraRaw.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/LNK.pm | 2 +- .../lib/Image/ExifTool/Lang/cs.pm | 2 +- .../lib/Image/ExifTool/Lang/de.pm | 62 +- .../lib/Image/ExifTool/Lang/en_ca.pm | 2 +- .../lib/Image/ExifTool/Lang/en_gb.pm | 2 +- .../lib/Image/ExifTool/Lang/es.pm | 6 +- .../lib/Image/ExifTool/Lang/fi.pm | 50 +- .../lib/Image/ExifTool/Lang/fr.pm | 6 +- .../lib/Image/ExifTool/Lang/it.pm | 11 +- .../lib/Image/ExifTool/Lang/ja.pm | 18 +- .../lib/Image/ExifTool/Lang/ko.pm | 7 +- .../lib/Image/ExifTool/Lang/nl.pm | 9 +- .../lib/Image/ExifTool/Lang/pl.pm | 6 +- .../lib/Image/ExifTool/Lang/ru.pm | 5884 +++++++- .../lib/Image/ExifTool/Lang/sv.pm | 2 +- .../lib/Image/ExifTool/Lang/tr.pm | 6 +- .../lib/Image/ExifTool/Lang/zh_cn.pm | 2 +- .../lib/Image/ExifTool/Lang/zh_tw.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/Leaf.pm | 2 +- .../lib/Image/ExifTool/Lytro.pm | 3 +- src/Image-ExifTool/lib/Image/ExifTool/M2TS.pm | 6 +- src/Image-ExifTool/lib/Image/ExifTool/MIE.pm | 21 +- .../lib/Image/ExifTool/MIEUnits.pod | 2 +- src/Image-ExifTool/lib/Image/ExifTool/MIFF.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/MNG.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/MOI.pm | 159 + src/Image-ExifTool/lib/Image/ExifTool/MPC.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/MPEG.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/MPF.pm | 6 +- src/Image-ExifTool/lib/Image/ExifTool/MWG.pm | 24 +- src/Image-ExifTool/lib/Image/ExifTool/MXF.pm | 2 +- .../lib/Image/ExifTool/MacOS.pm | 619 + .../lib/Image/ExifTool/MakerNotes.pm | 51 +- .../lib/Image/ExifTool/Matroska.pm | 6 +- .../lib/Image/ExifTool/Microsoft.pm | 4 +- .../lib/Image/ExifTool/Minolta.pm | 207 +- .../lib/Image/ExifTool/MinoltaRaw.pm | 2 +- .../lib/Image/ExifTool/Motorola.pm | 172 + .../lib/Image/ExifTool/Nikon.pm | 994 +- .../lib/Image/ExifTool/NikonCapture.pm | 2 +- .../lib/Image/ExifTool/NikonCustom.pm | 50 +- .../lib/Image/ExifTool/Nintendo.pm | 2 +- .../lib/Image/ExifTool/OOXML.pm | 5 +- src/Image-ExifTool/lib/Image/ExifTool/Ogg.pm | 2 +- .../lib/Image/ExifTool/Olympus.pm | 95 +- .../lib/Image/ExifTool/OpenEXR.pm | 9 +- src/Image-ExifTool/lib/Image/ExifTool/Opus.pm | 98 + src/Image-ExifTool/lib/Image/ExifTool/PCX.pm | 138 + src/Image-ExifTool/lib/Image/ExifTool/PDF.pm | 114 +- src/Image-ExifTool/lib/Image/ExifTool/PGF.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/PICT.pm | 8 +- .../lib/Image/ExifTool/PLIST.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/PLUS.pm | 2607 ++++ src/Image-ExifTool/lib/Image/ExifTool/PNG.pm | 248 +- src/Image-ExifTool/lib/Image/ExifTool/PPM.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/PSP.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/Palm.pm | 2 +- .../lib/Image/ExifTool/Panasonic.pm | 90 +- .../lib/Image/ExifTool/PanasonicRaw.pm | 45 +- .../lib/Image/ExifTool/Parrot.pm | 751 + .../lib/Image/ExifTool/Pentax.pm | 82 +- .../lib/Image/ExifTool/PhaseOne.pm | 7 +- .../lib/Image/ExifTool/PhotoCD.pm | 5 +- .../lib/Image/ExifTool/PhotoMechanic.pm | 6 +- .../lib/Image/ExifTool/Photoshop.pm | 45 +- .../lib/Image/ExifTool/PostScript.pm | 128 +- .../lib/Image/ExifTool/PrintIM.pm | 2 +- .../lib/Image/ExifTool/Qualcomm.pm | 2 +- .../lib/Image/ExifTool/QuickTime.pm | 1958 ++- .../lib/Image/ExifTool/QuickTimeStream.pl | 2266 +++ src/Image-ExifTool/lib/Image/ExifTool/README | 248 +- src/Image-ExifTool/lib/Image/ExifTool/RIFF.pm | 69 +- src/Image-ExifTool/lib/Image/ExifTool/RSRC.pm | 4 +- src/Image-ExifTool/lib/Image/ExifTool/RTF.pm | 4 +- .../lib/Image/ExifTool/Radiance.pm | 2 +- .../lib/Image/ExifTool/Rawzor.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/Real.pm | 2 +- .../lib/Image/ExifTool/Reconyx.pm | 131 +- src/Image-ExifTool/lib/Image/ExifTool/Red.pm | 325 + .../lib/Image/ExifTool/Ricoh.pm | 12 +- .../lib/Image/ExifTool/Samsung.pm | 164 +- .../lib/Image/ExifTool/Sanyo.pm | 2 +- .../lib/Image/ExifTool/Scalado.pm | 2 +- .../lib/Image/ExifTool/Shift.pl | 36 +- .../lib/Image/ExifTool/Shortcuts.pm | 7 +- .../lib/Image/ExifTool/Sigma.pm | 198 +- .../lib/Image/ExifTool/SigmaRaw.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/Sony.pm | 585 +- .../lib/Image/ExifTool/SonyIDC.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/Stim.pm | 2 +- .../lib/Image/ExifTool/TagInfoXML.pm | 22 +- .../lib/Image/ExifTool/TagLookup.pm | 11444 ++++++++-------- .../lib/Image/ExifTool/TagNames.pod | 4097 ++++-- src/Image-ExifTool/lib/Image/ExifTool/Text.pm | 245 + .../lib/Image/ExifTool/Theora.pm | 2 +- .../lib/Image/ExifTool/Torrent.pm | 16 +- .../lib/Image/ExifTool/Unknown.pm | 2 +- .../lib/Image/ExifTool/VCard.pm | 443 + .../lib/Image/ExifTool/Validate.pm | 672 + .../lib/Image/ExifTool/Vorbis.pm | 2 +- src/Image-ExifTool/lib/Image/ExifTool/WTV.pm | 319 + .../lib/Image/ExifTool/WriteCanonRaw.pl | 14 +- .../lib/Image/ExifTool/WriteExif.pl | 40 +- .../lib/Image/ExifTool/WriteIPTC.pl | 10 +- .../lib/Image/ExifTool/WritePDF.pl | 12 +- .../lib/Image/ExifTool/WritePNG.pl | 50 +- .../lib/Image/ExifTool/WritePhotoshop.pl | 6 +- .../lib/Image/ExifTool/WritePostScript.pl | 91 +- .../lib/Image/ExifTool/WriteQuickTime.pl | 1786 ++- .../lib/Image/ExifTool/WriteXMP.pl | 266 +- .../lib/Image/ExifTool/Writer.pl | 439 +- src/Image-ExifTool/lib/Image/ExifTool/XMP.pm | 219 +- src/Image-ExifTool/lib/Image/ExifTool/XMP2.pl | 360 +- .../lib/Image/ExifTool/XMPStruct.pl | 40 +- src/Image-ExifTool/lib/Image/ExifTool/ZIP.pm | 44 +- .../lib/Image/ExifTool/iWork.pm | 11 +- 189 files changed, 36658 insertions(+), 10582 deletions(-) create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Audible.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/BPG.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatin1.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatinUS.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/DJI.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/FITS.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/FLIF.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/GoPro.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/ISO.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/JSON.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/MOI.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/MacOS.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Motorola.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Opus.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/PCX.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/PLUS.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Parrot.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/QuickTimeStream.pl create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Red.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Text.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/VCard.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/Validate.pm create mode 100644 src/Image-ExifTool/lib/Image/ExifTool/WTV.pm diff --git a/src/Image-ExifTool/Changes b/src/Image-ExifTool/Changes index b4a11492..e822fb02 100644 --- a/src/Image-ExifTool/Changes +++ b/src/Image-ExifTool/Changes @@ -2,11 +2,863 @@ DO NOT EDIT THIS FILE -- it is generated from the html history files. ExifTool Version History -RSS feed: http://owl.phy.queensu.ca/~phil/exiftool/rss.xml +RSS feed: https://exiftool.org/rss.xml -Note: The most recent production release is Version 11.11. (Other versions are +Note: The most recent production release is Version 11.85. (Other versions are considered development releases, and are not uploaded to CPAN.) +Mar. 19, 2020 - Version 11.92 + + - Added a new Nikon LensID (thanks Wolfgang Exler) + - Decode a few new Leica tags (thanks Tim Gray) + - Decode CameraAngles from Samsung Gear 360 videos + - Fixed a couple of problems decoding timed GPS metadata from NextBase dashcam + videos + - Fixed problem where -X option could produce invalid XML when reading + corrupted XMP + +Mar. 5, 2020 - Version 11.91 + + - Decode a couple of new Panasonic tags + - Documented -ec option (available since version 11.54) + - Reverted -htmlDump fix of 11.90 because it broke more than it fixed, and + instead applied a targeted patch to fix this problem for RW2 files + +Mar. 3, 2020 - Version 11.90 + + - Added a new Sony LensType (thanks LibRaw and Jos Roost) + - Added two new Olympus LensType values + - Added a new Canon LensType + - Added some new Canon RecordMode values + - Added some new QuickTime GeneralProfileIDC values + - Added new values for a couple of FujiFilm tags + - Added a number of new QuickTime GenreID values + - Decode Nikon Z6/Z7 phase-detect AF points (thanks Andy Dragon) + - Patched to avoid possible "Undefined subroutine" error in MacOS 10.15 + - Fixed incorrect offsets in -htmlDump output for some file types + +Feb. 25, 2020 - Version 11.89 + + - Added support for Exif 2.32 for XMP + - Recognize the HIF file extension + - Improved verbose output for QuickTime iref items + - Patched to create new GPS metadata in Canon CR3 images using a default byte + order that is the same as existing EXIF boxes + - Patched to add missing newline that could occur in XMP with the API Compact + Shorthand option + +Feb. 20, 2020 - Version 11.88 + + - Added write support for new Google depth-map XMP tags + - Added config_files/depthmap.config to the distribution + - Added minor error when attempting to write FFF images due to incompatibility + with Hasselblad Phocus software + - Patched to avoid "Invalid iloc offset size" error when writing some + QuickTime-based files + - Fixed incorrect ColumnCount for CSV files + - Fixed various spelling errors (thanks Jens Schleusener) + - Fixed bug writing QuickTime:Rotation in HEIC files + +Feb. 13, 2020 - Version 11.87 + + - Added read support for CSV files + - Added "--" option to indicate the end of options + - Added ability to read/write/copy/delete the JPEG trailer as a block + - Added new Olympus CameraType and LensType values (thanks LibRaw) + - Decode a few more FujiFilm tags + - Enhanced -fast option (API FastScan) to bypass PNG CRC validation when + writing + +Feb. 4, 2020 - Version 11.86 + + - Added support for DNG version 1.5 + - Added config_files/acdsee.config to the full distribution (thanks StarGeek) + - Added a new Sony LensType (thanks Jos Roost and LibRaw) + - Decode two more bits from Nikon LensType (thanks LibRaw) + - Decode QuickTime MovieFragmentSequence + - Patched HEIC writer to add missing iref box if necessary + - Fixed typo in a Canon LensType value + - API Changes: + - Patched ImageInfo() to recognize a stringified object as a file name + +Jan. 28, 2020 - Version 11.85 (production release) + + - Added a new Sony LensType (thanks Jos Roost) + - Added a new Olympus CameraType (thanks LibRaw) + - Added a two new Pentax LensType values + - Added a new FujiFilm FocusMode + - Decode timed GPS from Akaso dashcam MOV videos + - Decode Insta360 trailer from INSP images and made Insta360 a deletable group + - Patched kml.fmt file to limit maximum image size (thanks Fedor Kotov) + - Fixed problem decoding values from Leica M10 and S maker notes + +Jan. 10, 2020 - Version 11.84 + + - Decode accelerometer data from timed metadata of more dashcam videos + - Decode Canon G9 white balance tags (thanks LibRaw) + - Recognize INSP files + +Jan. 9, 2020 - Version 11.83 + + - Added a couple of new XMP-crs tags (thanks Herb) + - Fixed bug introduced in 11.82 with the -php -D output + - Fixed problem where some flattened XMP tags could be written when they + should be avoided + +Jan. 8, 2020 - Version 11.82 + + - Added a new Canon LensType + - Added a new CanonModelID (thanks LibRaw) + - Added ability to process SubDirectories in QuickTime Keys tags + - Removed minor error when writing PDF 2.0 files (github issue #30) + - Fixed problem where trailing null bytes were removed from binary values in + the -php output when the -b option was used + +Jan. 2, 2020 - Version 11.81 + + - Added a new Nikon LensID + - Added two new CanonModelID's (thanks LibRaw) + - Decode AVIF AV1 configuration record + - Changed names of QuickTime MovieData tags to "MediaData" + - Patched to use 4-digit years in Time::Local calls + - Patched Composite sub-second date/time tags to do additional validation of + source EXIF date/time tags before adding sub seconds + - Fixed problem where -json output could produce invalid JSON when -struct was + used and the structure field names contained special characters (github + issue #32) + - Fixed spelling in a Panasonic SceneMode value (thanks Hubert) + +Dec. 17, 2019 - Version 11.80 + + - Added a new Canon LensType + - Added a new Nikon Z LensID (thanks LibRaw) + - Added a few new Sony LensType values (thanks Jos Roost) + - Attempt to improve reliability of Samsung DepthMapWidth/Height decoding + - Updated a number of Canon-mount Tamron lens names to include the Tamron + model number + - Patched MOV/MP4 writer to allow a small amount of garbage at the end of a + file to be deleted when writing with the -m option + - Fixed bug where some Composite tags may not have taken priority over other + tags as they should have + +Dec. 12, 2019 - Version 11.79 + + - Added support for AVIF files + - Added new Canon, Sigma and Sony LensType values (thanks LibRaw) + - Made PDF 2.0 writable at your own risk with the -m option (github issue #30) + - Enhanced -validate feature to warn about duplicate languages in an XMP + lang-alt list + - Fixed inconsistency between documentation and ExifTool capabilities for + "Writable" status of some tags + +Dec. 5, 2019 - Version 11.78 + + - Added a new Nikon LensID (thanks Chris) + - Added two new FujiFilm SceneRecognition values + - Patched to avoid crash in Windows when writing a negative epoch time using + the "-d %s" option + - Fixed problem editing MIE tags when using the "-wm w" option + +Nov. 27, 2019 - Version 11.77 + + - Added a new Nikon LensID (thanks Joe Schonberg) + - Added a number of new Olympus LensType values (thanks LibRaw) + - Added a new Canon LensType + - Decode timed GPS from Ambarella A12 dash cam MP4 videos + - Decode a number of new Sigma tags (thanks LibRaw) + - Decode a couple of new PanasonicRaw tags (thanks LibRaw) + - Enhanced -fileOrder option to add -fast feature + +Nov. 12, 2019 - Version 11.76 + + - Added support for the Sony ILCE-9M2 (thanks Jos Roost) + - Added a couple of new XMP-GCamera tags + - Added MIMEType values for some formats that previously reported + "application/unknown" + - Enhanced -geotag feature to write pitch to CameraElevationAngle if available + - Improved determination of MIMEEncoding for TXT files + +Nov. 4, 2019 - Version 11.75 + + - Added ability to read some basic characteristics of TXT files + - Added kml_track.fmt to the fmt_files of the full distribution + - Added built-in support for decoding GPS from the four video subtitle text + formats that were previously handled by separate config files, and removed + these config files from the distribution + - Derive GPSDateTime from CreateDate and SampleTime if not already available + when extracting timed GPS metadata from QuickTime-format videos + - Changed family 2 groups of some Extra tags + +Oct. 29, 2019 - Version 11.74 + + - Added support for new XMP IPTC Extension version 1.5 tags + - Added a new Nikon LensID (thanks LibRaw) + - Decode GPS track from Auto-Vox dashcam MOV videos + - Improved Russian translations (thanks Andrei Korzhyts and Alexander) + - Enhanced convert_regions.config to support new IPTC Extension 1.5 ImageRegion + - Changed the way the FlatName element works when used in a structure element + (the structure name is now added as a prefix to the flattened tag name) + - Patched gpx.fmt and gpx_wpt.fmt to support sub-seconds in GPSDateTime value + +Oct. 23, 2019 - Version 11.73 + + - Decode timed metadata from Parrot drone videos + - Patched dji.config file to properly handle time zones + - Fixed bug which caused runtime error when reading timed metadata from Cobra + Dash Cam AVI videos + +Oct. 22, 2019 - Version 11.72 + + - Added warning messages for corrupted Photoshop document data + - Added a new Olympus CameraType + - Added a new Canon LensType + - Decode more Sigma tags + - Improved Russian translations (thanks Alexander) + - Updated decoding of some CanonCustom settings for recent models + - Documented DNG OpcodeList values + +Oct. 16, 2019 - Version 11.71 + + - Added a new Sony LensType (thanks Jos Roost) + - Added a few new Nikon Z LensID's + - Added a simple print conversion for DNG OpcodeList tags (note that due to + this, these tags must now be copied using the -n option) + - Fixed problems determining some video parameters for DV files + - Changed behaviour of -sep option when writing empty list items + - API Changes: + - Changed ListSplit option to preserve empty list items + +Oct. 10, 2019 - Version 11.70 (production release) + + - Added a new CanonModelID (thanks Laurent Clevy) + - Improved identification of Office Open XML files (github issue #27) + - Removed RAF version check when writing FujiFilm RAF files + - Limited the number of accelerometer records that ExifTool will read by + default with the -ee option from INSV files to avoid excessive processing + times and memory usage + - Patched Windows version to allow reading of shared files with Unicode names + (thanks Eriksson) + - Patched to avoid converting some bad GPS coordinates (thanks Csaba Toth) + - Fixed verbose output to include YCbCrSubSampling for JPEG files + - Fixed conversion and group names for the new FujiFilm tag added in 11.68 + - Fixed format of GeoTiffDirectory and GeoTiffDoubleParams when writing + +Oct. 2, 2019 - Version 11.69 + + - Fixed bug introduced in version 11.66 where the sign was lost when writing + coordinate values between 0 and -1 to QuickTime:GPSCoordinates + +Oct. 1, 2019 - Version 11.68 + + - Added read support for yet another type of streaming GPS in MP4 videos + - Added a number of new FujiFlashMode values + - Decode a new FujiFilm tag + - Made NikonCaptureOffsets and NikonCaptureVersion deletable + - Enhanced tag name documentation to indicate deletable MakerNotes tags + +Sept. 30, 2019 - Version 11.67 + + - Added config_files/thinkware.config to the distribution + - Fixed bug decoding negative GPS coordinates from INSV videos + +Sept. 30, 2019 - Version 11.66 + + - Added a new Nikon LensID (thanks LibRaw) + - Added a few new Canon LensType values (thanks LibRaw and Tom Lachecki) + - Decode a few more Hasselblad tags (thanks LibRaw) + - Decode a new Canon tag (thanks Laurent Clevy) + - Decode more Samsung trailer tags + - Extract BWF iXML, aXML and UMID from RIFF-format files + - Extract ICC_Profile from more types of PDF files + - Enhanced %s of the -W option to recognize the PICT format + - Recognize MacOS alias files + - Changed name of Ricoh CropMode35mm tag and added a new value (thanks LibRaw) + - Minor change to a Minolta lens name (thanks Jos Roost) + - Fixed problem where NikonCapture information couldn't be deleted from an NEF + - Fixed problem identifying some SVG files + - Fixed typo in a CanonModelID value (thanks Dmitry) + - Fixed bug which could result in "Internal error: no list index" warning when + creating nested XMP lang-alt lists + - Fixed the names of a few Tamron lenses for Nikon (thanks Tom Lachecki) + - Fixed problem extracting Layer information from some PSD files + - Fixed writing of QuickTime GPSCoordinates to use the correct number of + digits before the decimal point for latitude and longitude + +Aug. 29, 2019 - Version 11.65 + + - Added new SonyModelID and Sony LensType values (thanks LibRaw and Jos Roost) + - Added support for some new Sony models (thanks Jos Roost) + - Added a couple of new CanonModelID values (thanks LibRaw) + - Added a new Canon ColorDataVersion value + - Enhanced FastScan option so a setting of 2 stops processing PNG images at + the IDAT chunk when reading + - Preserve order of nested lang-alt list entries when -struct option is used + +Aug. 28, 2019 - Version 11.64 + + - Added a new Canon LensType (thanks LibRaw) + - Added a new Nikon LensID (thanks Bruno) + - Added config file for converting streaming GPS from BlueSkySea dashcam + - Decode FocusDistance for Nikon Z6/Z7 + - Documented groups in families 5 and 6 (available but undocumented since + Exiftool version 8.22 and 11.50 respectively) + - Fixed some ordering problems when writing/copying nested XMP lang-alt lists + - Fixed some minor quirks with QuickTime language codes (thanks Hayo Baan) + - Fixed a CanonModelID value (thanks Dmitry) + - API Changes: + - Documented SavePath and SaveFormat options + +Aug. 20, 2019 - Version 11.63 - "PNG Early Text" + + - Added a few new Sigma lenses (thanks LibRaw) + - Improved handling of Canon CNTH atom in MOV/MP4 videos + - Changed PNG writer to place all text chunks before IDAT (not just XMP) + (github issue #23) + - Issue minor warning for any text chunk after PNG IDAT (not just XMP) + - Enhanced ForceWrite feature to allow "PNG" to be specified (to move existing + text chunks to before IDAT without editing any metadata) + - Removed Windows "surrogate" warning for files that wouldn't be processed + anyway + - Fixed some entries in the Minolta LensType list (thanks Jos Roost) + - Fixed identification of a Sony lens (thanks Jos Roost) + +Aug. 15, 2019 - Version 11.62 + + - Added a number of new Canon, Pentax, Sony and Sigma lenses (thanks LibRaw) + - Removed some extraneous verbose warnings when geotagging + - Removed Minolta LensType value for a non-existent lens (thanks LibRaw) + - Patched problem writing some simple qualified XMP values + - Patched to avoid writing files in Windows with Unicode surrogate characters + in their name unless the -overwrite_original_in_place option is used + - Fixed an incorrect Pentax LensType (thanks LibRaw) + - Fixed family 2 group names of some XMP-exifEX and XMP Composite tags + +Aug. 7, 2019 - Version 11.61 + + - Added a new FujiFilm CropMode (thanks LibRaw) + - Added a few new proprietary CustomRendered values (thanks Jeffrey Friedl) + - Added a new Nikon LensID and fixed a Canon LensType (thanks LibRaw) + - Added a new CanonModelID + - Decode more Sony DSC-RX100M7 tags (thanks Jos Roost) + - Write standard EXIF to PNG even if non-standard EXIF already exists + - Changed a Minolta/Sony LensType (thanks LibRaw) + - Changed Composite GPS reference direction tags to be derived from only the + XMP-exif GPS coordinate tags (and not other XMP GPS coordinates) + - Reverted a PNG Validation check that was removed from 11.60 + - Patched to avoid problems overriding new values when writing thumbnail and + preview images + +July 30, 2019 - Version 11.60 + + - Added a few new Sigma LensType values (thanks LibRaw) + - Updated Sony makernote decoding for the DSC-RX100M7 (thanks Jos Roost) + - Various internal improvements to PNG reader/writer + - Fixed bug in RIFF decoder that could cause an "undefined subroutine" error + (thanks Hayo Baan) + - Fixed problem writing some QuickTime tags if the PREFERRED levels were + changed via the config file + - Install Changes: + - Properly erase all temporary files after validation tests + +July 25, 2019 - Version 11.59 + + - Added a new SonyModelID (thanks LibRaw) + - Changed block delete to allow subsequent writing of tags from the same group + (like a group delete) + - Minor changes to warnings and verbose output when writing PNG images + - Fixed potential runtime warning on an error rewriting XMP in a PNG image + +July 25, 2019 - Version 11.58 + + - Added a number of new Canon and Sony LensType values (thanks LibRaw) + - Decode NikonMeteringMode for the D500 + - Decode LensID for Nikon Z lenses + - Extract RawThermalImage from Parrot Bebop-Pro Thermal images + - Validate PNG CRC values when writing or using the Validate option + - Improved Russian translation (thanks Andrei Korzhyts) + - Improved identification of some Tamron lenses for Canon cameras + - Changed name of D810MeteringMode tag to NikonMeteringMode + - Patched writing of XMP in PNG images to always come before IDAT, and warn if + XMP comes after IDAT when reading + - Fixed problem replacing multiple lang-alt default-language structure + elements in lists of XMP structures (behaviour for other languages still not + ideal) + - API Changes: + - Removed PNGEarlyXMP option + - Fixed problem introduced in 11.54 which caused Options('UserParam') to + return undef + - Internal Changes: + - A block delete of EXIF, XMP, IPTC, etc now sets the group delete flag + +July 19, 2019 - Version 11.57 + + - Improved decoding of some tags for the Sony ILCE-7RM4 (thanks Jos Roost) + - Minor change to a Sony lens name + - Fixed format of a number of 8-bit integer QuickTime tags when writing + - Fixed problem replacing multiple structure elements in lists of XMP + structures + +July 18, 2019 - Version 11.56 + + - Added support for the Sony ILCE-7RM4 (thanks Jos Roost) + - Added a new SonyModelID (thanks LibRaw) + - Added a few new Sony/Minolta LensType values (thanks LibRaw and Jos Roost) + - Decode some new Nikon and Motorola tags (thanks Neal Krawetz) + - Decode a couple more ColorData tags for some Canon models + - Extract PreviewImage from DNG files which don't have a .DNG extension + - Extract Huawei APP7 maker notes with the Unknown (-u) option + - Internal change in LensID logic for Sony E-type lenses + +July 12, 2019 - Version 11.55 + + - Added write support for XMP-crs:Texture and XMP-drs tags + - Added a number of new Panasonic NoiseReduction values + - Added definition for a new Kodak tag (thanks LibRaw) + - Added a couple of new Panasonic AFAreaMode values (thanks Daniel Beichl) + - Added a couple of new Sony/Minolta LensTypes (thanks Jos Roost and LibRaw) + - Added a new CanonModelID + - Decode HEVCConfiguration record from HEIC images + - Decode a new Panasonic tag + - Decode a new QuickTime tag + - Changed internal handling of Composite tag ID's to include module name + - Removed "FE" designation from Samyang E-mount lenses + - Dropped Validate warning about missing GPSProcessingMethod tag + +July 2, 2019 - Version 11.54 + + - Added new Canon and Sony/Minolta LensType values (thanks LibRaw) + - Added a number of new Sony/Minolta LensType values (thanks Jos Roost) + - Added "Unknown" value for new EXIF CompositeImage tag + - Added ability to write GSpherical tags in video track of MOV/MP4 files + - Added support for geotagging from GPS/IMU CSV-format files + - Improved Russian translation (thanks Alexander) + - Improved Validate feature to check ExifVersion/GPSVersionID numbers + - Accept unsigned numbers when setting GPSAltitudeRef from a numerical value + - Fixed decoding of DepthMapWidth/Height for some Samsung live-focus images + - Fixed a couple of incorrect/incomplete CanonModelID values (thanks LibRaw) + - Fixed problem identifying some Canon lenses when used on a Sony camera with + a Metabones adapter + - API Changes: + - Added FilterW option + - Enhanced Compact option to improve flexibility and include features of + XMPShorthand option + - Removed XMPShorthand option from documentation + +June 24, 2019 - Version 11.53 - "Exif 2.32" + + - Added support for the new tags of the Exif 2.32 specification + - Added a new SamsungModelID (thanks LibRaw) + - Added warning if extracting ZIP file contents without the -a option + - Added ability to extract EmbeddedVideo from the trailer of Android JPEG + images with the ExtractEmbedded option + - Decode timed GPS from Cobra Dash Cam AVI videos + - Decode a new GoPro tag + - Enhanced -struct option to allow extraction of structured Torrent Info + - Improved error handling when an unexpected terminator is encountered while + writing a QuickTime-format file + - Renamed one of the Nikon Saturation tags to "SaturationAdj" + - Removed warning message when writing FujiFilm RAFVersion 0240 and 0261 files + - Fixed encoding problem when writing some QuickTime UserData tags with + strings containing special characters + - API Changes: + - Enhanced XMPShorthand option to add level 2 + +June 17, 2019 - Version 11.52 + + - Added a few new Nikon CropHiSpeed values (thanks Hayo Baan) + - Added a new Nikon LensID (thanks Yves) + - Fixed problem where reading a large, corrupt AIFF file may could take an + excessively long time + - API Changes: + - Enhanced Compact option to add levels 3, 4 and 5 (github issue #16) + +June 13, 2019 - Version 11.51 + + - Decode Canon DistortionCorrection tags + - Removed a minor EXIF warning when processing EPS files with a DOS header + - Fixed bug which caused an error when rewriting some EPS files multiple times + +June 11, 2019 - Version 11.50 (production release) + + - Added a new Canon LensType and two new Sony LensTypes (thanks LibRaw) + - Added tiff_version and rotate_regions config files to the distribution + - Added two new QuickTime Keys tags and made some existing Keys unwritable + - Improved Composite LensID logic to make better use of EXIF LensModel + - Improved logic when writing BinaryData tags to allow multiple interdependent + tags to be written in a single command + - Improved -htmldump output to show names of Unknown tags + - Allow advanced formatting expressions to access the current tag key ($tag) + - Remove escaped nulls from -json string values + - Reverted change in ExifTool 11.38 so that Composite GPS reference directions + are generated again even if the EXIF versions of these tags already exist + - Fixed an incorrect FlashPix CodePage conversion + +June 5, 2019 - Version 11.49 + + - Added inverse print conversion for one of the QuickTime ItemList Genre tags + - Avoid creating a few obscure QuickTime UserData tags when writing + - Fixed problem where some QuickTime groups were not being created when + writing QuickTime tags without specifying a group + - Fixed problem where QuickTime Keys tags could be duplicated when writing an + existing alternate-language tag + - Fixed problem were QuickTime Keys alternate-language tags would not be + written when deleting the corresponding default-language tag in the same + command + - Fixed some inconsistencies when writing QuickTime tags using the -wm + (WriteMode) option + - Fixed an incorrect Pentax Sigma LensType value + +June 1, 2019 - Version 11.48 + + - Added write support for Google GCamera and GCreation XMP tags + - Renamed XMP-GDepth "Data" tag to "DepthImage" + - Fixed bug where some QuickTime UserData tags could be duplicated when + writing + +May 31, 2019 - Version 11.47 + + - Fixed problem which resulted in a warning for one of the CanonVRD tests on + some platforms + +May 31, 2019 - Version 11.46 - "CR3 update" + + - Added ability to write CanonVRD tags in CR3 images + - Decode a couple more tags from Canon CR3 images + - Enhanced Validate option to check for duplicate QuickTime atoms + - Relaxed constraints when writing IPTC date tags to allow use of separators + other than a colon + - Fixed CR3 writing to update CTBO table with any changed offsets or sizes + (although this table doesn't seem to be used by any RAW viewer, it may be + used in-camera to improve response time when browsing images) + +May 29, 2019 - Version 11.45 + + - CORRUPTION WARNING: Patched problem where Canon DPP would destroy a CR3 + image if the file had previously been edited by DPP then Exiftool + (If you have edited any CR3 images with ExifTool that had been previously + edited by DPP, then re-edit with ExifTool 11.45 or later to restructure the + file so DPP doesn't destroy it if used later to edit the file again) + - Added ability to create and delete QuickTime Keys tags + - Added sample config file (mini0806.config) to generate GPS tags from + subtitle Text in Mini 0806 dashcam videos + - Added new Canon and Nikon lenses (thanks LibRaw) + - Added a new Olympus CameraType (thanks LibRaw) + - Decode CanonVRD tags from CR3 images + - Improved handling of QuickTime language tags when writing + - Fixed bug introduced in 11.38 which could cause "Use of uninitialized value" + runtime warning when reading XMP GPS tags + - Fixed bug where QuickTime tags could be written when another group was + specified + - API Changes: + - Added QuickTimeHandler option + +May 21, 2019 - Version 11.44 + + - Added ability to extract XMP as a block from XMP files + - Prevent ExifIFD from being deleted from any RAW file type + - Fixed problem where some Canon tags couldn't be written in CR3 files + - Fixed problem reading QuickTime Keys tags with a space in the tag ID + - Fixed incorrect family 1 group when reading some QuickTime Keys tags + +May 17, 2019 - Version 11.43 - "Write HEIC and CR3" + + - Added ability to write/create EXIF and write ICC_Profile in HEIC images + - Added ability to write/create EXIF and write MakerNotes in CR3 images + (one might hope/expect EXIF to be stored in the same location for HEIC and + CR3 since they are both based on the QuickTime file format, but in fact they + couldn't be more different, and both are much more complicated than + necessary, which of course follows the seemingly established practice of + intentional obfuscation and zero standardization in video metadata) + - Added support for QuickTime ItemList:Author and Keys:DisplayName tags + - Prevent MakerNotes from being deleted from any RAW file type + - Fixed writing of XMP in HEIC files to conform with the HEIC specification + (obviously, Apple couldn't put this XMP in the same place as any other + QuickTime-based file format, because Apple is, after all, king of "Let's + reinvent the wheel!") + - Fixed problem where API WriteMode option wouldn't always prevent groups from + being created when group creation was disabled + +May 13, 2019 - Version 11.42 + + - Added ability to edit ThumbnailImage in Canon MOV videos + - Improved verbose hex dump for HEIC files + - Fixed another "Chunk offset outside movie data" error when writing some HEIC + files + +May 9, 2019 - Version 11.41 + + - Added write support and improved language handling for 3GP QuickTime tags + - Fixed format problems writing some binary values to QuickTime tags + - Fixed some language translations (thanks Herbert Kauer) + +May 7, 2019 - Version 11.40 + + - Added a new Canon LensType + - Added a new value for EXIF:SceneCaptureType used by some Samsung cameras + - Fixed QuickTime writing to preserve existing same-named default-language + tags in other groups when writing a default language tag + +May 3, 2019 - Version 11.39 - "Create QuickTime tags" + + - Added ability to create new QuickTime tags in MOV/MP4 videos + - Added two new Canon LensTypes and a new CanonModelID (thanks LibRaw) + - Added a few new Sony/Minolta LensType values (thanks Jos Roost) + - Added a number of new QuickTime GenreID values + - Added range check on date/time values when writing + - Decode Canon EOS D60 black levels + - Split off some QuickTime tags into different family 1 groups + - Fixed "Chunk offset outside movie data" error when writing some HEIC files + - Fixed decoding of Pentax AutoBracketing for K-1 and K-5 (github issue #15) + - Fixed some QuickTime family 2 group names + - Fixed bug introduced in 11.38 that broke extraction of thumbnail images from + Canon MOV videos + +Apr. 24, 2019 - Version 11.38 + + - Added Extra JPEGImageLength tag + - Added nksc.config to the sample config files + - Added a couple more Sony/Minolta LensTypes (thanks Jos Roost) + - Added a couple of new Sigma LensType values + - Decode a couple more tags from Pittasoft dashcam videos + - Decode two new FLIR tags (thanks Corinne Berthier) + - Decode a new ERF tag, and fix wrong format for some others (thanks LibRaw) + - Improved decoding of Sigma maker notes for some models + - Enhanced Composite tag logic to allow a scalar Inhibit entry + - Enhanced XMP processing to support readable subdirectories embedded in a tag + - Updated some language translations + - Patched Composite GPS reference direction tags to prevent them from being + created if these tags already exist + - Fixed problem reading some odd PDF files + +Apr. 17, 2019 - Version 11.37 + + - Added a new Sony AFAreaMode (thanks Jos Roost) + - Decode GPS and other tags from Pittasoft Blackvue dashcam videos + - Improved decoding of FujiFilm FlickerReduction + - Ignore any garbage before an NMEA sentence when geotagging + - Fixed bug which could result in loss of timed GPS metadata when writing MP4 + videos + +Apr. 15, 2019 - Version 11.36 + + - Added a number of new MacOS tags + - Added a new CanonModelID (thanks Laurent Clevy) + - Added some new Canon EasyMode and AFAreaMode values + - Added two new Canon AspectRatio values (thanks LibRaw) + - Decode a new Nikon tag (thanks LibRaw) + - Decode some new FujiFilm tags + - Updated Sony maker notes for the DSC-RX0M2 (thanks Jos Roost) + - Hide the Nikon ShotInfo offset tags + - Fixed problem decoding NikonCustom settings for some D810 firmware versions + - Fixed typo in a warning message (thanks Hayo Baan) + +Apr. 9, 2019 - Version 11.35 + + - Added print conversion for MDItemFSLabel + - Added a new Sony LensType (thanks Jos Roost) + - Added an additional -validate check for PNG images + - Decode a few more FujiFilm RAF tags (thanks LibRaw) + - Decode a couple more QuickTime tags + - Allow "Copy0" to be specified as a group name for the copy number of the + primary tag when extracting information + - Improved the Composite ImageSize tag to report the RawImageCroppedSize for + FujiFilm RAF images + - Changed Composite ImageSize tag to use a space instead of "x" as a separator + when the -n option is used + - Fixed problem writing user-defined PhaseOne SensorCalibration tags + - Fixed problem where a List-type tag may not be split into individual items + with the -sep option when using the advanced-formatting "@" feature + - API Changes: + - Patched a potential pitfall if calling code used both the old List and + ListSep options at the same time as the new ListJoin option + +Apr. 4, 2019 - Version 11.34 + + - Added a couple of new Canon LensType values (thanks LibRaw for one) + - Added a new CanonExposureMode value (thanks Arnold van Oostrum) + - Added support for FujiFilm X-H1 Ver2.01 RAF images + - Decode a couple of new Sony tags (thanks LibRaw) + - Improved decoding of Sony Shutter tag (thanks Jos Roost) + - Improved identification of some Sony lenses (thanks Jos Roost) + - Improved parsing of streamed metadata from TomTom Bandit videos + - Improved warning for truncated QuickTime atom + - Accept wider range of formats when writing QuickTime:GPSCoordinates + - API Changes: + - Changed SetFileName() 'Link' option name to 'HardLink' (but still allow + 'Link' for backward compatibility) + +Mar. 28, 2019 - Version 11.33 + + - Added write support for HEIC/HEIF files + - Added new write-only SymLink tag for creating symbolic links + - Made EXIF GDALMetadata and GDALNoData writable + - Enhanced writing capabilities for MOV/MP4 videos + - Enhanced -validate option to add more IPTC checks + - Updated decoding of Sony ILCE-9 maker notes for firmware version 5.00 + (thanks Jos Roost) + - Fixed problem reading streamed metadata from some TomTom Bandit videos + - API Changes: + - Added SymLink option to SetFileName() + +Mar. 14, 2019 - Version 11.32 + + - Added a new Nikon LensID (thanks Kenneth Cochran) + - Added a couple of new QuickTime HandlerType values + - Decode streamed metadata from DuDuBell M1 and VSYS M6L dashcam videos + - Attempt to improve Nikon lens identification + - API Changes: + - Added new single-argument version of ShiftTime() + +Mar. 7, 2019 - Version 11.31 + + - Added read support for FITS images + - Another try at removing spaces from some DICOM values (github issues #10/12) + +Mar. 6, 2019 - Version 11.30 (production release) + + - Added a new Sony/Minolta LensType (thanks Jos Roost) + - Decode streaming metadata from TomTom Bandit Action Cam MP4 videos + - Decode Reconyx HF2 PRO maker notes + - Decode ColorData for some new Canon models (thanks LibRaw) + - Enhanced -geotag feature to set AmbientTemperature if available + - Remove non-significant spaces from some DICOM values (github issues #10/12) + - Fixed possible "'x' outside of string" error when reading corrupted EXIF + - Fixed incorrect write group for GeoTIFF tags added in version 11.24 + +Feb. 28, 2019 - Version 11.29 + + - Added support for Ricoh GR III maker notes + - Added a new Canon LensType (thanks Claude Jolicoeur) + - Added a new XMP-crs tag (github issue #8) + - Enhanced -csv option to output base64-encoded binary data when combined with + -b or when the -charset option is used and the text has invalid characters + (github issue #11) + - Remove trailing space from even-length DICOM values (github issue #9) + - Patched to avoid "Hexadecimal number > 0xffffffff non-portable" warning + (github issue #6) + - Fixed meta charset attribute in -htmlDump output + +Feb. 21, 2019 - Version 11.28 + + - Added support for reading INSV video and decode streaming GPS + - Added a new Pentax LensType (thanks Louis Granboulan) + - Added a new FujiFilm ImageStabilization value + - Allow exiftool to be run via a symbolic link on Mac/Linux + - Reverted INDD patch of version 11.27 (ie. raise error again on incorrectly + terminated INDD object list) + - Changed handling of temporary documentation file in Windows version + +Feb. 14, 2019 - Version 11.27 + + - Added support for more XMP-dji-drone tags + - Added new Olympus CameraType and LensType values (thanks LibRaw) + - Added a new Canon LensType (thanks LibRaw) + - Added a new CanonModelID + - Decode yet another type of GPS from DashCam videos + - Allow FileName to be written when only case is changed on case-insensitive + filesystems + - Improved identification of some iWork file types + - Recognize the LRV file extension + - Changed Windows version to use the parent folder of PAR_GLOBAL_TEMP for the + temporary documentation file + - Don't raise an error if an INDD object list is terminated by spaces instead + of nulls + - Fixed some problems with new -htmldump IFD highlighting feature + - Fixed bug introduced in 11.24 with "-o -.EXT" feature + +Jan. 21, 2019 - Version 11.26 + + - Added a new Nikon LensID (thanks LibRaw) + - Decode more tags for the Sony ICLE-6400 (thanks Jos Roost and LibRaw) + - Enhanced -htmldump feature to highlight IFD when mousing over IFD offset + +Jan. 15, 2019 - Version 11.25 + + - Added a new Sony/Minolta LensType (thanks LibRaw) + - Added a new Nikon LensID + - Decode Leica D-Lux7 maker notes + - Decode more Nikon AF tags for newer models + - Decode Samsung Type2 maker notes with lower case Make + - Decode another Sony tag (thanks Jos Roost) + - Improved decoding of Nikon LensType + - Improved time shift feature to fix some incorrectly formatted date/time + values + - Renamed some Sony ImageCount tags to ShutterCount (thanks Jos Roost) + - Fixed problem reading back metadata written to some odd PDF files + +Jan. 8, 2019 - Version 11.24 + + - Compatibility Notice: Changed the meaning of '-' and '+' modifiers for %C + formatting code (does not affect lower-case %c code) + - Decode a number of new Nikon tags (thanks Michael Tapes for samples) + - Added new Olympus FlashType and FlashModel values (thanks Per) + - Added a new Canon LensType + - Added a new Nikon LensID + - Made more GeoTIFF tags writable + - Handle XMP rdf:value when reading + - Improved warning when trying to read a file with a zero-length name + - Fixed decoding of PictureControl tags for Nikon Z-7 + - Fixed problem writing date/time values with " DST" designator at end of + date/time string + - Fixed problem in Windows which could cause ExifTool to abort due to a + Win32::FindFile error if a file name contained surrogate Unicode characters + +Dec. 21, 2018 - Version 11.23 + + - Recognize DWG and DWF files + - Minor improvement to some -validate warnings + - Tolerate leading UTF-8 byte order mark (BOM) at start of JSON files + - Fixed problem recognizing some streaming camm metadata in QuickTime videos + +Dec. 13, 2018 - Version 11.22 + + - Added read support for PC Paintbrush (PCX) files + - Added two new Sony/Minolta LensTypes (thanks Jos Roost and LibRaw) + - Decode LensData tags for some newer Nikon models + - Decode ColorData for the Canon EOS R (thanks LibRaw) + - Recognize DCX files + +Dec. 7, 2018 - Version 11.21 + + - Added a new Sony/Minolta LensType (thanks Jos Roost) + - Added a new Olympus FlashModel (thanks Michael Meissner) + - Improved decoding of FujiFilm InternalSerialNumber (thanks LibRaw) + - Minor improvements to decoding of GPS from some dashcam videos + - Made XMP-getty:Personality a List-type tag + - Made it an error to use the -o option or write FileName or Directory tags + when using the TestName dry-run feature + - Fixed problem using -E with other character sets when writing + +Nov. 20, 2018 - Version 11.20 + + - Added a new Panasonic WhiteBalance value + - Added a new Nikon LensID (thanks LibRaw) + - Decode streaming GPS from MOV videos for another dashcam model + - Improved -E option to support character sets other than UTF-8 + +Nov. 14, 2018 - Version 11.19 + + - Added -fast4 option + - Enhanced -if option to allow arbitrary Perl expressions instead of just + logic expressions + - API Changes: + - Enhanced FastScan option to add a setting of 4 + +Nov. 12, 2018 - Version 11.18 + + - Decode a new Nikon tag (thanks Richard Butler) + - Decode a new FujiFilm tag + - Updated decoding of Sony maker notes for newer models (thanks Jos Roost) + - Enhanced -if option to allow fast processing pass to evaluate the condition + - Improved warning for unknown JPEG APP segment + +Nov. 4, 2018 - Version 11.17 + + - Added a new Canon LensType (thanks Norbert Wasser) + - Added a new Sony/Minolta LensType and a new SonyModelID (thanks LibRaw) + - Decode GPS from Garmin Dashcam videos + - Changed type of J2C files from a JPEG 2000 image to a JPEG 2000 codestream + Oct. 26, 2018 - Version 11.16 - Decode FLIR GPS information @@ -392,7 +1244,7 @@ Feb. 22, 2018 - Version 10.80 (production release) Feb. 11, 2018 - Version 10.79 - Added a new Olympus CameraType (thanks LibRaw) - - Added a new XMP-microsoft tag (thanks José Oliver-Didier) + - Added a new XMP-microsoft tag (thanks Jose Oliver-Didier) - Decode a new GoPro QuickTime tag - Convert nulls IPTC:DocumentHistory to newlines - Removed all null terminators from JSON and PHP output @@ -741,7 +1593,7 @@ Apr. 10, 2017 - Version 10.49 - Decode a new Panasonic tag - Fixed problem decoding Sony VariableLowPassFilter values (thanks Jos Roost) - Fixed problem setting XMP:About when creating new XMP in a file - - Fixed an incorect Pentax DriveMode value (thanks Andras Salamon) + - Fixed an incorrect Pentax DriveMode value (thanks Andras Salamon) - API Changes - Allow access to the advanced formatting expression via a new ExifTool "FMT_EXPR" member variable @@ -983,16 +1835,16 @@ Oct. 5, 2016 - Version 10.29 (ie. the date/time is not converted) unless the API StrictDate option is set in which case a warning is issued and the tag is not written -Sept. 27, 2016 - Version 10.28 - "EXIF 2.31" +Sept. 27, 2016 - Version 10.28 - "Exif 2.31" - - Added support for new EXIF 2.31 tags + - Added support for new Exif 2.31 tags - Added some new Canon LensType values (thanks Norbert Wasser for one) - Added a new Olympus LensType (thanks LibRaw and Niels Kristian Bech Jensen) - Added a new Sony LensType and SonyModelID (thanks Jos Roost) - Added a new Pentax LensType - Added fotoware.config and bibble.config files to the distribution - Made Composite SubSecDateTimeOriginal, SubSecCreateDate and SubSecModifyDate - tags writable, and expanded to include new EXIF 2.31 time zone tags + tags writable, and expanded to include new Exif 2.31 time zone tags - Fixed problem writing user-defined structured tag elements with a dot (.) in their tag ID @@ -1260,7 +2112,7 @@ Jan. 4, 2016 - Version 10.09 - Added ability to extract OS X system metadata ("MDItem" tags) - Added a value conversion for GoogleTrackDuration - - Enchanced the -i option to allow full path names to be specified + - Enhanced the -i option to allow full path names to be specified - Fixed a potential runtime error when writing corrupted JPEG images - API Changes: - Added MDItemTags option @@ -2579,7 +3431,7 @@ Jan. 18, 2013 - Version 9.14 - Decode new Canon 6D CustomFunctions - Improved calculation of ScaleFactor35efl for Canon cameras - Changed priority of PDF Info tags so tags from most recent Info dictionary - take precedence (to partially accomodate the questionable Acrobat Pro + take precedence (to partially accommodate the questionable Acrobat Pro incremental update technique) - Changed some verbose warnings when attempting to write "unsafe" tags - Changed behaviour so that "unsafe" tags are not copied for any tag specified @@ -2925,7 +3777,7 @@ Apr. 3, 2012 - Version 8.86 - Decode some new CanonVRD DLO tags - Changed decoding of CanonVRD VRDVersion tag - Changed formatting of a Pentax LensType for consistency with other lenses - - Patched decoding of Reconyx:DateTimeOriginal to accomodate values written + - Patched decoding of Reconyx:DateTimeOriginal to accommodate values written with an incorrect byte order by some models Mar. 25, 2012 - Version 8.85 (production release) @@ -3493,7 +4345,7 @@ Jan. 29, 2011 - Version 8.47 Jan. 22, 2011 - Version 8.46 - - Simpified definition of user-defined XMP structures: flattened tags are now + - Simplified definition of user-defined XMP structures: flattened tags are now automatically generated, and UserDefined::xmpStruct is no longer needed (but backward compatibility is maintained with the old-style definitions) - Added ability to handle multi-dimensional arrays in structured output @@ -3873,7 +4725,7 @@ June 2, 2010 - Version 8.21 - Updated default GPSVersionID to 2.3.0.0 when writing - Fixed bug geotagging from KML file (lat/long were swapped) -May 26, 2010 - Version 8.20 +May 26, 2010 - Version 8.20 - "Exif 2.3" - Added read support for Open Document files (ODP, ODS, ODT) - Added Composite:AudioBitrate tag for VBR MPEG audio @@ -4516,7 +5368,7 @@ June 7, 2009 - Version 7.77 - Decode large preview in APP2 of images from newer Samsung models - Extract FujiFilm PreviewImage from improperly written FPXR segment - Improved decoding of Nikon WB levels for some models - - Reduced memory useage when writing DNG and some other RAW image files + - Reduced memory usage when writing DNG and some other RAW image files - Changed format of Canon D30 SerialNumber to remove the hyphen and add leading 0's if less than 9 characters (now same format as printed on camera) - Changed writing of GPSTimeStamp and GPSDateStamp to adjust date/time to UTC @@ -5179,7 +6031,7 @@ May 28, 2008 - Version 7.29 - Renamed Pentax ModelRevision tag to ProductionCode and improved print conversion to indicate if camera has been serviced - Added check to prevent EXIF tags from being written to JPEG images if they - would obviously exceed the maximimum JPEG segment size limit + would obviously exceed the maximum JPEG segment size limit - Relaxed error checks when writing JPEG images to allow MakerNotes to be rebuilt if the MakerNote IFD is not contained within the MakerNotes data - Fixed decoding of Pentax ExternalFlashGuideNumber when AF360 is used with @@ -5925,7 +6777,7 @@ Feb. 20, 2007 - Version 6.77 - "XML/HTML special characters" - Translate all non-ASCII characters to HTML character entities with -h or -E - Added full UTF-8 translation support when run with Perl pre-5.6.1 - Decode a few new Sigma SD14 tags - - Decode a couple more Nikon tags + - Decode a couple more Nikon tags (thanks Greg Troxel) Feb. 16, 2007 - Version 6.76 (production release) @@ -6313,7 +7165,7 @@ Sept. 21, 2006 - Version 6.42 (production release) Sept. 18, 2006 - Version 6.41 - Fixed calculation of Canon ISO in some images and renamed ShotISO to BaseISO - - Minor improvment to order of operations when deleting multiple groups and + - Minor improvement to order of operations when deleting multiple groups and adding back information in batch mode Sept. 14, 2006 - Version 6.40 @@ -6438,7 +7290,7 @@ June 19, 2006 - Version 6.25 - Added read/write support for WDP (Windows Media Photo) images - Improved algorithm to recognize maker notes offsets which need fixing - Properly handle maker notes which have value offsets relative to the - individial IFD entries (Kyocera, Rollei and some Konica and Toshiba models) + individual IFD entries (Kyocera, Rollei and some Konica and Toshiba models) - Decode a couple of new Sigma lens values in Canon LensType - Decreased block size for buffered files to improve performance over slow pipes @@ -6479,7 +7331,8 @@ May 24, 2006 - Version 6.20 - Fixed bug where IgnoreMinorErrors option could get set when writing images with NikonCapture information - Fixed two ID3 tag names which contained spaces - - Fixed problem parsing DateTimeOriginal in Casio EX-Z30 AVI files + - Fixed problem parsing DateTimeOriginal in Casio EX-Z30 AVI files (thanks + Joachim Loehr) - Fixed problem with apostrophes in HTML documentation for some browsers - API Changes: - Can now call Options() with undefined value to set option value to undef @@ -6695,7 +7548,7 @@ Feb. 1, 2006 - Version 5.99 - Added Canon maker note footer when rewriting Canon maker notes - Attempt to fix problem where ScaleFactor35efl was calculated incorrectly for some Canon images - - Reduce memory useage and speed up writing of large TIFF images + - Reduce memory usage and speed up writing of large TIFF images - Fixed problem with binary data offsets in verbose dump - Fixed problem writing Comment if 'File' group specified - Fixed bug which could cause formatting error in htmlDump output @@ -6921,7 +7774,7 @@ Oct. 24, 2005 - Version 5.71 Oct. 23, 2005 - Version 5.70 - - Significant internal changes to improve speed and reduce memory useage + - Significant internal changes to improve speed and reduce memory usage - Fixed a bug introduced in version 5.63 which caused incorrect XMP GPS coordinates to be returned - Changed handling of Kodak date records @@ -6975,7 +7828,7 @@ Oct. 7, 2005 - Version 5.65 - Decode a few more Photoshop tags - Issue an error if there is extra data after the normal end of file when rewriting TIFF images (avoids possible data loss if attempting to write an - unsuported RAW image with a TIFF-like data structure) + unsupported RAW image with a TIFF-like data structure) - Added ability to replace existing tags with user defined tags - Denote minor errors/warnings by adding '[minor]' to the message (these are the errors which can be ignored with the -m option) @@ -7451,7 +8304,7 @@ Apr. 2, 2005 - Version 4.93 (production release) Mar. 31, 2005 - Version 4.92 - Added support for Kodak and Ricoh cameras - - Decode still more Olympus E-1/E-300 tags + - Decode still more Olympus E-1/E-300 tags (thanks Markku Hanninen) - Added 'Directory' tag - Decode a few more Pentax tags (thanks to John Francis) - Allow newlines in tag values on command line when writing @@ -7459,13 +8312,13 @@ Mar. 31, 2005 - Version 4.92 Mar. 28, 2005 - Version 4.91 - - Decode yet more Olympus E-1/E-300 tags + - Decode yet more Olympus E-1/E-300 tags (thanks Markku Hanninen) - Changed decoding of Olympus E-300 Quality tag - Patched bug in Olympus maker notes that was causing ExifTool to report an error when reading ORF files - Fixed problem where strings weren't being properly truncated at the null terminator if there was a newline after the terminator - - Improved decoding for some Nikon tags (credit Tom Christiansen) + - Improved decoding for some Nikon tags (thanks Tom Christiansen) - Added Nikon shortcut - Added composite SubSecDateTimeOriginal tag - Fixed problem where CRW file without file extension wasn't being identified @@ -7682,7 +8535,7 @@ Jan. 28, 2005 - Version 4.42 specific IPTC tag values with 'TAG-=VALUE' - Made EXIF SceneType writable - Renamed Nikon ISOUsed tag to ISO - - Added documention of Canon RAW (CRW) file format + - Added documentation of Canon RAW (CRW) file format Jan. 27, 2005 - Version 4.41 @@ -7873,7 +8726,7 @@ Jan. 7, 2005 - Version 4.10 Dec. 15, 2004 - Version 4.05 - - Added a couple of Nikon tags + - Added a couple of Nikon tags (thanks Brian Ristuccia) - Now preserves original file by renaming to "NAME_original" when writing information - Don't preserve file time by default when writing. Added -P option to do @@ -7891,7 +8744,7 @@ Dec. 6, 2004 - Version 4.03 - Major overhaul of verbose message output - Change -v option to allow verbose level to be specified (eg. -v3 = very very verbose) - - Added a new Nikon tag (SceneMode) + - Added a new Nikon tag (thanks Thomas Walter) - Count images which were unchanged when writing tags - Changed FileType 'JPG' to 'JPEG' @@ -8121,7 +8974,7 @@ Apr. 6, 2004 - Version 3.37 Apr. 6, 2004 - Version 3.36 - Added support for Sanyo and Minolta maker notes - - Added skeleton for interpeting Sony maker notes + - Added skeleton for interpreting Sony maker notes - Interpret Pentax PrintIM Apr. 6, 2004 - Version 3.35 @@ -8165,7 +9018,7 @@ Mar. 26, 2004 - Version 3.27 - Optimized a few routines to speed things up a bit - API Changes: - - Changed GetDescription() documention to indicate it is called with an + - Changed GetDescription() documentation to indicate it is called with an ExifTool object (this is still optional, but will be mandatory with the next version) @@ -8292,7 +9145,7 @@ Feb. 17, 2004 - Version 3.03 - Fixed RandomAccessFile package name (should have been File::RandomAccessFile) - - Added IxusAFPoint tag to Canon maker notes + - Added IxusAFPoint tag to Canon maker notes (thanks Michael Rommel) - Avoid scanning past end of Canon binary data blocks - API Changes: - GetFoundTags() and GetRequestedTags() now return list instead of list @@ -8349,7 +9202,7 @@ Feb. 11, 2004 - Version 2.70 Feb. 10, 2004 - Version 2.62 - Added -u option to allow display of unknown tags - - Major changes to Pentax maker notes (still needs work) + - Major changes to Pentax maker notes (still needs work) (thanks Wayne Smith) Feb. 09, 2004 - Version 2.61 @@ -8379,7 +9232,7 @@ Jan. 30, 2004 - Version 2.51 Jan. 29, 2004 - Version 2.50 - Changed API to return binary data as SCALAR reference and - list of values as ARRAY reference + list of values as ARRAY reference (thanks Dan Heller for the suggestions) - Attempt to make case of tag descriptions more consistent Jan. 28, 2004 - Version 2.41 @@ -8428,7 +9281,8 @@ Jan. 6, 2004 - Version 2.25 - Fixed problem with ImageInfo() function prototype - Fixed printout of JpgFromRaw message (doesn't affect JPG extraction) - - Set output files to binmode (including STDOUT) if -b option used + - Set output files to binmode (including STDOUT) if -b option used (thanks + David Anson) Jan. 1, 2004 - Version 2.24 @@ -8506,7 +9360,7 @@ Nov. 26, 2003 - Version 1.40 Nov. 25, 2003 - Version 1.30 - - Added experimental Canon RAW (CRW) file support + - Added experimental Canon RAW (CRW) file support Nov. 22, 2003 - Version 1.20 diff --git a/src/Image-ExifTool/README b/src/Image-ExifTool/README index 61524fe9..d1e50f87 100644 --- a/src/Image-ExifTool/README +++ b/src/Image-ExifTool/README @@ -1,4 +1,4 @@ -ExifTool by Phil Harvey (phil at owl.phy.queensu.ca) +ExifTool by Phil Harvey (philharvey66 at gmail.com) ---------------------------------------------------------------------------- ExifTool is a customizable set of Perl modules plus a full-featured @@ -14,44 +14,46 @@ supported by ExifTool (r = read, w = write, c = create): File Types ------------+-------------+-------------+-------------+------------ - 3FR r | DR4 r/w/c | J2C r | ODP r | RAW r/w - 3G2 r/w | DSS r | JNG r/w | ODS r | RIFF r - 3GP r/w | DV r | JP2 r/w | ODT r | RSRC r - A r | DVB r/w | JPEG r/w | OFR r | RTF r - AA r | DVR-MS r | JSON r | OGG r | RW2 r/w - AAE r | DYLIB r | K25 r | OGV r | RWL r/w - AAX r/w | EIP r | KDC r | OPUS r | RWZ r - ACR r | EPS r/w | KEY r | ORF r/w | RM r - AFM r | EPUB r | LA r | OTF r | SEQ r - AI r/w | ERF r/w | LFP r | PAC r | SKETCH r - AIFF r | EXE r | LNK r | PAGES r | SO r - APE r | EXIF r/w/c | M2TS r | PBM r/w | SR2 r/w - ARQ r/w | EXR r | M4A/V r/w | PCD r | SRF r - ARW r/w | EXV r/w/c | MAX r | PDB r | SRW r/w - ASF r | F4A/V r/w | MEF r/w | PDF r/w | SVG r - AVI r | FFF r/w | MIE r/w/c | PEF r/w | SWF r - AZW r | FLA r | MIFF r | PFA r | THM r/w - BMP r | FLAC r | MKA r | PFB r | TIFF r/w - BPG r | FLIF r/w | MKS r | PFM r | TORRENT r - BTF r | FLV r | MKV r | PGF r | TTC r - CHM r | FPF r | MNG r/w | PGM r/w | TTF r - COS r | FPX r | MOBI r | PLIST r | VCF r - CR2 r/w | GIF r/w | MODD r | PICT r | VRD r/w/c - CR3 r/w | GPR r/w | MOI r | PMP r | VSD r - CRM r/w | GZ r | MOS r/w | PNG r/w | WAV r - CRW r/w | HDP r/w | MOV r/w | PPM r/w | WDP r/w - CS1 r/w | HDR r | MP3 r | PPT r | WEBP r - DCM r | HEIC r | MP4 r/w | PPTX r | WEBM r - DCP r/w | HEIF r | MPC r | PS r/w | WMA r - DCR r | HTML r | MPG r | PSB r/w | WMV r - DFONT r | ICC r/w/c | MPO r/w | PSD r/w | WTV r - DIVX r | ICS r | MQV r/w | PSP r | WV r - DJVU r | IDML r | MRW r/w | QTIF r/w | X3F r/w - DLL r | IIQ r/w | MXF r | R3D r | XCF r - DNG r/w | IND r/w | NEF r/w | RA r | XLS r - DOC r | INX r | NRW r/w | RAF r/w | XLSX r - DOCX r | ISO r | NUMBERS r | RAM r | XMP r/w/c - DPX r | ITC r | O r | RAR r | ZIP r + 3FR r | DR4 r/w/c | ITC r | ODP r | RIFF r + 3G2 r/w | DSS r | J2C r | ODS r | RSRC r + 3GP r/w | DV r | JNG r/w | ODT r | RTF r + A r | DVB r/w | JP2 r/w | OFR r | RW2 r/w + AA r | DVR-MS r | JPEG r/w | OGG r | RWL r/w + AAE r | DYLIB r | JSON r | OGV r | RWZ r + AAX r/w | EIP r | K25 r | OPUS r | RM r + ACR r | EPS r/w | KDC r | ORF r/w | SEQ r + AFM r | EPUB r | KEY r | OTF r | SKETCH r + AI r/w | ERF r/w | LA r | PAC r | SO r + AIFF r | EXE r | LFP r | PAGES r | SR2 r/w + APE r | EXIF r/w/c | LNK r | PBM r/w | SRF r + ARQ r/w | EXR r | LRV r/w | PCD r | SRW r/w + ARW r/w | EXV r/w/c | M2TS r | PCX r | SVG r + ASF r | F4A/V r/w | M4A/V r/w | PDB r | SWF r + AVI r | FFF r/w | MAX r | PDF r/w | THM r/w + AVIF r/w | FITS r | MEF r/w | PEF r/w | TIFF r/w + AZW r | FLA r | MIE r/w/c | PFA r | TORRENT r + BMP r | FLAC r | MIFF r | PFB r | TTC r + BPG r | FLIF r/w | MKA r | PFM r | TTF r + BTF r | FLV r | MKS r | PGF r | TXT r + CHM r | FPF r | MKV r | PGM r/w | VCF r + COS r | FPX r | MNG r/w | PLIST r | VRD r/w/c + CR2 r/w | GIF r/w | MOBI r | PICT r | VSD r + CR3 r/w | GPR r/w | MODD r | PMP r | WAV r + CRM r/w | GZ r | MOI r | PNG r/w | WDP r/w + CRW r/w | HDP r/w | MOS r/w | PPM r/w | WEBP r + CS1 r/w | HDR r | MOV r/w | PPT r | WEBM r + CSV r | HEIC r/w | MP3 r | PPTX r | WMA r + DCM r | HEIF r/w | MP4 r/w | PS r/w | WMV r + DCP r/w | HTML r | MPC r | PSB r/w | WTV r + DCR r | ICC r/w/c | MPG r | PSD r/w | WV r + DFONT r | ICS r | MPO r/w | PSP r | X3F r/w + DIVX r | IDML r | MQV r/w | QTIF r/w | XCF r + DJVU r | IIQ r/w | MRW r/w | R3D r | XLS r + DLL r | IND r/w | MXF r | RA r | XLSX r + DNG r/w | INSP r/w | NEF r/w | RAF r/w | XMP r/w/c + DOC r | INSV r | NRW r/w | RAM r | ZIP r + DOCX r | INX r | NUMBERS r | RAR r | + DPX r | ISO r | O r | RAW r/w | Meta Information ----------------------+----------------------+--------------------- @@ -75,7 +77,7 @@ See html/index.html for more details about ExifTool features. ExifTool can be downloaded from - http://owl.phy.queensu.ca/~phil/exiftool/ + https://exiftool.org/ RUNNING @@ -103,8 +105,8 @@ your home directory, then you would type the following commands in a terminal window to extract and run ExifTool: cd ~/Desktop - gzip -dc Image-ExifTool-11.16.tar.gz | tar -xf - - cd Image-ExifTool-11.16 + gzip -dc Image-ExifTool-11.92.tar.gz | tar -xf - + cd Image-ExifTool-11.92 ./exiftool t/images/ExifTool.jpg Note: These commands extract meta information from one of the test images. @@ -158,7 +160,7 @@ for calculating digest values and providing other features listed below: COPYRIGHT AND LICENSE -Copyright 2003-2018, Phil Harvey +Copyright 2003-2020, Phil Harvey This is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -187,21 +189,27 @@ distribution package: xmp2iptc.args - Arguments for converting XMP to IPTC xmp2pdf.args - Arguments for converting XMP to PDF config_files/ - Sample ExifTool configuration files: + acdsee.config - Definitions for writing ACDSee XMP regions age.config - Calculate Age of person in photo bibble.config - Definitions for writing Bibble XMP tags - convert_regions.config - Convert between MWG and MP face regions - dji.config - Composite tags for metadata in DJI videos + convert_regions.config - Convert between MWG, MP and IPTC regions + depthmap.config - Extract Google DepthMap images example.config - General example showing config features fotoware.config - Definitions for writing Fotoware XMP tags gps2utm.config - Generate UTM coordinate tags from GPS info + gpsdatetime.config - Make GPSDateTime from CreateDate+SampleTime + nksc.config - Decode tags in Nikon ViewNX NKSC files photoshop_paths.config - For extracting or copying Photoshop paths picasa_faces.config - Convert from Picasa to MWG/MP face regions - time_zone.config - Calcuate time zone from EXIF tags + rotate_regions.config - Rotate MWG and MP region tags + tiff_version.config - Determine the version of a TIFF file + time_zone.config - Calculate time zone from EXIF tags exiftool - The exiftool application (Perl script) fmt_files/ - Output formatting example files: gpx.fmt - Format file for creating GPX track gpx_wpt.fmt - Format file for creating GPX waypoints - kml.fmt - Format file for creating KML output files + kml.fmt - Format file for creating KML placemarks + kml_track.fmt - Format file for creating KML track html/ - HTML documentation html/TagNames/ - HTML tag name documentation lib/ - ExifTool Perl library modules diff --git a/src/Image-ExifTool/exiftool b/src/Image-ExifTool/exiftool index 3039cc61..5b08108b 100755 --- a/src/Image-ExifTool/exiftool +++ b/src/Image-ExifTool/exiftool @@ -6,21 +6,28 @@ # # Revisions: Nov. 12/03 - P. Harvey Created # (See html/history.html for revision history) -# -# References: ATV - Alexander Vonk, private communication #------------------------------------------------------------------------------ use strict; require 5.004; -my $version = '11.16'; +my $version = '11.92'; # add our 'lib' directory to the include list BEFORE 'use Image::ExifTool' my $exeDir; BEGIN { + # (undocumented -xpath option added in 11.91, must come before other options) + $Image::ExifTool::exePath = @ARGV && lc($ARGV[0]) eq '-xpath' && shift() ? $^X : $0; # get exe directory - $exeDir = ($0 =~ /(.*)[\\\/]/) ? $1 : '.'; + $exeDir = ($Image::ExifTool::exePath =~ /(.*)[\\\/]/) ? $1 : '.'; + if (-l $0) { + my $lnk = eval { readlink $0 }; + if (defined $lnk) { + my $lnkDir = ($lnk =~ /(.*)[\\\/]/) ? $1 : '.'; + $exeDir = (($lnk =~ m(^/)) ? '' : $exeDir . '/') . $lnkDir; + } + } # add lib directory at start of include path - unshift @INC, "$exeDir/lib"; + unshift @INC, ($0 =~ /(.*)[\\\/]/) ? "$1/lib" : './lib'; # load or disable config file if specified if (@ARGV and lc($ARGV[0]) eq '-config') { shift; @@ -35,7 +42,7 @@ sub SigCont(); sub Cleanup(); sub GetImageInfo($$); sub SetImageInfo($$$); -sub DoHardLink($$$$); +sub DoHardLink($$$$$); sub CleanXML($); sub EncodeXML($); sub FormatXML($$$); @@ -60,7 +67,7 @@ sub MyConvertFileName($$); sub SuggestedExtension($$$); sub LoadPrintFormat($); sub FilenameSPrintf($;$@); -sub NextUnusedFilename($;$$); +sub NextUnusedFilename($;$); sub CreateDirectory($); sub OpenOutputFile($;@); sub AcceptFile($); @@ -78,6 +85,7 @@ END { # declare all static file-scope variables my @commonArgs; # arguments common to all commands +my @condition; # conditional processing of files my @csvFiles; # list of files when reading with CSV option (in ExifTool Charset) my @csvTags; # order of tags for first file with CSV option (lower case) my @delFiles; # list of files to delete @@ -91,6 +99,7 @@ my @requestTags; # tags to request (for -p or -if option arguments) my @srcFmt; # source file name format strings my @tags; # list of tags to extract my %appended; # list of files appended to +my %countLink; # count hard and symbolic links made my %created; # list of files we created my %csvTags; # lookup for all found tags with CSV option (lower case keys) my %database; # lookup for database information based on file name (in ExifTool Charset) @@ -105,24 +114,22 @@ my %utf8FileName; # lookup for file names that are UTF-8 encoded my %warnedOnce; # lookup for once-only warnings my %wext; # -W extensions to write my $allGroup; # show group name for all tags +my $altEnc; # alternate character encoding if not UTF-8 my $argFormat; # use exiftool argument-format output my $binaryOutput; # flag for binary output (undef or 1, or 0 for binary XML/PHP) my $binaryStdout; # flag set if we output binary to stdout my $binSep; # separator used for list items in binary output my $binTerm; # terminator used for binary output my $comma; # flag set if we need a comma in JSON output -my $condition; # conditional processing of files my $count; # count of files scanned when reading or deleting originals my $countBad; # count of files with errors my $countBadCr; # count files not created due to errors -my $countBadLink; # count bad links my $countBadWr; # count write errors my $countCopyWr; # count of files copied without being changed my $countDir; # count of directories scanned my $countFailed; # count files that failed condition my $countGoodCr; # count files created OK my $countGoodWr; # count files written OK -my $countLink; # count number of links created my $countNewDir; # count of directories created my $countSameWr; # count files written OK but not changed my $critical; # flag for critical operations (disable CTRL-C) @@ -133,10 +140,12 @@ my $deleteOrig; # 0=restore original files, 1=delete originals, 2=delete w/o my $disableOutput; # flag to disable normal output my $doSetFileName; # flag set if FileName may be written my $doUnzip; # flag to extract info from .gz and .bz2 files +my $escapeC; # C-style escape my $escapeHTML; # flag to escape printed values for html my $evalWarning; # warning from eval my $executeID; # -execute ID number my $failCondition; # flag to fail -if condition +my $fastCondition; # flag for fast -if condition my $fileHeader; # header to print to output file (or console, once) my $fileTrailer; # trailer for output file my $filtered; # flag indicating file was filtered by name @@ -172,7 +181,9 @@ my $saveCount; # count the number of times we will/did call SaveNewValues() my $scanWritable; # flag to process only writable file types my $sectHeader; # current section header for -p option my $sectTrailer; # section trailer for -p option +my $seqFileBase; # sequential file number at start of directory my $seqFileNum; # sequential file number used for %C +my $setCharset; # character set setting ('default' if not set and -csv -b used) my $showGroup; # number of group to show (may be zero or '') my $showTagID; # non-zero to show tag ID's my $stayOpenBuff='';# buffer for -stay_open file @@ -184,11 +195,11 @@ my $textOut; # extension for text output file (or undef for no output) my $textOverwrite; # flag to overwrite existing text output file (2=append, 3=over+append) my $tmpFile; # temporary file to delete on exit my $tmpText; # temporary text file -my $utf8; # flag set if we are using UTF-8 encoding my $validFile; # flag indicating we processed a valid file my $verbose; # verbose setting my $vout; # verbose output file reference (\*STDOUT or \*STDERR) my $windowTitle; # title for console window +my $isBinary; # true if value is a SCALAR ref my $xml; # flag for XML-formatted output # flag to keep the input -@ argfile open: @@ -211,6 +222,11 @@ my $isCRLF = { MSWin32 => 1, os2 => 1, dos => 1 }->{$^O}; # lookup for JSON characters that we escape specially my %jsonChar = ( '"'=>'"', '\\'=>'\\', "\t"=>'t', "\n"=>'n', "\r"=>'r' ); +# lookup for C-style escape sequences +my %escC = ( "\n" => '\n', "\r" => '\r', "\t" => '\t', '\\' => '\\\\'); +my %unescC = ( a => "\a", b => "\b", f => "\f", n => "\n", r => "\r", + t => "\t", 0 => "\0", '\\' => '\\' ); + # options requiring additional arguments # (used only to skip over these arguments when reading -stay_open ARGFILE) # (arg is converted to lower case then tested again unless an entry was found with the same case) @@ -230,7 +246,7 @@ my %optArgs = ( '-geotag' => 1, '-globaltimeshift' => 1, '-i' => 1, '-ignore' => 1, - '-if' => 1, + '-if' => 1, '-if0' => 1, '-if1' => 1, '-if2' => 1, '-if3' => 1, '-if4' => 1, '-lang' => 0, # (optional arg; cannot begin with "-") '-listitem' => 1, '-o' => 1, '-out' => 1, @@ -379,6 +395,7 @@ if ($stayOpen >= 2) { # initialize necessary static file-scope variables # (not done: @commonArgs, @moreArgs, $critical, $binaryStdout, $helped, # $interrupted, $mt, $pause, $rtnValApp, $rtnValPrev, $stayOpen, $stayOpenBuff, $stayOpenFile) +undef @condition; undef @csvFiles; undef @csvTags; undef @delFiles; @@ -391,6 +408,7 @@ undef @newValues; undef @srcFmt; undef @tags; undef %appended; +undef %countLink; undef %created; undef %csvTags; undef %database; @@ -405,12 +423,12 @@ undef %utf8FileName; undef %warnedOnce; undef %wext; undef $allGroup; +undef $altEnc; undef $argFormat; undef $binaryOutput; undef $binSep; undef $binTerm; undef $comma; -undef $condition; undef $csv; undef $csvAdd; undef $deleteOrig; @@ -418,9 +436,11 @@ undef $disableOutput; undef $doSetFileName; undef $doUnzip; undef $escapeHTML; +undef $escapeC; undef $evalWarning; undef $executeID; undef $failCondition; +undef $fastCondition; undef $fileHeader; undef $filtered; undef $fixLen; @@ -437,6 +457,7 @@ undef $progressMax; undef $recurse; undef $scanWritable; undef $sectHeader; +undef $setCharset; undef $showGroup; undef $showTagID; undef $structOpt; @@ -452,14 +473,12 @@ undef $windowTitle; $count = 0; $countBad = 0; $countBadCr = 0; -$countBadLink = 0; $countBadWr = 0; $countCopyWr = 0; $countDir = 0; $countFailed = 0; $countGoodCr = 0; $countGoodWr = 0; -$countLink = 0; $countNewDir = 0; $countSameWr = 0; $csvSaveCount = 0; @@ -476,18 +495,18 @@ $quiet = 0; $rtnVal = 0; $saveCount = 0; $sectTrailer = ''; +$seqFileBase = 0; $seqFileNum = 0; $tabFormat = 0; -$utf8 = 1; $vout = \*STDOUT; $xml = 0; # define local variables used only in this command loop my @fileOrder; # tags to use for ordering of input files -my %excludeGrp; # hash of tags excluded by group +my $fileOrderFast; # -fast level for -fileOrder option my $addGeotime; # automatically added geotime argument -my $allInGroup; # flag to show all tags in a group my $doGlob; # flag set to do filename wildcard expansion +my $endOfOpts; # flag set if "--" option encountered my $escapeXML; # flag to escape printed values for xml my $setTagsFile; # filename for last TagsFromFile option my $sortOpt; # sort option is used @@ -524,7 +543,7 @@ if (not $preserveTime and $^O eq 'MSWin32') { for (;;) { # execute the command now if no more arguments or -execute is used - if (not @ARGV or $ARGV[0] =~ /^(-|\xe2\x88\x92)execute(\d*)$/i) { + if (not @ARGV or ($ARGV[0] =~ /^(-|\xe2\x88\x92)execute(\d*)$/i and not $endOfOpts)) { if (@ARGV) { $executeID = $2; # save -execute number for "{ready}" response $helped = 1; # don't show help if we used -execute @@ -575,6 +594,7 @@ for (;;) { # process arguments which were deferred to the next pass unshift @ARGV, @nextPass; undef @nextPass; + undef $endOfOpts; ++$pass; next; } @@ -584,8 +604,14 @@ for (;;) { $_ = shift; next if $badCmd; # flush remaining arguments if aborting this command - if (s/^(-|\xe2\x88\x92)//) { # allow funny dashes (nroff dash bug for cut-n-paste from pod) + # allow funny dashes (nroff dash bug for cut-n-paste from pod) + if (not $endOfOpts and s/^(-|\xe2\x88\x92)//) { s/^\xe2\x88\x92/-/; # translate double-dash too + if ($_ eq '-') { + $pass or push @nextPass, '--'; + $endOfOpts = 1; + next; + } my $a = lc $_; if (/^list([wfrdx]|wf|g(\d*))?$/i) { $pass or push @nextPass, "-$_"; @@ -756,8 +782,16 @@ for (;;) { PrintTagList('Available character sets', sort keys %charsets); $helped = 1; } elsif ($charset !~ s/^(\w+)=// or lc($1) eq 'exiftool') { - $mt->Options(Charset => $charset); - $utf8 = ($mt->Options('Charset') eq 'UTF8'); + { + local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] }; + undef $evalWarning; + $mt->Options(Charset => $charset); + } + if ($evalWarning) { + warn $evalWarning; + } else { + $setCharset = $mt->Options('Charset'); + } } else { # set internal encoding of specified metadata type my $type = { id3 => 'ID3', iptc => 'IPTC', exif => 'EXIF', filename => 'FileName', @@ -810,6 +844,7 @@ for (;;) { (/^e$/ or $a eq '-composite') and $mt->Options(Composite => 0), next; (/^-e$/ or $a eq 'composite') and $mt->Options(Composite => 1), next; (/^E$/ or $a eq 'escapehtml') and require Image::ExifTool::HTML and $escapeHTML = 1, next; + ($a eq 'ec' or $a eq 'escapec') and $escapeC = 1, next; ($a eq 'ex' or $a eq 'escapexml') and $escapeXML = 1, next; if (/^echo(\d)?$/i) { my $n = $1 || 1; @@ -851,8 +886,10 @@ for (;;) { $mt->Options(FastScan => (length $1 ? $1 : 1)); next; } - if ($a eq 'fileorder') { + if (/^fileorder(\d*)$/i) { push @fileOrder, shift if @ARGV; + my $num = $1 || 0; + $fileOrderFast = $num if not defined $fileOrderFast or $fileOrderFast > $num; next; } $a eq 'globaltimeshift' and $mt->Options(GlobalTimeShift => shift), next; @@ -860,6 +897,7 @@ for (;;) { $showGroup = $3 || 0; $allGroup = ($2 ? lc($2) eq 'roupnames' : $1 eq 'G'); $mt->Options(SavePath => 1) if $showGroup =~ /\b5\b/; + $mt->Options(SaveFormat => 1) if $showGroup =~ /\b6\b/; next; } if ($a eq 'geotag') { @@ -908,18 +946,15 @@ for (;;) { $ignore{$dir} = 1; next; } - if ($a eq 'if') { + if (/^if(\d*)$/i) { my $cond = shift; + $fastCondition = $1 if length $1; defined $cond or Error("Expecting expression for -if option\n"), $badCmd=1, next; # prevent processing file unnecessarily for simple case of failed '$ok' or 'not $ok' $cond =~ /^\s*(not\s*)\$ok\s*$/i and ($1 xor $rtnValPrev) and $failCondition=1; # add to list of requested tags push @requestTags, $cond =~ /\$\{?((?:[-\w]+:)*[-\w?*]+)/g; - if (defined $condition) { - $condition .= " and ($cond)"; - } else { - $condition = "($cond)"; - } + push @condition, $cond; next; } if (/^j(son)?(\+?=.*)?$/i) { @@ -959,7 +994,7 @@ for (;;) { } /^(k|pause)$/i and $pause = 1, next; (/^l$/ or $a eq 'long') and --$outFormat, next; - (/^L$/ or $a eq 'latin') and $utf8 = 0, $mt->Options(Charset => 'Latin'), next; + (/^L$/ or $a eq 'latin') and $mt->Options(Charset => 'Latin'), next; if ($a eq 'lang') { $langOpt = (@ARGV and $ARGV[0] !~ /^(-|\xe2\x88\x92)/) ? shift : undef; if ($langOpt) { @@ -973,8 +1008,8 @@ for (;;) { my $langs = "Available languages:\n"; $langs .= " $_ - $Image::ExifTool::langName{$_}\n" foreach @Image::ExifTool::langs; $langs =~ tr/_/-/; # display dashes instead of underlines in language codes - $langs = $mt->Decode($langs, 'UTF8'); $langs = Image::ExifTool::HTML::EscapeHTML($langs) if $escapeHTML; + $langs = $mt->Decode($langs, 'UTF8'); $langOpt and Error("Invalid or unsupported language '${langOpt}'.\n$langs"), $badCmd=1, next; print $langs; $helped = 1; @@ -990,6 +1025,7 @@ for (;;) { /^(m|ignoreminorerrors)$/i and $mt->Options(IgnoreMinorErrors => 1), next; /^(n|-printconv)$/i and $mt->Options(PrintConv => 0), next; /^(-n|printconv)$/i and $mt->Options(PrintConv => 1), next; + $a eq 'nop' and $helped=1, next; # (undocumented) no operation, added in 11.25 if (/^o(ut)?$/i) { $outOpt = shift; defined $outOpt or Error("Expected output file or directory name for -o option\n"), $badCmd=1, next; @@ -1032,7 +1068,7 @@ for (;;) { } /^q(uiet)?$/i and ++$quiet, next; /^r(ecurse)?(\.?)$/i and $recurse = ($2 ? 2 : 1), next; - if ($a eq 'require') { # undocumented, added in version 8.65 + if ($a eq 'require') { # (undocumented) added in version 8.65 my $ver = shift; unless (defined $ver and Image::ExifTool::IsFloat($ver)) { Error("Expecting version number for -require option\n"); @@ -1203,7 +1239,7 @@ for (;;) { push @newValues, $_; if (/^mwg:/i) { $useMWG = 1; - } elsif (/^([-\w]+:)*(filename|directory)\b/i) { + } elsif (/^([-\w]+:)*(filename|directory|testname)\b/i) { $doSetFileName = 1; } elsif (/^([-\w]+:)*(geotag|geotime|geosync)\b/i) { if (lc $2 eq 'geotime') { @@ -1224,14 +1260,14 @@ for (;;) { push @{$setTags{$setTagsFile}}, $_; if (/>/) { $useMWG = 1 if /^(.*>\s*)?mwg:/si; - if (/\b(filename|directory)#?$/i) { + if (/\b(filename|directory|testname)#?$/i) { $doSetFileName = 1; } elsif (/\bgeotime#?$/i) { $addGeotime = ''; } } else { $useMWG = 1 if /^([^<]+<\s*(.*\$\{?)?)?mwg:/si; - if (/^([-\w]+:)*(filename|directory)\b/i) { + if (/^([-\w]+:)*(filename|directory|testname)\b/i) { $doSetFileName = 1; } elsif (/^([-\w]+:)*geotime\b/i) { $addGeotime = ''; @@ -1240,7 +1276,7 @@ for (;;) { } else { my $lst = s/^-// ? \@exclude : \@tags; unless (/^([-\w*]+:)*([-\w*?]+)#?$/) { - Warn(qq(Invalid TAG name: $_\n)); + Warn(qq(Invalid TAG name: "$_"\n)); } push @$lst, $_; # (push everything for backward compatibility) } @@ -1337,15 +1373,22 @@ if ($tagOut and ($csv or %printFmt or $tabFormat or $xml or ($verbose and $html) next; } -if ($csv and $csv eq 'CSV' and not $isWriting and ($textOut or $binaryOutput)) { - Warn 'Sorry, ' . ($textOut ? '-w' : '-b') . " may not be combined with -csv\n"; - $rtnVal = 1; - next; +if ($csv and $csv eq 'CSV' and not $isWriting) { + if ($textOut) { + Warn "Sorry, -w may not be combined with -csv\n"; + $rtnVal = 1; + next; + } + if ($binaryOutput) { + $binaryOutput = 0; + $setCharset = 'default' unless defined $setCharset; + } + require Image::ExifTool::XMP if $setCharset; } if ($escapeHTML or $json) { # must be UTF8 for HTML conversion and JSON output - $mt->Options(Charset => 'UTF8'); + $mt->Options(Charset => 'UTF8') if $json; # use Escape option to do our HTML escaping unless XML output $mt->Options(Escape => 'HTML') if $escapeHTML and not $xml; } elsif ($escapeXML and not $xml) { @@ -1551,6 +1594,9 @@ if (@newValues) { # set $newVal to '' if deleting nothing $newVal = '' if $1 eq '-' and not defined $newVal; } + if ($escapeC and defined $newVal) { + $newVal =~ s/\\(x([0-9a-fA-F]{2})|.)/$2 ? chr(hex($2)) : $unescC{$1} || $1/seg; + } my ($rtn, $wrn) = $mt->SetNewValue($tag, $newVal, %opts); $needSave = 1; ++$isWriting if $rtn; @@ -1625,8 +1671,12 @@ if ($outOpt) { $scanWritable = 1; } +# initialize alternate encoding flag +$altEnc = $mt->Options('Charset'); +undef $altEnc if $altEnc eq 'UTF8'; + # set flag to fix description lengths if necessary -if ($utf8 and $mt->Options('Lang') ne 'en' and eval { require Encode }) { +if (not $altEnc and $mt->Options('Lang') ne 'en' and eval { require Encode }) { # (note that Unicode::GCString is part of the Unicode::LineBreak package) $fixLen = eval { require Unicode::GCString } ? 2 : 1; } @@ -1636,6 +1686,7 @@ if (@fileOrder) { my @allFiles; ProcessFiles($mt, \@allFiles); my $sortTool = new Image::ExifTool; + $sortTool->Options(FastScan => $fileOrderFast) if $fileOrderFast; $sortTool->Options(PrintConv => $mt->Options('PrintConv')); $sortTool->Options(Duplicates => 0); my (%sortBy, %isFloat, @rev, $file); @@ -1755,7 +1806,7 @@ if (defined $deleteOrig) { # print summary my $tot = $count + $countBad; - if ($countDir or $totWr or $countFailed or $tot > 1 or $textOut or $countLink or $countBadLink) { + if ($countDir or $totWr or $countFailed or $tot > 1 or $textOut or %countLink) { my $o = (($html or $json or $xml or %printFmt or $csv) and not $textOut) ? \*STDERR : $vout; printf($o "%5d directories scanned\n", $countDir) if $countDir; printf($o "%5d directories created\n", $countNewDir) if $countNewDir; @@ -1770,8 +1821,10 @@ if (defined $deleteOrig) { printf($o "%5d files could not be read\n", $countBad) if $countBad; printf($o "%5d output files created\n", scalar(keys %created)) if $textOut; printf($o "%5d output files appended\n", scalar(keys %appended)) if %appended; - printf($o "%5d hard links created\n", $countLink) if $countLink or $countBadLink; - printf($o "%5d hard links could not be created\n", $countBadLink) if $countBadLink; + printf($o "%5d hard links created\n", $countLink{Hard} || 0) if $countLink{Hard} or $countLink{BadHard}; + printf($o "%5d hard links could not be created\n", $countLink{BadHard}) if $countLink{BadHard}; + printf($o "%5d symbolic links created\n", $countLink{Sym} || 0) if $countLink{Sym} or $countLink{BadSym}; + printf($o "%5d symbolic links could not be created\n", $countLink{BadSym}) if $countLink{BadSym}; } } @@ -1818,6 +1871,11 @@ sub GetImageInfo($$) $title =~ s/%([%bfpr])/$lkup{$1}/eg; SetWindowTitle($title); } + unless (length $orig or $outOpt) { + Warn qq(Error: Zero-length file name - ""\n); + ++$countBad; + return; + } # determine the name of the source file based on the original input file name if (@srcFmt) { my ($fmt, $first); @@ -1843,7 +1901,7 @@ sub GetImageInfo($$) } } # evaluate -if expression for conditional processing - if (defined $condition) { + if (@condition) { unless ($file eq '-' or $et->Exists($file)) { Warn "Error: File not found - $file\n"; FileNotFound($file); @@ -1857,27 +1915,35 @@ sub GetImageInfo($$) undef $evalWarning; local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] }; - my %info; + my (%info, $condition); # extract information and build expression for evaluation my $opts = { Duplicates => 1, RequestTags => \@requestTags, Verbose => 0, HtmlDump => 0 }; + $$opts{FastScan} = $fastCondition if defined $fastCondition; # return all tags but explicitly mention tags on command line so # requested images will generate the appropriate warnings @foundTags = ('*', @tags) if @tags; $info = $et->ImageInfo(Infile($pipe,$isWriting), \@foundTags, $opts); - my $cond = $et->InsertTagValues(\@foundTags, $condition, \%info); + foreach $condition (@condition) { + my $cond = $et->InsertTagValues(\@foundTags, $condition, \%info); + { + # set package so eval'd functions are in Image::ExifTool namespace + package Image::ExifTool; - #### eval "-if" condition (%info) - $result = eval $cond; + #### eval "-if" condition (%info) + $result = eval $cond; - $@ and $evalWarning = $@; - if ($evalWarning) { - # fail condition if warning is issued - undef $result; - if ($verbose) { - chomp $evalWarning; - $evalWarning =~ s/ at \(eval .*//s; - Warn "Condition: $evalWarning - $file\n"; + $@ and $evalWarning = $@; + } + if ($evalWarning) { + # fail condition if warning is issued + undef $result; + if ($verbose) { + chomp $evalWarning; + $evalWarning =~ s/ at \(eval .*//s; + Warn "Condition: $evalWarning - $file\n"; + } } + last unless $result; } } unless ($result) { @@ -1887,7 +1953,7 @@ sub GetImageInfo($$) } # can't make use of $info if verbose because we must reprocess # the file anyway to generate the verbose output - undef $info if $verbose; + undef $info if $verbose or defined $fastCondition; } if (defined $deleteOrig) { print $vout "======== $file$progStr\n" if defined $verbose; @@ -2131,8 +2197,10 @@ sub GetImageInfo($$) TAG: foreach $tag (@foundTags) { my $tagName = GetTagName($tag); my ($group, $valList); - # make sure this tag has a value + # get the value for this tag my $val = $$info{$tag}; + # set flag if this is binary data + $isBinary = (ref $val eq 'SCALAR' and defined $binaryOutput); if (ref $val) { # happens with -X, -j or -php when combined with -b: if (defined $binaryOutput and not $binaryOutput and $$et{TAG_INFO}{$tag}{Protected}) { @@ -2280,8 +2348,8 @@ TAG: foreach $tag (@foundTags) { } if ($escapeHTML) { $val =~ tr/\0-\x08\x0b\x0c\x0e-\x1f/./; - Image::ExifTool::XMP::FixUTF8(\$val) if $utf8; - $val = Image::ExifTool::HTML::EscapeHTML($val); + Image::ExifTool::XMP::FixUTF8(\$val) unless $altEnc; + $val = Image::ExifTool::HTML::EscapeHTML($val, $altEnc); } else { CleanXML(\$val); } @@ -2397,10 +2465,14 @@ TAG: foreach $tag (@foundTags) { } } - # translate unprintable chars in value and remove trailing spaces - $val =~ tr/\x01-\x1f\x7f/./; - $val =~ s/\x00//g; - $val =~ s/\s+$//; + if ($escapeC) { + $val =~ s/([\0-\x1f\\\x7f])/$escC{$1} || sprintf('\x%.2x', ord $1)/eg; + } else { + # translate unprintable chars in value and remove trailing spaces + $val =~ tr/\x01-\x1f\x7f/./; + $val =~ s/\x00//g; + $val =~ s/\s+$//; + } if ($html) { print $fp ""; @@ -2530,7 +2602,8 @@ TAG: foreach $tag (@foundTags) { sub SetImageInfo($$$) { my ($et, $file, $orig) = @_; - my ($outfile, $restored, $isTemporary, $isStdout, $outType, $tagsFromSrc, $hardLink, $testName); + my ($outfile, $restored, $isTemporary, $isStdout, $outType, $tagsFromSrc); + my ($hardLink, $symLink, $testName, $sameFile); my $infile = $file; # save infile in case we change it again # clean up old temporary file if necessary @@ -2702,15 +2775,21 @@ sub SetImageInfo($$$) } else { # get name of hard link if we are creating one $hardLink = $et->GetNewValues('HardLink'); + $symLink = $et->GetNewValues('SymLink'); $testName = $et->GetNewValues('TestName'); $hardLink = FilenameSPrintf($hardLink, $orig) if defined $hardLink; + $symLink = FilenameSPrintf($symLink, $orig) if defined $symLink; + # determine what our output file name should be + my $newFileName = $et->GetNewValues('FileName'); + my $newDir = $et->GetNewValues('Directory'); if (defined $testName) { + my $err; + $err = "You shouldn't write FileName or Directory with TestFile" if defined $newFileName or defined $newDir; + $err = "The -o option shouldn't be used with TestFile" if defined $outfile; + $err and Warn("Error: $err - $infile\n"), ++$countBadWr, return 0; $testName = FilenameSPrintf($testName, $orig); $testName = Image::ExifTool::GetNewFileName($file, $testName) if $file ne ''; } - # determine what our output file name should be - my $newFileName = $et->GetNewValues('FileName'); - my $newDir = $et->GetNewValues('Directory'); if (defined $newFileName or defined $newDir or ($doSetFileName and defined $outfile)) { if ($newFileName) { $newFileName = FilenameSPrintf($newFileName, $orig); @@ -2727,12 +2806,16 @@ sub SetImageInfo($$$) } $outfile = NextUnusedFilename($outfile, $infile); if ($et->Exists($outfile)) { - if ($infile ne $outfile) { + if ($infile eq $outfile) { + undef $outfile; # not changing the file name after all + # (allow for case-insensitive filesystems) + } elsif ($et->IsSameFile($infile, $outfile)) { + $sameFile = $outfile; # same file, but the name has a different case + } else { Warn "Error: '${outfile}' already exists - $infile\n"; ++$countBadWr; return 0; } - undef $outfile; # not changing the file name after all } } if (defined $outfile) { @@ -2786,13 +2869,13 @@ sub SetImageInfo($$$) } else { ++$countSameWr; } - if (defined $hardLink or defined $testName) { + if (defined $hardLink or defined $symLink or defined $testName) { my $src = (defined $outfile and $r4 > 0) ? $outfile : $file; - DoHardLink($et, $src, $hardLink, $testName); + DoHardLink($et, $src, $hardLink, $symLink, $testName); } return 1; } - unless (defined $outfile) { + if (not defined $outfile or defined $sameFile) { # write to a truly temporary file $outfile = "${file}_exiftool_tmp"; if ($et->Exists($outfile)) { @@ -2810,9 +2893,9 @@ sub SetImageInfo($$$) my $success = $et->WriteInfo(Infile($file), $outfile, $outType); # create hard link if specified - if ($success and (defined $hardLink or defined $testName)) { + if ($success and (defined $hardLink or defined $symLink or defined $testName)) { my $src = defined $outfile ? $outfile : $file; - DoHardLink($et, $src, $hardLink, $testName); + DoHardLink($et, $src, $hardLink, $symLink, $testName); } # get file time if preserving it @@ -2850,6 +2933,7 @@ sub SetImageInfo($$$) return 0; } } + my $dstFile = defined $sameFile ? $sameFile : $file; if ($overwriteOrig > 1) { # copy temporary file over top of original to preserve attributes my ($err, $buff); @@ -2901,19 +2985,19 @@ sub SetImageInfo($$$) # simply rename temporary file to replace original # (if we didn't already rename it to add "_original") - } elsif ($et->Rename($tmpFile, $file)) { + } elsif ($et->Rename($tmpFile, $dstFile)) { ++$countGoodWr; } else { my $newFile = $tmpFile; undef $tmpFile; # (avoid deleting file if we get interrupted) # unlink may fail if already renamed or no permission if (not $et->Unlink($file)) { - Warn "Error renaming temporary file to $file\n"; + Warn "Error renaming temporary file to $dstFile\n"; $et->Unlink($newFile); ++$countBadWr; # try renaming again now that the target has been deleted - } elsif (not $et->Rename($newFile, $file)) { - Warn "Error renaming temporary file to $file\n"; + } elsif (not $et->Rename($newFile, $dstFile)) { + Warn "Error renaming temporary file to $dstFile\n"; # (don't delete tmp file now because it is all we have left) ++$countBadWr; } else { @@ -2957,20 +3041,29 @@ sub SetImageInfo($$$) #------------------------------------------------------------------------------ # Make hard link and handle TestName if specified -# Inputs: 0) ExifTool ref, 1) source file name, 2) HardLink name, 3) TestFile name -sub DoHardLink($$$$) +# Inputs: 0) ExifTool ref, 1) source file name, 2) HardLink name, +# 3) SymLink name, 4) TestFile name +sub DoHardLink($$$$$) { - my ($et, $src, $hardLink, $testName) = @_; + my ($et, $src, $hardLink, $symLink, $testName) = @_; if (defined $hardLink) { $hardLink = NextUnusedFilename($hardLink); if ($et->SetFileName($src, $hardLink, 'Link') > 0) { - ++$countLink; + $countLink{Hard} = ($countLink{Hard} || 0) + 1; + } else { + $countLink{BadHard} = ($countLink{BadHard} || 0) + 1; + } + } + if (defined $symLink) { + $symLink = NextUnusedFilename($symLink); + if ($et->SetFileName($src, $symLink, 'SymLink') > 0) { + $countLink{Sym} = ($countLink{Sym} || 0) + 1; } else { - ++$countBadLink; + $countLink{BadSym} = ($countLink{BadSym} || 0) + 1; } } if (defined $testName) { - $testName = NextUnusedFilename($testName, $src, 1); + $testName = NextUnusedFilename($testName, $src); if ($usedFileName{$testName}) { $et->Warn("File '${testName}' would exist"); } elsif ($et->SetFileName($src, $testName, 'Test', $usedFileName{$testName}) == 1) { @@ -2990,7 +3083,7 @@ sub CleanXML($) # translate control characters that are invalid in XML $$strPt =~ tr/\0-\x08\x0b\x0c\x0e-\x1f/./; # fix malformed UTF-8 characters - Image::ExifTool::XMP::FixUTF8($strPt) if $utf8; + Image::ExifTool::XMP::FixUTF8($strPt) unless $altEnc; # escape necessary characters for XML $$strPt = Image::ExifTool::XMP::EscapeXML($$strPt); } @@ -3003,13 +3096,14 @@ sub EncodeXML($) { my $strPt = shift; if ($$strPt =~ /[\0-\x08\x0b\x0c\x0e-\x1f]/ or - ($utf8 and Image::ExifTool::XMP::IsUTF8($strPt) < 0)) + (not $altEnc and Image::ExifTool::XMP::IsUTF8($strPt) < 0)) { # encode binary data and non-UTF8 with special characters as base64 $$strPt = Image::ExifTool::XMP::EncodeBase64($$strPt); + # #ATV = Alexander Vonk, private communication return 'http://www.w3.org/2001/XMLSchema#base64Binary'; #ATV } elsif ($escapeHTML) { - $$strPt = Image::ExifTool::HTML::EscapeHTML($$strPt); + $$strPt = Image::ExifTool::HTML::EscapeHTML($$strPt, $altEnc); } else { $$strPt = Image::ExifTool::XMP::EscapeXML($$strPt); } @@ -3064,19 +3158,20 @@ sub EscapeJSON($;$) # (these big numbers caused problems for some JSON parsers, so be more conservative) return $str if $str =~ /^-?(\d|[1-9]\d{1,14})(\.\d{1,16})?(e[-+]?\d{1,3})?$/i; } - # encode JSON string as Base64 if necessary + # encode JSON string in base64 if necessary if ($json < 2 and defined $binaryOutput and Image::ExifTool::XMP::IsUTF8(\$str) < 0) { return '"base64:' . Image::ExifTool::XMP::EncodeBase64($str, 1) . '"'; } - $str =~ s/\0+$//; # remove trailing nulls # escape special characters $str =~ s/(["\t\n\r\\])/\\$jsonChar{$1}/sg; if ($json < 2) { # JSON + $str =~ tr/\0//d; # remove all nulls # escape other control characters with \u $str =~ s/([\0-\x1f])/sprintf("\\u%.4X",ord $1)/sge; # JSON strings must be valid UTF8 - Image::ExifTool::XMP::FixUTF8(\$str) if $utf8; + Image::ExifTool::XMP::FixUTF8(\$str) unless $altEnc; } else { # PHP + $str =~ s/\0+$// unless $isBinary; # remove trailing nulls unless binary # must escape "$" too for PHP $str =~ s/\$/\\\$/sg; # escape other control characters with \x @@ -3113,7 +3208,8 @@ sub FormatJSON($$$) print $fp $bra; foreach (sort keys %$val) { print $fp ',' if $comma; - print $fp qq(\n$ind "$_"$sep ); + my $key = EscapeJSON($_, 1); + print $fp qq(\n$ind $key$sep ); # hack to force decimal id's to be printed as strings with -H if ($showTagID and $_ eq 'id' and $showTagID eq 'H' and $$val{$_} =~ /^\d+\.\d+$/) { print $fp qq{"$$val{$_}"}; @@ -3136,10 +3232,16 @@ sub FormatJSON($$$) sub FormatCSV($) { my $val = shift; - # currently, the value may contain NULL characters. It is unclear - # whether or not this is valid CSV, but some readers may not like it. - # (if this becomes a problem, in the future values may need to be truncated at - # the first NULL character, but this would disable the use of CSV for binary data) + # check for valid encoding if the Charset option was used + if ($setCharset and ($val =~ /[^\x09\x0a\x0d\x20-\x7e\x80-\xff]/ or + ($setCharset eq 'UTF8' and Image::ExifTool::XMP::IsUTF8(\$val) < 0))) + { + $val = 'base64:' . Image::ExifTool::XMP::EncodeBase64($val, 1); + } + # currently, there is a chance that the value may contain NULL characters unless + # the -b option is used to encode as Base64. It is unclear whether or not this + # is valid CSV, but some readers may not like it. (If this becomes a problem, + # in the future values may need to be truncated at the first NULL character.) $val = qq{"$val"} if $val =~ s/"/""/g or $val =~ /(^\s+|\s+$)/ or $val =~ /[,\n\r]/; return $val; } @@ -3212,7 +3314,7 @@ sub ConvertBinary($) # (binaryOutput flag is set to 0 for binary mode of XML/PHP/JSON output formats) if (defined $binaryOutput) { $obj = $$obj; - # encode in base64 if necessary + # encode in base64 if necessary (0xf7 allows for up to 21-bit UTF-8 code space) if ($json == 1 and ($obj =~ /[^\x09\x0a\x0d\x20-\x7e\x80-\xf7]/ or Image::ExifTool::XMP::IsUTF8(\$obj) < 0)) { @@ -3220,7 +3322,7 @@ sub ConvertBinary($) } } else { # (-b is not valid for HTML output) - my $bOpt = ($html or ($csv and $csv eq 'CSV')) ? '' : ', use -b option to extract'; + my $bOpt = $html ? '' : ', use -b option to extract'; if ($$obj =~ /^Binary data \d+ bytes$/) { $obj = "($$obj$bOpt)"; } else { @@ -3416,7 +3518,7 @@ sub ScanDir($$;$) { local $_; my ($et, $dir, $list) = @_; - my (@fileList, $done, $file, $utf8Name); + my (@fileList, $done, $file, $utf8Name, $winSurrogate); my $enc = $et->Options('CharsetFileName'); # recode as UTF-8 if necessary if ($enc) { @@ -3427,17 +3529,30 @@ sub ScanDir($$;$) $utf8Name = 1; } return if $ignore{$dir}; + my $oldBase = $seqFileBase; + $seqFileBase = $seqFileNum; # use Win32::FindFile on Windows if available # (ReadDir will croak if there is a wildcard, so check for this) if ($^O eq 'MSWin32' and $dir !~ /[*?]/) { + undef $evalWarning; local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] };; if (CheckUTF8($dir, $enc) >= 0) { if (eval { require Win32::FindFile }) { - @fileList = Win32::FindFile::ReadDir($dir); - $_ = $_->cFileName foreach @fileList; - $et->Options(CharsetFileName => 'UTF8'); # now using UTF8 - $utf8Name = 1; # ReadDir returns UTF-8 file names - $done = 1; + eval { + @fileList = Win32::FindFile::ReadDir($dir); + $_ = $_->cFileName foreach @fileList; + }; + $@ and $evalWarning = $@; + if ($evalWarning) { + chomp $evalWarning; + $evalWarning =~ s/ at .*//s; + Warn "Warning: [Win32::FindFile] $evalWarning - $dir\n"; + $winSurrogate = 1 if $evalWarning =~ /surrogate/; + } else { + $et->Options(CharsetFileName => 'UTF8'); # now using UTF8 + $utf8Name = 1; # ReadDir returns UTF-8 file names + $done = 1; + } } else { $done = 0; } @@ -3445,7 +3560,11 @@ sub ScanDir($$;$) } unless ($done) { # use standard perl library routines to read directory - opendir(DIR_HANDLE, $dir) or Warn("Error opening directory $dir\n"), return; + unless (opendir(DIR_HANDLE, $dir)) { + Warn("Error opening directory $dir\n"); + $seqFileBase = $oldBase + ($seqFileNum - $seqFileBase); + return; + } @fileList = readdir(DIR_HANDLE); closedir(DIR_HANDLE); if (defined $done) { @@ -3489,6 +3608,16 @@ sub ScanDir($$;$) next unless $file =~ /\.(gz|bz2)$/i; } } + # Windows patch to avoid replacing filename containing Unicode surrogate with 8.3 name + if ($winSurrogate and $isWriting and + (not $overwriteOrig or $overwriteOrig != 2) and + not $doSetFileName and $file =~ /~/) # (8.3 name will contain a tilde) + { + Warn("Not writing $path\n"); + WarnOnce("Use -overwrite_original_in_place to write files with Unicode surrogate characters\n"); + ++$countBad; + next; + } $utf8FileName{$path} = 1 if $utf8Name; if ($list) { push(@$list, $path); @@ -3498,6 +3627,8 @@ sub ScanDir($$;$) } ++$countDir; $et->Options(CharsetFileName => $enc); # restore original setting + # update sequential file base for parent directory + $seqFileBase = $oldBase + ($seqFileNum - $seqFileBase); } #------------------------------------------------------------------------------ @@ -3521,23 +3652,35 @@ sub FindFileWindows($$) return (); } CheckUTF8($wildfile, $enc) >= 0 or return (); - local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] };; - my @names = Win32::FindFile::FindFile($wildfile) or return (); - # (apparently this isn't always sorted, so do a case-insensitive sort here) - @names = sort { uc($a) cmp uc($b) } @names; - my ($rname, $nm, @files); - # replace "\?" with ".", and "\*" with ".*" for regular expression - ($rname = quotemeta $wildname) =~ s/\\\?/./g; - $rname =~ s/\\\*/.*/g; - foreach $nm (@names) { - $nm = $nm->cFileName; - # make sure that FindFile behaves - # (otherwise "*.jpg" matches things like "a.jpg_original"!) - next unless $nm =~ /^$rname$/i; - next if $nm eq '.' or $nm eq '..'; # don't match "." and ".." - my $file = "$dir$nm"; # add back directory name - push @files, $file; - $utf8FileName{$file} = 1; # flag this file name as UTF-8 encoded + undef $evalWarning; + local $SIG{'__WARN__'} = sub { $evalWarning = $_[0] }; + my @files; + eval { + my @names = Win32::FindFile::FindFile($wildfile) or return; + # (apparently this isn't always sorted, so do a case-insensitive sort here) + @names = sort { uc($a) cmp uc($b) } @names; + my ($rname, $nm); + # replace "\?" with ".", and "\*" with ".*" for regular expression + ($rname = quotemeta $wildname) =~ s/\\\?/./g; + $rname =~ s/\\\*/.*/g; + foreach $nm (@names) { + $nm = $nm->cFileName; + # make sure that FindFile behaves + # (otherwise "*.jpg" matches things like "a.jpg_original"!) + next unless $nm =~ /^$rname$/i; + next if $nm eq '.' or $nm eq '..'; # don't match "." and ".." + my $file = "$dir$nm"; # add back directory name + push @files, $file; + $utf8FileName{$file} = 1; # flag this file name as UTF-8 encoded + } + }; + $@ and $evalWarning = $@; + if ($evalWarning) { + chomp $evalWarning; + $evalWarning =~ s/ at .*//s; + Warn "Error: [Win32::FindFile] $evalWarning - $wildfile\n"; + undef @files; + ++$countBad; } return @files; } @@ -3642,9 +3785,7 @@ sub SuggestedExtension($$$) $ext = 'xml'; } elsif ($$valPt =~ /^RIFF....WAVE/s) { $ext = 'wav'; - } elsif ($tag eq 'OriginalRawFileData' and - defined($ext = $et->GetValue('OriginalRawFileName'))) - { + } elsif ($tag eq 'OriginalRawFileData' and defined($ext = $et->GetValue('OriginalRawFileName'))) { $ext =~ s/^.*\.//s; $ext = $ext ? lc($ext) : 'raw'; } elsif ($tag eq 'EXIF') { @@ -3658,12 +3799,14 @@ sub SuggestedExtension($$$) $ext = $movType{$1} || $1; } elsif ($$valPt !~ /^.{0,4096}\0/s) { $ext = 'txt'; - } elsif ($$valPt =~ /^BM/) { + } elsif ($$valPt =~ /^BM.{15}\0/s) { $ext = 'bmp'; } elsif ($$valPt =~ /^CANON OPTIONAL DATA\0/) { $ext = 'vrd'; } elsif ($$valPt =~ /^IIII\x04\0\x04\0/) { $ext = 'dr4'; + } elsif ($$valPt =~ /^(.{10}|.{522})(\x11\x01|\x00\x11)/s) { + $ext = 'pict'; } else { $ext = 'dat'; } @@ -3772,11 +3915,10 @@ sub Num2Alpha($) #------------------------------------------------------------------------------ # Expand '%c' and '%C' codes if filename to get next unused file name # Inputs: 0) file name format string, 1) filename ok to use even if it exists -# 2) dry run (won't really be renaming file) # Returns: new file name -sub NextUnusedFilename($;$$) +sub NextUnusedFilename($;$) { - my ($fmt, $okfile, $dryRun) = @_; + my ($fmt, $okfile) = @_; return $fmt unless $fmt =~ /%[-+]?\d*\.?\d*[lun]?[cC]/; my %sep = ( '-' => '-', '+' => '_' ); my ($copy, $alpha) = (0, 'a'); @@ -3787,24 +3929,24 @@ sub NextUnusedFilename($;$$) $filename .= substr($fmt, $pos, pos($fmt) - $pos - length($1)); $pos = pos($fmt); my ($sign, $wid, $dec, $wid2, $mod, $tok) = ($2, $3 || 0, $4, $5 || 0, $6, $7); - my $diff = 0; + my $diff; if ($tok eq 'C') { - $diff = $wid; + $diff = $wid - ($sign eq '-' ? $seqFileBase : 0); $wid = $wid2; } else { next unless $dec or $copy; $wid = $wid2 if $wid < $wid2; + # add dash or underline separator if '-' or '+' specified + $filename .= $sep{$sign} if $sign; } - # add dash or underline separator if '-' or '+' specified - $filename .= $sep{$sign} if $sign; if ($mod and $mod ne 'n') { - my $a = $tok eq 'C' ? Num2Alpha($diff + $seq++) : $alpha; + my $a = $tok eq 'C' ? Num2Alpha($diff + $seq) : $alpha; my $str = ($wid and $wid > length $a) ? 'a' x ($wid - length($a)) : ''; $str .= $a; $str = uc $str if $mod eq 'u'; $filename .= $str; } else { - my $c = $tok eq 'C' ? ($diff + $seq++) : $copy; + my $c = $tok eq 'C' ? ($diff + $seq) : $copy; my $num = $c + ($mod ? 1 : 0); $filename .= $wid ? sprintf("%.${wid}d",$num) : $num; } @@ -3819,6 +3961,7 @@ sub NextUnusedFilename($;$$) } ++$copy; ++$alpha; + ++$seq; } } @@ -4065,18 +4208,18 @@ sub PrintTagList($@) } return; } - print ' '; - my $len = 1; + my ($len, $pad) = (0, $quiet ? '' : ' '); foreach $tag (@_) { my $taglen = length($tag); - if ($len + $taglen > 78) { - print "\n "; - $len = 1; + if ($len + $taglen > 77) { + print "\n"; + ($len, $pad) = (0, $quiet ? '' : ' '); } - print " $tag"; + print $pad, $tag; $len += $taglen + 1; + $pad = ' '; } - @_ or print ' [empty list]'; + @_ or print $pad, '[empty list]'; print "\n"; } @@ -4150,52 +4293,54 @@ directory are processed (in write mode only writable types are processed). However, files may be specified by name, or the B<-ext> option may be used to force processing of files with any extension. Hidden files in the directory are also processed. Adding the B<-r> option causes subdirectories -to be processed recursively, but those with names beginning with "." are -skipped unless B<-r.> is used. +to be processed recursively, but subdirectories with names beginning with +"." are skipped unless B<-r.> is used. Below is a list of file types and meta information formats currently supported by ExifTool (r = read, w = write, c = create): File Types ------------+-------------+-------------+-------------+------------ - 3FR r | DR4 r/w/c | J2C r | ODP r | RAW r/w - 3G2 r/w | DSS r | JNG r/w | ODS r | RIFF r - 3GP r/w | DV r | JP2 r/w | ODT r | RSRC r - A r | DVB r/w | JPEG r/w | OFR r | RTF r - AA r | DVR-MS r | JSON r | OGG r | RW2 r/w - AAE r | DYLIB r | K25 r | OGV r | RWL r/w - AAX r/w | EIP r | KDC r | OPUS r | RWZ r - ACR r | EPS r/w | KEY r | ORF r/w | RM r - AFM r | EPUB r | LA r | OTF r | SEQ r - AI r/w | ERF r/w | LFP r | PAC r | SKETCH r - AIFF r | EXE r | LNK r | PAGES r | SO r - APE r | EXIF r/w/c | M2TS r | PBM r/w | SR2 r/w - ARQ r/w | EXR r | M4A/V r/w | PCD r | SRF r - ARW r/w | EXV r/w/c | MAX r | PDB r | SRW r/w - ASF r | F4A/V r/w | MEF r/w | PDF r/w | SVG r - AVI r | FFF r/w | MIE r/w/c | PEF r/w | SWF r - AZW r | FLA r | MIFF r | PFA r | THM r/w - BMP r | FLAC r | MKA r | PFB r | TIFF r/w - BPG r | FLIF r/w | MKS r | PFM r | TORRENT r - BTF r | FLV r | MKV r | PGF r | TTC r - CHM r | FPF r | MNG r/w | PGM r/w | TTF r - COS r | FPX r | MOBI r | PLIST r | VCF r - CR2 r/w | GIF r/w | MODD r | PICT r | VRD r/w/c - CR3 r/w | GPR r/w | MOI r | PMP r | VSD r - CRM r/w | GZ r | MOS r/w | PNG r/w | WAV r - CRW r/w | HDP r/w | MOV r/w | PPM r/w | WDP r/w - CS1 r/w | HDR r | MP3 r | PPT r | WEBP r - DCM r | HEIC r | MP4 r/w | PPTX r | WEBM r - DCP r/w | HEIF r | MPC r | PS r/w | WMA r - DCR r | HTML r | MPG r | PSB r/w | WMV r - DFONT r | ICC r/w/c | MPO r/w | PSD r/w | WTV r - DIVX r | ICS r | MQV r/w | PSP r | WV r - DJVU r | IDML r | MRW r/w | QTIF r/w | X3F r/w - DLL r | IIQ r/w | MXF r | R3D r | XCF r - DNG r/w | IND r/w | NEF r/w | RA r | XLS r - DOC r | INX r | NRW r/w | RAF r/w | XLSX r - DOCX r | ISO r | NUMBERS r | RAM r | XMP r/w/c - DPX r | ITC r | O r | RAR r | ZIP r + 3FR r | DR4 r/w/c | ITC r | ODP r | RIFF r + 3G2 r/w | DSS r | J2C r | ODS r | RSRC r + 3GP r/w | DV r | JNG r/w | ODT r | RTF r + A r | DVB r/w | JP2 r/w | OFR r | RW2 r/w + AA r | DVR-MS r | JPEG r/w | OGG r | RWL r/w + AAE r | DYLIB r | JSON r | OGV r | RWZ r + AAX r/w | EIP r | K25 r | OPUS r | RM r + ACR r | EPS r/w | KDC r | ORF r/w | SEQ r + AFM r | EPUB r | KEY r | OTF r | SKETCH r + AI r/w | ERF r/w | LA r | PAC r | SO r + AIFF r | EXE r | LFP r | PAGES r | SR2 r/w + APE r | EXIF r/w/c | LNK r | PBM r/w | SRF r + ARQ r/w | EXR r | LRV r/w | PCD r | SRW r/w + ARW r/w | EXV r/w/c | M2TS r | PCX r | SVG r + ASF r | F4A/V r/w | M4A/V r/w | PDB r | SWF r + AVI r | FFF r/w | MAX r | PDF r/w | THM r/w + AVIF r/w | FITS r | MEF r/w | PEF r/w | TIFF r/w + AZW r | FLA r | MIE r/w/c | PFA r | TORRENT r + BMP r | FLAC r | MIFF r | PFB r | TTC r + BPG r | FLIF r/w | MKA r | PFM r | TTF r + BTF r | FLV r | MKS r | PGF r | TXT r + CHM r | FPF r | MKV r | PGM r/w | VCF r + COS r | FPX r | MNG r/w | PLIST r | VRD r/w/c + CR2 r/w | GIF r/w | MOBI r | PICT r | VSD r + CR3 r/w | GPR r/w | MODD r | PMP r | WAV r + CRM r/w | GZ r | MOI r | PNG r/w | WDP r/w + CRW r/w | HDP r/w | MOS r/w | PPM r/w | WEBP r + CS1 r/w | HDR r | MOV r/w | PPT r | WEBM r + CSV r | HEIC r/w | MP3 r | PPTX r | WMA r + DCM r | HEIF r/w | MP4 r/w | PS r/w | WMV r + DCP r/w | HTML r | MPC r | PSB r/w | WTV r + DCR r | ICC r/w/c | MPG r | PSD r/w | WV r + DFONT r | ICS r | MPO r/w | PSP r | X3F r/w + DIVX r | IDML r | MQV r/w | QTIF r/w | XCF r + DJVU r | IIQ r/w | MRW r/w | R3D r | XLS r + DLL r | IND r/w | MXF r | RA r | XLSX r + DNG r/w | INSP r/w | NEF r/w | RAF r/w | XMP r/w/c + DOC r | INSV r | NRW r/w | RAM r | ZIP r + DOCX r | INX r | NUMBERS r | RAR r | + DPX r | ISO r | O r | RAW r/w | Meta Information ----------------------+----------------------+--------------------- @@ -4226,7 +4371,7 @@ interpreted as tag names (for this reason, multiple single-character options may NOT be combined into one argument). Contrary to standard practice, options may appear after source file names on the exiftool command line. -=head2 Option Summary +=head2 Option Overview L @@ -4247,7 +4392,7 @@ L -csv[[+]=CSVFILE] Export/import tags in CSV format -d FMT (-dateFormat) Set format for date/time values -D (-decimal) Show tag ID numbers in decimal - -E, -ex (-escape(HTML|XML)) Escape values for HTML (-E) or XML (-ex) + -E,-ex,-ec (-escape(HTML|XML|C))Escape tag values for HTML, XML or C -f (-forcePrint) Force printing of all specified tags -g[NUM...] (-groupHeadings) Organize output by tag group -G[NUM...] (-groupNames) Print group name for each tag @@ -4278,14 +4423,14 @@ L L -a (-duplicates) Allow duplicate tags to be extracted - -e (--composite) Do not calculate composite tags + -e (--composite) Do not generate composite tags -ee (-extractEmbedded) Extract information from embedded files -ext[+] EXT (-extension) Process files with specified extension -F[OFFSET] (-fixBase) Fix the base for maker notes offsets - -fast[NUM] Increase speed for slow devices - -fileOrder [-]TAG Set file processing order + -fast[NUM] Increase speed when extracting metadata + -fileOrder[NUM] [-]TAG Set file processing order -i DIR (-ignore) Ignore specified directory name - -if EXPR Conditionally process files + -if[NUM] EXPR Conditionally process files -m (-ignoreMinorErrors) Ignore minor errors and warnings -o OUTFILE (-out) Set output file or directory name -overwrite_original Overwrite original by renaming tmp file @@ -4307,6 +4452,7 @@ L -k (-pause) Pause before terminating -list[w|f|wf|g[NUM]|d|x] List various exiftool capabilities -ver Print exiftool version number + -- End of options L @@ -4349,15 +4495,15 @@ C<-1IPTC:City>). Use the B<-listg> option to list available group names by family. A special tag name of C may be used to indicate all meta information -(ie. B<-All>). This is particularly useful when a group name is specified to -extract all information in a group (but beware that unless the B<-a> option -is also used, some tags in the group may be suppressed by same-named tags in -other groups). The wildcard characters C and C<*> may be used in a tag -name to match any single character and zero or more characters respectively. - These may not be used in a group name, with the exception that a group name -of C<*> (or C) may be used to extract all instances of a tag (as if -B<-a> was used). Note that arguments containing wildcards must be quoted on -the command line of most systems to prevent shell globbing. +(ie. B<-All>). This is particularly useful when a group name is specified +to extract all information in a group (but beware that unless the B<-a> +option is also used, some tags in the group may be suppressed by same-named +tags in other groups). The wildcard characters C and C<*> may be used in +a tag name to match any single character and zero or more characters +respectively. These may not be used in a group name, with the exception that +a group name of C<*> (or C) may be used to extract all instances of a +tag (as if B<-a> was used). Note that arguments containing wildcards must +be quoted on the command line of most systems to prevent shell globbing. A C<#> may be appended to the tag name to disable the print conversion on a per-tag basis (see the B<-n> option). This may also be used when writing or @@ -4517,19 +4663,20 @@ with a different name or group. This is done using E'-IEI'E or E'-IEI'E on the command line after B<-tagsFromFile>, and causes the value of I to be copied from -I and written to I in I. Note that this argument -must be quoted to prevent shell redirection, and there is no C<=> sign as -when assigning new values. Source and/or destination tags may be prefixed -by a group name and/or suffixed by C<#>. Wildcards are allowed in both the -source and destination tag names. A destination group and/or tag name of -C or C<*> writes to the same family 1 group and/or tag name as the -source. If no destination group is specified, the information is written to -the preferred group. Whitespace around the C> or C> is ignored. -As a convenience, C<-tagsFromFile @> is assumed for any redirected tags -which are specified without a prior B<-tagsFromFile> option. Copied tags -may also be added or deleted from a list with arguments of the form +I and written to I in I. Has no effect unless +I exists in I. Note that this argument must be quoted to +prevent shell redirection, and there is no C<=> sign as when assigning new +values. Source and/or destination tags may be prefixed by a group name +and/or suffixed by C<#>. Wildcards are allowed in both the source and +destination tag names. A destination group and/or tag name of C or +C<*> writes to the same family 1 group and/or tag name as the source. If no +destination group is specified, the information is written to the preferred +group. Whitespace around the C> or C> is ignored. As a +convenience, C<-tagsFromFile @> is assumed for any redirected tags which are +specified without a prior B<-tagsFromFile> option. Copied tags may also be +added or deleted from a list with arguments of the form E'-I+EI'E or -E'-I-EI'E. +E'-I-EI'E (but see Note 5 below). An extension of the redirection feature allows strings involving tag names to be used on the right hand side of the C> symbol with the syntax @@ -4592,7 +4739,8 @@ Other than these differences, the B<-tagsFromFile> and B<-addTagsFromFile> options are equivalent. 6) The B<-a> option (allow duplicate tags) is always in effect when copying -tags from I. +tags from I, but the highest priority tag is always copied last so +it takes precedence. 7) Structured tags are copied by default when copying tags. See the B<-struct> option for details. @@ -4600,13 +4748,26 @@ B<-struct> option for details. 8) With the redirection feature, copying a tag directly (ie. E'-IEI'E) is not the same as interpolating its value inside a string (ie. E'-IE$I'E) -for list-type tags, L, or tag -names containing wildcards. When copying directly, the values of each -matching source tag are copied individually to the destination tag (as if -they were separate assignments). However, when interpolated inside a -string, list items and the values of shortcut tags are concatenated (with a -separator set by the B<-sep> option), and wildcards are not allowed. Also, -UserParam variables are available only when interpolated in a string. +for list-type tags, L, tag names +containing wildcards, or UserParam variables. When copying directly, the +values of each matching source tag are copied individually to the +destination tag (as if they were separate assignments). However, when +interpolated inside a string, list items and the values of shortcut tags are +concatenated (with a separator set by the B<-sep> option), and wildcards are +not allowed. Also, UserParam variables are available only when interpolated +in a string. Another difference is that a minor warning is generated if a +tag doesn't exist when interpolating its value in a string (with C<$>), but +isn't when copying the tag directly. + +Finally, the behaviour is different when a destination tag or group of +C is used. When copying directly, a destination group and/or tag name +of C writes to the same family 1 group and/or tag name as the source. +But when interpolated in a string, the identity of the source tags are lost +and the value is written to all possible groups/tags. For example, the +string form must be used in the following command since the intent is to set +the value of all existing date/time tags from C: + + exiftool "-time:all<$createdate" -wm w FILE =item B<-x> I (B<-exclude>) @@ -4688,9 +4849,8 @@ coordinates as signed decimal degrees. If I is C or not specified, this option sets the ExifTool character encoding for output tag values when reading and input values when -writing. The default ExifTool encoding is C. If no I is -given, a list of available character sets is returned. Valid I -values are: +writing, with a default of C. If no I is given, a list of +available character sets is returned. Valid I values are: CHARSET Alias(es) Description ---------- --------------- ---------------------------------- @@ -4734,10 +4894,9 @@ encoding of various meta information formats. QuickTime Internal encoding of QuickTime strings MacRoman RIFF Internal encoding of RIFF strings 0 -See L for more -information about coded character sets, and the -L for more details about -the B<-charset> settings. +See L for more information about coded +character sets, and the L +for more details about the B<-charset> settings. =item B<-csv>[[+]=I] @@ -4769,10 +4928,14 @@ When exporting a CSV file, the B<-g> or B<-G> option adds group names to the tag headings. If the B<-a> option is used to allow duplicate tag names, the duplicate tags are only included in the CSV output if the column headings are unique. Adding the B<-G4> option ensures a unique column heading for -each tag. When exporting specific tags, the CSV columns are arranged in the -same order as the specified tags provided the column headings exactly match -the specified tag names, otherwise the columns are sorted in alphabetical -order. +each tag. The B<-b> option may be added to output binary data, encoded in +base64 if necessary (indicated by ASCII "base64:" as the first 7 bytes of +the value). Values may also be encoded in base64 if the B<-charset> option +is used and the value contains invalid characters. + +When exporting specific tags, the CSV columns are arranged in the same order +as the specified tags provided the column headings exactly match the +specified tag names, otherwise the columns are sorted in alphabetical order. When importing from a CSV file, only files specified on the command line are processed. Any extra entries in the CSV file are ignored. @@ -4788,7 +4951,9 @@ format options because it requires information from all input files to be buffered in memory before the output is written. This may result in excessive memory usage when processing a very large number of files with a single command. Also, it makes this option incompatible with the B<-w> -option. +option. When processing a large number of files, it is recommended to +either use the JSON (B<-j>) or XML (B<-X>) output format, or use B<-p> to +generate a fixed-column CSV file instead of using the B<-csv> option. =item B<-d> I (B<-dateFormat>) @@ -4806,14 +4971,15 @@ writing. Show tag ID number in decimal when extracting information. -=item B<-E>, B<-ex> (B<-escapeHTML>, B<-escapeXML>) +=item B<-E>, B<-ex>, B<-ec> (B<-escapeHTML>, B<-escapeXML>, B<-escapeC>) -Escape characters in output values for HTML (B<-E>) or XML (B<-ex>). For -HTML, all characters with Unicode code points above U+007F are escaped as -well as the following 5 characters: & (&) E<39> (') E (") -E (>) and E (<). For XML, only these 5 characters are -escaped. The B<-E> option is implied with B<-h>, and B<-ex> is implied with -B<-X>. The inverse conversion is applied when writing tags. +Escape characters in output tag values for HTML (B<-E>), XML (B<-ex>) or C +(B<-ec>). For HTML, all characters with Unicode code points above U+007F +are escaped as well as the following 5 characters: & (&) E<39> (') +E (") E (>) and E (<). For XML, only these 5 +characters are escaped. The B<-E> option is implied with B<-h>, and B<-ex> +is implied with B<-X>. For C, all control characters and the backslash are +escaped. The inverse conversion is applied when writing tags. =item B<-f> (B<-forcePrint>) @@ -4829,14 +4995,17 @@ B<-csv>=I feature. Organize output by tag group. I specifies a group family number, and may be 0 (general location), 1 (specific location), 2 (category), 3 -(document number) or 4 (instance number). B<-g0> is assumed if a family -number is not specified, and family numbers may be added wherever B<-g> is -mentioned in the documentation. Multiple families may be specified by -separating them with colons. By default the resulting group name is -simplified by removing any leading C and collapsing adjacent -identical group names, but this can be avoided by placing a colon before the -first family number (eg. B<-g:3:1>). Use the B<-listg> option to list group -names for a specified family. +(document number), 4 (instance number), 5 (metadata path) or 6 (EXIF/TIFF +format). B<-g0> is assumed if a family number is not specified, and family +numbers may be added wherever B<-g> is mentioned in the documentation. +Multiple families may be specified by separating them with colons. By +default the resulting group name is simplified by removing any leading +C and collapsing adjacent identical group names, but this can be +avoided by placing a colon before the first family number (eg. B<-g:3:1>). +Use the B<-listg> option to list group names for a specified family. The +SavePath and SaveFormat API options are automatically enabled if the +respective family 5 or 6 group names are requested. See the +L for more information. =item B<-G>[I][:I...] (B<-groupNames>) @@ -4884,10 +5053,10 @@ unique JSON names.) Adding the B<-D> or B<-H> option changes tag values to JSON objects with "val" and "id" fields, and adding B<-l> adds a "desc" field, and a "num" field if the numerical value is different from the converted "val". The B<-b> option may be added to output binary data, -encoded in base64 if necessary (indicated by "base64:" as the first 7 bytes -of the value), and B<-t> may be added to include tag table information (see -B<-t> for details). The JSON output is UTF-8 regardless of any B<-L> or -B<-charset> option setting, but the UTF-8 validation is disabled if a +encoded in base64 if necessary (indicated by ASCII "base64:" as the first 7 +bytes of the value), and B<-t> may be added to include tag table information +(see B<-t> for details). The JSON output is UTF-8 regardless of any B<-L> +or B<-charset> option setting, but the UTF-8 validation is disabled if a character set other than UTF-8 is specified. If I is specified, the file is imported and the tag definitions @@ -4932,18 +5101,42 @@ been implemented. May also be combined with B<-listx> to output descriptions in one language only. By default, ExifTool uses UTF-8 encoding for special characters, but the -the B<-L> or B<-charset> option may be used to invoke other encodings. +the B<-L> or B<-charset> option may be used to invoke other encodings. Note +that ExifTool uses Unicode::LineBreak if available to help preserve the +column alignment of the plain text output for languages with a +variable-width character set. Currently, the language support is not complete, but users are welcome to -help improve this by submitting their own translations. To submit a set of -translations, first use the B<-listx> option and redirect the output to a -file to generate an XML tag database, then add entries for other languages, -zip this file, and email it to phil at owl.phy.queensu.ca for inclusion in -ExifTool. +help improve this by submitting their own translations. To submit a +translation, follow these steps (you must have Perl installed for this): -Note: ExifTool uses Unicode::LineBreak if available to help preserve the -column alignment of the plain text output for languages with a -variable-width character set. +1. Download and unpack the latest Image-ExifTool full distribution. + +2. 'cd' into the Image-ExifTool directory. + +3. Run this command to make an XML file of the desired tags (eg. EXIF): + + ./exiftool -listx -exif:all > out.xml + +4. Copy this text into a file called 'import.pl' in the exiftool directory: + + push @INC, 'lib'; + require Image::ExifTool::TagInfoXML; + my $file = shift or die "Expected XML file name\n"; + $Image::ExifTool::TagInfoXML::makeMissing = shift; + Image::ExifTool::TagInfoXML::BuildLangModules($file,8); + +5. Run the 'import.pl' script to Import the XML file, generating the +'MISSING' entries for your language (eg. Russian): + + perl import.pl out.xml ru + +6. Edit the generated language module lib/Image/ExifTool/Lang/ru.pm, and +search and replace all 'MISSING' strings in the file with your translations. + +7. Email the module ('ru.pm' in this example) to philharvey66 at gmail.com + +8. Thank you!! =item B<-listItem> I @@ -4983,16 +5176,17 @@ when writing. For example, the following commands all have the same effect: Print output in the format specified by the given file or string. The argument is interpreted as a string unless a file of that name exists, in which case the string is loaded from the contents of the file. Tag names in -the format file or string begin with a C<$> symbol and may contain a leading -group names and/or a trailing C<#>. Case is not significant. Braces C<{}> -may be used around the tag name to separate it from subsequent text. Use -C<$$> to represent a C<$> symbol, and C<$/> for a newline. +the format file or string begin with a C<$> symbol and may contain leading +group names and/or a trailing C<#> (to disable print conversion). Case is +not significant. Braces C<{}> may be used around the tag name to separate +it from subsequent text. Use C<$$> to represent a C<$> symbol, and C<$/> +for a newline. Multiple B<-p> options may be used, each contributing a line (or more) of text to the output. Lines beginning with C<#[HEAD]> and C<#[TAIL]> are output before the first processed file and after the last processed file respectively. Lines beginning with C<#[SECT]> and C<#[ENDS]> are output -around each section of files. A section is defined as a group of +before and after each section of files. A section is defined as a group of consecutive files with the same section header (eg. files are grouped by directory if C<#[SECT]> contains C<$directory>). Lines beginning with C<#[BODY]> and lines not beginning with C<#> are output for each processed @@ -5012,7 +5206,7 @@ with this command: produces output like this: - -- Generated by ExifTool 11.16 -- + -- Generated by ExifTool 11.92 -- File: a.jpg - 2003:10:31 15:44:19 (f/5.6, 1/60s, ISO 100) File: b.jpg - 2006:05:23 11:57:38 @@ -5030,7 +5224,8 @@ If a specified tag does not exist, a minor warning is issued and the line with the missing tag is not printed. However, the B<-f> option may be used to set the value of missing tags to '-' (but this may be configured via the MissingTagValue API option), or the B<-m> option may be used to ignore minor -warnings and leave the missing values empty. +warnings and leave the missing values empty. Alternatively, B<-q -q> may be +used to simply suppress the warning messages. The L may be used to modify the values of individual tags with the B<-p> option. @@ -5079,10 +5274,10 @@ separator when reading, or split the value into individual characters when writing. For pure binary output (B<-b> used without B<-j>, B<-php> or B<-X>), the -first B<-sep> option specifies a list-item separator, and subsequent B<-sep> -options specify a terminator added to the end of the list (or after each -value if not a list). In these strings, C<\n>, C<\r> and C<\t> may be used -to represent a newline, carriage return and tab respectively. By default, +first B<-sep> option specifies a list-item separator, and a second B<-sep> +option specifies a terminator for the end of the list (or after each value +if not a list). In these strings, C<\n>, C<\r> and C<\t> may be used to +represent a newline, carriage return and tab respectively. By default, binary list items are separated by a newline, and no terminator is added. =item B<-sort>, B<--sort> @@ -5101,12 +5296,12 @@ Output structured XMP information instead of flattening to individual tags. This option works well when combined with the XML (B<-X>) and JSON (B<-j>) output formats. For other output formats, XMP structures and lists are serialized into the same format as when writing structured information (see -L for details). When -copying, structured tags are copied by default unless B<--struct> is used to -disable this feature (although flattened tags may still be copied by -specifying them individually unless B<-struct> is used). These options have -no effect when assigning new values since both flattened and structured tags -may always be used when writing. +L for details). When copying, structured +tags are copied by default unless B<--struct> is used to disable this +feature (although flattened tags may still be copied by specifying them +individually unless B<-struct> is used). These options have no effect when +assigning new values since both flattened and structured tags may always be +used when writing. =item B<-t> (B<-tab>) @@ -5237,10 +5432,11 @@ A special feature allows the copy number to be incremented for each processed file by using %C (upper case) instead of %c. This allows a sequential number to be added to output file names, even if the names are different. For %C, a copy number of zero is not omitted as it is with %c. -The number before the decimal place gives the starting index, the number -after the decimal place gives the field width. The following examples show -the output filenames when used with the command -C: +A leading '-' causes the number to be reset at the start of each new +directory, and '+' has no effect. The number before the decimal place gives +the starting index, the number after the decimal place gives the field +width. The following examples show the output filenames when used with the +command C: -w %C%f.txt # 0rose.txt, 1star.txt, 2jet.txt -w %f-%10C.txt # rose-10.txt, star-11.txt, jet-12.txt @@ -5287,10 +5483,10 @@ example, the following pairs of commands give the same result: exiftool test.jpg >> out.txt # shell redirection exiftool test.jpg -W+ out.txt # equivalent -W option -4) Adding the B<-v> option to B<-W> generates a list of the tags and output -file names instead of giving a verbose dump of the entire file. (Unless -appending all output to one file for each source file by using B<-W+> with -an output file I that does not contain %t, $g or %s.) +4) Adding the B<-v> option to B<-W> sends a list of the tags and output file +names to the console instead of giving a verbose dump of the entire file. +(Unless appending all output to one file for each source file by using +B<-W+> with an output file I that does not contain %t, $g or %s.) 5) Individual list items are stored in separate files when B<-W> is combined with B<-b>, but note that for separate files to be created %c or %C must be @@ -5339,14 +5535,15 @@ B<-o> option with an XMP extension for the output file. =item B<-a>, B<--a> (B<-duplicates>, B<--duplicates>) Allow (B<-a>) or suppress (B<--a>) duplicate tag names to be extracted. By -default, duplicate tags are suppressed unless the B<-ee> or B<-X> options -are used or the Duplicates option is enabled in the configuration file. -This option also has an affect when writing to allow duplicate Warning -messages to be shown. +default, duplicate tags are suppressed when reading unless the B<-ee> or +B<-X> options are used or the Duplicates option is enabled in the +configuration file. This option has an affect when writing only to allow +duplicate Warning messages to be shown. Duplicate tags are always extracted +when copying. =item B<-e> (B<--composite>) -Extract existing tags only -- don't calculate composite tags. +Extract existing tags only -- don't generate composite tags. =item B<-ee> (B<-extractEmbedded>) @@ -5358,13 +5555,13 @@ identify the originating document for extracted information. Embedded documents containing sub-documents are indicated with dashes in the family 3 group name. (eg. C is the 3rd sub-document of the 2nd embedded document.) Note that this option may increase processing time substantially, -especially for PDF files with many embedded images. +especially for PDF files with many embedded images or videos with streaming +metadata. When used with B<-ee>, the B<-p> option is evaluated for each embedded document as if it were a separate input file. This allows, for example, generation of GPS track logs from timed metadata in videos. See -L for -examples. +L for examples. =item B<-ext>[+] I, B<--ext> I (B<-extension>) @@ -5406,32 +5603,43 @@ permanently if B<-F> is used when writing EXIF to an image. eg) =item B<-fast>[I] -Increase speed of extracting information. With this option, ExifTool will -not scan to the end of a JPEG image to check for an AFCP or PreviewImage -trailer, or past the first comment in GIF images or the audio/video data in -WAV/AVI files to search for additional metadata. These speed benefits are -small when reading images directly from disk, but can be substantial if -piping images through a network connection. For more substantial speed -benefits, B<-fast2> also causes exiftool to avoid extracting any EXIF -MakerNote information. B<-fast3> avoids processing the file entirely, and -returns only an initial guess at FileType and the pseudo System tags. Has -no effect when writing. - -=item B<-fileOrder> [-]I +Increase speed of extracting information. With B<-fast> (or B<-fast1>), +ExifTool will not scan to the end of a JPEG image to check for an AFCP or +PreviewImage trailer, or past the first comment in GIF images or the +audio/video data in WAV/AVI files to search for additional metadata. These +speed benefits are small when reading images directly from disk, but can be +substantial if piping images through a network connection. For more +substantial speed benefits, B<-fast2> also causes exiftool to avoid +extracting any EXIF MakerNote information. B<-fast3> avoids extracting +metadata from the file, and returns only pseudo System tags, but still reads +the file header to obtain an educated guess at FileType. B<-fast4> doesn't +even read the file header, and returns only System tags and a FileType based +on the file extension. Has no effect when writing. + +Note that a separate B<-fast> setting may be used for evaluation of a B<-if> +condition, or when ordering files with the B<-fileOrder> option. See the +B<-if> and B<-fileOrder> options for details. + +=item B<-fileOrder>[I] [-]I Set file processing order according to the sorted value of the specified I. For example, to process files in order of date: exiftool -fileOrder DateTimeOriginal DIR -Additional B<-fileOrder> options may be added for secondary sort keys. +Additional B<-fileOrder> options may be added for secondary sort keys. Numbers are sorted numerically, and all other values are sorted -alphabetically. The sort order may be reversed by prefixing the tag name -with a C<-> (eg. C<-fileOrder -createdate>). Print conversion of the sorted -values is disabled with the B<-n> option, or a C<#> appended to the tag -name. Other formatting options (eg. B<-d>) have no effect on the sorted -values. Note that the B<-fileOrder> option has a large performance impact -since it involves an additional processing pass of each file. +alphabetically. Files missing the specified tag are sorted last. The sort +order may be reversed by prefixing the tag name with a C<-> (eg. +C<-fileOrder -createdate>). Print conversion of the sorted values is +disabled with the B<-n> option, or a C<#> appended to the tag name. Other +formatting options (eg. B<-d>) have no effect on the sorted values. Note +that the B<-fileOrder> option can have a large performance impact since it +involves an additional processing pass of each file, but this impact may be +reduced by specifying a I for the B<-fast> level used during the +metadata-extraction phase. For example, B<-fileOrder4> may be used if +I is a pseudo System tag. If multiple B<-fileOrder> options are used, +the extraction is done at the lowest B<-fast> level. =item B<-i> I (B<-ignore>) @@ -5442,7 +5650,7 @@ more than one directory name. A special I value of C (case sensitive) may be specified to ignore symbolic links when the B<-r> option is used. -=item B<-if> I +=item B<-if>[I] I Specify a condition to be evaluated before processing each I. I is a Perl-like logic expression containing tag names prefixed by C<$> @@ -5468,6 +5676,13 @@ conditions must be satisfied to process the file. Returns an exit status of # find images containing a specific keyword (case insensitive) exiftool -if '$keywords =~ /harvey/i' -filename dir +Adding I to the B<-if> option causes a separate processing pass to be +executed for evaluating I at a B<-fast> level given by I (see the +B<-fast> option documentation for details). Without I, only one +processing pass is done at the level specified by the B<-fast> option. For +example, using B<-if4> is possible if I uses only pseudo System tags, +and may significantly speed processing if enough files fail the condition. + Notes: 1) The B<-n> and B<-b> options also apply to tags used in I. @@ -5569,16 +5784,19 @@ of a temporary file before deleting the temporary. The extra step results in slower performance, so the B<-overwrite_original> option should be used instead unless necessary. +Note that this option reverts to the behaviour of the B<-overwrite_original> +option when also writing the FileName and/or Directory tags. + =item B<-P> (B<-preserve>) Preserve the filesystem modification date/time (C) of the original file when writing. Note that some filesystems store a creation -date (Windows C or Mac C) -which is not affected by this option. The creation date is preserved on -Windows systems where Win32API::File and Win32::API are available regardless -of this setting. For other systems, the B<-overwrite_original_in_place> -option may be used if necessary to preserve the creation date. This option -is superseded by any value written to the FileModifyDate tag. +date (ie. C on Windows and Mac systems) which is not +affected by this option. This creation date is preserved on Windows systems +where Win32API::File and Win32::API are available regardless of this +setting. For other systems, the B<-overwrite_original_in_place> option may +be used if necessary to preserve the creation date. The B<-P> option is +superseded by any value written to the FileModifyDate tag. =item B<-password> I @@ -5668,7 +5886,7 @@ available). When writing, causes compressed information to be written if supported by the metadata format (eg. compressed textual metadata in PNG), disables the recommended padding in embedded XMP (saving 2424 bytes when writing XMP in a file), and writes XMP in shorthand format -- the equivalent -of setting the API Compress, Compact and XMPShorthand options to 1. +of setting the API Compress=1 and Compact="NoPadding,Shorthand". =back @@ -5757,6 +5975,11 @@ addition system information (see the README file of the full distribution for more details about optional libraries), or B<-v2> to also list the Perl include directories. +=item B<--> + +Indicates the end of options. Any remaining arguments are treated as file +names, even if they begin with a dash (C<->). + =back =head3 Special features @@ -5766,12 +5989,12 @@ include directories. =item B<-geotag> I Geotag images from the specified GPS track log file. Using the B<-geotag> -option is equivalent to writing a value to the C tag. After the -B<-geotag> option has been specified, the value of the C tag is -written to define a date/time for the position interpolation. If C -is not specified, the value is copied from C (the C<#> is -added to copy the unformatted value, avoiding potential conflicts with the -B<-d> option). For example, the following two commands are equivalent: +option is equivalent to writing a value to the C tag. The GPS +position is interpolated from the track at a time specified by the value +written to the C tag. If C is not specified, the value is +copied from C (the C<#> is added to copy the unformatted +value, avoiding potential conflicts with the B<-d> option). For example, +the following two commands are equivalent: exiftool -geotag trk.log image.jpg exiftool -geotag trk.log "-Geotime or C may be specified to write only EXIF or XMP -tags respectively. Note that GPSPitch and GPSRoll are non-standard, and -require user-defined tags in order to be written. +GPSImgDirectionRef, GPSPitch, GPSRoll, AmbientTemperature and +CameraElevationAngle. By default, tags are created in EXIF, and updated in +XMP only if they already exist. However, C or C +may be specified to write only EXIF or XMP tags respectively. Note that +GPSPitch and GPSRoll are non-standard, and require user-defined tags in +order to be written. The C tag may be used to specify a time correction which is applied to each C value for synchronization with GPS time. For example, @@ -5796,7 +6020,6 @@ seconds behind GPS: exiftool -geosync=+1:20 -geotag a.log DIR -C must be set before C (if specified) to be effective. Advanced C features allow a linear time drift correction and synchronization from previously geotagged images. See "geotag.html" in the full ExifTool distribution for more information. @@ -5810,9 +6033,9 @@ Windows) to prevent filename expansion. For example: exiftool -geotag "TRACKDIR/*.log" IMAGEDIR Currently supported track file formats are GPX, NMEA RMC/GGA/GLL, KML, IGC, -Garmin XML and TCX, Magellan PMGNTRK, Honeywell PTNTHPR, Winplus Beacon -text, and Bramor gEO log files. See L for examples. -Also see "geotag.html" in the full ExifTool distribution and the +Garmin XML and TCX, Magellan PMGNTRK, Honeywell PTNTHPR, Bramor gEO, Winplus +Beacon TXT, and GPS/IMU CSV files. See L for +examples. Also see "geotag.html" in the full ExifTool distribution and the L for more details and for information about geotag configuration options. @@ -5838,11 +6061,11 @@ I string. For example: Add features from specified plug-in I. Currently, the MWG module is the only plug-in module distributed with exiftool. This module adds read/write support for tags as recommended by the Metadata Working Group. -To save typing, C<-use MWG> is assumed if the C group is specified for -any tag on the command line. See the -L for more -details. Note that this option is not reversible, and remains in effect -until the application terminates, even across the C<-execute> option. +As a convenience, C<-use MWG> is assumed if the C group is specified +for any tag on the command line. See the L for more details. Note +that this option is not reversible, and remains in effect until the +application terminates, even across the C<-execute> option. =back @@ -5911,7 +6134,7 @@ line and applies to all B<-execute>'d commands. The I must exist relative to the current working directory or the exiftool application directory unless an absolute path is specified. Loading of the default config file may be disabled by setting I to an empty string (ie. -""). See L and +""). See L and config_files/example.config in the full ExifTool distribution for details about the configuration file syntax. @@ -5946,9 +6169,10 @@ previews in a directory where other JPG images may exist: exiftool -ext nef -tagsfromfile @ -srcfile %d%f.jpg dir -If than one B<-srcfile> option is specified, the files are tested in order -and the first existing source file is processed. If none of the source -files already exist, then exiftool uses the first B<-srcfile> specified. +If more than one B<-srcfile> option is specified, the files are tested in +order and the first existing source file is processed. If none of the +source files already exist, then exiftool uses the first B<-srcfile> +specified. A I of C<@> may be used to represent the original I, which may be useful when specifying multiple B<-srcfile> options (eg. to fall back to @@ -6027,11 +6251,11 @@ placing braces around the tag name and inserting the expression after the name, separated by a semicolon (ie. C<${TAG;EXPR}>). The expression acts on the value of the tag through the default input variable (C<$_>), and has access to the full ExifTool API through the current ExifTool object -(C<$self>). It may contain any valid Perl code, including translation -(C) and substitution (C) operations, but note that braces -within the expression must be balanced. The example below prints the camera -Make with spaces translated to underlines, and multiple consecutive -underlines replaced by a single underline: +(C<$self>) and the tag key (C<$tag>). It may contain any valid Perl code, +including translation (C) and substitution (C) operations, but +note that braces within the expression must be balanced. The example below +prints the camera Make with spaces translated to underlines, and multiple +consecutive underlines replaced by a single underline: exiftool -p '${make;tr/ /_/;s/__+/_/g}' image.jpg @@ -6050,19 +6274,31 @@ used in file names.) =head4 Helper functions -ExifTool provides a C utility to simplify reformatting of -individual date/time values. The function acts on a standard EXIF-formatted -date/time value in C<$_> and formats it according to the specified format -string (see the B<-d> option). To avoid trying to reformat an already -formatted date/time value, a C<#> must be added to the tag name (as in the -example below) if the B<-d> option is also used. For example: +C + +Simplifies reformatting of individual date/time values. This function acts +on a standard EXIF-formatted date/time value in C<$_> and formats it +according to the specified format string (see the B<-d> option). To avoid +trying to reformat an already-formatted date/time value, a C<#> must be +added to the tag name (as in the example below) if the B<-d> option is also +used. For example: exiftool -p '${createdate#;DateFmt("%Y-%m-%d_%H%M%S")}' a.jpg -A C utility is also provided to remove duplicate items from a list -with a separator specified by the B<-sep> option. This function is most -useful when copying list-type tags. For example, the following command may -be used to remove duplicate Keywords: +C + +Shifts EXIF-formatted date/time string by a specified amount. Start with a +leading minus sign to shift backwards in time. See +L for details about +shift syntax. For example, to shift a date/time value back by one year: + + exiftool -p '${createdate;ShiftTime("-1:0:0 0")}' a.jpg + +C + +Removes duplicate items from a list with a separator specified by the +B<-sep> option. This function is most useful when copying list-type tags. +For example, the following command may be used to remove duplicate Keywords: exiftool -sep '##' '-keywords<${keywords;NoDups}' a.jpg @@ -6089,11 +6325,11 @@ ExifTool 9.79 and later allow the file name encoding to be specified with C<-charset filename=CHARSET>, where C is the name of a valid ExifTool character set, preferably C (see the B<-charset> option for a complete list). Setting this triggers the use of Windows wide-character i/o -routines, thus providing support for all Unicode file names. But note that -it is not trivial to pass properly encoded file names on the Windows command -line (see L for -details), so placing them in a UTF-8 encoded B<-@> argfile and using -C<-charset filename=utf8> is recommended if possible. +routines, thus providing support for most Unicode file names (see note 4). +But note that it is not trivial to pass properly encoded file names on the +Windows command line (see L for details), +so placing them in a UTF-8 encoded B<-@> argfile and using C<-charset +filename=utf8> is recommended if possible. A warning is issued if a specified filename contains special characters and the filename character set was not provided. However, the warning may be @@ -6125,6 +6361,9 @@ like Cygwin. 3) See L below for a note about editing read-only files with Unicode names. +4) Unicode file names with surrogate pairs (code points over U+FFFF) still +cause problems. + =head1 WRITING READ-ONLY FILES In general, ExifTool may be used to write metadata to read-only files @@ -6139,6 +6378,14 @@ there are three cases where file write permission is also required: B<-overwrite_original> option is used, or b) the C<_original> backup already exists. +Hidden files in Windows behave as read-only files when attempting to write +any real tags to the file -- an error is generated when using the +B<-overwrite_original_in_place>, otherwise writing should be successful and +the hidden attribute will be removed. But the B<-if> option may be used to +avoid processing hidden files (provided Win32API::File is available): + + exiftool -if "$fileattributes !~ /Hidden/" ... + =head1 READING EXAMPLES B: Beware when cutting and pasting these examples into your terminal! @@ -6153,7 +6400,11 @@ arguments containing special characters. =item exiftool -a -u -g1 a.jpg Print all meta information in an image, including duplicate and unknown -tags, sorted by group (for family 1). +tags, sorted by group (for family 1). For performance reasons, this command +may not extract all available metadata. (Metadata in embedded documents, +metadata extracted by external utilities, and metadata requiring excessive +processing time may not be extracted). Add C<-ee> and C<-api RequestAll=3> +to the command to extract absolutely everything available. =item exiftool -common dir @@ -6375,8 +6626,8 @@ Write ICC_Profile to an image from a C<.icc> file of the same name. =item exiftool -hierarchicalkeywords='{keyword=one,children={keyword=B}}' -Write structured XMP information. See -L for more details. +Write structured XMP information. See L +for more details. =item exiftool -trailer:all= image.jpg @@ -6537,8 +6788,8 @@ an extra '%' must be added to pass these codes through the date/time parser. (And further note that in a Windows batch file, all '%' characters must also be escaped, so in this extreme case '%%%%f' is necessary to pass a simple '%f' through the two levels of parsing.) See -L for additional -documentation and examples. +L for additional documentation and +examples. =over 5 @@ -6597,8 +6848,7 @@ CreateDate and FileNumber tags, in the form "20060507_118-1861.jpg". ExifTool implements geotagging via 3 special tags: Geotag (which for convenience is also implemented as an exiftool option), Geosync and Geotime. The examples below highlight some geotagging features. See -L for additional -documentation. +L for additional documentation. =over 5 @@ -6703,7 +6953,7 @@ the commands if B<-execute> was used). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey +Copyright 2003-2020, Phil Harvey This is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/File/RandomAccess.pm b/src/Image-ExifTool/lib/File/RandomAccess.pm index c689f56b..6a9fa300 100644 --- a/src/Image-ExifTool/lib/File/RandomAccess.pm +++ b/src/Image-ExifTool/lib/File/RandomAccess.pm @@ -25,7 +25,7 @@ # # May also be used for string i/o (just pass a scalar reference) # -# Legal: Copyright (c) 2003-2018 Phil Harvey (phil at owl.phy.queensu.ca) +# Legal: Copyright (c) 2003-2020 Phil Harvey (philharvey66 at gmail.com) # This library is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. #------------------------------------------------------------------------------ diff --git a/src/Image-ExifTool/lib/File/RandomAccess.pod b/src/Image-ExifTool/lib/File/RandomAccess.pod index d3a26f37..2ae6184a 100644 --- a/src/Image-ExifTool/lib/File/RandomAccess.pod +++ b/src/Image-ExifTool/lib/File/RandomAccess.pod @@ -3,7 +3,7 @@ # # Description: Buffer to support random access reading of sequential file # -# Legal: Copyright (c) 2003-2018 Phil Harvey (phil at owl.phy.queensu.ca) +# Legal: Copyright (c) 2003-2020 Phil Harvey (philharvey66 at gmail.com) # This library is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. #------------------------------------------------------------------------------ @@ -236,7 +236,7 @@ the end of file is not allowed. =head1 AUTHOR -Copyright 2003-2018 Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020 Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool.pm b/src/Image-ExifTool/lib/Image/ExifTool.pm index 40a86b7a..4999760a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool.pm @@ -3,12 +3,12 @@ # # Description: Read and write meta information # -# URL: http://owl.phy.queensu.ca/~phil/exiftool/ +# URL: https://exiftool.org/ # # Revisions: Nov. 12/2003 - P. Harvey Created # (See html/history.html for revision history) # -# Legal: Copyright (c) 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +# Legal: Copyright (c) 2003-2020, Phil Harvey (philharvey66 at gmail.com) # This library is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. #------------------------------------------------------------------------------ @@ -19,15 +19,16 @@ use strict; require 5.004; # require 5.004 for UNIVERSAL::isa (otherwise 5.002 would do) require Exporter; use File::RandomAccess; +use overload; use vars qw($VERSION $RELEASE @ISA @EXPORT_OK %EXPORT_TAGS $AUTOLOAD @fileTypes %allTables @tableOrder $exifAPP1hdr $xmpAPP1hdr $xmpExtAPP1hdr $psAPP13hdr $psAPP13old @loadAllTables %UserDefined $evalWarning %noWriteFile %magicNumber @langs $defaultLang %langName %charsetName %mimeType $swapBytes $swapWords $currentByteOrder %unpackStd - %jpegMarker %specialTags %fileTypeLookup); + %jpegMarker %specialTags %fileTypeLookup $testLen $exePath); -$VERSION = '11.16'; +$VERSION = '11.92'; $RELEASE = ''; @ISA = qw(Exporter); %EXPORT_TAGS = ( @@ -41,7 +42,7 @@ $RELEASE = ''; DataAccess => [qw( ReadValue GetByteOrder SetByteOrder ToggleByteOrder Get8u Get8s Get16u Get16s Get32u Get32s Get64u GetFloat GetDouble GetFixed32s Write - WriteValue Tell Set8u Set8s Set16u Set32u + WriteValue Tell Set8u Set8s Set16u Set32u Set64u )], Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)], Vars => [qw(%allTables @tableOrder @fileTypes)], @@ -53,7 +54,7 @@ Exporter::export_ok_tags(keys %EXPORT_TAGS); # test for problems that can arise if encoding.pm is used { my $t = "\xff"; die "Incompatible encoding!\n" if ord($t) != 0xff; } -# The following functions defined in Image::ExifTool::Writer are declared +# The following functions defined in Image::ExifTool::Writer.pl are declared # here so their prototypes will be available. These Writer routines will be # autoloaded when any of them is called. sub SetNewValue($;$$%); @@ -76,6 +77,8 @@ sub AddUserDefinedTags($%); # non-public routines below sub InsertTagValues($$$;$$$); sub IsWritable($); +sub IsSameFile($$$); +sub IsRawType($); sub GetNewFileName($$); sub LoadAllTables(); sub GetNewTagInfoList($;$); @@ -85,8 +88,10 @@ sub Get64s($$); sub Get64u($$); sub GetFixed64s($$); sub GetExtended($$); +sub Set64u(@); sub DecodeBits($$;$); sub EncodeBits($$;$$); +sub Filter($@); sub HexDump($;$%); sub DumpTrailer($$); sub DumpUnknownTrailer($$); @@ -105,7 +110,7 @@ sub CheckBinaryData($$$); sub WriteTIFF($$$); sub PackUTF8(@); sub UnpackUTF8($); -sub SetPreferredByteOrder($); +sub SetPreferredByteOrder($;$); sub CopyBlock($$$); sub CopyFileAttrs($$$); sub TimeNow(;$$); @@ -123,7 +128,7 @@ sub SetFileTime($$;$$$$); sub DoEscape($$); sub ConvertFileSize($); sub ParseArguments($;@); #(defined in attempt to avoid mod_perl problem) -sub ReadValue($$$$$;$); +sub ReadValue($$$;$$$); # list of main tag tables to load in LoadAllTables() (sub-tables are recursed # automatically). Note: They will appear in this order in the documentation @@ -131,15 +136,15 @@ sub ReadValue($$$$$;$); @loadAllTables = qw( PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw Lytro MinoltaRaw PanasonicRaw SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 BMP::Extra BPG BPG::Extensions - PICT PNG MNG FLIF DjVu DPX OpenEXR MIFF PGF PSP PhotoCD Radiance PDF + PICT PNG MNG FLIF DjVu DPX OpenEXR MIFF PCX PGF PSP PhotoCD Radiance PDF PostScript Photoshop::Header Photoshop::Layers Photoshop::ImageData FujiFilm::RAF FujiFilm::IFD Samsung::Trailer Sony::SRF2 Sony::SR2SubIFD Sony::PMP ITC ID3 FLAC Ogg Vorbis APE APE::NewHeader APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime QuickTime::ImageFile QuickTime::Stream Matroska MOI MXF DV Flash Flash::FLV Real::Media - Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM MIE JSON HTML + Real::Audio Real::Metafile Red RIFF AIFF ASF WTV DICOM FITS MIE JSON HTML XMP::SVG Palm Palm::MOBI Palm::EXTH Torrent EXE EXE::PEVersion EXE::PEString - EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard + EXE::MachO EXE::PEF EXE::ELF EXE::AR EXE::CHM LNK Font VCard Text VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS::MDItem MacOS::XAttr FlashPix::DocTable ); @@ -179,9 +184,10 @@ $defaultLang = 'en'; # default language @fileTypes = qw(JPEG EXV CRW DR4 TIFF GIF MRW RAF X3F JP2 PNG MIE MIFF PS PDF PSD XMP BMP BPG PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV OGG FLAC APE MPC MKV MXF DV PMP IND PGF ICC ITC FLIR FLIF FPF LFP - HTML VRD RTF XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2 TAR - RWZ EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS PHP - WTV Torrent VCard LRI R3D AA PDB MOI ISO JSON MP3 DICOM PCD); + HTML VRD RTF FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2 + TAR EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS PHP + PCX DCX DWF DWG WTV Torrent VCard LRI R3D AA PDB MOI ISO ALIAS + JSON MP3 DICOM PCD TXT); # file types that we can write (edit) my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS @@ -191,9 +197,9 @@ my %writeTypes; # lookup for writable file types (hash filled if required) # file extensions that we can't write for various base types %noWriteFile = ( TIFF => [ qw(3FR DCR K25 KDC SRF) ], - XMP => [ 'SVG', 'INX' ], - JP2 => [ 'J2C', 'JPC' ], - MOV => [ 'HEIC', 'HEIF' ], + XMP => [ qw(SVG INX) ], + JP2 => [ qw(J2C JPC) ], + MOV => [ qw(INSV) ], ); # file types that we can create from scratch @@ -222,6 +228,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); AIFC => ['AIFF', 'Audio Interchange File Format Compressed'], AIFF => ['AIFF', 'Audio Interchange File Format'], AIT => 'AI', + ALIAS=> ['ALIAS','MacOS file alias'], APE => ['APE', "Monkey's Audio format"], APNG => ['PNG', 'Animated Portable Network Graphics'], ARW => ['TIFF', 'Sony Alpha RAW format'], @@ -229,6 +236,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); ASF => ['ASF', 'Microsoft Advanced Systems Format'], AVC => ['AVC', 'Advanced Video Connection'], # (extensions are actually _AU,_AD,_IM,_ID) AVI => ['RIFF', 'Audio Video Interleaved'], + AVIF => ['MOV', 'AV1 Image File Format'], AZW => 'MOBI', # (see http://wiki.mobileread.com/wiki/AZW) AZW3 => 'MOBI', BMP => ['BMP', 'Windows Bitmap'], @@ -243,10 +251,12 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); CRM => ['MOV', 'Canon RAW Movie'], CRW => ['CRW', 'Canon RAW format'], CS1 => ['PSD', 'Sinar CaptureShop 1-Shot RAW'], + CSV => ['TXT', 'Comma-Separated Values'], DC3 => 'DICM', DCM => 'DICM', DCP => ['TIFF', 'DNG Camera Profile'], DCR => ['TIFF', 'Kodak Digital Camera RAW'], + DCX => ['DCX', 'Multi-page PC Paintbrush'], DEX => ['DEX', 'Dalvik Executable format'], DFONT=> ['Font', 'Macintosh Data fork Font'], DIB => ['BMP', 'Device Independent Bitmap'], @@ -273,6 +283,8 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); DV => ['DV', 'Digital Video'], DVB => ['MOV', 'Digital Video Broadcasting'], 'DVR-MS'=>['ASF', 'Microsoft Digital Video recording'], + DWF => ['DWF', 'Autodesk drawing (Design Web Format)'], + DWG => ['DWG', 'AutoCAD Drawing'], DYLIB=> ['EXE', 'Mach-O Dynamic Link Library'], EIP => ['ZIP', 'Capture One Enhanced Image Package'], EPS => ['EPS', 'Encapsulated PostScript Format'], @@ -290,6 +302,8 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); F4P => ['MOV', 'Adobe Flash Player 9+ Protected'], F4V => ['MOV', 'Adobe Flash Player 9+ Video'], FFF => [['TIFF','FLIR'], 'Hasselblad Flexible File Format'], + FIT => 'FITS', + FITS => ['FITS', 'Flexible Image Transport System'], FLAC => ['FLAC', 'Free Lossless Audio Codec'], FLA => ['FPX', 'Macromedia/Adobe Flash project'], FLIF => ['FLIF', 'Free Lossless Image Format'], @@ -305,6 +319,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); HDR => ['HDR', 'Radiance RGBE High Dynamic Range'], HEIC => ['MOV', 'High Efficiency Image Format still image'], HEIF => ['MOV', 'High Efficiency Image Format'], + HIF => 'HEIF', HTM => 'HTML', HTML => ['HTML', 'HyperText Markup Language'], ICAL => 'ICS', @@ -316,11 +331,13 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); IND => ['IND', 'Adobe InDesign'], INDD => ['IND', 'Adobe InDesign Document'], INDT => ['IND', 'Adobe InDesign Template'], + INSV => ['MOV', 'Insta360 Video'], + INSP => ['JPEG', 'Insta360 Picture'], INX => ['XMP', 'Adobe InDesign Interchange'], ISO => ['ISO', 'ISO 9660 disk image'], ITC => ['ITC', 'iTunes Cover Flow'], J2C => ['JP2', 'JPEG 2000 codestream'], - J2K => 'JP2', + J2K => 'J2C', JNG => ['PNG', 'JPG Network Graphics'], JP2 => ['JP2', 'JPEG 2000 file'], # JP4? - looks like a JPEG but the image data is different @@ -342,6 +359,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); LFR => 'LFP', # (Light Field RAW) LNK => ['LNK', 'Windows shortcut'], LRI => ['LRI', 'Light RAW'], + LRV => ['MOV', 'Low-Resolution Video'], M2T => 'M2TS', M2TS => ['M2TS', 'MPEG-2 Transport Stream'], M2V => ['MPEG', 'MPEG-2 Video'], @@ -399,6 +417,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); PBM => ['PPM', 'Portable BitMap'], PCD => ['PCD', 'Kodak Photo CD Image Pac'], PCT => 'PICT', + PCX => ['PCX', 'PC Paintbrush'], PDB => ['PDB', 'Palm Database'], PDF => ['PDF', 'Adobe Portable Document Format'], PEF => ['TIFF', 'Pentax (RAW) Electronic Format'], @@ -420,6 +439,8 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); POT => ['FPX', 'Microsoft PowerPoint Template'], POTM => [['ZIP','FPX'], 'Office Open XML Presentation Template Macro-enabled'], POTX => [['ZIP','FPX'], 'Office Open XML Presentation Template'], + PPAM => [['ZIP','FPX'], 'Office Open XML Presentation Addin Macro-enabled'], + PPAX => [['ZIP','FPX'], 'Office Open XML Presentation Addin'], PPM => ['PPM', 'Portable Pixel Map'], PPS => ['FPX', 'Microsoft PowerPoint Slideshow'], PPSM => [['ZIP','FPX'], 'Office Open XML Presentation Slideshow Macro-enabled'], @@ -469,7 +490,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); SVG => ['XMP', 'Scalable Vector Graphics'], SWF => ['SWF', 'Shockwave Flash'], TAR => ['TAR', 'TAR archive'], - THM => ['JPEG', 'Canon Thumbnail'], + THM => ['JPEG', 'Thumbnail'], THMX => [['ZIP','FPX'], 'Office Open XML Theme'], TIF => 'TIFF', TIFF => ['TIFF', 'Tagged Image File Format'], @@ -478,6 +499,7 @@ my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV); TTC => ['Font', 'True Type Font Collection'], TTF => ['Font', 'True Type Font'], TUB => 'PSP', + TXT => ['TXT', 'Text file'], VCARD=> ['VCard','Virtual Card'], VCF => 'VCARD', VOB => ['MPEG', 'Video Object'], @@ -541,6 +563,7 @@ my %fileDescription = ( AAE => 'application/vnd.apple.photos', AI => 'application/vnd.adobe.illustrator', AIFF => 'audio/x-aiff', + ALIAS=> 'application/x-macos', APE => 'audio/x-monkeys-audio', APNG => 'image/apng', ASF => 'video/x-ms-asf', @@ -551,11 +574,15 @@ my %fileDescription = ( BZ2 => 'application/bzip2', 'Canon 1D RAW' => 'image/x-raw', # (uses .TIF file extension) CHM => 'application/x-chm', + COS => 'application/octet-stream', #PH (NC) CR2 => 'image/x-canon-cr2', CR3 => 'image/x-canon-cr3', CRM => 'video/x-canon-crm', CRW => 'image/x-canon-crw', + CSV => 'text/csv', + DCP => 'application/octet-stream', #PH (NC) DCR => 'image/x-kodak-dcr', + DCX => 'image/dcx', DEX => 'application/octet-stream', DFONT=> 'application/x-dfont', DICOM=> 'application/dicom', @@ -569,21 +596,28 @@ my %fileDescription = ( DOTM => 'application/vnd.ms-word.template.macroEnabledTemplate', DOTX => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', DPX => 'image/x-dpx', + DR4 => 'application/octet-stream', #PH (NC) DS2 => 'audio/x-ds2', DSS => 'audio/x-dss', DV => 'video/x-dv', 'DVR-MS' => 'video/x-ms-dvr', + DWF => 'model/vnd.dwf', + DWG => 'image/vnd.dwg', EIP => 'application/x-captureone', #(NC) EPS => 'application/postscript', ERF => 'image/x-epson-erf', EXE => 'application/octet-stream', + EXR => 'image/x-exr', EXV => 'image/x-exv', FFF => 'image/x-hasselblad-fff', + FITS => 'image/fits', FLA => 'application/vnd.adobe.fla', FLAC => 'audio/flac', FLIF => 'image/flif', + FLIR => 'image/x-flir-fff', #PH (NC) FLV => 'video/x-flv', Font => 'application/x-font-type1', # covers PFA, PFB and PFM (not sure about PFM) + FPF => 'image/x-flir-fpf', #PH (NC) FPX => 'image/vnd.fpx', GIF => 'image/gif', GPR => 'image/x-gopro-gpr', @@ -599,22 +633,23 @@ my %fileDescription = ( INX => 'application/x-indesign-interchange', #PH (NC) ISO => 'application/x-iso9660-image', ITC => 'application/itunes', - JNG => 'image/jng', J2C => 'image/x-j2c', #PH (NC) + JNG => 'image/jng', JP2 => 'image/jp2', JPEG => 'image/jpeg', JPM => 'image/jpm', JPX => 'image/jpx', JSON => 'application/json', + JXR => 'image/jxr', K25 => 'image/x-kodak-k25', KDC => 'image/x-kodak-kdc', KEY => 'application/x-iwork-keynote-sffkey', LFP => 'image/x-lytro-lfp', #PH (NC) LNK => 'application/octet-stream', LRI => 'image/x-light-lri', - MAX => 'application/x-3ds', M2T => 'video/mpeg', M2TS => 'video/m2ts', + MAX => 'application/x-3ds', MEF => 'image/x-mamiya-mef', MIE => 'application/x-mie', MIFF => 'application/x-magick-image', @@ -623,6 +658,7 @@ my %fileDescription = ( MKV => 'video/x-matroska', MNG => 'video/mng', MOBI => 'application/x-mobipocket-ebook', + MOI => 'application/octet-stream', #PH (NC) MOS => 'image/x-raw', MOV => 'video/quicktime', MP3 => 'audio/mpeg', @@ -644,12 +680,12 @@ my %fileDescription = ( ODT => 'application/vnd.oasis.opendocument.text', OGG => 'audio/ogg', OGV => 'video/ogg', - EXR => 'image/x-exr', ORF => 'image/x-olympus-orf', OTF => 'application/x-font-otf', PAGES=> 'application/x-iwork-pages-sffpages', PBM => 'image/x-portable-bitmap', PCD => 'image/x-photo-cd', + PCX => 'image/pcx', PDB => 'application/vnd.palm', PDF => 'application/pdf', PEF => 'image/x-pentax-pef', @@ -659,10 +695,13 @@ my %fileDescription = ( PHP => 'application/x-httpd-php', PICT => 'image/pict', PLIST=> 'application/xml', # (binary PLIST format is 'application/x-plist', recognized at run time) + PMP => 'image/x-sony-pmp', #PH (NC) PNG => 'image/png', POT => 'application/vnd.ms-powerpoint', POTM => 'application/vnd.ms-powerpoint.template.macroEnabled', POTX => 'application/vnd.openxmlformats-officedocument.presentationml.template', + PPAM => 'application/vnd.ms-powerpoint.addin.macroEnabled', + PPAX => 'application/vnd.openxmlformats-officedocument.presentationml.addin', # (NC, PH invented) PPM => 'image/x-portable-pixmap', PPS => 'application/vnd.ms-powerpoint', PPSM => 'application/vnd.ms-powerpoint.slideshow.macroEnabled', @@ -689,6 +728,7 @@ my %fileDescription = ( RW2 => 'image/x-panasonic-rw2', RWL => 'image/x-leica-rwl', RWZ => 'image/x-rawzor', #(duplicated in Rawzor.pm) + SEQ => 'image/x-flir-seq', #PH (NC) SKETCH => 'application/sketch', SR2 => 'image/x-sony-sr2', SRF => 'image/x-sony-srf', @@ -701,7 +741,9 @@ my %fileDescription = ( Torrent => 'application/x-bittorrent', TTC => 'application/x-font-ttf', TTF => 'application/x-font-ttf', + TXT => 'text/plain', VCard=> 'text/vcard', + VRD => 'application/octet-stream', #PH (NC) VSD => 'application/x-visio', WDP => 'image/vnd.ms-photo', WEBM => 'video/webm', @@ -731,6 +773,7 @@ my %fileDescription = ( # - module name '0' indicates a recognized but unsupported file my %moduleName = ( AA => 'Audible', + ALIAS=> 0, AVC => 0, BTF => 'BigTIFF', BZ2 => 0, @@ -739,8 +782,11 @@ my %moduleName = ( COS => 'CaptureOne', DEX => 0, DOCX => 'OOXML', + DCX => 0, DR4 => 'CanonVRD', DSS => 'Olympus', + DWF => 0, + DWG => 0, EPS => 'PostScript', EXIF => '', EXR => 'OpenEXR', @@ -777,19 +823,23 @@ my %moduleName = ( SWF => 'Flash', TAR => 0, TIFF => '', + TXT => 'Text', VRD => 'CanonVRD', WMF => 0, X3F => 'SigmaRaw', XCF => 'GIMP', ); +$testLen = 1024; # number of bytes to read when testing for magic number + # quick "magic number" file test used to avoid loading module unnecessarily: -# - regular expression evaluated on first 1024 bytes of file +# - regular expression evaluated on first $testLen bytes of file # - must match beginning at first byte in file # - this test must not be more stringent than module logic %magicNumber = ( AA => '.{4}\x57\x90\x75\x36', AIFF => '(FORM....AIF[FC]|AT&TFORM)', + ALIAS=> "book\0\0\0\0mark\0\0\0\0", APE => '(MAC |APETAGEX|ID3)', ASF => '\x30\x26\xb2\x75\x8e\x66\xcf\x11\xa6\xd9\x00\xaa\x00\x62\xce\x6c', AVC => '\+A\+V\+C\+', @@ -800,6 +850,7 @@ my %moduleName = ( BZ2 => 'BZh[1-9]\x31\x41\x59\x26\x53\x59', CHM => 'ITSF.{20}\x10\xfd\x01\x7c\xaa\x7b\xd0\x11\x9e\x0c\0\xa0\xc9\x22\xe6\xec', CRW => '(II|MM).{4}HEAP(CCDR|JPGM)', + DCX => '\xb1\x68\xde\x3a', DEX => "dex\n035\0", DICOM=> '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)', DOCX => 'PK\x03\x04', @@ -807,11 +858,14 @@ my %moduleName = ( DR4 => 'IIII\x04\0\x04\0', DSS => '(\x02dss|\x03ds2)', DV => '\x1f\x07\0[\x3f\xbf]', # (not tested if extension recognized) + DWF => '\(DWF V\d', + DWG => 'AC10\d{2}\0', EPS => '(%!PS|%!Ad|\xc5\xd0\xd3\xc6)', EXE => '(MZ|\xca\xfe\xba\xbe|\xfe\xed\xfa[\xce\xcf]|[\xce\xcf]\xfa\xed\xfe|Joy!peff|\x7fELF|#!\s*/\S*bin/|!\x0a)', EXIF => '(II\x2a\0|MM\0\x2a)', EXR => '\x76\x2f\x31\x01', EXV => '\xff\x01Exiv2', + FITS => 'SIMPLE = {20}T', FLAC => '(fLaC|ID3)', FLIF => 'FLIF[0-\x6f][0-2]', FLIR => '[AF]FF\0', @@ -830,7 +884,7 @@ my %moduleName = ( ITC => '.{4}itch', JP2 => '(\0\0\0\x0cjP( |\x1a\x1a)\x0d\x0a\x87\x0a|\xff\x4f\xff\x51\0)', JPEG => '\xff\xd8\xff', - JSON => '\s*(\[\s*)?\{\s*"[^"]+"\s*:', + JSON => '(\xef\xbb\xbf)?\s*(\[\s*)?\{\s*"[^"]*"\s*:', LFP => '\x89LFP\x0d\x0a\x1a\x0a', LNK => '.{4}\x01\x14\x02\0{5}\xc0\0{6}\x46', LRI => 'LELR \0', @@ -849,6 +903,7 @@ my %moduleName = ( ORF => '(II|MM)', PDB => '.{60}(\.pdfADBE|TEXtREAd|BVokBDIC|DB99DBOS|PNRdPPrs|DataPPrs|vIMGView|PmDBPmDB|InfoINDB|ToGoToGo|SDocSilX|JbDbJBas|JfDbJFil|DATALSdb|Mdb1Mdb1|BOOKMOBI|DataPlkr|DataSprd|SM01SMem|TEXtTlDc|InfoTlIf|DataTlMl|DataTlPt|dataTDBP|TdatTide|ToRaTRPW|zTXTGPlm|BDOCWrdS)', # PCD => signature is at byte 2048 + PCX => '\x0a[\0-\x05]\x01[\x01\x02\x04\x08].{64}[\0-\x02]', PDF => '\s*%PDF-\d+\.\d+', PGF => 'PGF', PHP => '<\?php\s', @@ -872,6 +927,7 @@ my %moduleName = ( RWZ => 'rawzor', SWF => '[FC]WS[^\0]', TAR => '.{257}ustar( )?\0', # (this doesn't catch old-style tar files) + TXT => '(\xff\xfe|(\0\0)?\xfe\xff|(\xef\xbb\xbf)?[\x07-\x0d\x20-\x7e\x80-\xfe]*$)', TIFF => '(II|MM)', # don't test magic number (some raw formats are different) VCard=> '(?i)BEGIN:(VCARD|VCALENDAR)\r\n', VRD => 'CANON OPTIONAL DATA\0', @@ -888,7 +944,26 @@ my %weakMagic = ( MP3 => 1 ); # file types that are determined by the process proc when FastScan == 3 # (when done, the process proc must exit after SetFileType if FastScan is 3) -my %processType = map { $_ => 1 } qw(JPEG TIFF XMP AIFF EXE Font PS Real VCard); +my %processType = map { $_ => 1 } qw(JPEG TIFF XMP AIFF EXE Font PS Real VCard TXT); + +# Compact/XMPShorthand option settings +my %compactOpt = ( + nopadding => 'NoPadding', noindent => 'NoIndent', nonewline => 'NoNewline', + shorthand => 'Shorthand', onedesc => 'OneDesc', + all => ['NoPadding','NoIndent','NoNewline','Shorthand','OneDesc'], + allspace => ['NoPadding','NoIndent','NoNewline'], allformat => ['Shorthand','OneDesc'], + # aliases to cover anticipated user typos + nonewlines => 'NoNewline', nospace => 'NoIndent', nospaces => 'NoIndent', + nopad => 'NoPadding', onedescr => 'OneDesc', + # allow numerical settings for backward compatibility + 0 => 'None', + 1 => 'NoPadding', + 2 => ['NoPadding','NoIndent'], + 3 => ['NoPadding','NoIndent','OneDesc'], + 4 => ['NoPadding','NoIndent','OneDesc','NoNewline'], + 5 => ['NoPadding','NoIndent','OneDesc','NoNewline','Shorthand'], +); +my %xmpShorthandOpt = ( 0 => 'None', 1 => 'Shorthand', 2 => ['Shorthand','OneDesc'] ); # lookup for valid character set names (keys are all lower case) %charsetName = ( @@ -917,10 +992,12 @@ my %processType = map { $_ => 1 } qw(JPEG TIFF XMP AIFF EXE Font PS Real VCard); maccroatian => 'MacCroatian', cp10082 => 'MacCroatian', ); -# default group priority for writing +# default family 0 group priority for writing # (NOTE: tags in groups not specified here will not be written unless # overridden by the module or specified when writing) -my @defaultWriteGroups = qw(EXIF IPTC XMP MakerNotes Photoshop ICC_Profile CanonVRD Adobe); +my @defaultWriteGroups = qw( + EXIF IPTC XMP MakerNotes QuickTime Photoshop ICC_Profile CanonVRD Adobe +); # group hash for ExifTool-generated tags my %allGroupsExifTool = ( 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' ); @@ -932,7 +1009,7 @@ my %allGroupsExifTool = ( 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' ); WRITABLE TABLE_DESC NOTES IS_OFFSET IS_SUBDIR EXTRACT_UNKNOWN NAMESPACE PREFERRED SRC_TABLE PRIORITY AVOID WRITE_GROUP LANG_INFO VARS DATAMEMBER - SET_GROUP1 + SET_GROUP1 PERMANENT INIT_TABLE ); # headers for various segment types @@ -953,7 +1030,7 @@ sub DummyWriteProc { return 1; } my %systemTagsNotes = ( Notes => q{ - extracted only if specifically requested or the SystemTags or RequestAll API + extracted only if specifically requested or the L or L API option is set }, ); @@ -969,7 +1046,7 @@ my %systemTagsNotes = ( # accept either scalar or scalar reference RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)', # we allow preview image to be set to '', but we don't want a zero-length value - # in the IFD, so set it temorarily to 'none'. Note that the length is <= 4, + # in the IFD, so set it temporarily to 'none'. Note that the length is <= 4, # so this value will fit in the IFD so the preview fixup won't be generated. ValueConvInv => '$val eq "" and $val="none"; $val', ); @@ -987,7 +1064,7 @@ my %systemTagsNotes = ( Notes => q{ returns errors that may have occurred while reading or writing a file. Any Error will prevent the file from being processed. Minor errors may be - downgraded to warnings with the -m or IgnoreMinorErrors option + downgraded to warnings with the -m or L option }, }, Warning => { @@ -995,8 +1072,8 @@ my %systemTagsNotes = ( Groups => \%allGroupsExifTool, Notes => q{ returns warnings that may have occurred while reading or writing a file. - Use the -a or Duplicates option to see all warnings if more than one - occurred. Minor warnings may be ignored with the -m or IgnoreMinorErrors + Use the -a or L option to see all warnings if more than one + occurred. Minor warnings may be ignored with the -m or L option. Minor warnings with a capital "M" in the "[Minor]" designation indicate that the processing is affected by ignoring the warning }, @@ -1008,7 +1085,7 @@ my %systemTagsNotes = ( Priority => 0, # to preserve order of JPEG COM segments }, Directory => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ the directory of the file as specified in the call to ExifTool, or "." if no directory was specified. May be written to move the file to another @@ -1023,7 +1100,7 @@ my %systemTagsNotes = ( ValueConvInv => '$_ = $self->InverseFileName($val); m{[^/]$} and $_ .= "/"; $_', }, FileName => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Writable => 1, WritePseudo => 1, DelCheck => q{"Can't delete"}, @@ -1039,10 +1116,10 @@ my %systemTagsNotes = ( ValueConvInv => '$self->InverseFileName($val)', }, FilePath => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ absolute path of source file. Not generated unless specifically requested or - the RequestAll API option is set. Does not support Windows Unicode file + the L API option is set. Does not support Windows Unicode file names }, }, @@ -1065,11 +1142,11 @@ my %systemTagsNotes = ( sequence number for each source file when extracting or copying information, including files that fail the -if condition of the command-line application, beginning at 0 for the first file. Not generated unless specifically - requested or the RequestAll API option is set + requested or the L API option is set }, }, FileSize => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ note that the print conversion for this tag uses historic prefixes: 1 kB = 1024 bytes, etc. @@ -1077,10 +1154,10 @@ my %systemTagsNotes = ( PrintConv => \&ConvertFileSize, }, ResourceForkSize => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ size of the file's resource fork if it contains data. Mac OS only. If this - tag is generated the ExtractEmbedded option may be used to extract + tag is generated the L option may be used to extract resource-fork information as a sub-document. When writing, the resource fork is preserved by default, but it may be deleted with C<-rsrc:all=> on the command line @@ -1088,12 +1165,14 @@ my %systemTagsNotes = ( PrintConv => \&ConvertFileSize, }, FileType => { + Groups => { 2 => 'Other' }, Notes => q{ a short description of the file type. For many file types this is the just the uppercase file extension }, }, FileTypeExtension => { + Groups => { 2 => 'Other' }, Notes => q{ a common lowercase extension for this file type, or uppercase with the -n option @@ -1136,7 +1215,7 @@ my %systemTagsNotes = ( the filesystem creation date/time. Windows/Mac only. In Windows, the file creation date/time is preserved by default when writing if Win32API::File and Win32::API are available. On Mac, this tag is extracted only if it or - the MacOS group is specifically requested or the RequestAll API option is + the MacOS group is specifically requested or the L API option is set to 2 or higher. Requires "setfile" for writing on Mac }, Groups => { 1 => 'System', 2 => 'Time' }, @@ -1166,7 +1245,7 @@ my %systemTagsNotes = ( PrintConv => '$self->ConvertDateTime($val)', }, FilePermissions => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ r=read, w=write and x=execute permissions for the file owner, group and others. The ValueConv value is an octal number so bit test operations on @@ -1201,9 +1280,9 @@ my %systemTagsNotes = ( }, }, FileAttributes => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ - extracted only if specifically requested or the SystemTags or RequestAll API + extracted only if specifically requested or the L or L API option is set. 2 or 3 values: 0. File type, 1. Attribute bits, 2. Windows attribute bits if Win32API::File is available }, @@ -1248,17 +1327,17 @@ my %systemTagsNotes = ( }}], }, FileDeviceID => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes, PrintConv => '(($val >> 24) & 0xff) . "." . ($val & 0xffffff)', # (major.minor) }, - FileDeviceNumber => { Groups => { 1 => 'System' }, %systemTagsNotes }, - FileInodeNumber => { Groups => { 1 => 'System' }, %systemTagsNotes }, - FileHardLinks => { Groups => { 1 => 'System' }, %systemTagsNotes }, + FileDeviceNumber => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes }, + FileInodeNumber => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes }, + FileHardLinks => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes }, FileUserID => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ - extracted only if specifically requested or the SystemTags or RequestAll API + extracted only if specifically requested or the L or L API option is set. Returns user ID number with the -n option, or name otherwise. May be written with either user name or number }, @@ -1270,9 +1349,9 @@ my %systemTagsNotes = ( PrintConvInv => 'eval { getpwnam($val) } || ($val=~/[^0-9]/ ? undef : $val)', }, FileGroupID => { - Groups => { 1 => 'System' }, + Groups => { 1 => 'System', 2 => 'Other' }, Notes => q{ - extracted only if specifically requested or the SystemTags or RequestAll API + extracted only if specifically requested or the L or L API option is set. Returns group ID number with the -n option, or name otherwise. May be written with either group name or number }, @@ -1283,8 +1362,8 @@ my %systemTagsNotes = ( PrintConv => 'eval { getgrgid($val) } || $val', PrintConvInv => 'eval { getgrnam($val) } || ($val=~/[^0-9]/ ? undef : $val)', }, - FileBlockSize => { Groups => { 1 => 'System' }, %systemTagsNotes }, - FileBlockCount => { Groups => { 1 => 'System' }, %systemTagsNotes }, + FileBlockSize => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes }, + FileBlockCount => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes }, HardLink => { Writable => 1, DelCheck => q{"Can't delete"}, @@ -1292,16 +1371,34 @@ my %systemTagsNotes = ( WritePseudo => 1, Protected => 1, Notes => q{ - this write-only tag is used to create a hard link to the file. If the file - is edited, copied, renamed or moved in the same operation as writing - HardLink, then the link is made to the updated file. Note that subsequent - editing of either the linked file or the original by the exiftool - application will break the link unless the -overwrite_original_in_place - option is used + this write-only tag is used to create a hard link with the specified name to + the source file. If the source file is edited, copied, renamed or moved in + the same operation as writing HardLink, then the link is made to the updated + file. Note that subsequent editing of either hard-linked file by exiftool + will break the link unless the -overwrite_original_in_place option is used }, ValueConvInv => '$val=~tr/\\\\/\//; $val', }, - MIMEType => { Notes => 'the MIME type of the source file' }, + SymLink => { + Writable => 1, + DelCheck => q{"Can't delete"}, + WriteOnly => 1, + WritePseudo => 1, + Protected => 1, + Notes => q{ + this write-only tag is used to create a symbolic link with the specified + name to the source file. If the source file is edited, copied, renamed or + moved in the same operation as writing SymLink, then the link is made to the + updated file. The link uses an absolute path unless it is created in the + current working directory. Valid only for file systems that support + symbolic links. Note that subsequent editing of the file via the symbolic + link by exiftool will cause the link to be replaced by the edited file + without changing the original unless the -overwrite_original_in_place option + is used + }, + ValueConvInv => '$val=~tr/\\\\/\//; $val', + }, + MIMEType => { Notes => 'the MIME type of the source file', Groups => { 2 => 'Other' } }, ImageWidth => { Notes => 'the width of the image in number of pixels' }, ImageHeight => { Notes => 'the height of the image in number of pixels' }, XResolution => { Notes => 'the horizontal pixel resolution' }, @@ -1313,7 +1410,7 @@ my %systemTagsNotes = ( is generated only if specifically requested }, Groups => { 0 => 'EXIF', 1 => 'EXIF' }, - Flags => ['Writable' ,'Protected', 'Binary'], + Flags => ['Writable' ,'Protected', 'Binary', 'DelGroup'], WriteCheck => q{ return undef if $val =~ /^(II\x2a\0|MM\0\x2a)/; return 'Invalid EXIF data'; @@ -1325,7 +1422,7 @@ my %systemTagsNotes = ( requested }, Groups => { 0 => 'IPTC', 1 => 'IPTC' }, - Flags => ['Writable', 'Protected', 'Binary'], + Flags => ['Writable', 'Protected', 'Binary', 'DelGroup'], Priority => 0, # so main IPTC (which hopefully comes first) takes priority WriteCheck => q{ return undef if $val =~ /^(\x1c|\0+$)/; @@ -1338,7 +1435,7 @@ my %systemTagsNotes = ( into multiple blocks. This tag is generated only if specifically requested }, Groups => { 0 => 'XMP', 1 => 'XMP' }, - Flags => ['Writable', 'Protected', 'Binary'], + Flags => ['Writable', 'Protected', 'Binary', 'DelGroup'], Priority => 0, # so main xmp (which usually comes first) takes priority WriteCheck => q{ require Image::ExifTool::XMP; @@ -1351,7 +1448,7 @@ my %systemTagsNotes = ( requested }, Groups => { 0 => 'ICC_Profile', 1 => 'ICC_Profile' }, - Flags => ['Writable' ,'Protected', 'Binary'], + Flags => ['Writable' ,'Protected', 'Binary', 'DelGroup'], WriteCheck => q{ require Image::ExifTool::ICC_Profile; return Image::ExifTool::ICC_Profile::ValidateICC(\$val); @@ -1363,7 +1460,7 @@ my %systemTagsNotes = ( specifically requested }, Groups => { 0 => 'CanonVRD', 1 => 'CanonVRD' }, - Flags => ['Writable' ,'Protected', 'Binary'], + Flags => ['Writable' ,'Protected', 'Binary', 'DelGroup'], Permanent => 0, # (this is 1 by default for MakerNotes tags) WriteCheck => q{ return undef if $val =~ /^CANON OPTIONAL DATA\0/; @@ -1481,7 +1578,7 @@ my %systemTagsNotes = ( Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Other' }, Notes => q{ the clock time in seconds taken by ExifTool to extract information from this - file. Not generated unless specifically requested or the RequestAll API + file. Not generated unless specifically requested or the L API option is set. Requires Time::HiRes }, PrintConv => 'sprintf("%.3g s", $val)', @@ -1493,7 +1590,7 @@ my %systemTagsNotes = ( sub-sampling values to generate the value of this tag. The result is compared to known values in an attempt to deduce the originating software based only on the JPEG image data. For performance reasons, this tag is - generated only if specifically requested or the RequestAll API option is set + generated only if specifically requested or the L API option is set to 3 or higher }, }, @@ -1501,17 +1598,24 @@ my %systemTagsNotes = ( Notes => q{ an estimate of the IJG JPEG quality setting for the image, calculated from the quantization tables. For performance reasons, this tag is generated - only if specifically requested or the RequestAll API option is set to 3 or + only if specifically requested or the L API option is set to 3 or higher }, }, + JPEGImageLength => { + Notes => q{ + byte length of JPEG image without metadata. For performance reasons, this + tag is generated only if specifically requested or the L API option + is set to 3 or higher + }, + }, # Validate (added from Validate.pm) Now => { Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Time' }, Notes => q{ the current date/time. Useful when setting the tag values, eg. C<"-modifydate. Not generated unless specifically requested or the - RequestAll API option is set + L API option is set }, PrintConv => '$self->ConvertDateTime($val)', }, @@ -1522,7 +1626,7 @@ my %systemTagsNotes = ( YYYYmmdd-HHMM-SSNN-PPPP-RRRRRRRRRRRR, where Y=year, m=month, d=day, H=hour, M=minute, S=second, N=file sequence number in hex, P=process ID in hex, and R=random hex number; without dashes with the -n option. Not generated - unless specifically requested or the RequestAll API option is set + unless specifically requested or the L API option is set }, PrintConv => '$val =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/; $val', }, @@ -1564,7 +1668,7 @@ my %systemTagsNotes = ( causes GPS information to be written into the EXIF or XMP of the target files. The local system timezone is assumed if the date/time value does not contain a timezone. May be deleted to delete associated GPS tags. A group - name of 'EXIF' or 'XMP' may be specified to write or delete only EXIF or XMP + name of "EXIF" or "XMP" may be specified to write or delete only EXIF or XMP GPS tags }, DelCheck => q{ @@ -1602,14 +1706,21 @@ my %systemTagsNotes = ( Writable => 1, WriteOnly => 1, Notes => q{ - write-only tag used to force EXIF, IPTC and/or XMP in a file to be - rewritten. May be set to "EXIF", "IPTC" or "XMP" to force the corresponding - metadata type to be rewritten, "FixBase" to cause EXIF to be rewritten only if - the MakerNotes offset base was fixed, or "All" to rewrite all of these metadata - types. Values are case insensitive, and multiple values may be separated with - commas, eg. C<-ForceWrite=exif,xmp> + write-only tag used to force metadata in a file to be rewritten even if no + tag values are changed. May be set to "EXIF", "IPTC", "XMP" or "PNG" to + force the corresponding metadata type to be rewritten, "FixBase" to cause + EXIF to be rewritten only if the MakerNotes offset base was fixed, or "All" + to rewrite all of these metadata types. Values are case insensitive, and + multiple values may be separated with commas, eg. C<-ForceWrite=exif,xmp> }, }, + EmbeddedVideo => { Groups => { 0 => 'Trailer', 2 => 'Video' } }, + Trailer => { + Groups => { 0 => 'Trailer' }, + Notes => 'the full JPEG trailer data block. Extracted only if specifically requested', + Writable => 1, + Protected => 1, + }, ); # YCbCrSubSampling values (used by JPEG SOF, EXIF and XMP) @@ -1772,6 +1883,8 @@ my %systemTagsNotes = ( WRITE_PROC => \&DummyWriteProc, ); +my %compositeID; # lookup for new ID's of Composite tags based on original ID + # static private ExifTool variables %allTables = ( ); # list of all tables loaded (except Composite tags) @@ -1898,6 +2011,10 @@ sub Options($$;@) } } $oldVal = $$options{$param}; + if (ref $oldVal eq 'HASH' and ($param eq 'Compact' or $param eq 'XMPShorthand')) { + # get previous Compact/XMPShorthand setting + $oldVal = $$oldVal{$param}; + } last unless @_; my $newVal = shift; if ($param eq 'Lang') { @@ -1982,6 +2099,7 @@ sub Options($$;@) /^(.*:)?([-\w?*]*)#?$/ or next; push @{$$options{$param}}, lc($2) if $2; next unless $1; + # add requested groups with trailing colon push @{$$options{$param}}, lc($_).':' foreach split /:/, $1; } } else { @@ -1989,7 +2107,7 @@ sub Options($$;@) } } elsif ($param eq 'ListJoin') { $$options{$param} = $newVal; - # ListJoin just sets the List and ListSep options for backward compatibility + # set the old List and ListSep options for backward compatibility if (defined $newVal) { $$options{List} = 0; $$options{ListSep} = $newVal; @@ -1997,6 +2115,27 @@ sub Options($$;@) $$options{List} = 1; # (ListSep must be defined) } + } elsif ($param eq 'List') { + $$options{$param} = $newVal; + # set the new ListJoin option for forward compatibility + $$options{ListJoin} = $newVal ? undef : $$options{ListSep}; + } elsif ($param eq 'Compact' or $param eq 'XMPShorthand') { + # set Compact and XMPShorthand options, preserving backward compatibility + my ($p, %compact); + foreach $p ('Compact','XMPShorthand') { + my $val = $param eq $p ? $newVal : $$options{Compact}{$p}; + if (defined $val) { + my @v = ($val =~ /\w+/g); + my $opt = ($p eq 'Compact') ? \%compactOpt : \%xmpShorthandOpt; + foreach (@v) { + my $set = $$opt{lc $_} or warn("Invalid $p setting '${_}'\n"), return $oldVal; + ref $set or $compact{$set} = 1, next; + $compact{$_} = 1 foreach @$set; + } + } + $compact{$p} = $val; # preserve most recent setting + } + $$options{Compact} = $$options{XMPShorthand} = \%compact; } else { if ($param eq 'Escape') { # set ESCAPE_PROC @@ -2052,7 +2191,7 @@ sub ClearOptions($) CharsetPhotoshop => 'Latin', # internal encoding for Photoshop resource names CharsetQuickTime => 'MacRoman', # internal QuickTime string encoding CharsetRIFF => 0, # internal RIFF string encoding (0=default to Latin) - Compact => undef, # compact XMP and IPTC data + Compact => { }, # write compact XMP Composite => 1, # flag to calculate Composite tags Compress => undef, # flag to write new values as compressed if possible CoordFormat => undef, # GPS lat/long coordinate format @@ -2064,6 +2203,7 @@ sub ClearOptions($) ExtractEmbedded =>undef,# flag to extract information from embedded documents FastScan => undef, # flag to avoid scanning for trailer Filter => undef, # output filter for all tag values + FilterW => undef, # input filter when writing tag values FixBase => undef, # fix maker notes base offsets GeoMaxIntSecs => 1800, # geotag maximum interpolation time (secs) GeoMaxExtSecs => 1800, # geotag maximum extrapolation time (secs) @@ -2088,12 +2228,13 @@ sub ClearOptions($) MissingTagValue =>undef,# value for missing tags when expanded in expressions NoPDFList => undef, # flag to avoid splitting PDF List-type tag values Password => undef, # password for password-protected PDF documents - PNGEarlyXMP => undef, # write XMP in PNG images before IDAT chunk PrintConv => 1, # flag to enable print conversion + QuickTimeHandler => undef, # flag to add mdir Handler to newly created Meta box QuickTimeUTC=> undef, # assume that QuickTime date/time tags are stored as UTC RequestAll => undef, # extract all tags that must be specifically requested RequestTags => undef, # extra tags to request (on top of those in the tag list) - SavePath => undef, # (undocumented) save family 5 location path + SaveFormat => undef, # save family 6 tag TIFF format + SavePath => undef, # save family 5 location path ScanForXMP => undef, # flag to scan for XMP information in all files Sort => 'Input', # order to sort found tags (Input, File, Tag, Descr, Group#) Sort2 => 'File', # secondary sort order for tags in a group (File, Tag, Descr) @@ -2109,6 +2250,7 @@ sub ClearOptions($) WriteMode => 'wcg', # enable all write modes by default XAttrTags => undef, # extract MacOS extended attribute tags XMPAutoConv => 1, # automatic conversion of unknown XMP tag values + XMPShorthand=> 0, # (unused, but needed for backward compatibility) }; # keep necessary member variables in sync with options delete $$self{CUR_LANG}; @@ -2134,10 +2276,10 @@ sub ExtractInfo($;@) local $_; my $self = shift; my $options = $$self{OPTIONS}; # pointer to current options - my $fast = $$options{FastScan}; + my $fast = $$options{FastScan} || 0; my $req = $$self{REQ_TAG_LOOKUP}; my $reqAll = $$options{RequestAll} || 0; - my (%saveOptions, $reEntry, $rsize, $type, @startTime); + my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder); # check for internal ReEntry option to allow recursive calls to ExtractInfo if (ref $_[1] eq 'HASH' and $_[1]{ReEntry} and @@ -2151,6 +2293,7 @@ sub ExtractInfo($;@) EXIF_POS => $$self{EXIF_POS}, FILE_TYPE => $$self{FILE_TYPE}, }; + $saveOrder = GetByteOrder(), $$self{RAF} = new File::RandomAccess($_[0]); $$self{PROCESSED} = { }; delete $$self{EXIF_DATA}; @@ -2248,7 +2391,7 @@ sub ExtractInfo($;@) } } - if ($raf) { + while ($raf) { my (@stat, $fileSize); if ($reEntry) { # we already set these tags @@ -2321,12 +2464,21 @@ sub ExtractInfo($;@) $recognizedExt = $ext if defined $ext and not defined $magicNumber{$ext} and defined $moduleName{$ext} and not $moduleName{$ext}; my @fileTypeList = GetFileType($realname); + if ($fast >= 4) { + if (@fileTypeList) { + $type = shift @fileTypeList; + $self->SetFileType($$self{FILE_TYPE} = $type); + } else { + $self->Error('Unknown file type'); + } + last; # don't read the file + } if (@fileTypeList) { # add remaining types to end of list so we test them all my $pat = join '|', @fileTypeList; push @fileTypeList, grep(!/^($pat)$/, @fileTypes); $tiffType = $$self{FILE_EXT}; - unless ($fast and $fast == 3) { + unless ($fast == 3) { $noMagic{MXF} = 1; # don't do magic number test on MXF or DV files $noMagic{DV} = 1; } @@ -2339,20 +2491,24 @@ sub ExtractInfo($;@) # initialize the input file for seeking in binary data $raf->BinMode(); # set binary mode before we start reading my $pos = $raf->Tell(); # get file position so we can rewind - my %dirInfo = ( RAF => $raf, Base => $pos ); # loop through list of file types to test my ($buff, $seekErr); + my %dirInfo = ( RAF => $raf, Base => $pos, TestBuff => \$buff ); # read start of file for testing - my $testLen = 1024; $raf->Read($buff, $testLen) or $buff = ''; $raf->Seek($pos, 0) or $seekErr = 1; until ($seekErr) { my $unkHeader; $type = shift @fileTypeList; if ($type) { - # do quick test for this file type to avoid loading module unnecessarily - next if $magicNumber{$type} and $buff !~ /^$magicNumber{$type}/s and - not $noMagic{$type}; + if ($magicNumber{$type}) { + # do quick test for this file type to avoid loading module unnecessarily + next if $buff !~ /^$magicNumber{$type}/s and not $noMagic{$type}; + } else { + # keep checking for other types if we recognize this file only by extension + next if defined $moduleName{$type} and not $moduleName{$type}; + next if $fast > 2; # keep checking if we aren't processing the file + } next if $weakMagic{$type} and defined $recognizedExt; } elsif (not defined $type) { last; @@ -2372,7 +2528,7 @@ sub ExtractInfo($;@) $$self{FILE_TYPE} = $type; $dirInfo{Parent} = ($type eq 'TIFF') ? $tiffType : $type; # don't process the file when FastScan == 3 - if ($fast and $fast == 3 and not $processType{$type}) { + if ($fast == 3 and not $processType{$type}) { unless ($weakMagic{$type} and (not $ext or $ext ne $type)) { $self->SetFileType($dirInfo{Parent}); } @@ -2513,6 +2669,7 @@ sub ExtractInfo($;@) } } } + last; # (loop was a cheap "goto") } # generate Validate tag if requested @@ -2528,6 +2685,7 @@ sub ExtractInfo($;@) if ($reEntry) { # restore necessary members when exiting re-entrant code $$self{$_} = $$reEntry{$_} foreach keys %$reEntry; + SetByteOrder($saveOrder); } # ($type may be undef without an Error when processing sub-documents) @@ -2893,6 +3051,7 @@ sub GetValue($$;$) my $oldFilter = $$self{OPTIONS}{Filter}; delete $$self{OPTIONS}{Filter}; foreach (keys %$val) { + next unless defined $$val{$_}; $raw[$_] = $$rawValue{$$val{$_}}; ($val[$_], $prt[$_]) = $self->GetValue($$val{$_}, 'Both'); next if defined $val[$_] or not $$tagInfo{Require}{$_}; @@ -3010,7 +3169,7 @@ sub GetValue($$;$) # $valueConv is undefined if there was no print conversion done $valueConv = $value; } - $self->Filter(\$value) if defined $$self{OPTIONS}{Filter}; + Filter($$self{OPTIONS}{Filter}, \$value); # return Both values as a list (ValueConv, PrintConv) return ($valueConv, $value); } @@ -3018,7 +3177,7 @@ sub GetValue($$;$) DoEscape($value, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC}; # filter if necessary - $self->Filter(\$value) if defined $$self{OPTIONS}{Filter} and $type eq 'PrintConv'; + Filter($$self{OPTIONS}{Filter}, \$value) if $$self{OPTIONS}{Filter} and $type eq 'PrintConv'; if (ref $value eq 'ARRAY') { if (defined $$self{OPTIONS}{ListItem}) { @@ -3101,7 +3260,7 @@ sub GetDescription($$) # Returns: Scalar context: group name (for family 0 if not otherwise specified) # List context: group name if family specified, otherwise list of # group names for each family. Returns '' for undefined tag. -# Notes: Mutiple families may be specified with ':' in family argument (eg. '1:2') +# Notes: Multiple families may be specified with ':' in family argument (eg. '1:2') sub GetGroup($$;$) { local $_; @@ -3153,6 +3312,10 @@ sub GetGroup($$;$) $groups[1] = $$ex{G1} =~ /^\+(.*)/ ? "$groups[1]$1" : $$ex{G1} if $$ex{G1}; $groups[3] = 'Doc' . $$ex{G3} if $$ex{G3}; $groups[5] = $$ex{G5} || $groups[1] if defined $$ex{G5}; + if (defined $$ex{G6}) { + $groups[5] = '' unless defined $groups[5]; # (can't leave a hole in the array) + $groups[6] = $$ex{G6}; + } } if ($family) { return $groups[$family] || '' if $family > 0; @@ -3215,18 +3378,20 @@ sub GetGroups($;$$) # Set priority for group where new values are written # Inputs: 0) ExifTool object reference, # 1-N) group names (reset to default if no groups specified) +# - used when new tag values are set (ie. before files are written) sub SetNewGroups($;@) { local $_; my ($self, @groups) = @_; @groups or @groups = @defaultWriteGroups; - my $count = @groups; + my $count = @groups * 10; my %priority; foreach (@groups) { - $priority{lc($_)} = $count--; + $priority{lc($_)} = $count; + $count -= 10; } - $priority{file} = 10; # 'File' group is always written (Comment) - $priority{composite} = 10; # 'Composite' group is always written + $priority{file} = 500; # 'File' group is always written (Comment) + $priority{composite} = 500; # 'Composite' group is always written # set write priority (higher # is higher priority) $$self{WRITE_PRIORITY} = \%priority; $$self{WRITE_GROUPS} = \@groups; @@ -3244,20 +3409,24 @@ sub BuildCompositeTags($) my $self = shift; $$self{BuildingComposite} = 1; - + my $compTable = GetTagTable('Image::ExifTool::Composite'); my @tagList = sort keys %$compTable; my $rawValue = $$self{VALUE}; - my (%tagsUsed, %cache); + my $compKeys = $$self{COMP_KEYS}; + my (%cache, $allBuilt); for (;;) { my (%notBuilt, $tag, @deferredTags); - $notBuilt{$_} = 1 foreach @tagList; + foreach (@tagList) { + $notBuilt{$$compTable{$_}{Name}} = 1 unless $specialTags{$_}; + } COMPOSITE_TAG: foreach $tag (@tagList) { next if $specialTags{$tag}; my $tagInfo = $self->GetTagInfo($compTable, $tag); next unless $tagInfo; + my $tagName = $$compTable{$tag}{Name}; # put required tags into array and make sure they all exist my $subDoc = ($$tagInfo{SubDoc} and $$self{DOC_COUNT}); my $require = $$tagInfo{Require} || { }; @@ -3308,8 +3477,12 @@ COMPOSITE_TAG: } elsif ($reqTag =~ /^(.*):(.+)/) { my ($reqGroup, $name) = ($1, $2); if ($reqGroup eq 'Composite' and $notBuilt{$name}) { - push @deferredTags, $tag; - next COMPOSITE_TAG; + # defer only until all other tags are built if + # we are inhibiting based on another Composite tag + unless ($$inhibit{$index} and $allBuilt) { + push @deferredTags, $tag; + next COMPOSITE_TAG; + } } # (CAREFUL! keys may not be sequential if one was deleted) my ($i, $key, @keys); @@ -3321,7 +3494,7 @@ COMPOSITE_TAG: # find first matching tag $key = $self->GroupMatches($reqGroup, \@keys); $reqTag = $key || "$name (0)"; - } elsif ($notBuilt{$reqTag}) { + } elsif ($notBuilt{$reqTag} and not $$inhibit{$index}) { # calculate this tag later if it relies on another # Composite tag which hasn't been calculated yet push @deferredTags, $tag; @@ -3343,34 +3516,34 @@ COMPOSITE_TAG: if ($docNum) { if ($found) { $$self{DOC_NUM} = $docNum; + # save pointers to all used tag keys + foreach (keys %tagKey) { + $$compKeys{$_} or $$compKeys{$_} = [ ]; + push @{$$compKeys{$tagKey{$_}}}, [ \%tagKey, $_ ]; + } $self->FoundTag($tagInfo, \%tagKey); delete $$self{DOC_NUM}; } next if ++$docNum <= $$self{DOC_COUNT}; last; } elsif ($found) { - delete $notBuilt{$tag}; # this tag is OK to build now + delete $notBuilt{$tagName}; # this tag is OK to build now # keep track of all Require'd tag keys foreach (keys %tagKey) { # only tag keys with same name as a Composite tag # can be replaced (also eliminates keys with # instance numbers which can't be replaced either) - next unless $$compTable{$tagKey{$_}}; - my $keyRef = \$tagKey{$_}; - $tagsUsed{$$keyRef} or $tagsUsed{$$keyRef} = [ ]; - push @{$tagsUsed{$$keyRef}}, $keyRef; + next unless $compositeID{$tagKey{$_}}; + } + # save pointers to all used tag keys + foreach (keys %tagKey) { + $$compKeys{$_} or $$compKeys{$_} = [ ]; + push @{$$compKeys{$tagKey{$_}}}, [ \%tagKey, $_ ]; } # save reference to tag key lookup as value for Composite tag my $key = $self->FoundTag($tagInfo, \%tagKey); - # check to see if we just replaced one of the tag keys we Require'd - if (defined $key and $tagsUsed{$key}) { - foreach (@{$tagsUsed{$key}}) { - $$_ = $$self{MOVED_KEY}; # replace with new tag key - } - delete $tagsUsed{$key}; # can't be replaced again - } } elsif (not defined $found) { - delete $notBuilt{$tag}; # tag can't be built anyway + delete $notBuilt{$tagName}; # tag can't be built anyway } last unless $subDoc; # don't process sub-documents if there is no chance to build this tag @@ -3396,16 +3569,30 @@ COMPOSITE_TAG: } last unless @deferredTags; if (@deferredTags == @tagList) { - # everything was deferred in the last pass, - # must be a circular dependency - warn "Circular dependency in Composite tags\n"; - last; + if ($allBuilt) { + # everything was deferred in the last pass, + # must be a circular dependency + warn "Circular dependency in Composite tags\n"; + last; + } + $allBuilt = 1; # try once more, ignoring Composite Inhibit tags } @tagList = @deferredTags; # calculate deferred tags now } delete $$self{BuildingComposite}; } +#------------------------------------------------------------------------------ +# Get reference to Composite tag info hash +# Inputs: 0) case-sensitive Composite tag name +# Returns: tagInfo hash or undef +sub GetCompositeTagInfo($) +{ + my $tag = shift; + return undef unless $compositeID{$tag}; + return $Image::ExifTool::Composite{$compositeID{$tag}[0]}; +} + #------------------------------------------------------------------------------ # Get tag name (removes copy index) # Inputs: 0) Tag key @@ -3559,6 +3746,7 @@ sub Init($) $$self{WRITTEN} = { }; # list of tags written (selected tags only) $$self{FORCE_WRITE}= { }; # ForceWrite lookup (set from ForceWrite tag) $$self{FOUND_DIR} = { }; # hash of directory names found in file + $$self{COMP_KEYS} = { }; # lookup for tag keys used in Composite tags $$self{PATH} = [ ]; # current subdirectory path in file when reading $$self{NUM_FOUND} = 0; # total number of tags found (incl. duplicates) $$self{CHANGED} = 0; # number of tags changed (writer only) @@ -3570,6 +3758,7 @@ sub Init($) $$self{Make} = ''; # camera make $$self{Model} = ''; # camera model $$self{CameraType} = ''; # Olympus camera type + $$self{FileType} = ''; # identified file type if ($self->Options('HtmlDump')) { require Image::ExifTool::HtmlDump; $$self{HTML_DUMP} = new Image::ExifTool::HtmlDump; @@ -3730,7 +3919,11 @@ sub Open($*$;$) $create = Win32API::File::OPEN_EXISTING(); } } - my $wh = eval { Win32API::File::CreateFileW($file, $access, 0, [], $create, 0, []) }; + my $share = 0; + eval { + $share = Win32API::File::FILE_SHARE_READ() unless $access & Win32API::File::GENERIC_WRITE(); + }; + my $wh = eval { Win32API::File::CreateFileW($file, $access, $share, [], $create, 0, []) }; return undef unless $wh; my $fd = eval { Win32API::File::OsFHandleOpenFd($wh, 0) }; if (not defined $fd or $fd < 0) { @@ -3758,7 +3951,8 @@ sub Exists($$) if ($self->EncodeFileName($file)) { local $SIG{'__WARN__'} = \&SetWarning; my $wh = eval { Win32API::File::CreateFileW($file, - Win32API::File::GENERIC_READ(), 0, [], + Win32API::File::GENERIC_READ(), + Win32API::File::FILE_SHARE_READ(), [], Win32API::File::OPEN_EXISTING(), 0, []) }; return 0 unless $wh; eval { Win32API::File::CloseHandle($wh) }; @@ -3863,7 +4057,7 @@ sub ParseArguments($;@) # handle our input arguments while (@_) { my $arg = shift; - if (ref $arg) { + if (ref $arg and not overload::Method($arg, q[""])) { if (ref $arg eq 'ARRAY') { $$self{IO_TAG_LIST} = $arg; foreach (@$arg) { @@ -3966,6 +4160,7 @@ sub GroupMatches($$$) my (@fmys, $g); for ($g=0; $g<@grps; ++$g) { $fmys[$g] = $1 if $grps[$g] =~ s/^(\d+)//; + $grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag } foreach $tag (@$tagList) { my @groups = $self->GetGroup($tag, -1); @@ -3974,9 +4169,9 @@ sub GroupMatches($$$) next if $grp eq '*' or $grp eq 'all'; if (defined $fmys[$g]) { my $f = $fmys[$g]; - last unless $groups[$f] and $grps[$g] eq lc $groups[$f]; + last unless defined $groups[$f] and $grp eq lc $groups[$f]; } else { - last unless grep /^$grps[$g]$/i, @groups; + last unless grep /^$grp$/i, @groups; } } if ($g == @grps) { @@ -3986,6 +4181,7 @@ sub GroupMatches($$$) } } else { my $family = ($group =~ s/^(\d+)//) ? $1 : -1; + $group = '' if lc $group eq 'copy0'; # accept 'Copy0' for primary tag foreach $tag (@$tagList) { my @groups = $self->GetGroup($tag, $family); if (grep(/^$group$/i, @groups)) { @@ -4447,12 +4643,16 @@ sub AddCompositeTags($;$) { local $_; my ($add, $override) = @_; - my $module; + my ($module, $prefix, $tagID); unless (ref $add) { + ($prefix = $add) =~ s/.*:://; + $prefix .= '::'; $module = $add; $add .= '::Composite'; no strict 'refs'; $add = \%$add; + } else { + $prefix = 'UserDefined::'; } my $defaultGroups = $$add{GROUPS}; my $compTable = GetTagTable('Image::ExifTool::Composite'); @@ -4466,43 +4666,62 @@ sub AddCompositeTags($;$) $defaultGroups = $$add{GROUPS} = { 0 => 'Composite', 1 => 'Composite', 2 => 'Other' }; } SetupTagTable($add); # generate Name, TagID, etc - my $tagID; foreach $tagID (sort keys %$add) { next if $specialTags{$tagID}; # must skip special tags my $tagInfo = $$add{$tagID}; - # tagID's MUST be the exact tag name for logic in BuildCompositeTags() - my $tag = $$tagInfo{Name}; + my $new = $prefix . $tagID; # new tag ID for Composite table $$tagInfo{Module} = $module if $$tagInfo{Writable}; $$tagInfo{Override} = 1 if $override and not defined $$tagInfo{Override}; $$tagInfo{IsComposite} = 1; - # allow Composite tags with the same name - if ($$compTable{$tag}) { + # handle Composite tags with the same name + if ($compositeID{$tagID}) { # determine if we want to override this tag # (=0 keep both, >0 override, <0 keep existing) - my $over = ($$tagInfo{Override} || 0) - ($$compTable{$tag}{Override} || 0); + my $over = ($$tagInfo{Override} || 0) - ($$compTable{$compositeID{$tagID}[0]}{Override} || 0); next if $over < 0; - my $n; - my $new = $tag; - while ($$compTable{$new}) { - delete $$compTable{$new} if $over; # delete existing entries - $n = ($n || 1) + 1; - $new = "${tag}-$n"; - } - # use new ID and save it so we can use it in TagLookup - $$tagInfo{NewTagID} = $tag = $new unless $over; - } - # convert scalar Require/Desire entries - my $type; - foreach $type ('Require','Desire') { + if ($over) { + # remove existing tags with this ID + delete $$compTable{$_} foreach @{$compositeID{$tagID}}; + delete $compositeID{$tagID}; + } + } + # make sure new TagID is unique by adding index if necessary + # (could only happen for UserDefined tags now that module name is added to tag ID) + my $n = 0; + while ($$compTable{$new}) { + $new =~ s/-\d+$// if $n++; + $new .= "-$n"; + } + # use new ID and save it so we can use it in TagLookup + $$tagInfo{NewTagID} = $new unless $tagID eq $new; + + # add new ID to lookup of Composite tag ID's + $compositeID{$tagID} = [ ] unless $compositeID{$tagID}; + unshift @{$compositeID{$tagID}}, $new; # (most recent one first) + + # convert scalar Require/Desire/Inhibit entries + my ($type, @hashes, @scalars, %used); + foreach $type ('Require','Desire','Inhibit') { my $req = $$tagInfo{$type} or next; - $$tagInfo{$type} = { 0 => $req } if ref($req) ne 'HASH'; + push @{ref($req) eq 'HASH' ? \@hashes : \@scalars}, $type; + } + if (@scalars) { + # make lookup for indices that are used + foreach $type (@hashes) { + $used{$_} = 1 foreach keys %{$$tagInfo{$type}}; + } + my $next = 0; + foreach $type (@scalars) { + ++$next while $used{$next}; + $$tagInfo{$type} = { $next++ => $$tagInfo{$type} }; + } } # add this Composite tag to our main Composite table $$tagInfo{Table} = $compTable; # (use the original TagID, even if we changed it, so don't do this:) - # $$tagInfo{TagID} = $tag; - # save tag under NewTagID in Composite table - $$compTable{$tag} = $tagInfo; + $$tagInfo{TagID} = $new; + # save tag under new ID in Composite table + $$compTable{$new} = $tagInfo; # set all default groups in tag my $groups = $$tagInfo{Groups}; $groups or $groups = $$tagInfo{Groups} = { }; @@ -4926,11 +5145,12 @@ sub FormatSize($) { return $formatSize{$_[0]}; } #------------------------------------------------------------------------------ # Read value from binary data (with current byte ordering) # Inputs: 0) data reference, 1) value offset, 2) format string, -# 3) number of values (or undef to use all data) -# 4) valid data length relative to offset, 5) optional pointer to returned rational +# 3) number of values (or undef to use all data), +# 4) valid data length relative to offset (or undef to use all data), +# 5) optional pointer to returned rational # Returns: converted value, or undefined if data isn't there # or list of values in list context -sub ReadValue($$$$$;$) +sub ReadValue($$$;$$$) { my ($dataPt, $offset, $format, $count, $size, $ratPt) = @_; @@ -4939,6 +5159,7 @@ sub ReadValue($$$$$;$) warn "Unknown format $format"; $len = 1; } + $size = length($$dataPt) - $offset unless defined $size; unless ($count) { return '' if defined $count or $size < $len; $count = int($size / $len); @@ -5146,32 +5367,32 @@ sub GetDescriptions($$) #------------------------------------------------------------------------------ # Apply filter to value(s) if necessary -# Inputs: 0) ExifTool ref, 1-N) references to values(s) to filter +# Inputs: 0) filter expression, 1-N) references to values(s) to filter # Returns: nothing, but changes values if necessary sub Filter($@) { local $_; - my $self = shift; - return unless defined $$self{OPTIONS}{Filter}; + my $filter = shift; + return unless defined $filter; while (@_) { my $valPt = shift; next unless defined $$valPt; if (not ref $$valPt) { $_ = $$valPt; #### eval Filter ($_) - eval $$self{OPTIONS}{Filter}; + eval $filter; $$valPt = $_ if defined $_; } elsif (ref $$valPt eq 'SCALAR') { my $val = $$$valPt; # make a copy to avoid filtering twice - $self->Filter(\$val); + Filter($filter, \$val); $$valPt = \$val; } elsif (ref $$valPt eq 'ARRAY') { my @val = @{$$valPt}; # make a copy to avoid filtering twice - $self->Filter(\$_) foreach @val; + Filter($filter, \$_) foreach @val; $$valPt = \@val; } elsif (ref $$valPt eq 'HASH') { my %val = %{$$valPt}; # make a copy to avoid filtering twice - $self->Filter(\$val{$_}) foreach keys %val; + Filter($filter, \$val{$_}) foreach keys %val; $$valPt = \%val; } } @@ -5236,7 +5457,6 @@ sub ConvertDateTime($$) shift @a while @a > 6; # remove superfluous entries unshift @a, 1 while @a < 3; # add month and day if necessary unshift @a, 0 while @a < 6; # add h,m,s if necessary - $a[5] -= 1900; # base year is 1900 $a[4] -= 1; # base month is 1 # parse %z and %s ourself (to handle time zones properly) if ($fmt =~ /%[sz]/) { @@ -5251,6 +5471,7 @@ sub ConvertDateTime($$) $fmt =~ s/(^|[^%])((%%)*)%s/$1$2$s/g; # convert '%s' format codes } } + $a[5] -= 1900; # strftime year starts from 1900 $date = POSIX::strftime($fmt, @a); # generate the formatted date/time } elsif ($$self{OPTIONS}{StrictDate}) { undef $date; @@ -5342,15 +5563,25 @@ sub TimeZoneString($;$) #------------------------------------------------------------------------------ # Convert Unix time to EXIF date/time string -# Inputs: 0) Unix time value, 1) non-zero to convert to local time +# Inputs: 0) Unix time value, 1) non-zero to convert to local time, +# 2) number of digits after the decimal for fractional seconds # Returns: EXIF date/time string (with timezone for local times) -# Notes: fractional seconds are ignored -sub ConvertUnixTime($;$) +sub ConvertUnixTime($;$$) { - my ($time, $toLocal) = @_; + my ($time, $toLocal, $dec) = @_; return '0000:00:00 00:00:00' if $time == 0; - $time = int($time + 1e-6) if $time != int($time); # avoid round-off errors my (@tm, $tz); + if ($dec) { + my $frac = $time - int($time); + $time = int($time); + $frac < 0 and $frac += 1, $time -= 1; + $dec = sprintf('%.*f', $dec, $frac); + # remove number before decimal and increment integer time if it was rounded up + $dec =~ s/^(\d)// and $1 eq '1' and $time += 1; + } else { + $time = int($time + 1e-6) if $time != int($time); # avoid round-off errors + $dec = ''; + } if ($toLocal) { @tm = localtime($time); $tz = TimeZoneString(\@tm, $time); @@ -5358,7 +5589,7 @@ sub ConvertUnixTime($;$) @tm = gmtime($time); $tz = ''; } - my $str = sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d%s", + my $str = sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d$dec%s", $tm[5]+1900, $tm[4]+1, $tm[3], $tm[2], $tm[1], $tm[0], $tz); return $str; } @@ -5371,20 +5602,22 @@ sub GetUnixTime($;$) { my ($timeStr, $isLocal) = @_; return 0 if $timeStr eq '0000:00:00 00:00:00'; - my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)/); - return undef unless @tm == 6 and eval { require Time::Local }; - my $tzsec = 0; + my @tm = ($timeStr =~ /^(\d+):(\d+):(\d+)\s+(\d+):(\d+):(\d+)(.*)/); + return undef unless @tm == 7 and eval { require Time::Local }; + my ($tzStr, $tzSec) = (pop(@tm), 0); # use specified timezone offset (if given) instead of local system time # if we are converting a local time value - if ($isLocal and $timeStr =~ /(?:Z|([-+])(\d+):(\d+))$/i) { + if ($isLocal and $tzStr =~ /(?:Z|([-+])(\d+):(\d+))/i) { # use specified timezone if one exists - $tzsec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1; + $tzSec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1; undef $isLocal; # convert using GMT corrected for specified timezone } - $tm[0] -= 1900; # convert year $tm[1] -= 1; # convert month @tm = reverse @tm; # change to order required by timelocal() - return $isLocal ? TimeLocal(@tm) : Time::Local::timegm(@tm) - $tzsec; + my $val = $isLocal ? TimeLocal(@tm) : Time::Local::timegm(@tm) - $tzSec; + # handle fractional seconds + $val += $1 if $tzStr and $tzStr =~ /^(\.\d+)/; + return $val; } #------------------------------------------------------------------------------ @@ -5406,7 +5639,7 @@ sub ConvertFileSize($) #------------------------------------------------------------------------------ # Convert seconds to duration string (handles negative durations) # Inputs: 0) floating point seconds -# Returns: duration string in form "S.SS s", "MM:SS" or "H:MM:SS" +# Returns: duration string in form "S.SS s", "H:MM:SS" or "DD days HH:MM:SS" sub ConvertDuration($) { my $time = shift; @@ -5473,12 +5706,12 @@ sub InverseFileName($$) #------------------------------------------------------------------------------ # Save information for HTML dump # Inputs: 0) ExifTool hash ref, 1) start offset, 2) data size -# 3) comment string, 4) tool tip (or SAME), 5) flags -sub HDump($$$$;$$) +# 3) comment string, 4) tool tip (or SAME), 5) flags, 6) IFD name +sub HDump($$$$;$$$) { my $self = shift; $$self{HTML_DUMP} or return; - my ($pos, $len, $com, $tip, $flg) = @_; + my ($pos, $len, $com, $tip, $flg, $ifd) = @_; $pos += $$self{BASE} if $$self{BASE}; # skip structural data blocks which have been removed from the middle of this dump # (SkipData list contains ordered [start,end+1] offsets to skip) @@ -5489,14 +5722,14 @@ sub HDump($$$$;$$) $end <= $$skip[0] and last; $pos >= $$skip[1] and $pos += $$skip[1] - $$skip[0], next; if ($pos != $$skip[0]) { - $$self{HTML_DUMP}->Add($pos, $$skip[0]-$pos, $com, $tip, $flg); + $$self{HTML_DUMP}->Add($pos, $$skip[0]-$pos, $com, $tip, $flg, $ifd); $len -= $$skip[0] - $pos; $tip = 'SAME'; } $pos = $$skip[1]; } } - $$self{HTML_DUMP}->Add($pos, $len, $com, $tip, $flg); + $$self{HTML_DUMP}->Add($pos, $len, $com, $tip, $flg, $ifd); } #------------------------------------------------------------------------------ @@ -5529,6 +5762,8 @@ sub IdentifyTrailer($;$) $type = 'MIE'; } elsif ($buff =~ /\0\0(QDIOBS|SEFT)$/) { $type = 'Samsung'; + } elsif ($buff =~ /8db42d694ccc418790edff439fe026bf$/s) { + $type = 'Insta360'; } last; } @@ -5560,9 +5795,14 @@ sub ProcessTrailers($$) my $path = $$self{PATH}; for (;;) { # loop through all trailers - require "Image/ExifTool/$dirName.pm"; - my $proc = "Image::ExifTool::${dirName}::Process$dirName"; - my $outBuff; + my ($proc, $outBuff); + if ($dirName eq 'Insta360') { + require "Image/ExifTool/QuickTimeStream.pl"; + $proc = 'Image::ExifTool::QuickTime::ProcessInsta360'; + } else { + require "Image/ExifTool/$dirName.pm"; + $proc = "Image::ExifTool::${dirName}::Process$dirName"; + } if ($outfile) { # write to local buffer so we can add trailer in proper order later $$outfile and $$dirInfo{OutFile} = \$outBuff, $outBuff = ''; @@ -5577,8 +5817,9 @@ sub ProcessTrailers($$) push @$path, 'Trailer', $dirName; # read or write this trailer - # (proc takes Offset as offset from end of trailer to end of file, - # and returns DataPos and DirLen, and Fixup if applicable) + # (proc takes Offset as positive offset from end of trailer to end of file, + # and returns DataPos and DirLen, and Fixup if applicable, and updates + # OutFile when writing) no strict 'refs'; my $result = &$proc($self, $dirInfo); use strict 'refs'; @@ -5713,9 +5954,10 @@ sub ProcessJPEG($$) local $_; my ($self, $dirInfo) = @_; my ($ch, $s, $length); - my $verbose = $$self{OPTIONS}{Verbose}; - my $out = $$self{OPTIONS}{TextOut}; - my $fast = $$self{OPTIONS}{FastScan}; + my $options = $$self{OPTIONS}; + my $verbose = $$options{Verbose}; + my $out = $$options{TextOut}; + my $fast = $$options{FastScan} || 0; my $raf = $$dirInfo{RAF}; my $htmlDump = $$self{HTML_DUMP}; my %dumpParms = ( Out => $out ); @@ -5729,9 +5971,14 @@ sub ProcessJPEG($$) return 0 unless $raf->Read($s, 5) == 5 and $s eq 'Exiv2'; $$self{FILE_TYPE} = 'EXV'; } - if (not $$self{VALUE}{FileType} or ($$self{DOC_NUM} and $$self{OPTIONS}{ExtractEmbedded})) { + my $appBytes = 0; + my $calcImageLen = $$self{REQ_TAG_LOOKUP}{jpegimagelength}; + if ($$options{RequestAll} and $$options{RequestAll} > 2) { + $calcImageLen = 1; + } + if (not $$self{VALUE}{FileType} or ($$self{DOC_NUM} and $$options{ExtractEmbedded})) { $self->SetFileType(); # set FileType tag - return 1 if $fast and $fast == 3; # don't process file when FastScan == 3 + return 1 if $fast == 3; # don't process file when FastScan == 3 $$self{LOW_PRIORITY_DIR}{IFD1} = 1; # lower priority of IFD1 tags } $$raf{NoBuffer} = 1 if $self->Options('FastScan'); # disable buffering in FastScan mode @@ -5842,7 +6089,7 @@ sub ProcessJPEG($$) } if ($hmin and $vmin) { my ($hs, $vs) = ($hmax / $hmin, $vmax / $vmin); - $self->FoundTag($$sof{YCbCrSubSampling}, "$hs $vs"); + $self->HandleTag($sof, 'YCbCrSubSampling', "$hs $vs"); } next; } elsif ($marker == 0xd9) { # EOI @@ -5859,32 +6106,67 @@ sub ProcessJPEG($$) } else { $self->Warn('Missing JPEG SOS'); } + if ($$self{REQ_TAG_LOOKUP}{trailer}) { + # read entire trailer into memory + if ($raf->Seek(0,2)) { + my $len = $raf->Tell() - $pos; + if ($len) { + my $buff; + $raf->Seek($pos, 0); + $self->FoundTag(Trailer => \$buff) if $raf->Read($buff,$len) == $len; + $raf->Seek($pos, 0); + } + } else { + $self->Warn('Error seeking in file'); + } + } # we are here because we are looking for trailer information if ($wantTrailer) { my $start = $$self{PreviewImageStart}; - if ($start) { + if ($start or $$options{ExtractEmbedded}) { my $buff; # most previews start right after the JPEG EOI, but the Olympus E-20 # preview is 508 bytes into the trailer, the K-M Maxxum 7D preview is # 979 bytes in, and Sony previews can start up to 32 kB into the trailer. # (and Minolta and Sony previews can have a random first byte...) my $scanLen = $$self{Make} =~ /Sony/i ? 65536 : 1024; - if ($raf->Read($buff, $scanLen) and ($buff =~ /\xff\xd8\xff./g or - ($$self{Make} =~ /(Minolta|Sony)/i and $buff =~ /.\xd8\xff\xdb/g))) - { - # adjust PreviewImageStart to this location - my $actual = $pos + pos($buff) - 4; - if ($start ne $actual and $verbose > 1) { - print $out "(Fixed PreviewImage location: $start -> $actual)\n"; - } - # update preview image offsets - $$self{VALUE}{PreviewImageStart} = $actual if $$self{VALUE}{PreviewImageStart}; - $$self{PreviewImageStart} = $actual; - # load preview now if we tried and failed earlier - if ($$self{PreviewError} and $$self{PreviewImageLength}) { - if ($raf->Seek($actual, 0) and $raf->Read($buff, $$self{PreviewImageLength})) { - $self->FoundTag('PreviewImage', $buff); - delete $$self{PreviewError}; + if ($raf->Read($buff, $scanLen)) { + if ($buff =~ /^.{4}ftyp/s) { + my $val; + if ($raf->Seek(0,2)) { + my $len = $raf->Tell() - $pos; + if ($$options{Binary}) { + $val = \$buff if $raf->Seek($pos,0) and $raf->Read($buff,$len)==$len; + } else { + $val = \ "Binary data $len bytes"; + } + if ($val) { + $self->FoundTag('EmbeddedVideo', $val); + } else { + $self->Warn('Error reading trailer'); + } + } else { + $self->Warn('Error seeking to end of file'); + } + } elsif ($buff =~ /\xff\xd8\xff./g or + ($$self{Make} =~ /(Minolta|Sony)/i and $buff =~ /.\xd8\xff\xdb/g)) + { + # adjust PreviewImageStart to this location + my $actual = $pos + pos($buff) - 4; + if ($start and $start ne $actual and $verbose > 1) { + print $out "(Fixed PreviewImage location: $start -> $actual)\n"; + } + # update preview image offsets + if ($start) { + $$self{VALUE}{PreviewImageStart} = $actual if $$self{VALUE}{PreviewImageStart}; + $$self{PreviewImageStart} = $actual; + } + # load preview now if we tried and failed earlier + if ($$self{PreviewError} and $$self{PreviewImageLength}) { + if ($raf->Seek($actual, 0) and $raf->Read($buff, $$self{PreviewImageLength})) { + $self->FoundTag('PreviewImage', $buff); + delete $$self{PreviewError}; + } } } } @@ -5920,6 +6202,7 @@ sub ProcessJPEG($$) DirLen => $endPos - $pos }) if $endPos > $pos; } + $self->FoundTag('JPEGImageLength', $pos - $appBytes) if $calcImageLen; last; # all done parsing file } elsif ($marker == 0xda) { # SOS pop @$path; @@ -5934,7 +6217,7 @@ sub ProcessJPEG($$) # only if we can't finish without scanning from end of file) $self->ProcessTrailers($trailInfo) and undef $trailInfo; } - if ($wantTrailer) { + if ($wantTrailer and $$self{PreviewImageStart}) { # seek ahead and validate preview image my $buff; my $curPos = $raf->Tell(); @@ -5951,10 +6234,13 @@ sub ProcessJPEG($$) require Image::ExifTool::Panasonic; Image::ExifTool::Panasonic::ProcessLeicaTrailer($self); $wantTrailer = 1 if $$self{LeicaTrailer}; + } else { + $wantTrailer = 1 if $$options{ExtractEmbedded}; } next if $trailInfo or $wantTrailer or $verbose > 2 or $htmlDump; } - next if $$self{OPTIONS}{Validate}; # (validate to EOI) + # must scan to EOI if Validate or JpegCompressionFactor used + next if $$options{Validate} or $calcImageLen or $$self{REQ_TAG_LOOKUP}{trailer}; # nothing interesting to parse after start of scan (SOS) $success = 1; last; # all done parsing file @@ -5975,15 +6261,16 @@ sub ProcessJPEG($$) # specifically requested. The reason is that there is too much overhead involved # in the calculation of this tag to make this worth the CPU time.) ($$self{REQ_TAG_LOOKUP}{jpegdigest} or $$self{REQ_TAG_LOOKUP}{jpegqualityestimate} - or ($$self{OPTIONS}{RequestAll} and $$self{OPTIONS}{RequestAll} > 2))) + or ($$options{RequestAll} and $$options{RequestAll} > 2))) { my $num = unpack('C',$$segDataPt) & 0x0f; # get table index $dqt[$num] = $$segDataPt if $num < 4; # save for MD5 calculation } # handle all other markers my $dumpType = ''; - my ($desc, $tip); + my ($desc, $tip, $xtra); $length = length $$segDataPt; + $appBytes += $length + 4 if ($marker & 0xf0) == 0xe0; # total size of APP segments if ($verbose) { print $out "JPEG $markerName ($length bytes):\n"; if ($verbose > 2) { @@ -6016,7 +6303,7 @@ sub ProcessJPEG($$) my $tagInfo = $self->GetTagInfo($tagTablePtr, $tag); $self->FoundTag($tagInfo, substr($$segDataPt, 6)); } elsif ($$segDataPt =~ /^(II|MM).{4}HEAPJPGM/s) { - next if $fast and $fast > 1; # skip processing for very fast + next if $fast > 1; # skip processing for very fast $dumpType = 'CIFF'; my %dirInfo = ( RAF => new File::RandomAccess($segDataPt) ); $$self{SET_GROUP1} = 'CIFF'; @@ -6032,7 +6319,7 @@ sub ProcessJPEG($$) DirStart(\%dirInfo, 4); $self->ProcessDirectory(\%dirInfo, $tagTablePtr); } - } elsif ($marker == 0xe1) { # APP1 (EXIF, XMP, QVCI) + } elsif ($marker == 0xe1) { # APP1 (EXIF, XMP, QVCI, PARROT) # (some Kodak cameras don't put a second "\0", and I have seen an # example where there was a second 4-byte APP1 segment header) if ($$segDataPt =~ /^(.{0,4})Exif\0/is) { @@ -6079,7 +6366,7 @@ sub ProcessJPEG($$) DirStart(\%dirInfo, $hdrLen, $hdrLen); $$self{SkipData} = \@skipData if @skipData; # extract the EXIF information (it is in standard TIFF format) - $self->ProcessTIFF(\%dirInfo); + $self->ProcessTIFF(\%dirInfo) or $self->Warn('Malformed APP1 EXIF segment'); # avoid looking for preview unless necessary because it really slows # us down -- only look for it if we found pointer, and preview is # outside EXIF, and PreviewImage is specifically requested @@ -6093,7 +6380,7 @@ sub ProcessJPEG($$) $start + $plen > $$self{EXIF_POS} + length($$self{EXIF_DATA}) and ($$self{REQ_TAG_LOOKUP}{previewimage} or # (extracted normally, so check Binary option) - ($$self{OPTIONS}{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage}))) + ($$options{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage}))) { $$self{PreviewImageStart} = $start; $$self{PreviewImageLength} = $plen; @@ -6176,6 +6463,11 @@ sub ProcessJPEG($$) } else { $self->WarnOnce('Invalid or extraneous FLIR chunk(s)'); } + } elsif ($$segDataPt =~ /^PARROT\0(II\x2a\0|MM\0\x2a)/) { + # (don't know if this could span multiple segments) + my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Main'); + $self->HandleTag($tagTablePtr, 'APP1', $$segDataPt); + $dumpType = 'Parrot'; } else { # Hmmm. Could be XMP, let's see my $processed; @@ -6240,7 +6532,7 @@ sub ProcessJPEG($$) $self->WarnOnce('Invalid or extraneous ICC_Profile chunk(s)'); } } elsif ($$segDataPt =~ /^FPXR\0/) { - next if $fast and $fast > 1; # skip processing for very fast + next if $fast > 1; # skip processing for very fast $dumpType = 'FPXR'; my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main'); # set flag if this is the last FPXR segment @@ -6320,7 +6612,7 @@ sub ProcessJPEG($$) undef $scalado; } } elsif ($$segDataPt =~ /^FPXR\0/) { - next if $fast and $fast > 1; # skip processing for very fast + next if $fast > 1; # skip processing for very fast $dumpType = 'FPXR'; my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main'); # set flag if this is the last FPXR segment @@ -6331,6 +6623,7 @@ sub ProcessJPEG($$) $dumpType = 'PreviewImage'; $preview .= $$segDataPt; } + # (also seen "QTI Debug Metadata\0" segment in some newer Samsung images) # BenQ DC E1050 continues preview in APP5 if ($preview and $nextMarker ne 0xe5) { $self->FoundTag('PreviewImage', $preview); @@ -6344,6 +6637,9 @@ sub ProcessJPEG($$) DirStart(\%dirInfo, 6, 6); my $tagTablePtr = GetTagTable('Image::ExifTool::Ricoh::RMETA'); $self->ProcessDirectory(\%dirInfo, $tagTablePtr); + } elsif ($$segDataPt =~ /^ssuniqueid\0/) { + my $tagTablePtr = GetTagTable('Image::ExifTool::Samsung::APP5'); + $self->HandleTag($tagTablePtr, 'ssuniqueid', substr($$segDataPt, 11)); } elsif ($preview) { $dumpType = 'PreviewImage'; $preview .= $$segDataPt; @@ -6380,7 +6676,7 @@ sub ProcessJPEG($$) DirStart(\%dirInfo, 6); $self->ProcessDirectory(\%dirInfo, $tagTablePtr); } - } elsif ($marker == 0xe7) { # APP7 (Pentax, Qualcomm) + } elsif ($marker == 0xe7) { # APP7 (Pentax, Huawei, Qualcomm) if ($$segDataPt =~ /^PENTAX \0(II|MM)/) { # found in K-3 images (is this multi-segment??) SetByteOrder($1); @@ -6395,6 +6691,23 @@ sub ProcessJPEG($$) $dumpEnd = $segPos + $length; } $self->ProcessDirectory(\%dirInfo, $tagTablePtr); + } elsif ($$segDataPt =~ /^HUAWEI\0\0(II|MM)/) { + SetByteOrder($1); + undef $dumpType; # (dump this ourself) + my $hdrLen = 16; + my $tagTablePtr = GetTagTable('Image::ExifTool::Unknown::Main'); + DirStart(\%dirInfo, $hdrLen, 8); + $dirInfo{DirName} = 'Huawei APP7'; + if ($htmlDump) { + $self->HDump($segPos-4, 4, 'APP7 header', "Data size: $length bytes"); + $self->HDump($segPos, $hdrLen, 'Huawei header', 'APP7 data type: Huawei'); + $dumpEnd = $segPos + $length; + } + $$self{SET_GROUP0} = 'APP7'; + $$self{SET_GROUP1} = 'Huawei'; + $self->ProcessDirectory(\%dirInfo, $tagTablePtr); + delete $$self{SET_GROUP0}; + delete $$self{SET_GROUP1}; } elsif ($$segDataPt =~ /^\x1aQualcomm Camera Attributes/) { # found in HP iPAQ_VoiceMessenger $dumpType = 'Qualcomm'; @@ -6426,6 +6739,10 @@ sub ProcessJPEG($$) $dumpType = 'PhotoStudio'; my $comment = $self->Decode(substr($$segDataPt,8), 'UCS2', 'MM'); $self->FoundTag('Comment', $comment); + } elsif ($$segDataPt =~ /^AROT\0/ and $length > 10) { + # iPhone "AROT" segment containing integrated intensity per 16 scan lines + # (with number of elements N = ImageHeight / 16 - 1, ref PH/NealKrawetz) + $xtra = 'segment (N=' . unpack('x6N', $$segDataPt) . ')'; } } elsif ($marker == 0xeb) { # APP11 (JPEG-HDR) if ($$segDataPt =~ /^HDR_RI /) { @@ -6538,8 +6855,10 @@ sub ProcessJPEG($$) $desc = "[JPEG $markerName]"; # (other known JPEG segments) } if (defined $dumpType) { - if (not $dumpType and $$self{OPTIONS}{Unknown}) { - $self->Warn("Unknown $markerName segment", 1); + if (not $dumpType and ($$options{Unknown} or $$options{Validate})) { + my $str = ($$segDataPt =~ /^([\x20-\x7e]{1,20})\0/) ? " '${1}'" : ''; + $xtra = 'segment' unless $xtra; + $self->Warn("Unknown $markerName$str $xtra", 1); } if ($htmlDump) { $desc or $desc = $markerName . ($dumpType ? " $dumpType" : '') . ' segment'; @@ -6555,7 +6874,7 @@ sub ProcessJPEG($$) # GUID indicated by the last main XMP segment my $goodGuid = $$self{VALUE}{HasExtendedXMP} || ''; # GUID of the extended XMP that we will process ('2' for all) - my $readGuid = $$self{OPTIONS}{ExtendedXMP} || 0; + my $readGuid = $$options{ExtendedXMP} || 0; $readGuid = $goodGuid if $readGuid eq '1'; foreach $guid (sort keys %extendedXMP) { next unless length $guid == 32; # ignore other (internal) keys @@ -6698,15 +7017,20 @@ sub DoProcessTIFF($$;$) $$self{EXIF_DATA} = ''; } unless (defined $$self{EXIF_DATA}) { + # set default byte order for creating new GPS in CR3 images + my $defaultByteOrder; + if ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'GPS') { + $defaultByteOrder = $$self{SaveExifByteOrder}; + } # create TIFF information from scratch - if ($self->SetPreferredByteOrder() eq 'MM') { + if ($self->SetPreferredByteOrder($defaultByteOrder) eq 'MM') { $$self{EXIF_DATA} = "MM\0\x2a\0\0\0\x08"; } else { $$self{EXIF_DATA} = "II\x2a\0\x08\0\0\0"; } } - $$self{FIRST_EXIF_POS} = $base + $$self{BASE} unless defined $$self{FIRST_EXIF_POS}; $$self{EXIF_POS} = $base + $$self{BASE}; + $$self{FIRST_EXIF_POS} = $$self{EXIF_POS} unless defined $$self{FIRST_EXIF_POS}; $dataPt = \$$self{EXIF_DATA}; # set byte ordering @@ -6721,6 +7045,7 @@ sub DoProcessTIFF($$;$) # return 0 unless $identifier == 0x2a; # get offset to IFD0 + return 0 if length $$dataPt < 8; my $offset = Get32u($dataPt, 4); $offset >= 8 or return 0; @@ -6788,10 +7113,12 @@ sub DoProcessTIFF($$;$) # don't process file if FastScan == 3 return 1 if not $outfile and $$self{OPTIONS}{FastScan} and $$self{OPTIONS}{FastScan} == 3; } - # (accomodate CR3 images which have a TIFF directory with ExifIFD at the top level) + # (accommodate CR3 images which have a TIFF directory with ExifIFD at the top level) my $ifdName = ($$dirInfo{DirName} and $$dirInfo{DirName} =~ /^(ExifIFD|GPS)$/) ? $1 : 'IFD0'; if (not $tagTablePtr or $$tagTablePtr{GROUPS}{0} eq 'EXIF') { $self->FoundTag('ExifByteOrder', $byteOrder) unless $outfile; + } elsif ($$tagTablePtr{GROUPS}{0} eq 'MakerNotes') { # (for writing CR3 maker notes) + $ifdName = $$tagTablePtr{GROUPS}{0}; } else { $ifdName = $$tagTablePtr{GROUPS}{1}; } @@ -6988,8 +7315,8 @@ sub DoProcessTIFF($$;$) # check DNG version if ($$self{DNGVersion}) { my $ver = $$self{DNGVersion}; - # currently support up to DNG version 1.4 - unless ($ver =~ /^(\d+) (\d+)/ and "$1.$2" <= 1.4) { + # currently support up to DNG version 1.5 + unless ($ver =~ /^(\d+) (\d+)/ and "$1.$2" <= 1.5) { $ver =~ tr/ /./; $self->Error("DNG Version $ver not yet tested", 1); } @@ -7056,6 +7383,7 @@ sub GetTagTable($) no strict 'refs'; $table = \%$tableName; use strict 'refs'; + &{$$table{INIT_TABLE}}($table) if $$table{INIT_TABLE}; $$table{TABLE_NAME} = $tableName; # set table name ($$table{SHORT_NAME} = $tableName) =~ s/^Image::ExifTool:://; # set default group 0 and 1 from module name unless already specified @@ -7139,7 +7467,7 @@ sub ProcessDirectory($$$;$) $dirName = $$tagTablePtr{GROUPS}{1} if $dirName =~ /^APP\d+$/; # (use specific APP name) $$dirInfo{DirName} = $dirName; } - + # guard against cyclical recursion into the same directory if (defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos} and # directories don't overlap if the length is zero @@ -7162,7 +7490,9 @@ sub ProcessDirectory($$$;$) $$self{FOUND_DIR}{$dirName} = 1; # process the directory + no strict 'refs'; my $rtnVal = &$proc($self, $dirInfo, $tagTablePtr); + use strict 'refs'; pop @{$$self{PATH}}; @$self{'INDENT','DIR_NAME','Compression','SubfileType'} = @save; @@ -7254,7 +7584,9 @@ sub GetTagInfo($$$;$$$) next; } } - if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and not $$self{OPTIONS}{Verbose}) { + if ($$tagInfo{Unknown} and not $$self{OPTIONS}{Unknown} and + not $$self{OPTIONS}{Verbose} and not $$self{HTML_DUMP}) + { # don't return Unknown tags unless that option is set return undef; } @@ -7294,6 +7626,7 @@ sub GetTagInfo($$$;$$$) # Inputs: 0) reference to tag table, 1) tag ID # 2) [optional] tag name or reference to tag information hash # 3) [optional] flag to avoid adding prefix when generating tag name +# Returns: tagInfo ref # Notes: - will not override existing entry in table # - info need contain no entries when this routine is called # - tag name is made valid if necessary @@ -7318,6 +7651,9 @@ sub AddTagToTable($$;$$) $$tagInfo{GotGroups} = 1, $$tagInfo{Table} = $tagTablePtr; $$tagInfo{TagID} = $tagID; + if (defined $$tagTablePtr{AVOID} and not defined $$tagInfo{Avoid}) { + $$tagInfo{Avoid} = $$tagTablePtr{AVOID}; + } my $name = $$tagInfo{Name}; $name = $tagID unless defined $name; @@ -7337,13 +7673,14 @@ sub AddTagToTable($$;$$) unless (defined $$tagTablePtr{$tagID} or $specialTags{$tagID}) { $$tagTablePtr{$tagID} = $tagInfo; } + return $tagInfo; } #------------------------------------------------------------------------------ # Handle simple extraction of new tag information # Inputs: 0) ExifTool object ref, 1) tag table reference, 2) tagID, 3) value, # 4-N) parameters hash: Index, DataPt, DataPos, Base, Start, Size, Parent, -# TagInfo, ProcessProc, RAF, Format +# TagInfo, ProcessProc, RAF, Format, Count # Returns: tag key or undef if tag not found # Notes: if value is not defined, it is extracted from DataPt using TagInfo # Format and Count if provided @@ -7569,15 +7906,19 @@ sub FoundTag($$$;@) # increase 0-priority tags if this is the priority directory $priority = 1 if not $priority and $$self{DIR_NAME} and $$self{DIR_NAME} eq $$self{PRIORITY_DIR}; - } elsif ($$self{DIR_NAME} and $$self{LOW_PRIORITY_DIR}{$$self{DIR_NAME}}) { + } elsif ($$self{LOW_PRIORITY_DIR}{'*'} or + ($$self{DIR_NAME} and $$self{LOW_PRIORITY_DIR}{$$self{DIR_NAME}})) + { $priority = 0; # default is 0 for a LOW_PRIORITY_DIR } else { $priority = 1; # the normal default } - if ($priority >= $oldPriority and not $$self{DOC_NUM} and not $noListDel) { + if ($priority >= $oldPriority and (not $$self{DOC_NUM} or + ($$self{TAG_EXTRA}{$tag} and $$self{TAG_EXTRA}{$tag}{G3} and + $$self{DOC_NUM} eq $$self{TAG_EXTRA}{$tag}{G3})) and not $noListDel) + { # move existing tag out of the way since this tag is higher priority # (NOTE: any new members added here must also be added to DeleteTag()) - $$self{MOVED_KEY} = $nextTag; # used in BuildCompositeTags() $$self{PRIORITY}{$nextTag} = $$self{PRIORITY}{$tag}; $$valueHash{$nextTag} = $$valueHash{$tag}; $$self{FILE_ORDER}{$nextTag} = $$self{FILE_ORDER}{$tag}; @@ -7591,6 +7932,12 @@ sub FoundTag($$$;@) delete $$self{BOTH}{$tag}; # update tag key for list if necessary $$self{LIST_TAGS}{$oldInfo} = $nextTag if $$self{LIST_TAGS}{$oldInfo}; + # update this key if used in a Composite tag + if ($$self{COMP_KEYS}{$tag}) { + $$_[0]{$$_[1]} = $nextTag foreach @{$$self{COMP_KEYS}{$tag}}; + $$self{COMP_KEYS}{$nextTag} = $$self{COMP_KEYS}{$tag}; + delete $$self{COMP_KEYS}{$tag}; + } } else { $tag = $nextTag; # don't override the existing tag } @@ -7716,6 +8063,7 @@ sub SetFileType($;$$$) $normExt = $fileTypeExt{$fileType}; $normExt = $fileType unless defined $normExt; } + $$self{FileType} = $fileType; $self->FoundTag('FileType', $fileType); $self->FoundTag('FileTypeExtension', uc $normExt); $self->FoundTag('MIMEType', $mimeType || 'application/unknown'); @@ -7730,6 +8078,7 @@ sub OverrideFileType($$;$$) { my ($self, $fileType, $mimeType, $normExt) = @_; if (defined $$self{VALUE}{FileType} and $fileType ne $$self{VALUE}{FileType}) { + $$self{FileType} = $fileType; $$self{VALUE}{FileType} = $fileType; unless (defined $normExt) { $normExt = $fileTypeExt{$fileType}; @@ -8043,7 +8392,8 @@ sub ProcessBinaryData($$$) # hook to allow format, etc to be set dynamically if (defined $$tagInfo{Hook}) { my $oldVarSize = $varSize; - #### eval Hook ($format, $varSize, $size) + my $pos = $entry + $offset; + #### eval Hook ($format, $varSize, $size, $dataPt, $pos) eval $$tagInfo{Hook}; # save variable size data if required for writing (in case changed by Hook) if ($$dirInfo{VarFormatData}) { @@ -8169,7 +8519,8 @@ until ($Image::ExifTool::noConfig) { $file = $config; } # also check executable directory unless path is absolute - -r $file or $config =~ /^\// or $file = ($0 =~ /(.*[\\\/])/ ? $1 : './') . $config; + $exePath = $0 unless defined $exePath; # (undocumented $exePath setting) + -r $file or $config =~ /^\// or $file = ($exePath =~ /(.*[\\\/])/ ? $1 : './') . $config; unless (-r $file) { warn("Config file not found\n") if defined $Image::ExifTool::configFile; last; diff --git a/src/Image-ExifTool/lib/Image/ExifTool.pod b/src/Image-ExifTool/lib/Image/ExifTool.pod index 62caae75..8fa1991d 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool.pod +++ b/src/Image-ExifTool/lib/Image/ExifTool.pod @@ -3,9 +3,9 @@ # # Description: Read and write meta information # -# URL: http://owl.phy.queensu.ca/~phil/exiftool/ +# URL: https://exiftool.org/ # -# Legal: Copyright (c) 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +# Legal: Copyright (c) 2003-2020, Phil Harvey (philharvey66 at gmail.com) # This library is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. #------------------------------------------------------------------------------ @@ -65,44 +65,46 @@ supported by ExifTool (r = read, w = write, c = create): File Types ------------+-------------+-------------+-------------+------------ - 3FR r | DR4 r/w/c | J2C r | ODP r | RAW r/w - 3G2 r/w | DSS r | JNG r/w | ODS r | RIFF r - 3GP r/w | DV r | JP2 r/w | ODT r | RSRC r - A r | DVB r/w | JPEG r/w | OFR r | RTF r - AA r | DVR-MS r | JSON r | OGG r | RW2 r/w - AAE r | DYLIB r | K25 r | OGV r | RWL r/w - AAX r/w | EIP r | KDC r | OPUS r | RWZ r - ACR r | EPS r/w | KEY r | ORF r/w | RM r - AFM r | EPUB r | LA r | OTF r | SEQ r - AI r/w | ERF r/w | LFP r | PAC r | SKETCH r - AIFF r | EXE r | LNK r | PAGES r | SO r - APE r | EXIF r/w/c | M2TS r | PBM r/w | SR2 r/w - ARQ r/w | EXR r | M4A/V r/w | PCD r | SRF r - ARW r/w | EXV r/w/c | MAX r | PDB r | SRW r/w - ASF r | F4A/V r/w | MEF r/w | PDF r/w | SVG r - AVI r | FFF r/w | MIE r/w/c | PEF r/w | SWF r - AZW r | FLA r | MIFF r | PFA r | THM r/w - BMP r | FLAC r | MKA r | PFB r | TIFF r/w - BPG r | FLIF r/w | MKS r | PFM r | TORRENT r - BTF r | FLV r | MKV r | PGF r | TTC r - CHM r | FPF r | MNG r/w | PGM r/w | TTF r - COS r | FPX r | MOBI r | PLIST r | VCF r - CR2 r/w | GIF r/w | MODD r | PICT r | VRD r/w/c - CR3 r/w | GPR r/w | MOI r | PMP r | VSD r - CRM r/w | GZ r | MOS r/w | PNG r/w | WAV r - CRW r/w | HDP r/w | MOV r/w | PPM r/w | WDP r/w - CS1 r/w | HDR r | MP3 r | PPT r | WEBP r - DCM r | HEIC r | MP4 r/w | PPTX r | WEBM r - DCP r/w | HEIF r | MPC r | PS r/w | WMA r - DCR r | HTML r | MPG r | PSB r/w | WMV r - DFONT r | ICC r/w/c | MPO r/w | PSD r/w | WTV r - DIVX r | ICS r | MQV r/w | PSP r | WV r - DJVU r | IDML r | MRW r/w | QTIF r/w | X3F r/w - DLL r | IIQ r/w | MXF r | R3D r | XCF r - DNG r/w | IND r/w | NEF r/w | RA r | XLS r - DOC r | INX r | NRW r/w | RAF r/w | XLSX r - DOCX r | ISO r | NUMBERS r | RAM r | XMP r/w/c - DPX r | ITC r | O r | RAR r | ZIP r + 3FR r | DR4 r/w/c | ITC r | ODP r | RIFF r + 3G2 r/w | DSS r | J2C r | ODS r | RSRC r + 3GP r/w | DV r | JNG r/w | ODT r | RTF r + A r | DVB r/w | JP2 r/w | OFR r | RW2 r/w + AA r | DVR-MS r | JPEG r/w | OGG r | RWL r/w + AAE r | DYLIB r | JSON r | OGV r | RWZ r + AAX r/w | EIP r | K25 r | OPUS r | RM r + ACR r | EPS r/w | KDC r | ORF r/w | SEQ r + AFM r | EPUB r | KEY r | OTF r | SKETCH r + AI r/w | ERF r/w | LA r | PAC r | SO r + AIFF r | EXE r | LFP r | PAGES r | SR2 r/w + APE r | EXIF r/w/c | LNK r | PBM r/w | SRF r + ARQ r/w | EXR r | LRV r/w | PCD r | SRW r/w + ARW r/w | EXV r/w/c | M2TS r | PCX r | SVG r + ASF r | F4A/V r/w | M4A/V r/w | PDB r | SWF r + AVI r | FFF r/w | MAX r | PDF r/w | THM r/w + AVIF r/w | FITS r | MEF r/w | PEF r/w | TIFF r/w + AZW r | FLA r | MIE r/w/c | PFA r | TORRENT r + BMP r | FLAC r | MIFF r | PFB r | TTC r + BPG r | FLIF r/w | MKA r | PFM r | TTF r + BTF r | FLV r | MKS r | PGF r | TXT r + CHM r | FPF r | MKV r | PGM r/w | VCF r + COS r | FPX r | MNG r/w | PLIST r | VRD r/w/c + CR2 r/w | GIF r/w | MOBI r | PICT r | VSD r + CR3 r/w | GPR r/w | MODD r | PMP r | WAV r + CRM r/w | GZ r | MOI r | PNG r/w | WDP r/w + CRW r/w | HDP r/w | MOS r/w | PPM r/w | WEBP r + CS1 r/w | HDR r | MOV r/w | PPT r | WEBM r + CSV r | HEIC r/w | MP3 r | PPTX r | WMA r + DCM r | HEIF r/w | MP4 r/w | PS r/w | WMV r + DCP r/w | HTML r | MPC r | PSB r/w | WTV r + DCR r | ICC r/w/c | MPG r | PSD r/w | WV r + DFONT r | ICS r | MPO r/w | PSP r | X3F r/w + DIVX r | IDML r | MQV r/w | QTIF r/w | XCF r + DJVU r | IIQ r/w | MRW r/w | R3D r | XLS r + DLL r | IND r/w | MXF r | RA r | XLSX r + DNG r/w | INSP r/w | NEF r/w | RAF r/w | XMP r/w/c + DOC r | INSV r | NRW r/w | RAM r | ZIP r + DOCX r | INX r | NUMBERS r | RAR r | + DPX r | ISO r | O r | RAW r/w | Meta Information ----------------------+----------------------+--------------------- @@ -423,6 +425,9 @@ in the full ExifTool distribution for examples. =item Option Parameters: +Note that these API options may also be used in the exiftool application via +the command-line B<-api> option. + =over 4 =item Binary @@ -525,12 +530,22 @@ without recoding. Default is 0. =item Compact -Option to write compact XMP output. The XMP specification suggests that the -data be padded with blanks to allow in-place editing. With this flag set to -1, the 2 kB of padding is not written. Note that this only effects embedded -XMP since padding is never written for stand-alone XMP files. When set to -2, spaces to indent XMP for readability are also dropped. Default is undef. -Also see the XMPShorthand option for reducing the size of XMP. +Comma-delimited list of settings for writing compact XMP. Below is a list +of available settings. Note that 'NoPadding' effects only embedded XMP +since padding is never written for stand-alone XMP files. Also note that +'OneDesc' is not recommended when writing XMP larger than 64 kB to a JPG +file because it interferes with ExifTool's technique of splitting off large +rdf:Description elements into the extended XMP. Case is not significant for +any of these options. Aliases are given in brackets. Default is undef. + + NoPadding - Avoid 2 kB of recommended padding at end of XMP (NoPad) + NoIndent - No spaces to indent lines (NoSpace, NoSpaces) + NoNewline - Avoid unnecessary newlines (NoNewlines) + Shorthand - Use XMP Shorthand format + OneDesc - Combine properties into a single rdf:Description (OneDescr) + AllSpace - Equivalent to 'NoPadding,NoIndent,NoNewline' + AllFormat - Equivalent to 'Shorthand,OneDesc' + All - Equivalent to 'AllSpace,AllFormat' =item Composite @@ -599,39 +614,53 @@ GUID specified by the HasExtendedXMP tag, so by default ExifTool will ignore other extended XMP, but this option allows full control over the extended XMP to be extracted. - 0 - ignore all extended XMP - 1 - read extended XMP with valid GUID only (default) - 2 - read extended XMP with any GUID - - read extended XMP with a specific GUID + 0 - Ignore all extended XMP + 1 - Read extended XMP with valid GUID only (default) + 2 - Read extended XMP with any GUID + - Read extended XMP with a specific GUID =item ExtractEmbedded Flag to extract information from embedded documents in EPS files, embedded EPS information and JPEG and Jpeg2000 images in PDF files, embedded MPF -images in JPEG and MPO files, streaming metadata in AVCHD videos, and the -resource fork of Mac OS files. Default is undef. +images in JPEG and MPO files, timed metadata in videos, and the resource +fork of Mac OS files. Default is undef. =item FastScan -Flag to increase speed of extracting information from JPEG images. With -this option set to 1, ExifTool will not scan to the end of a JPEG image to -check for an AFCP, CanonVRD, FotoStation, PhotoMechanic, MIE or PreviewImage -trailer. This also stops the parsing after the first comment in GIF images, -and at the audio/video data with RIFF-format files (AVI, WAV, etc), so any -trailing metadata (eg. XMP written by some utilities) may be missed. Also -disables input buffering for some types of files to reduce memory usage when -reading from a non-seekable stream. When combined with the ScanForXMP -option, prevents scanning for XMP in recognized file types. With a value of -2, ExifTool will also avoid extracting any EXIF MakerNote information. When -set to 3, the file is not actually parsed, and only an initial guess at -FileType and some pseudo tags are returned. Default is undef. +Flag to increase speed when reading files by avoiding extraction of some +types of metadata. With this option set to 1, ExifTool will not scan to the +end of a JPEG image to check for an AFCP, CanonVRD, FotoStation, +PhotoMechanic, MIE or PreviewImage trailer. This also stops the parsing +after the first comment in GIF images, and at the audio/video data of +RIFF-format files (AVI, WAV, etc), so any trailing metadata (eg. XMP written +by some utilities) may be missed. Also disables input buffering for some +types of files to reduce memory usage when reading from a non-seekable +stream, and bypasses CRC validation for speed when writing PNG files. When +combined with the ScanForXMP option, prevents scanning for XMP in recognized +file types. With a value of 2, ExifTool will also avoid extracting any EXIF +MakerNote information, and will stop parsing at the IDAT chunk of PNG +images. (By the PNG specification, metadata is allowed after IDAT, but +ExifTool always writes it before because some utilities will ignore it +otherwise.) When set to 3 or 4, only pseudo system tags and FileType are +generated. For 3, the file header is read to provide an educated guess at +FileType. For 4, the file is not read at all and FileType is determined +based on the file's extension. Default is undef. =item Filter Perl expression used to filter values for all tags. The expression acts on the value of the Perl default variable ($_), and changes the value of this -variable as required. The value is not changed if $_ is set to undef. -Applies to all returned values unless PrintConv option is disabled. +variable as required. The value is not changed if $_ is set to undef. List +items are filtered individually. Applies to all returned values unless +PrintConv option is disabled. + +=item FilterW + +Perl expression used to filter PrintConv values when writing. The +expression acts on the value of the Perl default variable ($_), and changes +the value of this variable as required. The value is not changed if $_ is +set to undef. =item FixBase @@ -657,8 +686,9 @@ it is within GeoMaxExtSecs, otherwise geotagging fails). Default is 1800. Maximum extrapolation time in seconds for geotagging. Geotagging fails if the Geotime value lies outside a GPS track by a number of seconds greater -than this. Otherwise, the coordinates of the nearest fix are taken. -Default is 1800. +than this. Otherwise, for an extrapolation the coordinates of the nearest +fix are taken (ie. it is assumed that you weren't moving during this +period). Default is 1800. =item GeoMaxHDOP @@ -772,9 +802,10 @@ L for more information). =item MissingTagValue -Value for missing tags in tag name expressions. If not set, a minor error -is issued for missing values, or the value is set to '' if -L is set. Default is undef. +Value for missing tags in tag name expressions (or tags where the advanced +formatting expression returns undef). If not set, a minor error is issued +for missing values, or the value is set to '' if L is +set. Default is undef. =item NoPDFList @@ -787,28 +818,18 @@ Password for reading/writing password-protected PDF documents. Ignored if a password is not required. Character encoding of the password is determined by the value of the Charset option at processing time. Default is undef. -=item PNGEarlyXMP - -Flag to write XMP in PNG images before the IDAT (image data) chunk. By -default, ExifTool adds new XMP to the end of a PNG file (just before IEND). -This is allowed by the PNG and XMP specifications, but some utilities seem -to ignore XMP if it comes after the image data. The PNGEarlyXMP option -causes ExifTool to instead add new XMP before the PNG IDAT chunk. However, -since ExifTool uses a single-pass writing algorithm, it has no way to tell -if XMP already exists later in the file before writing the new XMP in this -location. If this happens, a minor error is issued when the extra XMP is -encountered, and the file is not written. Adding the L -option causes the XMP after IDAT to be deleted, thus resolving the conflict -(at the expense of possible metadata loss), and allowing the file to be -written. The PNGEarlyXMP option is applied automatically when deleting all -XMP and writing new XMP back in one step. When reading, this option causes -a warning to be issued if standard XMP is found after the IDAT chunk. - =item PrintConv Flag to enable automatic print conversion. Also enables inverse print conversion for writing. Default is 1. +=item QuickTimeHandler + +Flag set to add an 'mdir' Handler to a newly created Meta box when adding +QuickTime ItemList tags. Adobe Bridge does not add this Handler, but it is +commonly found in samples from other software, so it is possible that this +could affect the interoperability of ItemList tags. Default is undef. + =item QuickTimeUTC Flag set to assume that QuickTime date/time values are stored as UTC, @@ -838,6 +859,19 @@ current RequestTags list. Groups are requested by adding a colon after the name (eg. "MacOS:"). Names are converted to lower case as they are added to the list. Default is undef. +=item SaveFormat + +Flag to save EXIF/TIFF format type as the family 6 group name when +extracting information. Without this option set, the family 6 group names +are not generated. Default is undef. See the L option for more +details. + +=item SavePath + +Flag to save the metadata path as the family 5 group name when extracting +information. Without this option set, the family 5 group names are not +generated. Default is undef. See the L option for more details. + =item ScanForXMP Flag to scan all files (even unrecognized formats) for XMP information @@ -943,8 +977,8 @@ user parameters (with lower-case names). =item Validate -Flag to perform extra validation checks when reading, causing extra warnings -to be generated if problems are found. Default is undef. +Flag to perform extra validation metadata checks when reading, causing extra +warnings to be generated if problems are found. Default is undef. =item Verbose @@ -967,7 +1001,9 @@ list below. Default is 'wcg'. The level of the group differs for different types of metadata. For XMP or IPTC this is the full XMP/IPTC block (the family 0 group), but for EXIF this -is the individual IFD (the family 1 group). +is the individual IFD (the family 1 group). The 'w' and 'c' modes are +tested only when L is called, but the 'g' mode is also tested +in L. =item XAttrTags @@ -979,10 +1015,6 @@ and L for more information). Flag to enable automatic conversion for unknown XMP tags with values that look like rational numbers or dates. Default is 1. -=item XMPShorthand - -Flag set to write xmp in shorthand format. Default is undef. - =back =item Return Values: @@ -1030,9 +1062,9 @@ Binary, Charset, CharsetEXIF, CharsetFileName, CharsetID3, CharsetIPTC, CharsetPhotoshop, CharsetQuickTime, CharsetRIFF, Composite, ExtendedXMP, ExtractEmbedded, FastScan, FixBase, HtmlDump, HtmlDumpBase, IgnoreMinorErrors, Lang, LargeFileSupport, MakerNotes, MDItemTags, -NoPDFList, Password, PNGEarlyXMP, QuickTimeUTC (enforced 1904 time zero), -RequestAll, RequestTags, ScanForXMP, Struct, TextOut, Unknown, Verbose, -XAttrTags and XMPAutoConv. +NoPDFList, Password, QuickTimeUTC (enforced 1904 time zero), RequestAll, +RequestTags, SaveFormat, SavePath, ScanForXMP, Struct, TextOut, Unknown, +Verbose, XAttrTags and XMPAutoConv. =item Return Value: @@ -1163,7 +1195,8 @@ called with a source file name. The following ExifTool options are effective in the call to L: ByteOrder, Charset, CharsetEXIF, CharsetFileName, CharsetIPTC, Compact, -Compress, FixBase, IgnoreMinorErrors, Password, PNGEarlyXMP and Verbose. +Compress, FixBase, IgnoreMinorErrors, Password, QuickTimeHandler, Verbose +and WriteMode. =head2 GetTagList @@ -1290,8 +1323,8 @@ optional group specifier), use L instead. The following options are in effect when L is called: Charset, CoordFormat, DateFormat, Escape, Filter, GlobalTimeShift, Lang, -ListItem, ListJoin, PrintConv, QuickTimeUTC (conversion to local time), and -StrictDate. +ListItem, ListJoin, PrintConv, QuickTimeUTC (conversion to local time), +StrictDate and TimeZone. =over 4 @@ -1398,8 +1431,8 @@ name for each value, or call with a reference to the list of values. # write structured information as a serialized string $exifTool->SetNewValue('XMP:Flash'=>'{mode=on,fired=true,return=not}'); -(See L for -a description of the structure serialization technique.) +(See L for a description of the +structure serialization technique.) =over 4 @@ -1437,9 +1470,9 @@ hash reference or a serialized string (see the last two examples above). =item AddValue Specifies that the value be added to an existing list in a file rather than -overwriting. Valid settings are 0 (overwrite any existing tag value), 1 -(add to an existing list and warn for non-list tags) or 2 (add to existing -list and overwrite non-list tags). Default is 0. +overwriting the existing values. Valid settings are 0 (overwrite any +existing tag value), 1 (add to an existing list and warn for non-list tags) +or 2 (add to existing list and overwrite non-list tags). Default is 0. =item DelValue @@ -1501,8 +1534,8 @@ Flag to replace the previous new values for this tag (ie. replace the values set in previous calls to L). This option is most commonly used to replace previously-set new values for list-type tags. Valid values are 0 (set new value normally -- adds to new values for list-type tags), 1 -(reset previous new values for this tag and replace with the specified new -value) or 2 (reset previous new values only). +(reset any previous new values before setting new value) or 2 (reset +previous new values only; new value argument is ignored). Default is 0. =item Shift @@ -1546,7 +1579,7 @@ explicitly, either by group (with 'Adobe:*') or as a block (with 'Adobe'). The following ExifTool options are effective in the call to L: Charset, DateFormat, Escape, IgnoreMinorErrors, Lang, ListJoin, ListSplit, -PrintConv, QuickTimeUTC, StrictDate, Verbose and WriteMode. +PrintConv, QuickTimeUTC, StrictDate, TimeZone, Verbose and WriteMode. =head2 GetNewValue @@ -1814,11 +1847,11 @@ systems only. Set the file name and directory, or create a hard link. If not specified, the new file name is derived from the new values of the FileName and -Directory tags, or from the HardLink tag if creating a link. If the -FileName tag contains a '/', then the file is renamed into a new directory. -If FileName ends with '/', then it is taken as a directory name and the file -is moved into the new directory. The new value for the Directory tag takes -precedence over any directory specified in FileName. +Directory tags, or from the HardLink or SymLink tag if creating a link. If +the FileName tag contains a '/', then the file is renamed into a new +directory. If FileName ends with '/', then it is taken as a directory name +and the file is moved into the new directory. The new value for the +Directory tag takes precedence over any directory specified in FileName. $result = $exifTool->SetFileName($file); $result = $exifTool->SetFileName($file, $newName); @@ -1833,14 +1866,14 @@ precedence over any directory specified in FileName. 2) [optional] New file name -3) [optional] 'Link' to create a hard link instead of renaming the file, or -'Test' to test renaming feature by printing the old and new names instead of -changing anything. +3) [optional] 'HardLink' or 'SymLink' to create a hard or symbolic link +instead of renaming the file, or 'Test' to test renaming feature by printing +the old and new names instead of changing anything. =item Return Value: -1 if the file name or directory was changed, 0 if nothing was done, or -1 if -there was an error renaming the file. +1 on success, 0 if nothing was done, or -1 if there was an error renaming the +file or creating the link. =item Notes: @@ -1854,8 +1887,9 @@ Set the order of the preferred groups when adding new information. In subsequent calls to L, new information will be created in the first valid group of this list. This has an impact only if the group is not specified when calling L and if the tag name exists in more -than one group. The default order is EXIF, IPTC then XMP. Any family 0 -group name may be used. Case is not significant. +than one group. The default order is EXIF, IPTC, XMP, MakerNotes, +QuickTime, Photoshop, ICC_Profile, CanonVRD, Adobe. Any family 0 group name +may be used. Case is not significant. $exifTool->SetNewGroups('XMP','EXIF','IPTC'); @@ -1984,6 +2018,8 @@ The group family numbers are currently available: 2) Category (eg. Author, Time) 3) Document Number (eg. Main, Doc1, Doc3-2) 4) Instance Number (eg. Copy1, Copy2, Copy3...) + 5) Metadata Path (eg. JPEG-APP1-IFD0-ExifIFD) + 6) EXIF/TIFF Format (eg. int8u, int32u, undef, string) Families 0 and 1 are based on the file structure, and are similar except that family 1 is more specific and sub-divides some groups to give more @@ -2009,13 +2045,23 @@ L option for extracting tags from embedded documents.) Nested sub-documents (if they exist) are indicated by numbers separated with dashes in the group name, to an arbitrary depth. (eg. 'Doc2-3-1' is the 1st sub-sub-document of the 3rd sub-document of the 2nd embedded document of the -main file.) +main file.) Document numbers are also used to differentiate samples for +timed metadata in videos. Family 4 provides a method for differentiating tags when multiple tags exist with the same name in the same location. The primary instance of a tag (the tag extracted when the Duplicates option is disabled and no group is -specified) has no family 4 group name, but additional instances have have -family 4 group names of 'Copy1', 'Copy2', 'Copy3', etc. +specified) has no family 4 group name, but additional instances have family +4 group names of 'Copy1', 'Copy2', 'Copy3', etc. For convenience, the +primary tag may also be accessed using a group name of 'Copy0'. + +Family 5 is experimental, and gives the complete path for the metadata in +the file. Generated only if the L option is used when +extracting. + +Family 6 is currently used only for EXIF/TIFF metadata, and gives the format +type of the extracted value. Generated only if the L option is +used when extracting. See L for complete lists of group names. @@ -2188,46 +2234,48 @@ Here is a complete list of groups for each of these families: AFCP, AIFF, APE, APP0, APP1, APP11, APP12, APP13, APP14, APP15, APP4, APP5, APP6, APP8, ASF, Audible, CanonVRD, Composite, DICOM, DNG, DV, DjVu, Ducky, -EXE, EXIF, ExifTool, FLAC, FLIR, File, Flash, FlashPix, Font, FotoStation, -GIF, GIMP, GeoTiff, GoPro, H264, HTML, ICC_Profile, ID3, IPTC, ISO, ITC, -JFIF, JPEG, JSON, Jpeg2000, LNK, Leaf, Lytro, M2TS, MIE, MIFF, MNG, MOI, -MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, Ogg, OpenEXR, Opus, PDF, -PICT, PLIST, PNG, PSP, Palm, PanasonicRaw, PhotoCD, PhotoMechanic, -Photoshop, PostScript, PrintIM, QuickTime, RAF, RIFF, RSRC, RTF, Radiance, -Rawzor, Real, Red, SVG, SigmaRaw, Stim, Theora, Torrent, VCard, Vorbis, WTV, -XML, XMP, ZIP +EXE, EXIF, ExifTool, FITS, FLAC, FLIR, File, Flash, FlashPix, Font, +FotoStation, GIF, GIMP, GeoTiff, GoPro, H264, HTML, ICC_Profile, ID3, IPTC, +ISO, ITC, JFIF, JPEG, JSON, Jpeg2000, LNK, Leaf, Lytro, M2TS, MIE, MIFF, +MNG, MOI, MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, Ogg, OpenEXR, +Opus, PDF, PICT, PLIST, PNG, PSP, Palm, Parrot, PanasonicRaw, PhotoCD, +PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF, RIFF, RSRC, +RTF, Radiance, Rawzor, Real, Red, SVG, SigmaRaw, Stim, Theora, Torrent, +Trailer, VCard, Vorbis, WTV, XML, XMP, ZIP =item Family 1 (Specific Location): AC3, AFCP, AIFF, APE, ASF, AVI1, Adobe, AdobeCM, AdobeDNG, Apple, Audible, CIFF, CameraIFD, Canon, CanonCustom, CanonRaw, CanonVRD, Casio, Chapter#, Composite, DICOM, DJI, DNG, DV, DjVu, DjVu-Meta, Ducky, EPPIM, EXE, EXIF, -ExifIFD, ExifTool, FLAC, FLIR, File, Flash, FlashPix, Font, FotoStation, -FujiFilm, FujiIFD, GE, GIF, GIMP, GPS, GeoTiff, GlobParamIFD, GoPro, -GraphConv, H264, HP, HTC, HTML, HTML-dc, HTML-ncc, HTML-office, HTML-prod, -HTML-vw96, HTTP-equiv, ICC-chrm, ICC-clrt, ICC-header, ICC-meas, ICC-meta, -ICC-view, ICC_Profile, ICC_Profile#, ID3, ID3v1, ID3v1_Enh, ID3v2_2, -ID3v2_3, ID3v2_4, IFD0, IFD1, IPTC, IPTC#, ISO, ITC, InteropIFD, JFIF, JFXX, -JPEG, JPEG-HDR, JSON, JVC, Jpeg2000, KDC_IFD, Kodak, KodakBordersIFD, -KodakEffectsIFD, KodakIFD, KyoceraRaw, LNK, Leaf, LeafSubIFD, Leica, Lytro, -M2TS, MAC, MIE-Audio, MIE-Camera, MIE-Canon, MIE-Doc, MIE-Extender, -MIE-Flash, MIE-GPS, MIE-Geo, MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes, -MIE-Meta, MIE-Orient, MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown, -MIE-Video, MIFF, MNG, MOBI, MOI, MPC, MPEG, MPF0, MPImage, MS-DOC, MXF, -MacOS, MakerNotes, MakerUnknown, Matroska, MediaJukebox, MetaIFD, Microsoft, -Minolta, MinoltaRaw, Motorola, NITF, Nikon, NikonCapture, NikonCustom, -NikonScan, Nintendo, Ocad, Ogg, Olympus, OpenEXR, Opus, PDF, PICT, PNG, -PNG-pHYs, PSP, Palm, Panasonic, PanasonicRaw, Pentax, PhaseOne, PhotoCD, -PhotoMechanic, Photoshop, PictureInfo, PostScript, PreviewIFD, PrintIM, -ProfileIFD, Qualcomm, QuickTime, RAF, RAF2, RIFF, RMETA, RSRC, RTF, -Radiance, Rawzor, Real, Real-CONT, Real-MDPR, Real-PROP, Real-RA3, Real-RA4, -Real-RA5, Real-RJMD, Reconyx, Red, Ricoh, SPIFF, SR2, SR2DataIFD, SR2SubIFD, -SRF#, SVG, Samsung, Sanyo, Scalado, Sigma, SigmaRaw, Sony, SonyIDC, Stim, -SubIFD, System, Theora, Torrent, Track#, VCalendar, VCard, Version0, Vorbis, -WTV, XML, XMP, XMP-DICOM, XMP-GAudio, XMP-GImage, XMP-GPano, XMP-GSpherical, -XMP-MP, XMP-MP1, XMP-PixelLive, XMP-aas, XMP-acdsee, XMP-album, -XMP-apple-fi, XMP-aux, XMP-cc, XMP-cell, XMP-creatorAtom, XMP-crs, XMP-dc, -XMP-dex, XMP-digiKam, XMP-drone-dji, XMP-dwc, XMP-exif, XMP-exifEX, +ExifIFD, ExifTool, FITS, FLAC, FLIR, File, Flash, FlashPix, Font, +FotoStation, FujiFilm, FujiIFD, GE, GIF, GIMP, GPS, GeoTiff, GlobParamIFD, +GoPro, GraphConv, H264, HP, HTC, HTML, HTML-dc, HTML-ncc, HTML-office, +HTML-prod, HTML-vw96, HTTP-equiv, ICC-chrm, ICC-clrt, ICC-header, ICC-meas, +ICC-meta, ICC-view, ICC_Profile, ICC_Profile#, ID3, ID3v1, ID3v1_Enh, +ID3v2_2, ID3v2_3, ID3v2_4, IFD0, IFD1, IPTC, IPTC#, ISO, ITC, Insta360, +InteropIFD, ItemList, JFIF, JFXX, JPEG, JPEG-HDR, JSON, JVC, Jpeg2000, +KDC_IFD, Keys, Kodak, KodakBordersIFD, KodakEffectsIFD, KodakIFD, +KyoceraRaw, LNK, Leaf, LeafSubIFD, Leica, Lytro, M2TS, MAC, MIE-Audio, +MIE-Camera, MIE-Canon, MIE-Doc, MIE-Extender, MIE-Flash, MIE-GPS, MIE-Geo, +MIE-Image, MIE-Lens, MIE-Main, MIE-MakerNotes, MIE-Meta, MIE-Orient, +MIE-Preview, MIE-Thumbnail, MIE-UTM, MIE-Unknown, MIE-Video, MIFF, MNG, +MOBI, MOI, MPC, MPEG, MPF0, MPImage, MS-DOC, MXF, MacOS, MakerNotes, +MakerUnknown, Matroska, MediaJukebox, Meta, MetaIFD, Microsoft, Minolta, +MinoltaRaw, Motorola, NITF, Nikon, NikonCapture, NikonCustom, NikonScan, +Nintendo, Ocad, Ogg, Olympus, OpenEXR, Opus, PDF, PICT, PNG, PNG-pHYs, PSP, +Palm, Panasonic, PanasonicRaw, Pentax, PhaseOne, PhotoCD, PhotoMechanic, +Photoshop, PictureInfo, PostScript, PreviewIFD, PrintIM, ProfileIFD, +Qualcomm, QuickTime, RAF, RAF2, RIFF, RMETA, RSRC, RTF, Radiance, Rawzor, +Real, Real-CONT, Real-MDPR, Real-PROP, Real-RA3, Real-RA4, Real-RA5, +Real-RJMD, Reconyx, Red, Ricoh, SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, +SVG, Samsung, Sanyo, Scalado, Sigma, SigmaRaw, Sony, SonyIDC, Stim, SubIFD, +System, Theora, Torrent, Track#, UserData, VCalendar, VCard, Version0, +Vorbis, WTV, XML, XMP, XMP-DICOM, XMP-Device, XMP-GAudio, XMP-GDepth, +XMP-GFocus, XMP-GImage, XMP-GPano, XMP-GSpherical, XMP-LImage, XMP-MP, +XMP-MP1, XMP-PixelLive, XMP-aas, XMP-acdsee, XMP-album, XMP-apple-fi, +XMP-aux, XMP-cc, XMP-cell, XMP-creatorAtom, XMP-crs, XMP-dc, XMP-dex, +XMP-digiKam, XMP-drone-dji, XMP-dwc, XMP-exif, XMP-exifEX, XMP-expressionmedia, XMP-extensis, XMP-fpv, XMP-getty, XMP-ics, XMP-iptcCore, XMP-iptcExt, XMP-lr, XMP-mediapro, XMP-microsoft, XMP-mwg-coll, XMP-mwg-kw, XMP-mwg-rs, XMP-pdf, XMP-pdfx, XMP-photomech, @@ -2237,8 +2285,8 @@ XMP-xmpNote, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg, ZIP =item Family 2 (Category): -Audio, Author, Camera, Document, ExifTool, Image, Location, Other, Preview, -Printing, Time, Unknown, Video +Audio, Author, Camera, Device, Document, ExifTool, Image, Location, Other, +Preview, Printing, Time, Unknown, Video =item Family 3 (Document Number): @@ -2248,6 +2296,15 @@ Doc#, Main Copy# +=item Family 5 (Metadata Path): + +eg. JPEG-APP1-IFD0-ExifIFD + +=item Family 6 (EXIF/TIFF Format): + +int8u, string, int16u, int32u, rational64u, int8s, undef, int16s, int32s, +rational64s, float, double, ifd, unicode, complex, int64u, int64s, ifd64 + =back =head2 GetDeleteGroups [static] @@ -2613,7 +2670,7 @@ specified by the L option. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey +Copyright 2003-2020, Phil Harvey This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/AES.pm b/src/Image-ExifTool/lib/Image/ExifTool/AES.pm index b949e3d0..4754a2b7 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/AES.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/AES.pm @@ -477,7 +477,7 @@ main purpose of encryption, so this really can't be considered a bug. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/AFCP.pm b/src/Image-ExifTool/lib/Image/ExifTool/AFCP.pm index 1d4da145..58d3a52a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/AFCP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/AFCP.pm @@ -259,7 +259,7 @@ scanning for AFCP information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/AIFF.pm b/src/Image-ExifTool/lib/Image/ExifTool/AIFF.pm index 6241c5d1..bc9c6e7c 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/AIFF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/AIFF.pm @@ -18,7 +18,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::ID3; -$VERSION = '1.09'; +$VERSION = '1.10'; # information for time/date-based tags (time zero is Jan 1, 1904) my %timeInfo = ( @@ -185,7 +185,7 @@ sub ProcessAIFF($$) { my ($et, $dirInfo) = @_; my $raf = $$dirInfo{RAF}; - my ($buff, $err, $tagTablePtr, $page, $type); + my ($buff, $err, $tagTablePtr, $page, $type, $n); # verify this is a valid AIFF file return 0 unless $raf->Read($buff, 12) == 12; @@ -202,7 +202,7 @@ sub ProcessAIFF($$) $et->SetFileType('DJVU'); return 1 if $fast3; $tagTablePtr = GetTagTable('Image::ExifTool::DjVu::Main'); - # modifiy FileType to indicate a multi-page document + # modify FileType to indicate a multi-page document $$et{VALUE}{FileType} .= " (multi-page)" if $buf2 eq 'DJVM'; $type = 'DjVu'; } else { @@ -217,14 +217,24 @@ sub ProcessAIFF($$) # # Read through the IFF chunks # - for (;;) { + for ($n=0;;++$n) { $raf->Read($buff, 8) == 8 or last; $pos += 8; my ($tag, $len) = unpack('a4N', $buff); my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); - $et->VPrint(0, "AIFF '${tag}' chunk ($len bytes of data):\n"); + $et->VPrint(0, "AIFF '${tag}' chunk ($len bytes of data): ", $raf->Tell(),"\n"); # AIFF chunks are padded to an even number of bytes my $len2 = $len + ($len & 0x01); + if ($len2 > 100000000) { + if ($len2 >= 0x80000000 and not $et->Options('LargeFileSupport')) { + $et->Warn('End of processing at large chunk (LargeFileSupport not enabled)'); + last; + } + if ($tagInfo) { + $et->Warn("Skipping large $$tagInfo{Name} chunk (> 100 MB)"); + undef $tagInfo; + } + } if ($tagInfo) { if ($$tagInfo{TypeOnly}) { $len = $len2 = 4; @@ -241,6 +251,10 @@ sub ProcessAIFF($$) Start => 0, Size => $len, ); + } elsif (not $len) { + next if ++$n < 100; + $et->Warn('Aborting scan. Too many empty chunks'); + last; } elsif ($verbose > 2 and $len2 < 1024000) { $raf->Read($buff, $len2) == $len2 or $err = 1, last; $et->VerboseDump(\$buff); @@ -248,6 +262,7 @@ sub ProcessAIFF($$) $raf->Seek($len2, 1) or $err=1, last; } $pos += $len2; + $n = 0; } $err and $et->Warn("Error reading $type file (corrupted?)"); return 1; @@ -272,7 +287,7 @@ information from AIFF (Audio Interchange File Format) audio files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/APE.pm b/src/Image-ExifTool/lib/Image/ExifTool/APE.pm index ee1f71fc..587500a9 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/APE.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/APE.pm @@ -263,7 +263,7 @@ Currently doesn't parse MAC header unless it is at the start of the file. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/APP12.pm b/src/Image-ExifTool/lib/Image/ExifTool/APP12.pm index 023506f2..6059a90a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/APP12.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/APP12.pm @@ -305,7 +305,7 @@ APP12 meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/ASF.pm b/src/Image-ExifTool/lib/Image/ExifTool/ASF.pm index 1af2010b..a836d14d 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/ASF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/ASF.pm @@ -876,7 +876,7 @@ Windows Media Audio (WMA) and Windows Media Video (WMV) files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Apple.pm b/src/Image-ExifTool/lib/Image/ExifTool/Apple.pm index aac34b38..f6da77f3 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Apple.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Apple.pm @@ -68,7 +68,7 @@ $VERSION = '1.04'; }, # 0x000c - rational64s[2]: eg) "0.1640625 0.19921875" # 0x000d - int32s: 0,1,6,20,24,32,40 - # 0x000e - int32s: 0,1,4,12 (Orienation? 0=landscape? 4=portrait? ref 1) + # 0x000e - int32s: 0,1,4,12 (Orientation? 0=landscape? 4=portrait? ref 1) # 0x000f - int32s: 2,3 # 0x0010 - int32s: 1 0x0011 => { @@ -148,7 +148,7 @@ Apple maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Audible.pm b/src/Image-ExifTool/lib/Image/ExifTool/Audible.pm new file mode 100644 index 00000000..8bd2e4ae --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Audible.pm @@ -0,0 +1,317 @@ +#------------------------------------------------------------------------------ +# File: Audible.pm +# +# Description: Read metadata from Audible audio books +# +# Revisions: 2015/04/05 - P. Harvey Created +# +# References: 1) https://github.com/jteeuwen/audible +# 2) https://code.google.com/p/pyaudibletags/ +# 3) http://wiki.multimedia.cx/index.php?title=Audible_Audio +#------------------------------------------------------------------------------ + +package Image::ExifTool::Audible; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.02'; + +sub ProcessAudible_meta($$$); +sub ProcessAudible_cvrx($$$); + +%Image::ExifTool::Audible::Main = ( + GROUPS => { 2 => 'Audio' }, + NOTES => q{ + ExifTool will extract any information found in the metadata dictionary of + Audible .AA files, even if not listed in the table below. + }, + # tags found in the metadata dictionary (chunk 2) + pubdate => { Name => 'PublishDate', Groups => { 2 => 'Time' } }, + pub_date_start => { Name => 'PublishDateStart', Groups => { 2 => 'Time' } }, + author => { Name => 'Author', Groups => { 2 => 'Author' } }, + copyright => { Name => 'Copyright', Groups => { 2 => 'Author' } }, + # also seen (ref PH): + # product_id, parent_id, title, provider, narrator, price, description, + # long_description, short_title, is_aggregation, title_id, codec, HeaderSeed, + # EncryptedBlocks, HeaderKey, license_list, CPUType, license_count, <12 hex digits>, + # parent_short_title, parent_title, aggregation_id, short_description, user_alias + + # information extracted from other chunks + _chapter_count => { Name => 'ChapterCount' }, # from chunk 6 + _cover_art => { # from chunk 11 + Name => 'CoverArt', + Groups => { 2 => 'Preview' }, + Binary => 1, + }, +); + +# 'tags' atoms observed in Audible .m4b audio books (ref PH) +%Image::ExifTool::Audible::tags = ( + GROUPS => { 0 => 'QuickTime', 2 => 'Audio' }, + NOTES => 'Information found in "tags" atom of Audible M4B audio books.', + meta => { + Name => 'Audible_meta', + SubDirectory => { TagTable => 'Image::ExifTool::Audible::meta' }, + }, + cvrx => { + Name => 'Audible_cvrx', + SubDirectory => { TagTable => 'Image::ExifTool::Audible::cvrx' }, + }, + tseg => { + Name => 'Audible_tseg', + SubDirectory => { TagTable => 'Image::ExifTool::Audible::tseg' }, + }, +); + +# 'meta' information observed in Audible .m4b audio books (ref PH) +%Image::ExifTool::Audible::meta = ( + PROCESS_PROC => \&ProcessAudible_meta, + GROUPS => { 0 => 'QuickTime', 2 => 'Audio' }, + NOTES => 'Information found in Audible M4B "meta" atom.', + Album => 'Album', + ALBUMARTIST => { Name => 'AlbumArtist', Groups => { 2 => 'Author' } }, + Artist => { Name => 'Artist', Groups => { 2 => 'Author' } }, + Comment => 'Comment', + Genre => 'Genre', + itunesmediatype => { Name => 'iTunesMediaType', Description => 'iTunes Media Type' }, + SUBTITLE => 'Subtitle', + Title => 'Title', + TOOL => 'CreatorTool', + Year => { Name => 'Year', Groups => { 2 => 'Time' } }, + track => 'ChapterName', # (found in 'meta' of 'tseg' atom) +); + +# 'cvrx' information observed in Audible .m4b audio books (ref PH) +%Image::ExifTool::Audible::cvrx = ( + PROCESS_PROC => \&ProcessAudible_cvrx, + GROUPS => { 0 => 'QuickTime', 2 => 'Audio' }, + NOTES => 'Audible cover art information in M4B audio books.', + VARS => { NO_ID => 1 }, + CoverArtType => 'CoverArtType', + CoverArt => { + Name => 'CoverArt', + Groups => { 2 => 'Preview' }, + Binary => 1, + }, +); + +# 'tseg' information observed in Audible .m4b audio books (ref PH) +%Image::ExifTool::Audible::tseg = ( + GROUPS => { 0 => 'QuickTime', 2 => 'Audio' }, + tshd => { + Name => 'ChapterNumber', + Format => 'int32u', + ValueConv => '$val + 1', # start counting from 1 + }, + meta => { + Name => 'Audible_meta2', + SubDirectory => { TagTable => 'Image::ExifTool::Audible::meta' }, + }, +); + +#------------------------------------------------------------------------------ +# Process Audible 'meta' tags from M4B files (ref PH) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub ProcessAudible_meta($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dataPos = $$dirInfo{DataPos}; + my $dirLen = length $$dataPt; + return 0 if $dirLen < 4; + my $num = Get32u($dataPt, 0); + $et->VerboseDir('Audible_meta', $num); + my $pos = 4; + my $index; + for ($index=0; $index<$num; ++$index) { + last if $pos + 3 > $dirLen; + my $unk = Get8u($dataPt, $pos); # ? (0x80 or 0x00) + last unless $unk == 0x80 or $unk == 0x00; + my $len = Get16u($dataPt, $pos + 1); # tag length + $pos += 3; + last if $pos + $len + 6 > $dirLen or not $len; + my $tag = substr($$dataPt, $pos, $len); # tag ID + my $ver = Get16u($dataPt, $pos + $len); # version? + last unless $ver == 0x0001; + my $size = Get32u($dataPt, $pos + $len + 2);# data size + $pos += $len + 6; + last if $pos + $size > $dirLen; + my $val = $et->Decode(substr($$dataPt, $pos, $size), 'UTF8'); + unless ($$tagTablePtr{$tag}) { + my $name = Image::ExifTool::MakeTagName(($tag =~ /[a-z]/) ? $tag : lc($tag)); + AddTagToTable($tagTablePtr, $tag, { Name => $name }); + } + $et->HandleTag($tagTablePtr, $tag, $val, + DataPt => $dataPt, + DataPos => $dataPos, + Start => $pos, + Size => $size, + Index => $index, + ); + $pos += $size; + } + return 1; +} + +#------------------------------------------------------------------------------ +# Process Audible 'cvrx' cover art atom from M4B files (ref PH) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub ProcessAudible_cvrx($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dataPos = $$dirInfo{DataPos}; + my $dirLen = length $$dataPt; + return 0 if 0x0a > $dirLen; + my $len = Get16u($dataPt, 0x08); + return 0 if 0x0a + $len + 6 > $dirLen; + my $size = Get32u($dataPt, 0x0a + $len + 2); + return 0 if 0x0a + $len + 6 + $size > $dirLen; + $et->VerboseDir('Audible_cvrx', undef, $dirLen); + $et->HandleTag($tagTablePtr, 'CoverArtType', undef, + DataPt => $dataPt, + DataPos => $dataPos, + Start => 0x0a, + Size => $len, + ); + $et->HandleTag($tagTablePtr, 'CoverArt', undef, + DataPt => $dataPt, + DataPos => $dataPos, + Start => 0x0a + $len + 6, + Size => $size, + ); + return 1; +} + +#------------------------------------------------------------------------------ +# Read information from an Audible .AA file +# Inputs: 0) ExifTool ref, 1) dirInfo ref +# Returns: 1 on success, 0 if this wasn't a valid AA file +sub ProcessAA($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $toc, $entry, $i); + + # check magic number + return 0 unless $raf->Read($buff, 16) == 16 and $buff=~/^.{4}\x57\x90\x75\x36/s; + # check file size + if (defined $$et{VALUE}{FileSize}) { + # first 4 bytes of the file should be the filesize + unpack('N', $buff) == $$et{VALUE}{FileSize} or return 0; + } + $et->SetFileType(); + SetByteOrder('MM'); + my $bytes = 12 * Get32u(\$buff, 8); # table of contents size in bytes + $bytes > 0xc00 and $et->Warn('Invalid TOC'), return 1; + # read the table of contents + $raf->Read($toc, $bytes) == $bytes or $et->Warn('Truncated TOC'), return 1; + my $tagTablePtr = GetTagTable('Image::ExifTool::Audible::Main'); + # parse table of contents (in $toc) + for ($entry=0; $entry<$bytes; $entry+=12) { + my $type = Get32u(\$toc, $entry); + next unless $type == 2 or $type == 6 or $type == 11; + my $offset = Get32u(\$toc, $entry + 4); + my $length = Get32u(\$toc, $entry + 8) or next; + $raf->Seek($offset, 0) or $et->Warn("Chunk $type seek error"), last; + if ($type == 6) { # offset table + next if $length < 4 or $raf->Read($buff, 4) != 4; # only read the chapter count + $et->HandleTag($tagTablePtr, '_chapter_count', Get32u(\$buff, 0)); + next; + } + # read the chunk + $length > 100000000 and $et->Warn("Chunk $type too big"), next; + $raf->Read($buff, $length) == $length or $et->Warn("Chunk $type read error"), last; + if ($type == 11) { # cover art + next if $length < 8; + my $len = Get32u(\$buff, 0); + my $off = Get32u(\$buff, 4); + next if $off < $offset + 8 or $off - $offset + $len > $length; + $et->HandleTag($tagTablePtr, '_cover_art', substr($buff, $off-$offset, $len)); + next; + } + # parse metadata dictionary (in $buff) + $length < 4 and $et->Warn('Bad dictionary'), next; + my $num = Get32u(\$buff, 0); + $num > 0x200 and $et->Warn('Bad dictionary count'), next; + my $pos = 4; # dictionary starts immediately after count + require Image::ExifTool::HTML; # (for UnescapeHTML) + $et->VerboseDir('Audible Metadata', $num); + for ($i=0; $i<$num; ++$i) { + my $tagPos = $pos + 9; # position of tag string + $tagPos > $length and $et->Warn('Truncated dictionary'), last; + # (1 unknown byte ignored at start of each dictionary entry) + my $tagLen = Get32u(\$buff, $pos + 1); # tag string length + my $valLen = Get32u(\$buff, $pos + 5); # value string length + my $valPos = $tagPos + $tagLen; # position of value string + my $nxtPos = $valPos + $valLen; # position of next entry + $nxtPos > $length and $et->Warn('Bad dictionary entry'), last; + my $tag = substr($buff, $tagPos, $tagLen); + my $val = substr($buff, $valPos, $valLen); + unless ($$tagTablePtr{$tag}) { + my $name = Image::ExifTool::MakeTagName($tag); + $name =~ s/_(.)/\U$1/g; # change from underscore-separated to mixed case + AddTagToTable($tagTablePtr, $tag, { Name => $name }); + } + # unescape HTML character references and convert from UTF-8 + $val = $et->Decode(Image::ExifTool::HTML::UnescapeHTML($val), 'UTF8'); + $et->HandleTag($tagTablePtr, $tag, $val, + DataPos => $offset, + DataPt => \$buff, + Start => $valPos, + Size => $valLen, + Index => $i, + ); + $pos = $nxtPos; # step to next dictionary entry + } + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Audible - Read meta information from Audible audio books + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read meta +information from Audible audio books. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L + +=item L + +=item L + +=back + +=head1 SEE ALSO + +L, +L + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/BMP.pm b/src/Image-ExifTool/lib/Image/ExifTool/BMP.pm index 161a3be9..5b546667 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/BMP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/BMP.pm @@ -335,7 +335,7 @@ This module contains definitions required by Image::ExifTool to read BMP =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/BPG.pm b/src/Image-ExifTool/lib/Image/ExifTool/BPG.pm new file mode 100644 index 00000000..1edbd756 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/BPG.pm @@ -0,0 +1,253 @@ +#------------------------------------------------------------------------------ +# File: BPG.pm +# +# Description: Read BPG meta information +# +# Revisions: 2016-07-05 - P. Harvey Created +# +# References: 1) http://bellard.org/bpg/ +#------------------------------------------------------------------------------ + +package Image::ExifTool::BPG; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.01'; + +# BPG information +%Image::ExifTool::BPG::Main = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, + NOTES => q{ + The information listed below is extracted from BPG (Better Portable + Graphics) images. See L for the specification. + }, + 4 => { + Name => 'PixelFormat', + Format => 'int16u', + Mask => 0xe000, + PrintConv => { + 0 => 'Grayscale', + 1 => '4:2:0 (chroma at 0.5, 0.5)', + 2 => '4:2:2 (chroma at 0.5, 0)', + 3 => '4:4:4', + 4 => '4:2:0 (chroma at 0, 0.5)', + 5 => '4:2:2 (chroma at 0, 0)', + }, + }, + 4.1 => { + Name => 'Alpha', + Format => 'int16u', + Mask => 0x1004, + BitShift => 0, + PrintHex => 1, + PrintConv => { + 0x0000 => 'No Alpha Plane', + 0x1000 => 'Alpha Exists (color not premultiplied)', + 0x1004 => 'Alpha Exists (color premultiplied)', + 0x0004 => 'Alpha Exists (W color component)', + }, + }, + 4.2 => { + Name => 'BitDepth', + Format => 'int16u', + Mask => 0x0f00, + ValueConv => '$val + 8', + }, + 4.3 => { + Name => 'ColorSpace', + Format => 'int16u', + Mask => 0x00f0, + PrintConv => { + 0 => 'YCbCr (BT 601)', + 1 => 'RGB', + 2 => 'YCgCo', + 3 => 'YCbCr (BT 709)', + 4 => 'YCbCr (BT 2020)', + 5 => 'BT 2020 Constant Luminance', + }, + }, + 4.4 => { + Name => 'Flags', + Format => 'int16u', + Mask => 0x000b, + PrintConv => { BITMASK => { + 0 => 'Animation', + 1 => 'Limited Range', + 3 => 'Extension Present', + }}, + }, + 6 => { Name => 'ImageWidth', Format => 'var_ue7' }, + 7 => { Name => 'ImageHeight', Format => 'var_ue7' }, + # length of image data or 0 to EOF + # (must be decoded so we know where the extension data starts) + 8 => { Name => 'ImageLength', Format => 'var_ue7' }, +); + +%Image::ExifTool::BPG::Extensions = ( + GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, + VARS => { ALPHA_FIRST => 1 }, + 1 => { + Name => 'EXIF', + SubDirectory => { + TagTable => 'Image::ExifTool::Exif::Main', + ProcessProc => \&Image::ExifTool::ProcessTIFF, + }, + }, + 2 => { + Name => 'ICC_Profile', + SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' }, + }, + 3 => { + Name => 'XMP', + SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, + }, + 4 => { + Name => 'ThumbnailBPG', + Binary => 1, + }, + 5 => { + Name => 'AnimationControl', + Binary => 1, + Unknown => 1, + }, +); + +#------------------------------------------------------------------------------ +# Get ue7 integer from binary data (max 32 bits) +# Inputs: 0) data ref, 1) location in data (undef for 0) +# Returns: 0) ue7 as integer or undef on error, 1) length of ue7 in bytes +sub Get_ue7($;$) +{ + my $dataPt = shift; + my $pos = shift || 0; + my $size = length $$dataPt; + my $val = 0; + my $i; + for ($i=0; ; ) { + return() if $pos+$i >= $size or $i >= 5; + my $byte = Get8u($dataPt, $pos + $i); + $val = ($val << 7) | ($byte & 0x7f); + unless ($byte & 0x80) { + return() if $i == 4 and $byte & 0x70; # error if bits 32-34 are set + last; # this was the last byte + } + return() if $i == 0 and $byte == 0x80; # error if first byte is 0x80 + ++$i; # step to the next byte + } + return($val, $i+1); +} + +#------------------------------------------------------------------------------ +# Extract EXIF information from a BPG image +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid BPG file +sub ProcessBPG($$) +{ + local $_; + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $size, $n, $len, $pos); + + # verify this is a valid BPG file + return 0 unless $raf->Read($buff, 21) == 21; # (21 bytes is maximum header length) + return 0 unless $buff =~ /^BPG\xfb/; + $et->SetFileType(); # set the FileType tag + + SetByteOrder('MM'); + my %dirInfo = ( + DataPt => \$buff, + DirStart => 0, + DirLen => length($buff), + VarFormatData => [ ], + ); + $et->ProcessDirectory(\%dirInfo, GetTagTable('Image::ExifTool::BPG::Main')); + + return 1 unless $$et{VALUE}{Flags} & 0x0008; # all done unless extension flag is set + + # add varSize from last entry in VarFormatData to determine + # the current read position in the file + my $dataPos = 9 + $dirInfo{VarFormatData}[-1][1]; + # read extension length + unless ($raf->Seek($dataPos, 0) and $raf->Read($buff, 5) == 5) { + $et->Warn('Missing BPG extension data'); + return 1; + } + ($size, $n) = Get_ue7(\$buff); + defined $size or $et->Warn('Corrupted BPG extension length'), return 1; + $dataPos += $n; + $size > 10000000 and $et->Warn('BPG extension is too large'), return 1; + unless ($raf->Seek($dataPos, 0) and $raf->Read($buff, $size) == $size) { + $et->Warn('Truncated BPG extension'); + return 1; + } + my $tagTablePtr = GetTagTable('Image::ExifTool::BPG::Extensions'); + # loop through the individual extensions + for ($pos=0; $pos<$size; $pos+=$len) { + my $type = Get8u(\$buff, $pos); + # get length of this extension + ($len, $n) = Get_ue7(\$buff, ++$pos); + defined $len or $et->Warn('Corrupted BPG extension'), last; + $pos += $n; # point to start of data for this extension + $pos + $len > $size and $et->Warn('Invalid BPG extension size'), last; + $$tagTablePtr{$type} or $et->Warn("Unrecognized BPG extension $type ($len bytes)", 1), next; + # libbpg (in my opinion) incorrectly copies the padding byte after the + # "EXIF\0" APP1 header to the start of the BPG EXIF extension, so issue a + # minor warning and ignore the padding if we find it before the TIFF header + if ($type == 1 and $len > 3 and substr($buff,$pos,3)=~/^.(II|MM)/s) { + $et->Warn("Ignored extra byte at start of EXIF extension", 1); + ++$pos; + --$len; + } + $et->HandleTag($tagTablePtr, $type, undef, + DataPt => \$buff, + DataPos => $dataPos, + Start => $pos, + Size => $len, + Parent => 'BPG', + ); + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::BPG - Read BPG meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read BPG +(Better Portable Graphics) images. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L + +=back + +=head1 SEE ALSO + +L, +L + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/BZZ.pm b/src/Image-ExifTool/lib/Image/ExifTool/BZZ.pm index ac2da1bf..b0edcfa0 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/BZZ.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/BZZ.pm @@ -445,7 +445,7 @@ compression ability). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) Copyright 2002, Leon Bottou and Yann Le Cun Copyright 2001, AT&T Copyright 1999-2001, LizardTech Inc. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/BigTIFF.pm b/src/Image-ExifTool/lib/Image/ExifTool/BigTIFF.pm index 9e8ed0f6..215c27e9 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/BigTIFF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/BigTIFF.pm @@ -15,7 +15,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.06'; +$VERSION = '1.07'; my $maxOffset = 0x7fffffff; # currently supported maximum data offset/size @@ -31,8 +31,12 @@ sub ProcessBigIFD($$$) my $htmlDump = $$et{HTML_DUMP}; my $dirName = $$dirInfo{DirName}; my $dirStart = $$dirInfo{DirStart}; + my ($offName, $nextOffName); - $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once + if ($htmlDump) { + $verbose = -1; # mix htmlDump into verbose so we can test for both at once + $offName = $$dirInfo{OffsetName}; + } # loop through IFD chain for (;;) { @@ -64,10 +68,13 @@ sub ProcessBigIFD($$$) my $nextIFD; $raf->Read($nextIFD, 8) == 8 or undef $nextIFD; # try to read next IFD pointer if ($htmlDump) { - $et->HDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries"); + $et->HDump($bufPos-8, 8, "$dirName entries", "Entry count: $numEntries", undef, $offName); if (defined $nextIFD) { - my $tip = sprintf("Offset: 0x%.8x", Image::ExifTool::Get64u(\$nextIFD, 0)); - $et->HDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0); + my $off = Image::ExifTool::Get64u(\$nextIFD, 0); + my $tip = sprintf("Offset: 0x%.8x", $off); + my $id = $offName; + ($nextOffName, $id) = Image::ExifTool::Exif::NextOffsetName($et, $id) if $off; + $et->HDump($bufPos + 20 * $numEntries, 8, "Next IFD", $tip, 0, $id); } } # loop through all entries in this BigTIFF IFD @@ -79,7 +86,7 @@ sub ProcessBigIFD($$$) my $formatSize = $Image::ExifTool::Exif::formatSize[$format]; unless (defined $formatSize) { $et->HDump($bufPos+$entry,20,"[invalid IFD entry]", - "Bad format value: $format", 1); + "Bad format value: $format", 1, $offName); # warn unless the IFD was just padded with zeros $et->Warn(sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID)); return 0; # assume corrupted IFD @@ -89,7 +96,7 @@ sub ProcessBigIFD($$$) my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID); next unless defined $tagInfo or $verbose; my $valuePtr = $entry + 12; - my ($valBuff, $valBase, $rational); + my ($valBuff, $valBase, $rational, $subOffName); if ($size > 8) { if ($size > $maxOffset) { $et->Warn("Can't handle $dirName entry $index (huge size)"); @@ -148,11 +155,17 @@ sub ProcessBigIFD($$$) } } $tip .= "Value: $tval"; - $et->HDump($entry+$bufPos, 20, "$dname $colName", $tip, 1); + my ($id, $sid); + if ($tagInfo and $$tagInfo{SubIFD}) { + ($subOffName, $id, $sid) = Image::ExifTool::Exif::NextOffsetName($et, $offName); + } else { + $id = $offName; + } + $et->HDump($entry+$bufPos, 20, "$dname $colName", $tip, 1, $id); if ($size > 8) { # add value data block my $flg = ($tagInfo and $$tagInfo{SubDirectory} and $$tagInfo{MakerNotes}) ? 4 : 0; - $et->HDump($valuePtr,$size,"$tagName value",'SAME', $flg); + $et->HDump($valuePtr,$size,"$tagName value",'SAME', $flg, $sid); } } if ($tagInfo and $$tagInfo{SubIFD}) { @@ -174,11 +187,12 @@ sub ProcessBigIFD($$$) my $subdirName = $$tagInfo{Name}; $subdirName .= $i if $i; my %subdirInfo = ( - RAF => $raf, - DataPos => 0, - DirStart => $offsets[$i], - DirName => $subdirName, - Parent => $dirInfo, + RAF => $raf, + DataPos => 0, + DirStart => $offsets[$i], + DirName => $subdirName, + Parent => $dirName, + OffsetName => $subOffName, ); $et->ProcessDirectory(\%subdirInfo, $tagTablePtr, \&ProcessBigIFD); } @@ -201,6 +215,7 @@ sub ProcessBigIFD($$$) defined $nextIFD or $et->Warn("Bad $dirName pointer"), return 0; $dirStart = Image::ExifTool::Get64u(\$nextIFD, 0); $dirStart or last; + $offName = $nextOffName; } return 1; } @@ -260,7 +275,7 @@ information in BigTIFF images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/BuildTagLookup.pm b/src/Image-ExifTool/lib/Image/ExifTool/BuildTagLookup.pm index f15e2bd2..fcec11ba 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/BuildTagLookup.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/BuildTagLookup.pm @@ -31,15 +31,18 @@ use Image::ExifTool::IPTC; use Image::ExifTool::XMP; use Image::ExifTool::Canon; use Image::ExifTool::Nikon; +use Image::ExifTool::Sony; use Image::ExifTool::Validate; use Image::ExifTool::MacOS; -$VERSION = '3.18'; +$VERSION = '3.34'; @ISA = qw(Exporter); sub NumbersFirst($$); sub SortedTagTablekeys($); +my $createDate = 'Feb 15, 2005'; + # global variables to control sorting order of table entries my $numbersFirst = 1; # set to -1 to sort numbers last, or 2 to put negative numbers last my $caseInsensitive; # flag to ignore case when sorting tag names @@ -55,7 +58,7 @@ my $docType = q{ }; -my $homePage = 'http://owl.phy.queensu.ca/~phil/exiftool'; +my $homePage = 'https://exiftool.org'; # tweak the ordering of tables in the documentation my %tweakOrder = ( @@ -67,7 +70,8 @@ my %tweakOrder = ( Composite => 'Extra', GeoTiff => 'GPS', CanonVRD=> 'CanonCustom', - FLIR => 'Casio', + DJI => 'Casio', + FLIR => 'DJI', FujiFilm => 'FLIR', Kodak => 'JVC', Leaf => 'Kodak', @@ -109,6 +113,7 @@ my %formatOK = ( %Image::ExifTool::Exif::formatNumber, 0 => 1, 1 => 1, + 2 => 1, # (writable for docs only) real => 1, integer => 1, date => 1, @@ -158,6 +163,7 @@ meta information extracted from or written to a file. }, ExifTool => q{ The tables listed below give the names of all tags recognized by ExifTool. +They contain a total of $$self{COUNT}{'total tags'} tags, with $$self{COUNT}{'unique tag names'} unique tag names. }, ExifTool2 => q{ B, B or B is given in the first column of each @@ -166,8 +172,10 @@ is the identifier that is actually stored in the file. B refers to the offset of a value when found at a fixed position within a data block (B<#> is the multiplier for calculating a byte offset: B<1>, B<2>, B<4> or B<8>). These offsets may have a decimal part which is used only to -differentiate tags which have values stored at the same position. -B gives the order of values for a serial data stream. +differentiate tags with values stored at the same position. (Note that +writable tags within binary data blocks are not individually deletable, +and the usual alternative is to set them to a value of zero.) B +gives the order of values for a serial data stream. A B is the handle by which the information is accessed in ExifTool. In some instances, more than one name may correspond to a single @@ -175,7 +183,7 @@ tag ID. In these cases, the actual name used depends on the context in which the information is found. Case is not significant for tag names. A question mark (C) after a tag name indicates that the information is either not understood, not verified, or not very useful -- these tags are -not extracted by ExifTool unless the Unknown (-u) option is enabled. Be +not extracted by ExifTool unless the L (-u) option is enabled. Be aware that some tag names are different than the descriptions printed out by default when extracting information with exiftool. To see the tag names instead of the descriptions, use C. @@ -183,20 +191,20 @@ instead of the descriptions, use C. The B column indicates whether the tag is writable by ExifTool. Anything but a C in this column means the tag is writable. A C indicates writable information that is either unformatted or written using -the existing format. Other expressions give details about the information -format, and vary depending on the general type of information. The format -name may be followed by a number in square brackets to indicate the number -of values written, or the number of characters in a fixed-length string -(including a null terminator which is added if required). +the existing format. Other expressions give details about the format of the +stored value, and vary depending on the general type of information. The +format name may be followed by a number in square brackets to indicate the +number of values written, or the number of characters in a fixed-length +string (including a null terminator which is added if required). A plus sign (C<+>) after an entry in the B column indicates a I tag which supports multiple values and allows individual values to be added and deleted. A slash (C) indicates a tag that ExifTool will -I when writing. These tags are not created when writing if another -same-named tag may be created instead. To write these tags, the group +I when writing. These will be edited but not created if another +same-named tag may be created instead. To create these tags, the group should be specified. A tilde (C<~>) indicates a tag this is writable only -when the print conversion is disabled (by setting PrintConv to 0, using the --n option, or suffixing the tag name with a C<#> character). An exclamation +when the print conversion is disabled (by setting L to 0, using the +-n option, or suffixing the tag name with a C<#> character). An exclamation point (C) indicates a tag that is considered I to write under normal circumstances. These tags are not written unless specified explicitly (ie. not when wildcards or "all" are used), and care should be @@ -206,15 +214,16 @@ writable directly, but is written automatically by ExifTool (often when a corresponding L or L tag is written). A colon (C<:>) indicates a I tag which may be added automatically when -writing. +writing. Normally MakerNotes tags may not be deleted individually, but a +caret (C<^>) indicates a I MakerNotes tag. The HTML version of these tables also lists possible B for discrete-valued tags, as well as B for some tags. The B are -listed as the computer-readable and human-readable values on the left and -right hand side of an equals sign (C<=>) respectively. The human-readable +listed with the computer-readable values on the left of the equals sign +(C<=>), and the human-readable values on the right. The human-readable values are used by default when reading and writing, but the computer-readable values may be accessed by disabling the value conversion -with the -n option on the command line, by setting the ValueConv option to 0 +with the -n option on the command line, by setting the L option to 0 in the API, or or on a per-tag basis by adding a hash (C<#>) after the tag name. @@ -252,11 +261,11 @@ tags remain. The table below lists all EXIF tags. Also listed are TIFF, DNG, HDP and other tags which are not part of the EXIF specification, but may co-exist -with EXIF tags in some images. Tags which are part of the EXIF 2.31 +with EXIF tags in some images. Tags which are part of the EXIF 2.32 specification have an underlined B in the HTML version of this documentation. See -L for the -official EXIF 2.31 specification. +L +for the official EXIF 2.32 specification. }, GPS => q{ These GPS tags are part of the EXIF standard, and are stored in a separate @@ -272,7 +281,7 @@ Some GPS tags have values which are fixed-length strings. For these, the indicated string lengths include a null terminator which is added automatically by ExifTool. Remember that the descriptive values are used when writing (eg. 'Above Sea Level', not '0') unless the print conversion is -disabled (with '-n' on the command line or the PrintConv option in the API, +disabled (with '-n' on the command line or the L option in the API, or by suffixing the tag name with a C<#> character). When adding GPS information to an image, it is important to set all of the @@ -305,17 +314,17 @@ HH:MM:SS[.ss][+/-HH:MM]", C is either "True" or "False", C indicates a structured tag, and C is a tag that supports alternate languages. -When reading, C tags are extracted only if the Struct (-struct) +When reading, C tags are extracted only if the L (-struct) option is used. Otherwise the corresponding I tags, indicated by an underline (C<_>) after the B type, are extracted. When copying, by default both structured and flattened tags are available, but -the flattened tags are considered "unsafe" so they they aren't copied unless -specified explicitly. The Struct option may be disabled by setting Struct +the flattened tags are considered "unsafe" so they aren't copied unless +specified explicitly. The L option may be disabled by setting Struct to 0 via the API or with --struct on the command line to copy only flattened tags, or enabled by setting Struct to 1 via the API or with -struct on the -command line to copy only as structures. When writing, the Struct option +command line to copy only as structures. When writing, the L option has no effect, and both structured and flattened tags may be written. See -L for more details. +L for more details. Individual languages for C tags are accessed by suffixing the tag name with a '-', followed by an RFC 3066 language code (eg. "XMP:Title-fr", @@ -327,12 +336,13 @@ to preserve other existing languages (eg. "XMP-dc:Description-x-default"). When reading, "x-default" is not specified. The XMP tags are organized according to schema B in the following -tables. In general, the ExifTool family 1 group names are derived from the -namespace prefixes by adding a leading "XMP-" (eg. "XMP-dc"), but a few of -the longer prefixes have been shortened for convenience (as mentioned in the -documentation below). The tags of any namespace may be deleted as a group -by specifying the family 1 group name (eg. "-XMP-dc:all=" on the command -line). This includes namespaces which are not pre-defined by ExifTool. +tables. The ExifTool family 1 group names are derived from the namespace +prefixes by adding a leading "XMP-" (eg. "XMP-dc"). A few of the longer +prefixes have been shortened (as mentioned in the documentation below) to +avoid excessively long ExifTool group names. The tags of any namespace may +be deleted as a group by specifying the family 1 group name (eg. +"-XMP-dc:all=" on the command line). This includes namespaces which are not +pre-defined by ExifTool. In cases where a tag name exists in more than one namespace, less common namespaces are avoided when writing. However, a specific namespace may be @@ -345,7 +355,7 @@ recommended if possible. For structures, the heading of the first column is B. Field names are very similar to tag names, except they are used to identify fields inside structures instead of stand-alone tags. See -L for more +L for more details. ExifTool will extract XMP information even if it is not listed in these @@ -379,7 +389,7 @@ the B format name. For tags where a range of lengths is allowed, the minimum and maximum lengths are separated by a comma within the brackets. When writing, ExifTool issues a minor warning and truncates the value if it is longer than allowed by the IPTC specification. Minor errors -may be ignored with the IgnoreMinorErrors (-m) option, allowing longer +may be ignored with the L (-m) option, allowing longer values to be written, but beware that values like this may cause problems for some other IPTC readers. ExifTool will happily read IPTC values of any length. @@ -402,6 +412,54 @@ number added for non-standard IPTC ("IPTC2", "IPTC3", etc), but when writing only "IPTC" may be specified as the group. To keep the IPTC consistent, ExifTool updates tags in all existing IPTC locations, but will create a new IPTC group only in the standard location. +}, + QuickTime => q{ +The QuickTime format is used for many different types of audio, video and +image files (most notably, MOV/MP4 videos and HEIC/CR3 images). Exiftool +extracts standard meta information and a variety of audio, video and image +parameters, as well as proprietary information written by many camera +models. Tags with a question mark after their name are not extracted unless +the L option is set. + +When writing, ExifTool creates both QuickTime and XMP tags by default, but +the group may be specified to write one or the other separately. If no +location is specified, newly created QuickTime tags are added in the +L location if +possible, otherwise in +L, and +finally in L, +but this order may be changed by setting the PREFERRED level of the +appropriate table in the config file (see +L in the full distribution for +an example). ExifTool currently writes only top-level metadata in +QuickTime-based files; it extracts other track-specific and timed +metadata, but can not yet edit tags in these locations (with the +exception of track-level date/time tags). + +Alternate language tags may be accessed for +L and +L tags by adding +a 3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2 +country code to the tag name (eg. "ItemList:Artist-deu" or +"ItemList::Artist-deu-DE"). Most +L tags support a +language code, but without a country code. If no language code is specified +when writing, alternate languages for the tag are deleted. Use the "und" +language code to write the default language without deleting alternate +languages. Note that "eng" is treated as a default language when reading, +but not when writing. + +According to the specification, integer-format QuickTime date/time tags +should be stored as UTC. Unfortunately, digital cameras often store local +time values instead (presumably because they don't know the time zone). For +this reason, by default ExifTool does not assume a time zone for these +values. However, if the L API option is set, then ExifTool will +assume these values are properly stored as UTC, and will convert them to +local time when extracting. + +See +L +for the official specification. }, Photoshop => q{ Photoshop tags are found in PSD and PSB files, as well as inside embedded @@ -411,7 +469,7 @@ a few). Many Photoshop tags are marked as Unknown (indicated by a question mark after the tag name) because the information they provide is not very useful under normal circumstances. These unknown tags are not extracted unless the -Unknown (-u) option is used. See +L (-u) option is used. See L for the official specification @@ -422,7 +480,7 @@ access to this information. }, PrintIM => q{ The format of the PrintIM information is known, however no PrintIM tags have -been decoded. Use the Unknown (-u) option to extract PrintIM information. +been decoded. Use the L (-u) option to extract PrintIM information. }, GeoTiff => q{ ExifTool extracts the following tags from GeoTIFF images. See @@ -470,7 +528,9 @@ These tags apply to CRW-format Canon RAW files and information in the APP0 "CIFF" segment of JPEG images. When writing CanonRaw/CIFF information, the length of the information is preserved (and the new information is truncated or padded as required) unless B is C. Currently, only -JpgFromRaw and ThumbnailImage are allowed to change size. +JpgFromRaw and ThumbnailImage are allowed to change size. See +L for a description of the Canon CRW +format. CRW images also support the addition of a CanonVRD trailer, which in turn supports XMP. This trailer is created automatically if necessary when @@ -485,7 +545,7 @@ settings have not been decoded for all models. The tables below list the custom settings for the currently supported models. }, Unknown => q{ -The following tags are decoded in unsupported maker notes. Use the Unknown +The following tags are decoded in unsupported maker notes. Use the L (-u) option to display other unknown tags. }, PDF => q{ @@ -497,7 +557,7 @@ specification. ExifTool supports reading and writing PDF documents up to version 1.7 extension level 3, including support for RC4, AES-128 and AES-256 -encryption. A Password option is provided to allow processing of +encryption. A L option is provided to allow processing of password-protected PDF files. ExifTool may be used to write native PDF and XMP metadata to PDF files. It @@ -571,10 +631,9 @@ new XMP tags which are listed in the subsequent tables below. See L for the official MWG specification. }, MacOS => q{ -On MacOS systems, there are a number of additional tags with names beginning -with "MDItem" and "XAttr" that may be extracted. These tags are not -extracted by default -- they must be specifically requested or enabled via -an API option. +On MacOS systems, the there are additional MDItem and XAttr Finder tags that +may be extracted. These tags are not extracted by default -- they must be +specifically requested or enabled via an API option. The tables below list some of the tags that may be extracted, but ExifTool will extract all available information even for tags not listed. @@ -591,7 +650,7 @@ L. ~head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -664,7 +723,7 @@ sub new my $that = shift; my $class = ref($that) || $that || 'Image::ExifTool::BuildTagLookup'; my $self = bless {}, $class; - my (%subdirs, %isShortcut, %allStructs); + my (%subdirs, %isShortcut); my %count = ( 'unique tag names' => 0, 'total tags' => 0, @@ -767,7 +826,8 @@ sub new $hexID = $$vars{HEX_ID}; my $processBinaryData = ($$table{PROCESS_PROC} and ( $$table{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData or - $$table{PROCESS_PROC} eq \&Image::ExifTool::Nikon::ProcessNikonEncrypted)); + $$table{PROCESS_PROC} eq \&Image::ExifTool::Nikon::ProcessNikonEncrypted or + $$table{PROCESS_PROC} eq \&Image::ExifTool::Sony::ProcessEnciphered)); if ($$vars{ID_LABEL} or $processBinaryData) { my $s = $$table{FORMAT} ? Image::ExifTool::FormatSize($$table{FORMAT}) || 1 : 1; $binaryTable = 1; @@ -883,6 +943,10 @@ TagID: foreach $tagID (@keys) { } elsif (not $$tagInfo{SubDirectory}) { $writable = $$table{WRITABLE}; } + # in general, we can't write unless we have a WRITE_PROC + if ($writable and not ($$table{WRITE_PROC} or $tableName =~ /Shortcuts/ or $writable eq '2')) { + undef $writable; + } # validate some characteristics of obvious date/time tags my @g = $et->GetGroup($tagInfo); if ($$tagInfo{List} and $g[2] eq 'Time' and $writable and not $$tagInfo{Protected} and @@ -905,6 +969,11 @@ TagID: foreach $tagID (@keys) { $$tagInfo{Groups}{2} ne 'Time') and $short ne 'DICOM') { warn "$short $name should be in 'Time' group!\n"; } + if ($name eq 'DateTimeOriginal' and (not $$tagInfo{Description} or + $$tagInfo{Description} ne 'Date/Time Original')) + { + warn "Need Description for $short DateTimeOriginal\n"; + } # validate Description (can't contain special characters) if ($$tagInfo{Description} and $$tagInfo{Description} ne EscapeHTML($$tagInfo{Description})) @@ -1101,7 +1170,7 @@ TagID: foreach $tagID (@keys) { my $n = scalar @values; my ($bits, $i, $v); foreach (@pk) { - next if $_ eq ''; + next if $_ eq '' and $$printConv{$_} eq ''; $_ eq 'BITMASK' and $bits = $$printConv{$_}, next; $_ eq 'OTHER' and next; my $index; @@ -1195,12 +1264,21 @@ TagID: foreach $tagID (@keys) { } } if ($subdir and not $$tagInfo{SeparateTable}) { - # subdirectories are only writable if specified explicitly - my $tw = $$tagInfo{Writable}; - $writable = 'yes' if $tw and $writable eq '1'; - $writable = '-' . ($tw ? $writable : ''); - $writable .= '!' if $tw and ($$tagInfo{Protected} || 0) & 0x01; - $writable .= '+' if $$tagInfo{List}; + if ($writable) { + # subdirectories are only writable if specified explicitly + my $tw = $$tagInfo{Writable}; + $writable = 'yes' if $tw and $writable eq '1' or $writable eq '2'; + $writable = '-' . ($tw ? $writable : ''); + $writable .= '!' if $tw and ($$tagInfo{Protected} || 0) & 0x01; + $writable .= '+' if $$tagInfo{List}; + if (defined $$tagInfo{Permanent}) { + $writable .= '^' unless $$tagInfo{Permanent}; + } elsif (defined $$table{PERMANENT}) { + $writable .= '^' unless $$table{PERMANENT}; + } + } else { + $writable = '-'; + } } else { # not writable if we can't do the inverse conversions my $noPrintConvInv; @@ -1220,7 +1298,7 @@ TagID: foreach $tagID (@keys) { if (not $writable) { $writable = 'no'; } else { - $writable eq '1' and $writable = $format ? $format : 'yes'; + $writable = $format ? $format : 'yes' if $writable eq '1' or $writable eq '2'; my $count = $$tagInfo{Count} || 1; # adjust count to Writable size if different than Format if ($writable and $format and $writable ne $format and @@ -1248,6 +1326,11 @@ TagID: foreach $tagID (@keys) { $writable .= '_' if defined $$tagInfo{Flat}; $writable .= '+' if $$tagInfo{List}; $writable .= ':' if $$tagInfo{Mandatory}; + if (defined $$tagInfo{Permanent}) { + $writable .= '^' unless $$tagInfo{Permanent}; + } elsif (defined $$table{PERMANENT}) { + $writable .= '^' unless $$table{PERMANENT}; + } # separate tables link like subdirectories (flagged with leading '-') $writable = "-$writable" if $subdir; } @@ -1371,11 +1454,13 @@ TagID: foreach $tagID (@keys) { if ($$table{$var}) { foreach $tagID (@{$$table{$var}}) { $$hash{$tagID} and delete($$hash{$tagID}), next; - warn "Warning: Extra $var for $short tag $tagID\n"; + warn sprintf("Warning: Extra %s for %s tag %d (0x%.4x)\n", + $var, $short, $tagID, $tagID); } } foreach $tagID (sort keys %$hash) { - warn "Warning: Missing $var for $short $$hash{$tagID}\n"; + warn sprintf("Warning: Missing %s for %s %s, tag %d (0x%.4x)\n", + $var, $short, $$hash{$tagID}, $tagID, $tagID); } } } @@ -1389,7 +1474,7 @@ TagID: foreach $tagID (@keys) { my $tag; foreach $tag (sort keys %$struct) { my $tagInfo = $$struct{$tag}; - next unless ref $tagInfo eq 'HASH'; + next unless ref $tagInfo eq 'HASH' and $tag ne 'NAMESPACE'; my $writable = $$tagInfo{Writable}; my @vals; unless ($writable) { @@ -1513,7 +1598,10 @@ sub WriteTagLookup($$) } elsif ($tagID =~ /^\d+$/) { $entry = sprintf('0x%x',$tagID); } else { - $entry = "'${tagID}'"; + my $quot = "'"; + # escape non-printable characters in tag ID if necessary + $quot = '"' if $tagID =~ s/[\x00-\x1f,\x7f-\xff]/sprintf('\\x%.2x',ord($&))/ge; + $entry = "$quot${tagID}$quot"; } my $wrNum = $wrNum{$tableNum}; push @entries, "$wrNum => $entry"; @@ -1652,9 +1740,9 @@ sub Doc2Html($) $doc =~ s/B<(.*?)>/$1<\/b>/sg; $doc =~ s/C<(.*?)>/$1<\/code>/sg; $doc =~ s/I<(.*?)>/$1<\/i>/sg; - # L --> some text + # L --> some text $doc =~ s{L<([^&]+?)\|\Q$homePage\E/(.*?)>}{$1<\/a>}sg; - # L --> http://owl.phy.queensu.ca/~phil/exiftool/struct.html + # L --> https://exiftool.org/struct.html $doc =~ s{L<\Q$homePage\E/(.*?)>}{$1<\/a>}sg; # L --> <a href="XMP.html#DICOM">XMP DICOM Tags</a> # (specify "Image::ExifTool::TagNames" to link to another html file) @@ -1851,7 +1939,9 @@ sub OpenHtmlFile($;$$) open(HTMLFILE, ">>${htmlFile}_tmp") or return 0; } else { open(HTMLFILE, ">${htmlFile}_tmp") or return 0; - print HTMLFILE "$docType<html>\n<head>\n<title>$title</title>\n"; + print HTMLFILE "$docType<html>\n"; + print HTMLFILE "<!-- (this file generated automatically by Image::ExifTool::BuildTagLookup) -->\n"; + print HTMLFILE "<head>\n<title>$title</title>\n"; print HTMLFILE "<link rel=stylesheet type='text/css' href='style.css' title='Style'>\n"; print HTMLFILE "</head>\n<body>\n"; if ($category ne $class and $docs{$class}) { @@ -1896,6 +1986,7 @@ sub CloseHtmlFiles($) # write the trailers print HTMLFILE "<hr>\n"; print HTMLFILE "(This document generated automatically by Image::ExifTool::BuildTagLookup)\n"; + print HTMLFILE "<br><i>Created $createDate</i>\n" if $htmlFile eq 'html/TagNames/index.html'; print HTMLFILE "<br><i>Last revised $fileDate</i>\n"; print HTMLFILE "<p class=lf><a href="; if ($htmlFile =~ /index\.html$/) { @@ -1977,6 +2068,7 @@ sub WriteTagNames($$) # open the file and write the header open(PODFILE, ">$podFile") or return 0; + $docs{ExifTool} = eval qq{"$docs{ExifTool}"}; print PODFILE Doc2Pod($docs{PodHeader}, $docs{ExifTool}, $docs{ExifTool2}); mkdir "$htmldir/TagNames", 0777; OpenHtmlFile($htmldir) or return 0; @@ -2060,6 +2152,9 @@ sub WriteTagNames($$) my $w = length($_) + length($$printConv{$_}); $wid = $w if $wid < $w; push @keys, $_; + if ($$printConv{$_} =~ /[\0-\x1f\x7f-\xff]/) { + warn "Warning: Special characters in $tableName PrintConv ($$printConv{$_})\n"; + } } $wid = length($tableName)+7 if $wid < length($tableName)+7; # print in multiple columns if there is room @@ -2438,10 +2533,11 @@ sub WriteTagNames($$) '!' => 'Unsafe', '*' => 'Protected', ':' => 'Mandatory', + '^' => 'Deletable', ); my ($wstr, %hasAttr, @hasAttr); foreach $wstr (@$writable) { - next unless $wstr =~ m{([+/~!*:_]+)$}; + next unless $wstr =~ m{([+/~!*:_^]+)$}; my @a = split //, $1; foreach (@a) { next if $hasAttr{$_}; @@ -2472,6 +2568,7 @@ sub WriteTagNames($$) my ($smallNote, @values); foreach (@$values) { if (/^\(/) { + $_ = Doc2Html($_); # set the note font $smallNote = 1 if $numTags < 2; push @values, ($smallNote ? $noteFontSmall : $noteFont) . "$_</span>"; @@ -2482,6 +2579,7 @@ sub WriteTagNames($$) if (s/^\[!HTML\]//) { push @values, $_; } else { + $_ = Doc2Html($_); push @values, "<span class=s>$_</span>"; } next; @@ -2610,13 +2708,13 @@ WriteTagNames(). =item WRITE_PSEUDO -List of writable pseudo tags. +Returned list of writable pseudo tags. =back =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Canon.pm b/src/Image-ExifTool/lib/Image/ExifTool/Canon.pm index f214ba35..cf223d6a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Canon.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Canon.pm @@ -63,10 +63,11 @@ # 47) http://www.exiv2.org/ # 48) Tomasz A. Kawecki private communication (550D, firmware 1.0.6, 1.0.8) # 49) http://www.listware.net/201101/digikam-users/49795-digikam-users-re-lens-recognition.html -# 50) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3833.0.html -# 51) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4110.0.html +# 50) https://exiftool.org/forum/index.php/topic,3833.0.html +# 51) https://exiftool.org/forum/index.php/topic,4110.0.html # 52) Kai Harrekilde-Petersen private communication # 53) Anton Reiser private communication +# 54) https://github.com/lclevy/canon_cr3 # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication # JR) Jos Roost private communication @@ -87,7 +88,7 @@ sub ProcessCTMD($$$); sub ProcessExifInfo($$$); sub SwapWords($); -$VERSION = '4.02'; +$VERSION = '4.35'; # Note: Removed 'USM' from 'L' lenses since it is redundant - PH # (or is it? Ref 32 shows 5 non-USM L-type lenses) @@ -101,7 +102,8 @@ $VERSION = '4.02'; }, -1 => 'n/a', 1 => 'Canon EF 50mm f/1.8', - 2 => 'Canon EF 28mm f/2.8', + 2 => 'Canon EF 28mm f/2.8 or Sigma Lens', + 2.1 => 'Sigma 24mm f/2.8 Super Wide II', #ClaudeJolicoeur # (3 removed in current Kamisaka list) 3 => 'Canon EF 135mm f/2.8 Soft', #15/32 4 => 'Canon EF 35-105mm f/3.5-4.5 or Sigma Lens', #28 @@ -143,11 +145,14 @@ $VERSION = '4.02'; 26.2 => 'Tamron SP AF 90mm f/2.8 Di Macro', #15 26.3 => 'Tamron SP AF 180mm f/3.5 Di Macro', #15 26.4 => 'Carl Zeiss Planar T* 50mm f/1.4', #PH + 26.5 => 'Voigtlander APO Lanthar 125mm F2.5 SL Macro', #JR + 26.6 => 'Carl Zeiss Planar T 85mm f/1.4 ZE', #IB 27 => 'Canon EF 35-80mm f/4-5.6', #32 # 27 => 'Carl Zeiss Distagon T* 28mm f/2 ZF', #PH (must be with an adapter, because the ZF version is a Nikon mount) # 27 => 'EMF adapter for Canon EOS digital cameras', #50 (reports MaxFocalLength of 65535) # 27 => optix adapter # 27 => Venus Optics Laowa 12mm f2.8 Zero-D or 105mm f2 (T3.2) Smooth Trans Focus (ref IB) + # 27 => Venus Optics Laowa 105mm f2 STF (ref IB) 28 => 'Canon EF 80-200mm f/4.5-5.6 or Tamron Lens', #32 28.1 => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF', #15 28.2 => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro', #4 @@ -179,7 +184,7 @@ $VERSION = '4.02'; 36 => 'Canon EF 38-76mm f/4.5-5.6', #32 37 => 'Canon EF 35-80mm f/4-5.6 or Tamron Lens', #32 37.1 => 'Tamron 70-200mm f/2.8 Di LD IF Macro', #PH - 37.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro Model A20', #38 + 37.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro (A20)', #38 37.3 => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical [IF]', #34 37.4 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical [IF] Macro', #forum2937 38 => 'Canon EF 80-200mm f/4.5-5.6', #32 @@ -187,13 +192,14 @@ $VERSION = '4.02'; 40 => 'Canon EF 28-80mm f/3.5-5.6', 41 => 'Canon EF 28-90mm f/4-5.6', #32 42 => 'Canon EF 28-200mm f/3.5-5.6 or Tamron Lens', #32 - 42.1 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro Model A20', #15 + 42.1 => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical [IF] Macro (A20)', #15 43 => 'Canon EF 28-105mm f/4-5.6', #10 44 => 'Canon EF 90-300mm f/4.5-5.6', #32 45 => 'Canon EF-S 18-55mm f/3.5-5.6 [II]', #PH (same ID for version II, ref 20) 46 => 'Canon EF 28-90mm f/4-5.6', #32 47 => 'Zeiss Milvus 35mm f/2 or 50mm f/2', #IB 47.1 => 'Zeiss Milvus 50mm f/2 Makro', #IB + 47.2 => 'Zeiss Milvus 135mm f/2 ZE', #IB 48 => 'Canon EF-S 18-55mm f/3.5-5.6 IS', #20 49 => 'Canon EF-S 55-250mm f/4-5.6 IS', #23 50 => 'Canon EF-S 18-200mm f/3.5-5.6 IS', @@ -210,10 +216,17 @@ $VERSION = '4.02'; 103 => 'Samyang AF 14mm f/2.8 EF or Rokinon Lens', #IB 103.1 => 'Rokinon SP 14mm f/2.4', #IB 103.2 => 'Rokinon AF 14mm f/2.8 EF', #IB + 106 => 'Rokinon SP / Samyang XP 35mm f/1.2', #IB + 112 => 'Sigma 28mm f/1.5 FF High-speed Prime or other Sigma Lens', #IB + 112.1 => 'Sigma 40mm f/1.5 FF High-speed Prime', #IB + 112.2 => 'Sigma 105mm f/1.5 FF High-speed Prime', #IB + 117 => 'Tamron 35-150mm f/2.8-4.0 Di VC OSD (A043) or other Tamron Lens', #IB + 117.1 => 'Tamron SP 35mm f/1.4 Di USD (F045)', #Exiv2#1064 124 => 'Canon MP-E 65mm f/2.8 1-5x Macro Photo', #9 125 => 'Canon TS-E 24mm f/3.5L', 126 => 'Canon TS-E 45mm f/2.8', #15 - 127 => 'Canon TS-E 90mm f/2.8', #15 + 127 => 'Canon TS-E 90mm f/2.8 or Tamron Lens', #15 + 127.1 => 'Tamron 18-200mm f/3.5-6.3 Di II VC (B018)', #TomLachecki 129 => 'Canon EF 300mm f/2.8L USM', #32 130 => 'Canon EF 50mm f/1.0L USM', #10/15 131 => 'Canon EF 28-80mm f/2.8-4L USM or Sigma Lens', #32 @@ -226,10 +239,12 @@ $VERSION = '4.02'; # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 2x', #15 131.6 => 'Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye', #PH 131.7 => 'Sigma 70-200mm f/2.8 APO EX HSM', #PH (http://www.lensrentals.com/blog/2012/08/canon-illumination-correction-and-third-party-lenses) + 131.8 => 'Sigma 28-70mm f/2.8-4 DG', #IB 132 => 'Canon EF 1200mm f/5.6L USM', #32 134 => 'Canon EF 600mm f/4L IS USM', #15 135 => 'Canon EF 200mm f/1.8L USM', 136 => 'Canon EF 300mm f/2.8L USM', + 136.1 => 'Tamron SP 15-30mm f/2.8 Di VC USD (A012)', #TomLachecki 137 => 'Canon EF 85mm f/1.2L USM or Sigma or Tamron Lens', #10 137.1 => 'Sigma 18-50mm f/2.8-4.5 DC OS HSM', #PH 137.2 => 'Sigma 50-200mm f/4-5.6 DC OS HSM', #PH @@ -239,14 +254,15 @@ $VERSION = '4.02'; 137.6 => 'Sigma 17-70mm f/2.8-4 DC Macro OS HSM | C', #forum2819 (Contemporary version has this ID - PH) 137.7 => 'Sigma 17-50mm f/2.8 OS HSM', #47 137.8 => 'Sigma 18-200mm f/3.5-6.3 DC OS HSM [II]', #PH - 137.9 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD', #(model B008)forum3090 + 137.9 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)', #forum3090 '137.10' => 'Sigma 8-16mm f/4.5-5.6 DC HSM', #50-Zwielicht - '137.11' => 'Tamron SP 17-50mm f/2.8 XR Di II VC', #50 (model B005) - '137.12' => 'Tamron SP 60mm f/2 Macro Di II', #50 (model G005) + '137.11' => 'Tamron SP 17-50mm f/2.8 XR Di II VC (B005)', #50 + '137.12' => 'Tamron SP 60mm f/2 Macro Di II (G005)', #50 '137.13' => 'Sigma 10-20mm f/3.5 EX DC HSM', #Gerald Erdmann '137.14' => 'Tamron SP 24-70mm f/2.8 Di VC USD', #PH '137.15' => 'Sigma 18-35mm f/1.8 DC HSM', #David Monro '137.16' => 'Sigma 12-24mm f/4.5-5.6 DG HSM II', #IB + '137.17' => 'Sigma 70-300mm f/4-5.6 DG OS', #IB 138 => 'Canon EF 28-80mm f/2.8-4L', #32 139 => 'Canon EF 400mm f/2.8L USM', 140 => 'Canon EF 500mm f/4.5L USM', #32 @@ -265,23 +281,28 @@ $VERSION = '4.02'; 150.2 => 'Sigma 30mm f/1.4 DC HSM', #15 150.3 => 'Sigma 24mm f/1.8 DG Macro EX', #15 150.4 => 'Sigma 28mm f/1.8 DG Macro EX', #IB + 150.5 => 'Sigma 18-35mm f/1.8 DC HSM | A', #IB 151 => 'Canon EF 200mm f/2.8L USM', 152 => 'Canon EF 300mm f/4L IS USM or Sigma Lens', #15 152.1 => 'Sigma 12-24mm f/4.5-5.6 EX DG ASPHERICAL HSM', #15 152.2 => 'Sigma 14mm f/2.8 EX Aspherical HSM', #15 152.3 => 'Sigma 10-20mm f/4-5.6', #14 152.4 => 'Sigma 100-300mm f/4', # (ref Bozi) + 152.5 => 'Sigma 300-800mm f/5.6 APO EX DG HSM', #IB 153 => 'Canon EF 35-350mm f/3.5-5.6L USM or Sigma or Tamron Lens', #PH 153.1 => 'Sigma 50-500mm f/4-6.3 APO HSM EX', #15 153.2 => 'Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical [IF] Macro', - 153.3 => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro Model A14', #15 + 153.3 => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical [IF] Macro (A14)', #15 153.4 => 'Tamron 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro', #PH 154 => 'Canon EF 20mm f/2.8 USM or Zeiss Lens', #15 154.1 => 'Zeiss Milvus 21mm f/2.8', #IB - 155 => 'Canon EF 85mm f/1.8 USM', + 154.2 => 'Zeiss Milvus 15mm f/2.8 ZE', #IB + 154.3 => 'Zeiss Milvus 18mm f/2.8 ZE', #IB + 155 => 'Canon EF 85mm f/1.8 USM or Sigma Lens', + 155.1 => 'Sigma 14mm f/1.8 DG HSM | A', #IB (A017) 156 => 'Canon EF 28-105mm f/3.5-4.5 USM or Tamron Lens', - 156.1 => 'Tamron SP 70-300mm f/4-5.6 Di VC USD', #PH (model A005) - 156.2 => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF', #JR (Model 176D) + 156.1 => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)', #PH + 156.2 => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF (176D)', #JR 160 => 'Canon EF 20-35mm f/3.5-4.5 USM or Tamron or Tokina Lens', 160.1 => 'Tamron AF 19-35mm f/3.5-4.5', #44 160.2 => 'Tokina AT-X 124 AF Pro DX 12-24mm f/4', #49 @@ -294,7 +315,7 @@ $VERSION = '4.02'; 161.3 => 'Sigma 24-60mm f/2.8 EX DG', #PH (http://www.lensrentals.com/blog/2012/08/canon-illumination-correction-and-third-party-lenses) 161.4 => 'Tamron AF 17-50mm f/2.8 Di-II LD Aspherical', #40 161.5 => 'Tamron 90mm f/2.8', - 161.6 => 'Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF', #IB (A05) + 161.6 => 'Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF (A05)', #IB 161.7 => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF] Macro', #IB/NJ 161.8 => 'Tokina AT-X 24-70mm f/2.8 PRO FX (IF)', #IB 162 => 'Canon EF 200mm f/2.8L USM', #32 @@ -314,18 +335,30 @@ $VERSION = '4.02'; 169.6 => 'Sigma 30mm f/1.4 EX DC HSM', #Rodolfo Borges 169.7 => 'Sigma 35mm f/1.4 DG HSM', #PH (also "| A" version, ref 50) 169.8 => 'Sigma 35mm f/1.5 FF High-Speed Prime | 017', #IB - 170 => 'Canon EF 200mm f/2.8L II USM', #9 + 169.9 => 'Sigma 70mm f/2.8 Macro EX DG', #IB + 170 => 'Canon EF 200mm f/2.8L II USM or Sigma Lens', #9 + 170.1 => 'Sigma 300mm f/2.8 APO EX DG HSM', #IB + 170.2 => 'Sigma 800mm f/5.6 APO EX DG HSM', #IB 171 => 'Canon EF 300mm f/4L USM', #15 172 => 'Canon EF 400mm f/5.6L USM or Sigma Lens', #32 172.1 =>'Sigma 150-600mm f/5-6.3 DG OS HSM | S', #50 + 172.2 => 'Sigma 500mm f/4.5 APO EX DG HSM', #IB 173 => 'Canon EF 180mm Macro f/3.5L USM or Sigma Lens', #9 173.1 => 'Sigma 180mm EX HSM Macro f/3.5', #14 173.2 => 'Sigma APO Macro 150mm f/2.8 EX DG HSM', #14 + 173.3 => 'Sigma 10mm f/2.8 EX DC Fisheye', #IB + 173.4 => 'Sigma 15mm f/2.8 EX DG Diagonal Fisheye', #IB + 173.5 => 'Venus Laowa 100mm F2.8 2X Ultra Macro APO', #IB 174 => 'Canon EF 135mm f/2L USM or Other Lens', #9 174.1 => 'Sigma 70-200mm f/2.8 EX DG APO OS HSM', #PH (probably version II of this lens) 174.2 => 'Sigma 50-500mm f/4.5-6.3 APO DG OS HSM', #forum4031 174.3 => 'Sigma 150-500mm f/5-6.3 APO DG OS HSM', #47 174.4 => 'Zeiss Milvus 100mm f/2 Makro', #IB + 174.5 => 'Sigma APO 50-150mm f/2.8 EX DC OS HSM', #IB + 174.6 => 'Sigma APO 120-300mm f/2.8 EX DG OS HSM', #IB + 174.7 => 'Sigma 120-300mm f/2.8 DG OS HSM S013', #IB + 174.8 => 'Sigma 120-400mm f/4.5-5.6 APO DG OS HSM', #IB + 174.9 => 'Sigma 200-500mm f/2.8 APO EX DG', #IB 175 => 'Canon EF 400mm f/2.8L USM', #32 176 => 'Canon EF 24-85mm f/3.5-4.5 USM', 177 => 'Canon EF 300mm f/4L IS USM', #9 @@ -340,6 +373,8 @@ $VERSION = '4.02'; 180.6 => 'Sigma 24mm f/1.5 FF High-Speed Prime | 017', #IB 180.7 => 'Sigma 50mm f/1.5 FF High-Speed Prime | 017', #IB 180.8 => 'Sigma 85mm f/1.5 FF High-Speed Prime | 017', #IB + 180.9 => 'Tokina Opera 50mm f/1.4 FF', #IB + '180.10' => 'Sigma 20mm f/1.4 DG HSM | A', #IB (015) 181 => 'Canon EF 100-400mm f/4.5-5.6L IS USM + 1.4x or Sigma Lens', #15 181.1 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S + 1.4x', #50 182 => 'Canon EF 100-400mm f/4.5-5.6L IS USM + 2x or Sigma Lens', @@ -366,28 +401,32 @@ $VERSION = '4.02'; 195 => 'Canon EF 35-105mm f/4.5-5.6 USM', #32 196 => 'Canon EF 75-300mm f/4-5.6 USM', #15/32 197 => 'Canon EF 75-300mm f/4-5.6 IS USM or Sigma Lens', - 197.1 => 'Sigma 18-300mm f/3.5-6.3 DC Macro OS HS', #50 - 198 => 'Canon EF 50mm f/1.4 USM or Zeiss Lens', + 197.1 => 'Sigma 18-300mm f/3.5-6.3 DC Macro OS HSM', #50 + 198 => 'Canon EF 50mm f/1.4 USM or Other Lens', 198.1 => 'Zeiss Otus 55mm f/1.4 ZE', #JR (seen only on Sony camera) 198.2 => 'Zeiss Otus 85mm f/1.4 ZE', #JR (NC) 198.3 => 'Zeiss Milvus 25mm f/1.4', #IB + 198.4 => 'Zeiss Otus 100mm f/1.4', #IB + 198.5 => 'Zeiss Milvus 35mm f/1.4 ZE', #IB + 198.6 => 'Yongnuo YN 35mm f/2', #IB 199 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32 200 => 'Canon EF 75-300mm f/4-5.6 USM', #32 201 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32 202 => 'Canon EF 28-80mm f/3.5-5.6 USM IV', 208 => 'Canon EF 22-55mm f/4-5.6 USM', #32 - 209 => 'Canon EF 55-200mm f/4.5-5.6', #32 + 209 => 'Canon EF 55-200mm f/4.5-5.6', #32 (USM mk I version? ref IB) 210 => 'Canon EF 28-90mm f/4-5.6 USM', #32 211 => 'Canon EF 28-200mm f/3.5-5.6 USM', #15 212 => 'Canon EF 28-105mm f/4-5.6 USM', #15 213 => 'Canon EF 90-300mm f/4.5-5.6 USM or Tamron Lens', - 213.1 => 'Tamron SP 150-600mm f/5-6.3 Di VC USD', #topic5565 (model A011) - 213.2 => 'Tamron 16-300mm f/3.5-6.3 Di II VC PZD Macro', #PH (model B016) - 213.3 => 'Tamron SP 35mm f/1.8 Di VC USD', #PH (model F012) - 213.4 => 'Tamron SP 45mm f/1.8 Di VC USD', #PH (model F013) + 213.1 => 'Tamron SP 150-600mm f/5-6.3 Di VC USD (A011)', #forum5565 + 213.2 => 'Tamron 16-300mm f/3.5-6.3 Di II VC PZD Macro (B016)', #PH + 213.3 => 'Tamron SP 35mm f/1.8 Di VC USD (F012)', #PH + 213.4 => 'Tamron SP 45mm f/1.8 Di VC USD (F013)', #PH 214 => 'Canon EF-S 18-55mm f/3.5-5.6 USM', #PH/34 215 => 'Canon EF 55-200mm f/4.5-5.6 II USM', 217 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD', #47 + 220 => 'Yongnuo YN 50mm f/1.8', #IB 224 => 'Canon EF 70-200mm f/2.8L IS USM', #11 225 => 'Canon EF 70-200mm f/2.8L IS USM + 1.4x', #11 226 => 'Canon EF 70-200mm f/2.8L IS USM + 2x', #14 @@ -395,7 +434,8 @@ $VERSION = '4.02'; 228 => 'Canon EF 28-105mm f/3.5-4.5 USM', #32 229 => 'Canon EF 16-35mm f/2.8L USM', #PH 230 => 'Canon EF 24-70mm f/2.8L USM', #9 - 231 => 'Canon EF 17-40mm f/4L USM', + 231 => 'Canon EF 17-40mm f/4L USM or Sigma Lens', + 231.1 => 'Sigma 12-24mm f/4 DG HSM A016', #IB 232 => 'Canon EF 70-300mm f/4.5-5.6 DO IS USM', #15 233 => 'Canon EF 28-300mm f/3.5-5.6L IS USM', #PH 234 => 'Canon EF-S 17-85mm f/4-5.6 IS USM or Tokina Lens', #19 @@ -419,14 +459,20 @@ $VERSION = '4.02'; 248.1 => 'Sigma 24-35mm f/2 DG HSM | A', #JR 248.2 => 'Sigma 135mm f/2 FF High-Speed Prime | 017', #IB 248.3 => 'Sigma 24-35mm f/2.2 FF Zoom | 017', #IB + 248.4 => 'Sigma 135mm f/1.8 DG HSM A017', #IB 249 => 'Canon EF 800mm f/5.6L IS USM', #35 250 => 'Canon EF 24mm f/1.4L II USM or Sigma Lens', #41 250.1 => 'Sigma 20mm f/1.4 DG HSM | A', #IB 250.2 => 'Sigma 20mm f/1.5 FF High-Speed Prime | 017', #IB + 250.3 => 'Tokina Opera 16-28mm f/2.8 FF', #IB + 250.4 => 'Sigma 85mm f/1.4 DG HSM A016', #IB 251 => 'Canon EF 70-200mm f/2.8L IS II USM', + 251.1 => 'Canon EF 70-200mm f/2.8L IS III USM', #IB 252 => 'Canon EF 70-200mm f/2.8L IS II USM + 1.4x', #50 (1.4x Mk II) + 252.1 => 'Canon EF 70-200mm f/2.8L IS III USM + 1.4x', #PH (NC) 253 => 'Canon EF 70-200mm f/2.8L IS II USM + 2x', #PH (NC) - # 253.1 => 'Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025) + 2x', #forum9367 + 253.1 => 'Canon EF 70-200mm f/2.8L IS III USM + 2x', #PH (NC) + # 253.2 => 'Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025) + 2x', #forum9367 254 => 'Canon EF 100mm f/2.8L Macro IS USM', #42 255 => 'Sigma 24-105mm f/4 DG OS HSM | A or Other Sigma Lens', #50 255.1 => 'Sigma 180mm f/2.8 EX DG OS HSM APO Macro', #50 @@ -435,6 +481,12 @@ $VERSION = '4.02'; 368.2 => 'Sigma 50mm f/1.4 DG HSM | A', #50 368.3 => 'Sigma 40mm f/1.4 DG HSM | A', #IB (018) 368.4 => 'Sigma 60-600mm f/4.5-6.3 DG OS HSM | S', #IB (018) + 368.5 => 'Sigma 28mm f/1.4 DG HSM | A', #IB (A019) + 368.6 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S', #50 + 368.7 => 'Sigma 85mm f/1.4 DG HSM | A', #IB (016) + 368.8 => 'Sigma 105mm f/1.4 DG HSM', #IB (A018) + 368.9 => 'Sigma 14-24mm f/2.8 DG HSM', #IB (A018) + '368.10' => 'Sigma 70mm f/2.8 DG Macro', #IB (A018) # Note: LensType 488 (0x1e8) is reported as 232 (0xe8) in 7D CameraSettings 488 => 'Canon EF-S 15-85mm f/3.5-5.6 IS USM', #PH 489 => 'Canon EF 70-300mm f/4-5.6L IS USM', #Gerald Kapounek @@ -451,24 +503,28 @@ $VERSION = '4.02'; 493.1 => 'Canon EF 24-105mm f/4L IS USM', #PH (should recheck this) 494 => 'Canon EF 600mm f/4L IS II USM', #PH 495 => 'Canon EF 24-70mm f/2.8L II USM or Sigma Lens', #PH - 495.1 => 'Sigma 24-70mm F2.8 DG OS HSM | A', #IB (017) + 495.1 => 'Sigma 24-70mm f/2.8 DG OS HSM | A', #IB (017) 496 => 'Canon EF 200-400mm f/4L IS USM', #PH 499 => 'Canon EF 200-400mm f/4L IS USM + 1.4x', #50 - 502 => 'Canon EF 28mm f/2.8 IS USM', #PH + 502 => 'Canon EF 28mm f/2.8 IS USM or Tamron Lens', #PH + 502.1 => 'Tamron 35mm f/1.8 Di VC USD (F012)', #forum9757 503 => 'Canon EF 24mm f/2.8 IS USM', #PH 504 => 'Canon EF 24-70mm f/4L IS USM', #PH 505 => 'Canon EF 35mm f/2 IS USM', #PH 506 => 'Canon EF 400mm f/4 DO IS II USM', #42 507 => 'Canon EF 16-35mm f/4L IS USM', #42 508 => 'Canon EF 11-24mm f/4L USM or Tamron Lens', #PH - 508.1 => 'Tamron 10-24mm f/3.5-4.5 Di II VC HLD', #PH (B023) + 508.1 => 'Tamron 10-24mm f/3.5-4.5 Di II VC HLD (B023)', #PH + 624 => 'Sigma 70-200mm f/2.8 DG OS HSM | S', #IB (018) 747 => 'Canon EF 100-400mm f/4.5-5.6L IS II USM or Tamron Lens', #JR 747.1 => 'Tamron SP 150-600mm f/5-6.3 Di VC USD G2', #50 748 => 'Canon EF 100-400mm f/4.5-5.6L IS II USM + 1.4x or Tamron Lens', #JR (1.4x Mk III) 748.1 => 'Tamron 100-400mm f/4.5-6.3 Di VC USD A035E + 1.4x', #IB 748.2 => 'Tamron 70-210mm f/4 Di VC USD (A034) + 2x', #IB 749 => 'Tamron 100-400mm f/4.5-6.3 Di VC USD A035E + 2x', #IB - 750 => 'Canon EF 35mm f/1.4L II USM', #42 + 750 => 'Canon EF 35mm f/1.4L II USM or Tamron Lens', #42 + 750.1 => 'Tamron SP 85mm f/1.8 Di VC USD (F016)', #Exiv2#1072 + 750.2 => 'Tamron SP 45mm f/1.8 Di VC USD (F013)', #PH 751 => 'Canon EF 16-35mm f/2.8L III USM', #42 752 => 'Canon EF 24-105mm f/4L IS II USM', #42 753 => 'Canon EF 85mm f/1.4L IS USM', #42 @@ -493,9 +549,11 @@ $VERSION = '4.02'; 4154 => 'Canon EF-S 24mm f/2.8 STM', #IB 4155 => 'Canon EF-M 28mm f/3.5 Macro IS STM', #42 4156 => 'Canon EF 50mm f/1.8 STM', #42 - 4157 => 'Canon EF-M 18-150mm 1:3.5-6.3 IS STM', #42 + 4157 => 'Canon EF-M 18-150mm f/3.5-6.3 IS STM', #42 4158 => 'Canon EF-S 18-55mm f/4-5.6 IS STM', #PH + 4159 => 'Canon EF-M 32mm f/1.4 STM', #42 4160 => 'Canon EF-S 35mm f/2.8 Macro IS STM', #42 + 4208 => 'Sigma 56mm f/1.4 DC DN | C', #forum10603 # (Nano USM lenses - 0x90xx) 36910 => 'Canon EF 70-300mm f/4-5.6 IS II USM', #42 36912 => 'Canon EF-S 18-135mm f/3.5-5.6 IS USM', #42 @@ -510,6 +568,10 @@ $VERSION = '4.02'; 61182.1 => 'Canon RF 50mm F1.2 L USM', #IB 61182.2 => 'Canon RF 24-105mm F4 L IS USM', #IB 61182.3 => 'Canon RF 28-70mm F2 L USM', #IB + 61182.4 => 'Canon RF 85mm F1.2L USM', #IB + 61182.5 => 'Canon RF 24-240mm F4-6.3 IS USM', #IB + 61182.6 => 'Canon RF 24-70mm F2.8 L IS USM', #PH + 61182.7 => 'Canon RF 15-35mm F2.8 L IS USM', #PH 65535 => 'n/a', ); @@ -683,6 +745,7 @@ $VERSION = '4.02'; 0x3260000 => 'PowerShot A3400 IS', 0x3270000 => 'PowerShot A2400 IS', 0x3280000 => 'PowerShot A2300', + 0x3320000 => 'PowerShot S100V', #IB 0x3330000 => 'PowerShot G15', #25 0x3340000 => 'PowerShot SX50 HS', #25/forum8196 0x3350000 => 'PowerShot SX160 IS', @@ -741,7 +804,7 @@ $VERSION = '4.02'; 0x4020000 => 'PowerShot SX420 IS', 0x4030000 => 'PowerShot ELPH 190 IS / IXUS 180 / IXY 190', 0x4040000 => 'PowerShot G1', - 0x4040001 => 'IXY 180', # ?? (from Canon sample) + 0x4040001 => 'PowerShot ELPH 180 IS / IXUS 175 / IXY 180', #forum10402 0x4050000 => 'PowerShot SX720 HS', 0x4060000 => 'PowerShot SX620 HS', 0x4070000 => 'EOS M6', @@ -753,7 +816,11 @@ $VERSION = '4.02'; 0x4180000 => 'PowerShot G1 X Mark III', #IB 0x6040000 => 'PowerShot S100 / Digital IXUS / IXY Digital', 0x801 => 'PowerShot SX740 HS', + 0x804 => 'PowerShot G5 X Mark II', 0x805 => 'PowerShot SX70 HS', + 0x808 => 'PowerShot G7 X Mark III', + 0x811 => 'EOS M6 Mark II', #IB + 0x812 => 'EOS M200', #25 # (see http://cweb.canon.jp/e-support/faq/answer/digitalcamera/10447-1.html for PowerShot/IXUS/IXY names) @@ -835,7 +902,7 @@ $VERSION = '4.02'; 0x80000325 => 'EOS 70D', 0x80000326 => 'EOS Rebel T5i / 700D / Kiss X7i', 0x80000327 => 'EOS Rebel T5 / 1200D / Kiss X70 / Hi', - 0x80000328 => 'EOS-1D X MARK II', #42 + 0x80000328 => 'EOS-1D X Mark II', #42 0x80000331 => 'EOS M', 0x80000350 => 'EOS 80D', #42 0x80000355 => 'EOS M2', @@ -851,8 +918,14 @@ $VERSION = '4.02'; 0x80000408 => 'EOS 77D / 9000D', 0x80000417 => 'EOS Rebel SL2 / 200D / Kiss X9', #IB/42 0x80000422 => 'EOS Rebel T100 / 4000D / 3000D', #IB (3000D in China; Kiss? - PH) - 0x80000424 => 'EOR R', #IB + 0x80000424 => 'EOS R', #IB + 0x80000428 => 'EOS-1D X Mark III', #IB 0x80000432 => 'EOS Rebel T7 / 2000D / 1500D / Kiss X90', #IB + 0x80000433 => 'EOS RP', + 0x80000436 => 'EOS SL3 / 250D / Kiss X10', #25 + 0x80000437 => 'EOS 90D', #IB + 0x80000520 => 'EOS D2000C', #IB + 0x80000560 => 'EOS D6000C', #PH (guess) ); my %canonQuality = ( @@ -1520,7 +1593,10 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); ValueConv => 'unpack("H*", $val)', ValueConvInv => 'pack("H*", $val)', }, - # 0x29 - WBInfo (ref IB, offset 0x6 is int32u[4] WB_GRBGLevels as shot for PowerShot G9) + 0x29 => { #IB (G9) + Name => 'WBInfo', + SubDirectory => { TagTable => 'Image::ExifTool::Canon::WBInfo' }, + }, # 0x2d - changes with categories (ref 31) 0x2f => { #PH (G12) Name => 'FaceDetect3', @@ -1529,6 +1605,8 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); TagTable => 'Image::ExifTool::Canon::FaceDetect3', }, }, + # 0x32 - if length is 768, starting at offset 4 there are 6 RGGB 1/val int16 records: + # daylight,cloudy,tungsten,fluorescent,flash,kelvin (D30 2001, ref IB) 0x35 => { #PH Name => 'TimeInfo', SubDirectory => { @@ -1719,6 +1797,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); PrintConv => { 1 => 'sRGB', 2 => 'Adobe RGB', + 65535 => 'n/a', }, }, 0xb6 => { @@ -1796,8 +1875,8 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); Name => 'ColorData8', SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData8' }, }, - { # (int16u[1820]) - M50, ref PH - Condition => '$count == 1820', + { # (int16u[1816|1820|1824]) - M50 (1820) ref PH, EOS R (1824), EOS RP, SX70 (1816) ref IB + Condition => '$count == 1816 or $count == 1820 or $count == 1824', Name => 'ColorData9', SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData9' }, }, @@ -1825,7 +1904,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); }, 0x4008 => { #53 Name => 'PictureStyleUserDef', # (BasePictStyleOfUser) - Format => 'int16u', + Writable => 'int16u', Count => 3, # UserDef1, UserDef2, UserDef3 PrintHex => 1, SeparateTable => 'PictureStyle', @@ -1833,7 +1912,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); }, 0x4009 => { #53 Name => 'PictureStylePC', # (BasePictStyleOfUser) - Format => 'int16u', + Writable => 'int16u', Count => 3, # PC1, PC2, PC3 PrintHex => 1, SeparateTable => 'PictureStyle', @@ -1937,6 +2016,13 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); TagTable => 'Image::ExifTool::Canon::AFConfig', } }, + 0x403f => { #25 + Name => 'RawBurstModeRoll', + SubDirectory => { + Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)', + TagTable => 'Image::ExifTool::Canon::RawBurstInfo', + } + }, ); #.............................................................................. @@ -1975,7 +2061,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); 4 => { Name => 'CanonFlashMode', PrintConv => { - -1 => "n/a", # (PH, EOS M MOV video) + -1 => 'n/a', # (PH, EOS M MOV video) 0 => 'Off', 1 => 'Auto', 2 => 'On', @@ -1996,7 +2082,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); 4 => 'Continuous, Low', #PH 5 => 'Continuous, High', #PH 6 => 'Silent Single', #PH - # ref A: http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5701.msg27843.html#msg27843 + # ref A: https://exiftool.org/forum/index.php/topic,5701.msg27843.html#msg27843 9 => 'Single, Silent', #A 10 => 'Continuous, Silent', #A # 11 - seen for SX260 @@ -2036,6 +2122,8 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); 11 => 'CRM', #PH (C200 CRM) 12 => 'CR3', #PH (EOS R) 13 => 'CR3+JPEG', #PH (EOS R) + 14 => 'HIF', #PH (NC) + 15 => 'CR3+HIF', #PH (1DXmkIII) }, }, 10 => { @@ -2114,6 +2202,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); 60 => 'High-speed Burst HQ', #PH (C='High-speed Burst HQ', same as 59) 61 => 'Smooth Skin', #51 62 => 'Soft Focus', #PH (SX260,IXUS240) + 68 => 'Food', #PH (250D) + # 83 - seen for EOS M200 (ref PH) + 84 => 'HDR Art Standard', #PH (80D) + 85 => 'HDR Art Vivid', #PH (80D) + 93 => 'HDR Art Bold', #PH (80D) # 83 - seen for EOS M3 night shot (PH) 257 => 'Spotlight', #PH 258 => 'Night 2', #PH @@ -2214,6 +2307,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); 5 => 'Depth-of-field AE', 6 => 'M-Dep', #PH 7 => 'Bulb', #30 + 8 => 'Flexible-priority AE', #ArnoldVanOostrum }, }, 22 => { #4 @@ -6075,8 +6169,8 @@ my %ciMaxFocal = ( 8 => 'AF Point Expansion (4 point)', #46/PH/forum6237 9 => 'Spot AF', #46 10 => 'AF Point Expansion (8 point)', #forum6237 - 11 => 'Flexizone Multi', #PH (NC, EOS M, live view) - # 12 - also "Flexizone Multi"? (PH) + 11 => 'Flexizone Multi (49 point)', #PH (NC, EOS M, live view; 750D 49 points) + 12 => 'Flexizone Multi (9 point)', #PH (750D, 9 points) 13 => 'Flexizone Single', #PH (EOS M default, live view) 14 => 'Large Zone AF', #PH/forum6237 (7DmkII) }, @@ -6159,7 +6253,7 @@ my %ciMaxFocal = ( # DPP shows "On" for any value except 0xffff when bit 0x08 is set my ($val, $inv) = @_; if ($inv) { - $val =~ /(0x[0-9a-f]+)/i or $val =~ /(\d+)/; + $val =~ /(0x[0-9a-f]+)/i or $val =~ /(\d+)/ or return undef; return $1; } else { return sprintf("On (0x%.2x)",$val) if $val & 0x08; @@ -6346,6 +6440,25 @@ my %ciMaxFocal = ( 0x02 => 'FacesDetected', ); +# G9 white balance information (MakerNotes tag 0x29) (ref IB) +%Image::ExifTool::Canon::WBInfo = ( + %binaryDataAttrs, + NOTES => 'WB tags for the Canon G9.', + FORMAT => 'int32u', + FIRST_ENTRY => 1, + GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + 0x02 => { Name => 'WB_GRGBLevelsAuto', Format => 'int32s[4]' }, + 0x0a => { Name => 'WB_GRGBLevelsDaylight', Format => 'int32s[4]' }, + 0x12 => { Name => 'WB_GRGBLevelsCloudy', Format => 'int32s[4]' }, + 0x1a => { Name => 'WB_GRGBLevelsTungsten', Format => 'int32s[4]' }, + 0x22 => { Name => 'WB_GRGBLevelsFluorescent', Format => 'int32s[4]' }, + 0x2a => { Name => 'WB_GRGBLevelsFluorHigh', Format => 'int32s[4]' }, + 0x32 => { Name => 'WB_GRGBLevelsFlash', Format => 'int32s[4]' }, + 0x3a => { Name => 'WB_GRGBLevelsUnderwater', Format => 'int32s[4]' }, + 0x42 => { Name => 'WB_GRGBLevelsCustom1', Format => 'int32s[4]' }, + 0x4a => { Name => 'WB_GRGBLevelsCustom2', Format => 'int32s[4]' }, +); + # yet more face detect information (MakerNotes tag 0x2f) - PH (G12) %Image::ExifTool::Canon::FaceDetect3 = ( %binaryDataAttrs, @@ -6602,6 +6715,8 @@ my %ciMaxFocal = ( 2 => '4:3', 7 => '16:9', 8 => '4:5', + 12 => '3:2 (APS-H crop)', #IB + 13 => '3:2 (APS-C crop)', #IB }, }, # (could use better names for these, or the Crop tags above, or both) @@ -6689,7 +6804,15 @@ my %ciMaxFocal = ( 17 => { Name => 'WB_RGGBLevelsTungsten', Format => 'int16s[4]' }, 21 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' }, 25 => { Name => 'WB_RGGBLevelsFlash', Format => 'int16s[4]' }, - 29 => { Name => 'WB_RGGBLevelsCustom', Format => 'int16s[4]' }, # (actually black levels for D60, ref IB) + 29 => [{ + Name => 'WB_RGGBLevelsCustom', + Notes => 'black levels for the D60', + Condition => '$$self{Model} !~ /EOS D60\b/', + Format => 'int16s[4]', + },{ # (black levels for D60, ref IB) + Name => 'BlackLevels', + Format => 'int16s[4]', + }], 33 => { Name => 'WB_RGGBLevelsKelvin', Format => 'int16s[4]' }, 37 => { Name => 'WB_RGGBBlackLevels', Format => 'int16s[4]' }, #IB ); @@ -7287,7 +7410,7 @@ my %ciMaxFocal = ( NOTES => q{ Camera color calibration data. For the 20D, 350D, 1DmkII and 1DSmkII the order of the coefficients is A, B, C, Temperature, but for newer models it - is B, C, A, Temperature. These tags are extracted only when the Unknown + is B, C, A, Temperature. These tags are extracted only when the L<Unknown|../ExifTool.html#Unknown> option is used. }, 0x00 => { Name => 'CameraColorCalibration01', %cameraColorCalibration }, @@ -7384,6 +7507,16 @@ my %ciMaxFocal = ( Condition => '$$self{ColorDataVersion} == -4', Format => 'int16s[4]', }, + 0x0569 => { #PH (NC) + Name => 'NormalWhiteLevel', + Condition => '$$self{ColorDataVersion} == -4', + Format => 'int16u', + }, + 0x056a => { #PH (NC) + Name => 'SpecularWhiteLevel', + Condition => '$$self{ColorDataVersion} == -4', + Format => 'int16u', + }, ); # Color data (MakerNotes tag 0x4001, count=1273|1275) (ref PH) @@ -7779,7 +7912,7 @@ my %ciMaxFocal = ( }, ); -# Color data (MakerNotes tag 0x4001, count=1820) (ref PH) +# Color data (MakerNotes tag 0x4001, count=1820,etc) (ref PH) %Image::ExifTool::Canon::ColorData9 = ( %binaryDataAttrs, FORMAT => 'int16s', @@ -7793,6 +7926,9 @@ my %ciMaxFocal = ( RawConv => '$$self{ColorDataVersion} = $val', PrintConv => { 16 => '16 (M50)', + 17 => '17 (EOS R)', # (and PowerShot SX740HS) + 18 => '18 (EOS RP)', # (and PowerShot SX70HS) + 19 => '19 (90D/M6mkII/M200)',# (and PowerShot G7XmkIII) }, }, 0x47 => { Name => 'WB_RGGBLevelsAsShot', Format => 'int16s[4]' }, @@ -7971,6 +8107,10 @@ my %ciMaxFocal = ( Name => 'PeripheralLighting', PrintConv => \%offOn, }, + 3 => { + Name => 'DistortionCorrection', + PrintConv => \%offOn, + }, 4 => { Name => 'ChromaticAberrationCorr', PrintConv => \%offOn, @@ -7980,6 +8120,7 @@ my %ciMaxFocal = ( PrintConv => \%offOn, }, 6 => 'PeripheralLightingValue', + 9 => 'DistortionCorrectionValue', # 10 - flags? 11 => { Name => 'OriginalImageWidth', @@ -8015,6 +8156,10 @@ my %ciMaxFocal = ( Name => 'ChromaticAberrationSetting', PrintConv => \%offOn, }, + 7 => { + Name => 'DistortionCorrectionSetting', + PrintConv => \%offOn, + }, ); # Auto Lighting Optimizater information (MakerNotes tag 0x4018) (ref PH) @@ -8059,7 +8204,7 @@ my %ciMaxFocal = ( }, }, # 6 - related to ChromaticAberrationCorr - # 7 - related to DistortionCorrection + # 7 - related to DistortionCorrection (0=off, 1=On in a 5DmkIV sample) # 8 - related to PeripheralIlluminationCorr and ChromaticAberrationCorr ); @@ -8341,9 +8486,20 @@ my %filterConv = ( }, ); +# RAW burst mode info (MakerNotes tag 0x403f) (ref 25) +%Image::ExifTool::Canon::RawBurstInfo = ( + %binaryDataAttrs, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + FORMAT => 'int32u', + FIRST_ENTRY => 1, + 1 => 'RawBurstImageNum', + 2 => 'RawBurstImageCount', +); + # Canon UUID atoms (ref PH, SX280) %Image::ExifTool::Canon::uuid = ( GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' }, + WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime', NOTES => q{ Tags extracted from the uuid atom of MP4 videos from cameras such as the SX280, and CR3 images from cameras such as the EOS M50. @@ -8366,12 +8522,14 @@ my %filterConv = ( }, }, # CTBO - (CR3 files) int32u entry count N, N x (int32u index, int64u offset, int64u size) - # index 1=XMP, 2=PRVW, 3=mdat + # index: 1=XMP, 2=PRVW, 3=mdat, 4=?, 5=? + # --> ignored when reading, but offsets are updated when writing CMT1 => { # (CR3 files) Name => 'IFD0', SubDirectory => { TagTable => 'Image::ExifTool::Exif::Main', ProcessProc => \&Image::ExifTool::ProcessTIFF, + WriteProc => \&Image::ExifTool::WriteTIFF, }, }, CMT2 => { # (CR3 files) @@ -8379,6 +8537,7 @@ my %filterConv = ( SubDirectory => { TagTable => 'Image::ExifTool::Exif::Main', ProcessProc => \&Image::ExifTool::ProcessTIFF, + WriteProc => \&Image::ExifTool::WriteTIFF, }, }, CMT3 => { # (CR3 files) @@ -8386,6 +8545,7 @@ my %filterConv = ( SubDirectory => { TagTable => 'Image::ExifTool::Canon::Main', ProcessProc => \&Image::ExifTool::ProcessTIFF, + WriteProc => \&Image::ExifTool::WriteTIFF, }, }, CMT4 => { # (CR3 files) @@ -8393,6 +8553,7 @@ my %filterConv = ( SubDirectory => { TagTable => 'Image::ExifTool::GPS::Main', ProcessProc => \&Image::ExifTool::ProcessTIFF, + WriteProc => \&Image::ExifTool::WriteTIFF, DirName => 'GPS', }, }, @@ -8408,6 +8569,18 @@ my %filterConv = ( }, ); +# Canon top-level uuid atoms (ref PH, written by DPP4) +%Image::ExifTool::Canon::uuid2 = ( + WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime', + CNOP => { + Name => 'CanonVRD', + SubDirectory => { + TagTable => 'Image::ExifTool::CanonVRD::Main', + WriteProc => 'Image::ExifTool::CanonVRD::WriteCanonDR4', + }, + }, +); + %Image::ExifTool::Canon::UnknownIFD = ( GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, ); @@ -8418,10 +8591,30 @@ my %filterConv = ( # CCDT - int32u[3]: 0. 0, 1. decoder type?, 2. 0, 3. index ); +# 'CMP1' atom information (ref 54, CR3 files) +%Image::ExifTool::Canon::CMP1 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' }, + FORMAT => 'int16u', + FIRST_ENTRY => 0, + PRIORITY => 0, + 8 => { Name => 'ImageWidth', Format => 'int32u' }, + 10 => { Name => 'ImageHeight', Format => 'int32u' }, + # (the rest of the documented tags don't seem to produced good values with my samples - PH) +); + # 'CDI1' atom information (ref PH, CR3 files) %Image::ExifTool::Canon::CDI1 = ( - GROUPS => { 0 => 'QuickTime', 1 => 'Canon', 2 => 'Image' }, - # IAD1 - 32/48 bytes + GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' }, + IAD1 => { Name => 'IAD1', SubDirectory => { TagTable => 'Image::ExifTool::Canon::IAD1' } }, +); + +# 'IAD1' atom information (ref 54, CR3 files) +%Image::ExifTool::Canon::IAD1 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' }, + FORMAT => 'int16u', + FIRST_ENTRY => 0, ); # Canon Timed MetaData (ref PH, CR3 files) @@ -8429,7 +8622,7 @@ my %filterConv = ( GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' }, PROCESS_PROC => \&ProcessCTMD, NOTES => q{ - Canon Timed MetaData tags found in CR3 images. The ExtractEmbedded option + Canon Timed MetaData tags found in CR3 images. The L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option is automatically applied when reading CR3 files to be able to extract this information. }, @@ -8525,9 +8718,12 @@ my %filterConv = ( %Image::ExifTool::Canon::CNTH = ( GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' }, + VARS => { ATOM_COUNT => 1 }, # only one contained atom + WRITABLE => 1, + WRITE_PROC => 'Image::ExifTool::QuickTime::WriteQuickTime', NOTES => q{ - Canon-specific QuickTime tags found in the CNTH atom of MOV videos from some - cameras such as the PowerShot S95. + Canon-specific QuickTime tags found in the CNTH atom of MOV/MP4 videos from + some cameras. }, CNDA => { Name => 'ThumbnailImage', @@ -8541,13 +8737,14 @@ my %filterConv = ( $$self{DOC_NUM} = 0; return \$val; }, + RawConvInv => '$val', }, ); # Canon CNOP atoms (ref PH) %Image::ExifTool::Canon::CNOP = ( GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' }, - # CNFB - 52 bytes (7DmkII,M50) + # CNFB - 52 bytes (7DmkII,M50,C200) # CNMI - 4 bytes: "0x20000001" (C200) # CNCM - 48 bytes: original file name in bytes 24-31 (C200) ); @@ -8881,9 +9078,10 @@ sub PrintLensID(@) } @matches = @best if @best; } + @matches = @likely unless @matches; + @matches = @maybe unless @matches; + Image::ExifTool::Exif::MatchLensModel(\@matches, $lensModel); return join(' or ', @matches) if @matches; - return join(' or ', @likely) if @likely; - return join(' or ', @maybe) if @maybe; } elsif ($lensModel and $lensModel =~ /\d/) { # use lens model as written by the camera if ($printConv eq \%canonLensTypes) { @@ -9231,7 +9429,7 @@ sub PrintAFPoints1D($) $focusing = "$row$col" if $focus eq $focusPt; push @points, "$row$col" if shift @bits; } - $focusing or $focusing = ($focus eq 0xff) ? 'Auto' : sprintf('Unknown (0x%.2x)',$focus); + $focusing or $focusing = ($focus == 0xff) ? 'Auto' : sprintf('Unknown (0x%.2x)',$focus); return "$focusing (" . join(',',@points) . ')'; } @@ -9466,7 +9664,7 @@ Canon maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/CanonCustom.pm b/src/Image-ExifTool/lib/Image/ExifTool/CanonCustom.pm index bfee19a6..2cb7405b 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/CanonCustom.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/CanonCustom.pm @@ -19,7 +19,7 @@ use Image::ExifTool qw(:DataAccess); use Image::ExifTool::Canon; use Image::ExifTool::Exif; -$VERSION = '1.55'; +$VERSION = '1.56'; sub ProcessCanonCustom($$$); sub ProcessCanonCustom2($$$); @@ -1319,7 +1319,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); }, 0x0108 => { Name => 'SafetyShift', - Notes => 'value of 2 not used by 40D, 50D, 60D, 5DmkII and 7D', + Notes => 'value of 2 not used by some models', # eg. 40D, 50D, 60D, 5DmkII, 7D, 250D PrintConv => { 0 => 'Disable', 1 => 'Enable (Tv/Av)', @@ -1328,7 +1328,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); }, 0x0109 => { Name => 'UsableShootingModes', - Count => 2, + Count => 2, # (Count is 1 for 1DXmkIII -- need to decode this) PrintConv => [ \%disableEnable, 'sprintf("Flags 0x%x",$val)', # (M, Tv, Av, P, Bulb) @@ -1340,7 +1340,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); }, 0x010a => { Name => 'UsableMeteringModes', - Count => 2, + Count => 2, # (Count is 1 for 1DXmkIII -- need to decode this) PrintConv => [ \%disableEnable, 'sprintf("Flags 0x%x",$val)', # (evaluative,partial,spot,center-weighted average) @@ -1678,11 +1678,13 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); 0x040a => { # new for 5DmkIII Name => 'ViewfinderWarnings', PrintConv => { BITMASK => { #(NC) - 0 => 'Monochrome', # (have seen for: 5DmkII, 6D) - 1 => 'WB corrected', # (have seen for: 5DmkII, 6D) + 0 => 'Monochrome', # (have seen for: 5DmkII, 6D, 250D, 90D) + 1 => 'WB corrected', # (have seen for: 5DmkII, 6D, 90D) 2 => 'One-touch image quality', # (have seen for: 5DmkII; doesn't exist for 6D) 3 => 'ISO expansion', # (have seen for: 5DmkII) 4 => 'Spot metering', # (have seen for: 5DmkII, 6D) + 6 => 'Noise reduction', # (have seen for: 250D, 90D) + 7 => 'HDR', # (have seen for: 90D) }}, }, 0x040b => { # new for 5DmkIII @@ -1920,6 +1922,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); 1 => 'AF point button: Auto selection; Rear dial: Manual selection', }, }, + # (this is 2 values for 90D,M6mkII, seen: "1046 1046") ], 0x0510 => [ # new for 40D { @@ -1963,6 +1966,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); 1 => 'Enable', 2 => 'Register', 3 => 'Select AF-modes', + # also seen: 87 (90D), 1142 (RP) }, 'sprintf("Flags 0x%x",$val)', # (70D=Manual 1pt,Manual zone,Auto 19pt) ], @@ -2090,7 +2094,7 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); }, 0x0612 => { # (1DX) Name => 'RestrictDriveModes', - Count => 2, + Count => 2, # (Count is 1 for 1DXmkIII -- need to decode this) PrintConv => [ \%disableEnable, 'sprintf("Flags 0x%x",$val)', # (Single,Cont Hi,Cont Lo,Timer 10,Timer 2,Silent,Super Hi) @@ -2116,6 +2120,17 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); 3 => 'AE/AF, No AE lock', }, }, + { + Name => 'Shutter-AELock', + Condition => '$count == 2', + Notes => '250D', + PrintConv => { + '0 0' => 'AF/AE lock', + '1 0' => 'AE lock/AF', + '2 0' => 'AF/AF lock, No AE lock', + '3 0' => 'AE/AF, No AE lock', + }, + }, { Name => 'AFAndMeteringButtons', Condition => '$$self{Model} =~ /\b60D\b/', @@ -2233,6 +2248,13 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); 5 => 'Disabled', }, }, + { + Name => 'SetButtonWhenShooting', + Notes => '250D', + Condition => '$count == 2', + # (not sure how to decode this. seen: "37 0") + PrintConv => { }, + }, { Name => 'SetButtonWhenShooting', Notes => '1DmkIII and 1DmkIV', @@ -2508,6 +2530,10 @@ my %convPFn = ( PrintConv => \&ConvertPfn, PrintConvInv => \&ConvertPfnInv ); Name => 'AddIPTCInformation', PrintConv => \%disableEnable, }, + 0x0816 => { # (90D,RP) + Name => 'AudioCompression', + PrintConv => \%enableDisable, + } ); #------------------------------------------------------------------------------ @@ -2753,7 +2779,7 @@ Image::ExifTool to read this information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/CanonRaw.pm b/src/Image-ExifTool/lib/Image/ExifTool/CanonRaw.pm index c33d08b0..1375ead8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/CanonRaw.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/CanonRaw.pm @@ -683,7 +683,7 @@ sub ProcessCanonRaw($$$) my ($value, $delRawConv); if ($valueInDir) { # is the value data in the directory? # this type of tag stores the value in the 'size' and 'ptr' fields - $valueDataPos = $dirOffset + $pt + 4; + $valueDataPos = $dirOffset + $pt + 4; # (remember, +2 for the entry count) $size = 8; $value = substr($buff, $pt+2, $size); # set count to 1 by default for normal values in directory @@ -877,7 +877,7 @@ tags.) =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -892,7 +892,7 @@ under the same terms as Perl itself. =item L<http://xyrion.org/ciff/> -=item L<http://owl.phy.queensu.ca/~phil/exiftool/canon_raw.html> +=item L<https://exiftool.org/canon_raw.html> =back diff --git a/src/Image-ExifTool/lib/Image/ExifTool/CanonVRD.pm b/src/Image-ExifTool/lib/Image/ExifTool/CanonVRD.pm index 7794b649..a40ed3f4 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/CanonVRD.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/CanonVRD.pm @@ -13,7 +13,7 @@ # 2018/03/13 - PH Update to DPP 4.8.20 # # References: 1) Bogdan private communication (Canon DPP v3.4.1.1) -# 2) Gert Kello private communiation (DPP 3.8) +# 2) Gert Kello private communication (DPP 3.8) #------------------------------------------------------------------------------ package Image::ExifTool::CanonVRD; @@ -23,7 +23,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Canon; -$VERSION = '1.32'; +$VERSION = '1.33'; sub ProcessCanonVRD($$;$); sub WriteCanonVRD($$;$); @@ -150,8 +150,8 @@ my $blankFooter = "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9"; },{ Name => 'IHL_EXIF', Notes => q{ - extracted as a block if the Unknown option is used, or processed as the - first sub-document with the ExtractEmbedded option + extracted as a block if the L<Unknown|../ExifTool.html#Unknown> option is used, or processed as the + first sub-document with the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option }, Binary => 1, Unknown => 1, @@ -1818,7 +1818,7 @@ sub ProcessDR4($$;$) if (not $format) { $val = unpack 'H*', substr($$dataPt, $off, $len); $format = 'undef'; - } elsif ($format eq 'double' and $len eq 8) { + } elsif ($format eq 'double' and $len == 8) { # avoid teeny weeny values $val = ReadValue($dataPt, $off, $format, undef, $len); $val = 0 if abs($val) < 1e-100; @@ -1954,6 +1954,28 @@ sub WriteCanonVRD($$;$) return $val; } +#------------------------------------------------------------------------------ +# Write DR4-type CanonVRD edit record +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: VRD data block (may be empty if deleted, of undef on error) +sub WriteCanonDR4($$;$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + $et or return 1; # allow dummy access + my $nvHash = $et->GetNewValueHash($Image::ExifTool::Extra{CanonDR4}); + my $val = $et->GetNewValue($nvHash); + if (defined $val) { + return undef unless $et->IsOverwriting($nvHash, $val); + $et->VPrint(0, " Writing CanonDR4 as a block\n"); + ++$$et{CHANGED}; + return WrapDR4($val); + } + my $buff = ''; + $$dirInfo{OutFile} = \$buff; + return $buff if ProcessCanonVRD($et, $dirInfo, $tagTablePtr) > 0; + return undef; +} + #------------------------------------------------------------------------------ # Read/write CanonVRD information (from VRD file or VRD trailer) # Inputs: 0) ExifTool object reference, 1) dirInfo reference @@ -2015,7 +2037,7 @@ sub ProcessCanonVRD($$;$) # (so we must disable all Write() calls for this case) $dataPt = $outfile; } - if ($fromFile) { + if ($fromFile or $$dirInfo{DirStart}) { $dataPt = \$buff unless $dataPt; # read VRD data into memory if necessary unless ($raf->Read($$dataPt, $dirLen) == $dirLen) { @@ -2112,7 +2134,7 @@ sub ProcessCanonVRD($$;$) $blockType = Get32u($dataPt, $pos); $blockLen = Get32u($dataPt, $pos + 4); } - $vrdType = 'DR4' if $blockType eq 0xffff00f7; + $vrdType = 'DR4' if $blockType == 0xffff00f7; $pos += 8; # move to start of block if ($pos + $blockLen > $end) { $et->Warn('Possibly corrupt CanonVRD block'); @@ -2242,7 +2264,7 @@ files, and as a trailer in JPEG, CRW, CR2 and TIFF images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/CaptureOne.pm b/src/Image-ExifTool/lib/Image/ExifTool/CaptureOne.pm index 85f4a392..3e7e5895 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/CaptureOne.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/CaptureOne.pm @@ -221,7 +221,7 @@ settings files (COS). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Casio.pm b/src/Image-ExifTool/lib/Image/ExifTool/Casio.pm index df1af014..6cb921e7 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Casio.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Casio.pm @@ -11,7 +11,7 @@ # 3) http://homepage3.nifty.com/kamisaka/makernote/makernote_casio.htm # 4) http://gvsoft.homedns.org/exif/makernote-casio-type1.html # 5) Robert Chi private communication (EX-F1) -# 6) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3701.html +# 6) https://exiftool.org/forum/index.php/topic,3701.html # JD) Jens Duttke private communication #------------------------------------------------------------------------------ @@ -2034,7 +2034,7 @@ Casio maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Charset.pm b/src/Image-ExifTool/lib/Image/ExifTool/Charset.pm index 9486a45d..8663d000 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Charset.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Charset.pm @@ -419,7 +419,7 @@ when decoding certain types of information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatin1.pm b/src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatin1.pm new file mode 100644 index 00000000..2e3fd15b --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatin1.pm @@ -0,0 +1,49 @@ +#------------------------------------------------------------------------------ +# File: DOSLatin1.pm +# +# Description: cp850 to Unicode +# +# Revisions: 2017/10/31- P. Harvey created +# +# References: 1) http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT +# +# Notes: The table omits 1-byte characters with the same values as Unicode +#------------------------------------------------------------------------------ +use strict; + +%Image::ExifTool::Charset::DOSLatin1 = ( + 0x80 => 0x00c7, 0x81 => 0x00fc, 0x82 => 0x00e9, 0x83 => 0x00e2, + 0x84 => 0x00e4, 0x85 => 0x00e0, 0x86 => 0x00e5, 0x87 => 0x00e7, + 0x88 => 0x00ea, 0x89 => 0x00eb, 0x8a => 0x00e8, 0x8b => 0x00ef, + 0x8c => 0x00ee, 0x8d => 0x00ec, 0x8e => 0x00c4, 0x8f => 0x00c5, + 0x90 => 0x00c9, 0x91 => 0x00e6, 0x92 => 0x00c6, 0x93 => 0x00f4, + 0x94 => 0x00f6, 0x95 => 0x00f2, 0x96 => 0x00fb, 0x97 => 0x00f9, + 0x98 => 0x00ff, 0x99 => 0x00d6, 0x9a => 0x00dc, 0x9b => 0x00f8, + 0x9c => 0x00a3, 0x9d => 0x00d8, 0x9e => 0x00d7, 0x9f => 0x0192, + 0xa0 => 0x00e1, 0xa1 => 0x00ed, 0xa2 => 0x00f3, 0xa3 => 0x00fa, + 0xa4 => 0x00f1, 0xa5 => 0x00d1, 0xa6 => 0x00aa, 0xa7 => 0x00ba, + 0xa8 => 0x00bf, 0xa9 => 0x00ae, 0xaa => 0x00ac, 0xab => 0x00bd, + 0xac => 0x00bc, 0xad => 0x00a1, 0xae => 0x00ab, 0xaf => 0x00bb, + 0xb0 => 0x2591, 0xb1 => 0x2592, 0xb2 => 0x2593, 0xb3 => 0x2502, + 0xb4 => 0x2524, 0xb5 => 0x00c1, 0xb6 => 0x00c2, 0xb7 => 0x00c0, + 0xb8 => 0x00a9, 0xb9 => 0x2563, 0xba => 0x2551, 0xbb => 0x2557, + 0xbc => 0x255d, 0xbd => 0x00a2, 0xbe => 0x00a5, 0xbf => 0x2510, + 0xc0 => 0x2514, 0xc1 => 0x2534, 0xc2 => 0x252c, 0xc3 => 0x251c, + 0xc4 => 0x2500, 0xc5 => 0x253c, 0xc6 => 0x00e3, 0xc7 => 0x00c3, + 0xc8 => 0x255a, 0xc9 => 0x2554, 0xca => 0x2569, 0xcb => 0x2566, + 0xcc => 0x2560, 0xcd => 0x2550, 0xce => 0x256c, 0xcf => 0x00a4, + 0xd0 => 0x00f0, 0xd1 => 0x00d0, 0xd2 => 0x00ca, 0xd3 => 0x00cb, + 0xd4 => 0x00c8, 0xd5 => 0x0131, 0xd6 => 0x00cd, 0xd7 => 0x00ce, + 0xd8 => 0x00cf, 0xd9 => 0x2518, 0xda => 0x250c, 0xdb => 0x2588, + 0xdc => 0x2584, 0xdd => 0x00a6, 0xde => 0x00cc, 0xdf => 0x2580, + 0xe0 => 0x00d3, 0xe1 => 0x00df, 0xe2 => 0x00d4, 0xe3 => 0x00d2, + 0xe4 => 0x00f5, 0xe5 => 0x00d5, 0xe6 => 0x00b5, 0xe7 => 0x00fe, + 0xe8 => 0x00de, 0xe9 => 0x00da, 0xea => 0x00db, 0xeb => 0x00d9, + 0xec => 0x00fd, 0xed => 0x00dd, 0xee => 0x00af, 0xef => 0x00b4, + 0xf0 => 0x00ad, 0xf1 => 0x00b1, 0xf2 => 0x2017, 0xf3 => 0x00be, + 0xf4 => 0x00b6, 0xf5 => 0x00a7, 0xf6 => 0x00f7, 0xf7 => 0x00b8, + 0xf8 => 0x00b0, 0xf9 => 0x00a8, 0xfa => 0x00b7, 0xfb => 0x00b9, + 0xfc => 0x00b3, 0xfd => 0x00b2, 0xfe => 0x25a0, 0xff => 0x00a0, +); + +1; # end diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatinUS.pm b/src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatinUS.pm new file mode 100644 index 00000000..7f76823f --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Charset/DOSLatinUS.pm @@ -0,0 +1,49 @@ +#------------------------------------------------------------------------------ +# File: DOSLatinUS.pm +# +# Description: cp437 to Unicode +# +# Revisions: 2017/10/31- P. Harvey created +# +# References: 1) http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP437.TXT +# +# Notes: The table omits 1-byte characters with the same values as Unicode +#------------------------------------------------------------------------------ +use strict; + +%Image::ExifTool::Charset::DOSLatinUS = ( + 0x80 => 0x00c7, 0x81 => 0x00fc, 0x82 => 0x00e9, 0x83 => 0x00e2, + 0x84 => 0x00e4, 0x85 => 0x00e0, 0x86 => 0x00e5, 0x87 => 0x00e7, + 0x88 => 0x00ea, 0x89 => 0x00eb, 0x8a => 0x00e8, 0x8b => 0x00ef, + 0x8c => 0x00ee, 0x8d => 0x00ec, 0x8e => 0x00c4, 0x8f => 0x00c5, + 0x90 => 0x00c9, 0x91 => 0x00e6, 0x92 => 0x00c6, 0x93 => 0x00f4, + 0x94 => 0x00f6, 0x95 => 0x00f2, 0x96 => 0x00fb, 0x97 => 0x00f9, + 0x98 => 0x00ff, 0x99 => 0x00d6, 0x9a => 0x00dc, 0x9b => 0x00a2, + 0x9c => 0x00a3, 0x9d => 0x00a5, 0x9e => 0x20a7, 0x9f => 0x0192, + 0xa0 => 0x00e1, 0xa1 => 0x00ed, 0xa2 => 0x00f3, 0xa3 => 0x00fa, + 0xa4 => 0x00f1, 0xa5 => 0x00d1, 0xa6 => 0x00aa, 0xa7 => 0x00ba, + 0xa8 => 0x00bf, 0xa9 => 0x2310, 0xaa => 0x00ac, 0xab => 0x00bd, + 0xac => 0x00bc, 0xad => 0x00a1, 0xae => 0x00ab, 0xaf => 0x00bb, + 0xb0 => 0x2591, 0xb1 => 0x2592, 0xb2 => 0x2593, 0xb3 => 0x2502, + 0xb4 => 0x2524, 0xb5 => 0x2561, 0xb6 => 0x2562, 0xb7 => 0x2556, + 0xb8 => 0x2555, 0xb9 => 0x2563, 0xba => 0x2551, 0xbb => 0x2557, + 0xbc => 0x255d, 0xbd => 0x255c, 0xbe => 0x255b, 0xbf => 0x2510, + 0xc0 => 0x2514, 0xc1 => 0x2534, 0xc2 => 0x252c, 0xc3 => 0x251c, + 0xc4 => 0x2500, 0xc5 => 0x253c, 0xc6 => 0x255e, 0xc7 => 0x255f, + 0xc8 => 0x255a, 0xc9 => 0x2554, 0xca => 0x2569, 0xcb => 0x2566, + 0xcc => 0x2560, 0xcd => 0x2550, 0xce => 0x256c, 0xcf => 0x2567, + 0xd0 => 0x2568, 0xd1 => 0x2564, 0xd2 => 0x2565, 0xd3 => 0x2559, + 0xd4 => 0x2558, 0xd5 => 0x2552, 0xd6 => 0x2553, 0xd7 => 0x256b, + 0xd8 => 0x256a, 0xd9 => 0x2518, 0xda => 0x250c, 0xdb => 0x2588, + 0xdc => 0x2584, 0xdd => 0x258c, 0xde => 0x2590, 0xdf => 0x2580, + 0xe0 => 0x03b1, 0xe1 => 0x00df, 0xe2 => 0x0393, 0xe3 => 0x03c0, + 0xe4 => 0x03a3, 0xe5 => 0x03c3, 0xe6 => 0x00b5, 0xe7 => 0x03c4, + 0xe8 => 0x03a6, 0xe9 => 0x0398, 0xea => 0x03a9, 0xeb => 0x03b4, + 0xec => 0x221e, 0xed => 0x03c6, 0xee => 0x03b5, 0xef => 0x2229, + 0xf0 => 0x2261, 0xf1 => 0x00b1, 0xf2 => 0x2265, 0xf3 => 0x2264, + 0xf4 => 0x2320, 0xf5 => 0x2321, 0xf6 => 0x00f7, 0xf7 => 0x2248, + 0xf8 => 0x00b0, 0xf9 => 0x2219, 0xfa => 0x00b7, 0xfb => 0x221a, + 0xfc => 0x207f, 0xfd => 0x00b2, 0xfe => 0x25a0, 0xff => 0x00a0, +); + +1; # end diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DICOM.pm b/src/Image-ExifTool/lib/Image/ExifTool/DICOM.pm index 2075cc73..2a788385 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/DICOM.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/DICOM.pm @@ -20,7 +20,7 @@ use strict; use vars qw($VERSION %uid); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.19'; +$VERSION = '1.22'; # DICOM VR (Value Representation) format conversions my %dicomFormat = ( @@ -3759,6 +3759,8 @@ sub ProcessDICOM($$) } my $val; my $format = $dicomFormat{$vr}; + # remove trailing space used to pad to an even number of characters + $buff =~ s/ $// unless $format or length($buff) & 0x01; if ($len > 1024) { # treat large data elements as binary data my $binData; @@ -3778,13 +3780,13 @@ sub ProcessDICOM($$) $format = 'string'; if ($vr eq 'DA') { # format date values - $val =~ s/^(\d{4})(\d{2})(\d{2})/$1:$2:$3/; + $val =~ s/^ *(\d{4})(\d{2})(\d{2})/$1:$2:$3/; } elsif ($vr eq 'TM') { # format time values - $val =~ s/^(\d{2})(\d{2})(\d{2}.*)/$1:$2:$3/; + $val =~ s/^ *(\d{2})(\d{2})(\d{2}[^ ]*)/$1:$2:$3/; } elsif ($vr eq 'DT') { # format date/time values - $val =~ s/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}.*)/$1:$2:$3 $4:$5:$6/; + $val =~ s/^ *(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}[^ ]*)/$1:$2:$3 $4:$5:$6/; } elsif ($vr eq 'AT' and $len == 4) { # convert attribute tag ID to hex format my ($g, $e) = (Get16u(\$buff,0), Get16u(\$buff,2)); @@ -3793,6 +3795,11 @@ sub ProcessDICOM($$) # add PrintConv to translate registered UID's $val =~ s/\0.*//s; # truncate at null $$tagInfo{PrintConv} = \%uid if $uid{$val} and $tagInfo; + } elsif ($vr =~ /^(AE|CS|DS|IS|LO|PN|SH)$/) { + $val =~ s/ +$//; # leading/trailing spaces not significant + $val =~ s/^ +//; + } elsif ($vr =~ /^(LT|ST|UT)$/) { + $val =~ s/ +$//; # trailing spaces not significant } } # save the group 2 end position and transfer syntax @@ -3846,7 +3853,7 @@ No translation of special characters sets is done. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DJI.pm b/src/Image-ExifTool/lib/Image/ExifTool/DJI.pm new file mode 100644 index 00000000..5596fe29 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/DJI.pm @@ -0,0 +1,138 @@ +#------------------------------------------------------------------------------ +# File: DJI.pm +# +# Description: DJI Phantom maker notes tags +# +# Revisions: 2016-07-25 - P. Harvey Created +# 2017-06-23 - PH Added XMP tags +#------------------------------------------------------------------------------ + +package Image::ExifTool::DJI; + +use strict; +use vars qw($VERSION); +use Image::ExifTool::Exif; +use Image::ExifTool::XMP; +use Image::ExifTool::GPS; + +$VERSION = '1.02'; + +my %convFloat2 = ( + PrintConv => 'sprintf("%+.2f", $val)', + PrintConvInv => '$val', +); + +# DJI maker notes (ref PH, mostly educated guesses based on DJI QuickTime::UserData tags) +%Image::ExifTool::DJI::Main = ( + WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, + CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + NOTES => q{ + This table lists tags found in the maker notes of images from some DJI + Phantom drones. + }, + 0x01 => { Name => 'Make', Writable => 'string' }, + # 0x02 - int8u[4]: "1 0 0 0", "1 1 0 0" + 0x03 => { Name => 'SpeedX', Writable => 'float', %convFloat2 }, # (guess) + 0x04 => { Name => 'SpeedY', Writable => 'float', %convFloat2 }, # (guess) + 0x05 => { Name => 'SpeedZ', Writable => 'float', %convFloat2 }, # (guess) + 0x06 => { Name => 'Pitch', Writable => 'float', %convFloat2 }, + 0x07 => { Name => 'Yaw', Writable => 'float', %convFloat2 }, + 0x08 => { Name => 'Roll', Writable => 'float', %convFloat2 }, + 0x09 => { Name => 'CameraPitch',Writable => 'float', %convFloat2 }, + 0x0a => { Name => 'CameraYaw', Writable => 'float', %convFloat2 }, + 0x0b => { Name => 'CameraRoll', Writable => 'float', %convFloat2 }, +); + +%Image::ExifTool::DJI::XMP = ( + %Image::ExifTool::XMP::xmpTableDefaults, + GROUPS => { 0 => 'XMP', 1 => 'XMP-drone-dji', 2 => 'Location' }, + NAMESPACE => 'drone-dji', + TABLE_DESC => 'XMP DJI', + VARS => { NO_ID => 1 }, + NOTES => 'XMP tags used by DJI for images from drones.', + AbsoluteAltitude => { Writable => 'real' }, + RelativeAltitude => { Writable => 'real' }, + GimbalRollDegree => { Writable => 'real' }, + GimbalYawDegree => { Writable => 'real' }, + GimbalPitchDegree => { Writable => 'real' }, + FlightRollDegree => { Writable => 'real' }, + FlightYawDegree => { Writable => 'real' }, + FlightPitchDegree => { Writable => 'real' }, + GpsLatitude => { + Name => 'GPSLatitude', + Writable => 'real', + Avoid => 1, + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + }, + GpsLongtitude => { # (sic) + Name => 'GPSLongtitude', + Writable => 'real', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + }, + GpsLongitude => { #PH (NC) + Name => 'GPSLongitude', + Writable => 'real', + Avoid => 1, + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + }, + FlightXSpeed => { Writable => 'real' }, + FlightYSpeed => { Writable => 'real' }, + FlightZSpeed => { Writable => 'real' }, + CamReverse => { }, # integer? + GimbalReverse => { }, # integer? + SelfData => { Groups => { 2 => 'Image' } }, + CalibratedFocalLength => { Writable => 'real', Groups => { 2 => 'Image' } }, + CalibratedOpticalCenterX => { Writable => 'real', Groups => { 2 => 'Image' } }, + CalibratedOpticalCenterY => { Writable => 'real', Groups => { 2 => 'Image' } }, + RtkFlag => { }, # integer? + RtkStdLon => { Writable => 'real' }, + RtkStdLat => { Writable => 'real' }, + RtkStdHgt => { Writable => 'real' }, + DewarpData => { Groups => { 2 => 'Image' } }, + DewarpFlag => { Groups => { 2 => 'Image' } }, # integer? + Latitude => { + Name => 'Latitude', + Writable => 'real', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + }, + Longitude => { + Name => 'Longitude', + Writable => 'real', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + }, +); + +__END__ + +=head1 NAME + +Image::ExifTool::DJI - DJI Phantom maker notes tags + +=head1 SYNOPSIS + +This module is loaded automatically by Image::ExifTool when required. + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to interpret +the maker notes in images from some DJI Phantom drones. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/DJI Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DNG.pm b/src/Image-ExifTool/lib/Image/ExifTool/DNG.pm index 07e057be..70348bbe 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/DNG.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/DNG.pm @@ -616,7 +616,7 @@ sub ProcessAdobeIFD($$$) # parse the mutilated IFD. This is similar to a TIFF IFD, except: # - data follows directly after Count entry in IFD - # - byte order of IFD entires is always big-endian, but byte order of data changes + # - byte order of IFD entries is always big-endian, but byte order of data changes SetByteOrder('MM'); # IFD structure is always big-endian my $entries = Get16u($dataPt, $pos + 2); $et->VerboseDir($dirInfo, $entries); @@ -820,7 +820,7 @@ information in DNG (Digital Negative) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DPX.pm b/src/Image-ExifTool/lib/Image/ExifTool/DPX.pm index 0b59fa99..b2b61e9f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/DPX.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/DPX.pm @@ -160,7 +160,7 @@ metadata from DPX (Digital Picture Exchange) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DV.pm b/src/Image-ExifTool/lib/Image/ExifTool/DV.pm index 03a6c483..0b95c80e 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/DV.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/DV.pm @@ -15,7 +15,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.01'; +$VERSION = '1.02'; # DV profiles (ref 1) my @dvProfiles = ( @@ -24,7 +24,6 @@ my @dvProfiles = ( VideoSType => 0x0, FrameSize => 120000, VideoFormat => 'IEC 61834, SMPTE-314M - 525/60 (NTSC)', - VideoScanType => 'Progressive', Colorimetry => '4:1:1', FrameRate => 30000/1001, ImageHeight => 480, @@ -34,7 +33,6 @@ my @dvProfiles = ( VideoSType => 0x0, FrameSize => 144000, VideoFormat => 'IEC 61834 - 625/50 (PAL)', - VideoScanType => 'Progressive', Colorimetry => '4:2:0', FrameRate => 25/1, ImageHeight => 576, @@ -44,7 +42,6 @@ my @dvProfiles = ( VideoSType => 0x0, FrameSize => 144000, VideoFormat => 'SMPTE-314M - 625/50 (PAL)', - VideoScanType => 'Progressive', Colorimetry => '4:1:1', FrameRate => 25/1, ImageHeight => 576, @@ -54,7 +51,6 @@ my @dvProfiles = ( VideoSType => 0x4, FrameSize => 240000, VideoFormat => 'DVCPRO50: SMPTE-314M - 525/60 (NTSC) 50 Mbps', - VideoScanType => 'Progressive', Colorimetry => '4:2:2', FrameRate => 30000/1001, ImageHeight => 480, @@ -64,7 +60,6 @@ my @dvProfiles = ( VideoSType => 0x4, FrameSize => 288000, VideoFormat => 'DVCPRO50: SMPTE-314M - 625/50 (PAL) 50 Mbps', - VideoScanType => 'Progressive', Colorimetry => '4:2:2', FrameRate => 25/1, ImageHeight => 576, @@ -74,7 +69,6 @@ my @dvProfiles = ( VideoSType => 0x14, FrameSize => 480000, VideoFormat => 'DVCPRO HD: SMPTE-370M - 1080i60 100 Mbps', - VideoScanType => 'Interlaced', Colorimetry => '4:2:2', FrameRate => 30000/1001, ImageHeight => 1080, @@ -84,7 +78,6 @@ my @dvProfiles = ( VideoSType => 0x14, FrameSize => 576000, VideoFormat => 'DVCPRO HD: SMPTE-370M - 1080i50 100 Mbps', - VideoScanType => 'Interlaced', Colorimetry => '4:2:2', FrameRate => 25/1, ImageHeight => 1080, @@ -94,7 +87,6 @@ my @dvProfiles = ( VideoSType => 0x18, FrameSize => 240000, VideoFormat => 'DVCPRO HD: SMPTE-370M - 720p60 100 Mbps', - VideoScanType => 'Progressive', Colorimetry => '4:2:2', FrameRate => 60000/1001, ImageHeight => 720, @@ -104,7 +96,6 @@ my @dvProfiles = ( VideoSType => 0x18, FrameSize => 288000, VideoFormat => 'DVCPRO HD: SMPTE-370M - 720p50 100 Mbps', - VideoScanType => 'Progressive', Colorimetry => '4:2:2', FrameRate => 50/1, ImageHeight => 720, @@ -114,7 +105,6 @@ my @dvProfiles = ( VideoSType => 0x1, FrameSize => 144000, VideoFormat => 'IEC 61883-5 - 625/50 (PAL)', - VideoScanType => 'Progressive', Colorimetry => '4:2:0', FrameRate => 25/1, ImageHeight => 576, @@ -136,6 +126,7 @@ my @dvTags = ( VARS => { NO_ID => 1 }, NOTES => 'The following tags are extracted from DV videos.', DateTimeOriginal => { + Description => 'Date/Time Original', Groups => { 2 => 'Time' }, PrintConv => '$self->ConvertDateTime($val)', }, @@ -182,7 +173,7 @@ sub ProcessDV($$) $et->SetFileType(); my $pos = $start; - my $dsf = Get8u(\$buff, $pos + 3) & 0x80 >> 7; + my $dsf = (Get8u(\$buff, $pos + 3) & 0x80) >> 7; my $stype = Get8u(\$buff, $pos + 80*5 + 48 + 3) & 0x1f; # 576i50 25Mbps 4:1:1 is a special case @@ -207,7 +198,8 @@ sub ProcessDV($$) # read DVPack metadata from the VAUX DIF's to extract video tags delete $$profile{DateTimeOriginal}; delete $$profile{AspectRatio}; - my ($date, $time, $is16_9); + delete $$profile{VideoScanType}; + my ($date, $time, $is16_9, $interlace); for ($i=1; $i<6; ++$i) { $pos += 80; my $type = Get8u(\$buff, $pos); @@ -219,6 +211,7 @@ sub ProcessDV($$) my $apt = Get8u(\$buff, $start + 4) & 0x07; my $t = Get8u(\$buff, $p + 2); $is16_9 = (($t & 0x07) == 0x02 or (not $apt and ($t & 0x07) == 0x07)); + $interlace = Get8u(\$buff, $p + 3) & 0x10; # (ref 2) } elsif ($type == 0x62) { # date # mask off unused bits my @d = unpack('C*', substr($buff, $p + 1, 4)); @@ -244,7 +237,10 @@ sub ProcessDV($$) } if ($date and $time) { $$profile{DateTimeOriginal} = "$date $time"; - $$profile{AspectRatio} = $is16_9 ? '16:9' : '5:4' if defined $is16_9; + if (defined $is16_9) { + $$profile{AspectRatio} = $is16_9 ? '16:9' : '4:3'; + $$profile{VideoScanType} = $interlace ? 'Interlaced' : 'Progressive'; + } } # read audio tags if available @@ -295,7 +291,7 @@ information from DV (raw Digital Video) files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DarwinCore.pm b/src/Image-ExifTool/lib/Image/ExifTool/DarwinCore.pm index e0aed749..ee13dd25 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/DarwinCore.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/DarwinCore.pm @@ -6,7 +6,7 @@ # Revisions: 2013-01-28 - P. Harvey Created # # References: 1) http://rs.tdwg.org/dwc/index.htm -# 2) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4442.0/all.html +# 2) https://exiftool.org/forum/index.php/topic,4442.0/all.html #------------------------------------------------------------------------------ package Image::ExifTool::DarwinCore; @@ -341,7 +341,7 @@ This file contains tag definitions for the Darwin Core XMP namespace. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/DjVu.pm b/src/Image-ExifTool/lib/Image/ExifTool/DjVu.pm index 13a2006e..4c493091 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/DjVu.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/DjVu.pm @@ -235,8 +235,7 @@ Tok: for (;;) { pos($$dataPt) = pos($$dataPt) - 1; # allow anything in key but whitespace, braces and double quotes # (this is one of those assumptions I mentioned) - $$dataPt =~ /([^\s()"]+)/sg; - $tok = $1; + $tok = $$dataPt =~ /([^\s()"]+)/sg ? $1 : undef; } push @toks, $tok if defined $tok; } @@ -353,7 +352,7 @@ Image::ExifTool::AIFF. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/EXE.pm b/src/Image-ExifTool/lib/Image/ExifTool/EXE.pm index cc899dba..c31fe238 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/EXE.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/EXE.pm @@ -21,7 +21,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.15'; +$VERSION = '1.16'; sub ProcessPEResources($$); sub ProcessPEVersion($$); @@ -52,6 +52,10 @@ my %resourceType = ( ); my %languageCode = ( + Notes => q{ + See L<https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid> + for the full list of Microsoft language codes. + }, '0000' => 'Neutral', '007F' => 'Invariant', '0400' => 'Process default', @@ -397,7 +401,7 @@ my %languageCode = ( existing StringFileInfo tags even if not listed in this table. }, LanguageCode => { - Notes => 'extracted from the StringFileInfo value', + Notes => 'Windows code page; extracted from the StringFileInfo value', # ref http://techsupt.winbatch.com/TS/T000001050F49.html # (also see http://support.bigfix.com/fixlet/documents/WinInspectors-2006-08-10.pdf) # (also see ftp://ftp.dyu.edu.tw/pub/cpatch/faq/tech/tech_nlsnt.txt) @@ -1362,7 +1366,7 @@ sub ProcessEXE($$) python => 'py', ruby => 'rb', php => 'php', - }->{$1}; + }->{$prog}; # use '.sh' for extension of all shell scripts $ext = $prog =~ /sh$/ ? 'sh' : '' unless defined $ext; } @@ -1391,7 +1395,7 @@ library files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Exif.pm b/src/Image-ExifTool/lib/Image/ExifTool/Exif.pm index a516f866..97b5fa2f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Exif.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Exif.pm @@ -42,6 +42,7 @@ # 29) http://www.libtiff.org # 30) http://geotiff.maptools.org/spec/geotiffhome.html # 31) https://android.googlesource.com/platform/external/dng_sdk/+/refs/heads/master/source/dng_tag_codes.h +# 32) Jeffry Friedl private communication # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication #------------------------------------------------------------------------------ @@ -55,7 +56,7 @@ use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::MakerNotes; -$VERSION = '4.07'; +$VERSION = '4.29'; sub ProcessExif($$$); sub WriteExif($$$); @@ -67,6 +68,7 @@ sub ValidateImageData($$$;$); sub ProcessTiffIFD($$$); sub PrintParameter($$$); sub GetOffList($$$$$); +sub PrintOpcode($$$); sub PrintLensInfo($); sub ConvertLensInfo($); @@ -262,6 +264,7 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; } 32845 => 'Pixar LogLuv', #3 32892 => 'Sequential Color Filter', #JR (Sony ARQ) 34892 => 'Linear Raw', #2 + 51177 => 'Depth Map', # (DNG 1.5) ); %orientation = ( @@ -276,7 +279,7 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; } ); %subfileType = ( - 0 => 'Full-resolution Image', + 0 => 'Full-resolution image', 1 => 'Reduced-resolution image', 2 => 'Single page of multi-page image', 3 => 'Single page of multi-page reduced-resolution image', @@ -284,14 +287,17 @@ sub BINARY_DATA_LIMIT { return 10 * 1024 * 1024; } 5 => 'Transparency mask of reduced-resolution image', 6 => 'Transparency mask of multi-page image', 7 => 'Transparency mask of reduced-resolution multi-page image', + 8 => 'Depth map', # (DNG 1.5) + 9 => 'Depth map of reduced-resolution image', # (DNG 1.5) + 16 => 'Enhanced image data', # (DNG 1.5) 0x10001 => 'Alternate reduced-resolution image', # (DNG 1.2) 0xffffffff => 'invalid', #(found in E5700 NEF's) BITMASK => { 0 => 'Reduced resolution', 1 => 'Single page', 2 => 'Transparency mask', - 3 => 'TIFF/IT final page', #20 - 4 => 'TIFF-FX mixed raster content', #20 + 3 => 'TIFF/IT final page', #20 (repurposed as DepthMap repurposes by DNG 1.5) + 4 => 'TIFF-FX mixed raster content', #20 (repurposed as EnhancedImageData by DNG 1.5) }, ); @@ -336,6 +342,33 @@ my %sampleFormat = ( 0x115 => 1, # SamplesPerPixel ); +# conversions for DNG OpcodeList tags +my %opcodeInfo = ( + Writable => 'undef', + WriteGroup => 'SubIFD', + Protected => 1, + Binary => 1, + ConvertBinary => 1, # needed because the ValueConv value is binary + PrintConvColumns => 2, + PrintConv => { + OTHER => \&PrintOpcode, + 1 => 'WarpRectilinear', + 2 => 'WarpFisheye', + 3 => 'FixVignetteRadial', + 4 => 'FixBadPixelsConstant', + 5 => 'FixBadPixelsList', + 6 => 'TrimBounds', + 7 => 'MapTable', + 8 => 'MapPolynomial', + 9 => 'GainMap', + 10 => 'DeltaPerRow', + 11 => 'DeltaPerColumn', + 12 => 'ScalePerRow', + 13 => 'ScalePerColumn', + }, + PrintConvInv => undef, # (so the inverse conversion is not performed) +); + # main EXIF tag table %Image::ExifTool::Exif::Main = ( GROUPS => { 0 => 'EXIF', 1 => 'IFD0', 2 => 'Image'}, @@ -404,7 +437,7 @@ my %sampleFormat = ( Writable => 'int32u', WriteGroup => 'IFD0', # Note: priority 0 tags automatically have their priority increased for the - # priority direcory (the directory with a SubfileType of "Full-resolution image") + # priority directory (the directory with a SubfileType of "Full-resolution image") Priority => 0, }, 0x101 => { @@ -530,7 +563,7 @@ my %sampleFormat = ( # (APP1 IFD2 is for Leica JPEG preview) Condition => q[ not ($$self{TIFF_TYPE} eq 'CR2' and $$self{DIR_NAME} eq 'IFD0') and - not ($$self{TIFF_TYPE} eq 'DNG' and $$self{Compression} eq '7' and $$self{SubfileType} ne '0') and + not ($$self{TIFF_TYPE} =~ /^(DNG|TIFF)$/ and $$self{Compression} eq '7' and $$self{SubfileType} ne '0') and not ($$self{TIFF_TYPE} eq 'APP1' and $$self{DIR_NAME} eq 'IFD2') ], Name => 'StripOffsets', @@ -616,7 +649,7 @@ my %sampleFormat = ( # (APP1 IFD2 is for Leica JPEG preview) Condition => q[ not ($$self{TIFF_TYPE} eq 'CR2' and $$self{DIR_NAME} eq 'IFD0') and - not ($$self{TIFF_TYPE} eq 'DNG' and $$self{Compression} eq '7' and $$self{SubfileType} ne '0') and + not ($$self{TIFF_TYPE} =~ /^(DNG|TIFF)$/ and $$self{Compression} eq '7' and $$self{SubfileType} ne '0') and not ($$self{TIFF_TYPE} eq 'APP1' and $$self{DIR_NAME} eq 'IFD2') ], Name => 'StripByteCounts', @@ -786,7 +819,8 @@ my %sampleFormat = ( Name => 'Software', Writable => 'string', WriteGroup => 'IFD0', - RawConv => '$val =~ s/\s+$//; $val', # trim trailing blanks + DataMember => 'Software', + RawConv => '$val =~ s/\s+$//; $$self{Software} = $val', # trim trailing blanks }, 0x132 => { Name => 'ModifyDate', @@ -820,6 +854,11 @@ my %sampleFormat = ( PrintConv => { 1 => 'None', 2 => 'Horizontal differencing', + 3 => 'Floating point', # (DNG 1.5) + 34892 => 'Horizontal difference X2', # (DNG 1.5) + 34893 => 'Horizontal difference X4', # (DNG 1.5) + 34894 => 'Floating point X2', # (DNG 1.5) + 34895 => 'Floating point X4', # (DNG 1.5) }, }, 0x13e => { @@ -1479,6 +1518,22 @@ my %sampleFormat = ( WriteGroup => 'SubIFD', Count => 17, }, + 0x74c7 => { #IB (in ARW images from some Sony cameras) + Name => 'SonyCropTopLeft', + Writable => 'int32u', + WriteGroup => 'SubIFD', + Count => 2, + Permanent => 1, + Protected => 1, + }, + 0x74c8 => { #IB (in ARW images from some Sony cameras) + Name => 'SonyCropSize', + Writable => 'int32u', + WriteGroup => 'SubIFD', + Count => 2, + Permanent => 1, + Protected => 1, + }, 0x800d => 'ImageID', #10 0x80a3 => { Name => 'WangTag1', Binary => 1 }, #20 0x80a4 => { Name => 'WangAnnotation', Binary => 1 }, @@ -1542,19 +1597,6 @@ my %sampleFormat = ( Format => 'undef', Writable => 'string', WriteGroup => 'IFD0', - RawConvInv => '$val . "\0"', - PrintConvInv => sub { - my ($val, $self) = @_; - # encode if necessary (not automatic because Format is 'undef') - my $enc = $self->Options('CharsetEXIF'); - $val = $self->Encode($val,$enc) if $enc and $val !~ /\0/; - if ($val =~ /(.*?)\s*[\n\r]+\s*(.*)/s) { - return $1 unless length $2; - # photographer copyright set to ' ' if it doesn't exist, according to spec. - return((length($1) ? $1 : ' ') . "\0" . $2); - } - return $val; - }, Notes => q{ may contain copyright notices for photographer and editor, separated by a newline. As per the EXIF specification, the newline is replaced by a null @@ -1576,6 +1618,19 @@ my %sampleFormat = ( $val = $self->Decode($val,$enc) if $enc; return $val; }, + RawConvInv => '$val . "\0"', + PrintConvInv => sub { + my ($val, $self) = @_; + # encode if necessary (not automatic because Format is 'undef') + my $enc = $self->Options('CharsetEXIF'); + $val = $self->Encode($val,$enc) if $enc and $val !~ /\0/; + if ($val =~ /(.*?)\s*[\n\r]+\s*(.*)/s) { + return $1 unless length $2; + # photographer copyright set to ' ' if it doesn't exist, according to spec. + return((length($1) ? $1 : ' ') . "\0" . $2); + } + return $val; + }, }, 0x829a => { Name => 'ExposureTime', @@ -1600,7 +1655,12 @@ my %sampleFormat = ( 0x82aa => 'MDPrepDate', #3 0x82ab => 'MDPrepTime', #3 0x82ac => 'MDFileUnits', #3 - 0x830e => 'PixelScale', #30 + 0x830e => { #30 (GeoTiff) + Name => 'PixelScale', + Writable => 'double', + WriteGroup => 'IFD0', + Count => 3, + }, 0x8335 => 'AdventScale', #20 0x8336 => 'AdventRevision', #20 0x835c => 'UIC1Tag', #23 @@ -1627,11 +1687,19 @@ my %sampleFormat = ( }, 0x847e => 'IntergraphPacketData', #3 0x847f => 'IntergraphFlagRegisters', #3 - 0x8480 => 'IntergraphMatrix', #30 + 0x8480 => { #30 (GeoTiff, obsolete) + Name => 'IntergraphMatrix', + Writable => 'double', + WriteGroup => 'IFD0', + Count => -1, + }, 0x8481 => 'INGRReserved', #20 - 0x8482 => { #30 + 0x8482 => { #30 (GeoTiff) Name => 'ModelTiePoint', Groups => { 2 => 'Location' }, + Writable => 'double', + WriteGroup => 'IFD0', + Count => -1, }, 0x84e0 => 'Site', #9 0x84e1 => 'ColorSequence', #9 @@ -1694,9 +1762,12 @@ my %sampleFormat = ( }, 0x85b8 => 'PixelMagicJBIGOptions', #20 0x85d7 => 'JPLCartoIFD', #exifprobe (NC) - 0x85d8 => { #30 + 0x85d8 => { #30 (GeoTiff) Name => 'ModelTransform', Groups => { 2 => 'Location' }, + Writable => 'double', + WriteGroup => 'IFD0', + Count => 16, }, 0x8602 => { #16 Name => 'WB_GRGBLevels', @@ -1776,14 +1847,14 @@ my %sampleFormat = ( 0x87af => { #30 Name => 'GeoTiffDirectory', Format => 'undef', - Binary => 1, + Writable => 'int16u', Notes => q{ these "GeoTiff" tags may read and written as a block, but they aren't extracted unless specifically requested. Byte order changes are handled automatically when copying between TIFF images with different byte order }, - Writable => 'undef', WriteGroup => 'IFD0', + Binary => 1, RawConv => '$val . GetByteOrder()', # save byte order # swap byte order if necessary RawConvInv => q{ @@ -1798,9 +1869,9 @@ my %sampleFormat = ( 0x87b0 => { #30 Name => 'GeoTiffDoubleParams', Format => 'undef', - Binary => 1, - Writable => 'undef', + Writable => 'double', WriteGroup => 'IFD0', + Binary => 1, RawConv => '$val . GetByteOrder()', # save byte order # swap byte order if necessary RawConvInv => q{ @@ -1815,6 +1886,7 @@ my %sampleFormat = ( }, 0x87b1 => { #30 Name => 'GeoTiffAsciiParams', + Format => 'undef', Writable => 'string', WriteGroup => 'IFD0', Binary => 1, @@ -1942,7 +2014,8 @@ my %sampleFormat = ( Writable => 'undef', Mandatory => 1, RawConv => '$val=~s/\0+$//; $val', # (some idiots add null terminators) - PrintConvInv => '$val=~tr/.//d; $val=~/^\d{4}$/ ? $val : undef', + # (allow strings like "2.31" when writing) + PrintConvInv => '$val=~tr/.//d; $val=~/^\d{4}$/ ? $val : $val =~ /^\d{3}$/ ? "0$val" : undef', }, 0x9003 => { Name => 'DateTimeOriginal', @@ -2518,11 +2591,11 @@ my %sampleFormat = ( PrintConv => { 0 => 'Normal', 1 => 'Custom', - # 2 - also seen (Apple iOS) - 3 => 'HDR', # non-standard (Apple iOS) - # 4 - also seen (Apple iOS) - normal image from iOS Camera app (ref http://regex.info/blog/lightroom-goodies/metadata-presets) + 2 => 'HDR (no original saved)', #32 non-standard (Apple iOS) + 3 => 'HDR (original saved)', #32 non-standard (Apple iOS) + 4 => 'Original (for HDR)', #32 non-standard (Apple iOS) 6 => 'Panorama', # non-standard (Apple iOS, horizontal or vertical) - # 7 - also seen (Apple iOS) + 7 => 'Portrait HDR', #32 non-standard (Apple iOS) 8 => 'Portrait', # non-standard (Apple iOS, blurred background) # 9 - also seen (Apple iOS) (HDR Portrait?) }, @@ -2568,12 +2641,13 @@ my %sampleFormat = ( Name => 'SceneCaptureType', Groups => { 2 => 'Camera' }, Writable => 'int16u', + Notes => 'the value of 4 is non-standard, and used by some Samsung models', PrintConv => { 0 => 'Standard', 1 => 'Landscape', 2 => 'Portrait', 3 => 'Night', - # 4 - HDR (Samsung GT-I9300) + 4 => 'Other', # (non-standard Samsung, ref forum 5724) }, }, 0xa407 => { @@ -2665,15 +2739,85 @@ my %sampleFormat = ( 0xa433 => { Name => 'LensMake', Writable => 'string' }, #24 0xa434 => { Name => 'LensModel', Writable => 'string' }, #24 0xa435 => { Name => 'LensSerialNumber', Writable => 'string' }, #24 - 0xa480 => 'GDALMetadata', #3 - 0xa481 => 'GDALNoData', #3 - 0xa500 => { Name => 'Gamma', Writable => 'rational64u' }, + 0xa460 => { #Exif2.32 + Name => 'CompositeImage', + Writable => 'int16u', + PrintConv => { + 0 => 'Unknown', + 1 => 'Not a Composite Image', + 2 => 'General Composite Image', + 3 => 'Composite Image Captured While Shooting', + }, + }, + 0xa461 => { #Exif2.32 + Name => 'CompositeImageCount', + Notes => q{ + 2 values: 1. Number of source images, 2. Number of images used. Called + SourceImageNumberOfCompositeImage by the EXIF spec. + }, + Writable => 'int16u', + Count => 2, + }, + 0xa462 => { #Exif2.32 + Name => 'CompositeImageExposureTimes', + Notes => q{ + 11 or more values: 1. Total exposure time period, 2. Total exposure of all + source images, 3. Total exposure of all used images, 4. Max exposure time of + source images, 5. Max exposure time of used images, 6. Min exposure time of + source images, 7. Min exposure of used images, 8. Number of sequences, 9. + Number of source images in sequence. 10-N. Exposure times of each source + image. Called SourceExposureTimesOfCompositeImage by the EXIF spec. + }, + Writable => 'undef', + RawConv => sub { + my $val = shift; + my @v; + my $i = 0; + for (;;) { + if ($i == 56 or $i == 58) { + last if $i + 2 > length $val; + push @v, Get16u(\$val, $i); + $i += 2; + } else { + last if $i + 8 > length $val; + push @v, Image::ExifTool::GetRational64u(\$val, $i); + $i += 8; + } + } + return join ' ', @v; + }, + RawConvInv => sub { + my $val = shift; + my @v = split ' ', $val; + my $i; + for ($i=0; ; ++$i) { + last unless defined $v[$i]; + $v[$i] = ($i == 7 or $i == 8) ? Set16u($v[$i]) : Image::ExifTool::SetRational64u($v[$i]); + } + return join '', @v; + }, + PrintConv => sub { + my $val = shift; + my @v = split ' ', $val; + my $i; + for ($i=0; ; ++$i) { + last unless defined $v[$i]; + $v[$i] = PrintExposureTime($v[$i]) unless $i == 7 or $i == 8; + } + return join ' ', @v; + }, + PrintConvInv => '$val', + }, + 0xa480 => { Name => 'GDALMetadata', Writable => 'string', WriteGroup => 'IFD0' }, #3 + 0xa481 => { Name => 'GDALNoData', Writable => 'string', WriteGroup => 'IFD0' }, #3 + 0xa500 => { Name => 'Gamma', Writable => 'rational64u' }, 0xafc0 => 'ExpandSoftware', #JD (Opanda) 0xafc1 => 'ExpandLens', #JD (Opanda) 0xafc2 => 'ExpandFilm', #JD (Opanda) 0xafc3 => 'ExpandFilterLens', #JD (Opanda) 0xafc4 => 'ExpandScanner', #JD (Opanda) 0xafc5 => 'ExpandFlashLamp', #JD (Opanda) + 0xb4c3 => { Name => 'HasselbladRawImage', Format => 'undef', Binary => 1 }, #IB # # Windows Media Photo / HD Photo (WDP/HDP) tags # @@ -2836,6 +2980,16 @@ my %sampleFormat = ( }, PrintConvInv => '$val =~ /^PrintIM/ ? $val : undef', # quick validation }, + 0xc51b => { # (Hasselblad H3D) + Name => 'HasselbladExif', + Format => 'undef', + RawConv => q{ + $$self{DOC_NUM} = ++$$self{DOC_COUNT}; + $self->ExtractInfo(\$val, { ReEntry => 1 }); + $$self{DOC_NUM} = 0; + return undef; + }, + }, 0xc573 => { #PH Name => 'OriginalFileName', Notes => 'used by some obscure software', # (possibly Swizzy Photosmacker?) @@ -3130,7 +3284,7 @@ my %sampleFormat = ( Groups => { 1 => 'SR2' }, Flags => 'SubIFD', Format => 'int32u', - # some utilites have problems unless this is int8u format: + # some utilities have problems unless this is int8u format: # - Adobe Camera Raw 5.3 gives an error # - Apple Preview 10.5.8 gets the wrong white balance FixFormat => 'int8u', # (stupid Sony) @@ -3192,6 +3346,23 @@ my %sampleFormat = ( }, Format => 'undef', }, + { + # Ricoh models such as the GR III + Condition => '$$valPt =~ /^RICOH\0(II|MM)/', + Name => 'MakerNoteRicohPentax', + MakerNotes => 1, + Binary => 1, + WriteGroup => 'IFD0', # (for Validate) + SubDirectory => { + TagTable => 'Image::ExifTool::Pentax::Main', + Start => '$valuePtr + 8', + Base => '$start - 8', + ByteOrder => 'Unknown', + }, + Format => 'undef', + }, + # the DJI FC2103 writes some interesting stuff here (with sections labelled + # awb_dbg_info, ae_dbg_info, ae_histogram_info, af_dbg_info, hiso, xidiri) - PH { Name => 'DNGPrivateData', Flags => [ 'Binary', 'Protected' ], @@ -3566,41 +3737,9 @@ my %sampleFormat = ( Protected => 1, Binary => 1, }, - 0xc740 => { # DNG 1.3 - Name => 'OpcodeList1', - Writable => 'undef', - WriteGroup => 'SubIFD', - Protected => 1, - Binary => 1, - # opcodes: - # 1 => 'WarpRectilinear', - # 2 => 'WarpFisheye', - # 3 => 'FixVignetteRadial', - # 4 => 'FixBadPixelsConstant', - # 5 => 'FixBadPixelsList', - # 6 => 'TrimBounds', - # 7 => 'MapTable', - # 8 => 'MapPolynomial', - # 9 => 'GainMap', - # 10 => 'DeltaPerRow', - # 11 => 'DeltaPerColumn', - # 12 => 'ScalePerRow', - # 13 => 'ScalePerColumn', - }, - 0xc741 => { # DNG 1.3 - Name => 'OpcodeList2', - Writable => 'undef', - WriteGroup => 'SubIFD', - Protected => 1, - Binary => 1, - }, - 0xc74e => { # DNG 1.3 - Name => 'OpcodeList3', - Writable => 'undef', - WriteGroup => 'SubIFD', - Protected => 1, - Binary => 1, - }, + 0xc740 => { Name => 'OpcodeList1', %opcodeInfo }, # DNG 1.3 + 0xc741 => { Name => 'OpcodeList2', %opcodeInfo }, # DNG 1.3 + 0xc74e => { Name => 'OpcodeList3', %opcodeInfo }, # DNG 1.3 0xc761 => { # DNG 1.3 Name => 'NoiseProfile', Writable => 'double', @@ -3823,6 +3962,68 @@ my %sampleFormat = ( Count => 4, Protected => 1, }, + 0xc7d5 => { #PH (in SubIFD1 of Nikon Z6/Z7 NEF images) + Name => 'NikonNEFInfo', + Condition => '$$valPt =~ /^Nikon\0/', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::NEFInfo', + Start => '$valuePtr + 18', + Base => '$start - 8', + ByteOrder => 'Unknown', + }, + }, + # 0xc7d6 - int8u: 1 (SubIFD1 of Nikon Z6/Z7 NEF) + 0xc7e9 => { # DNG 1.5 + Name => 'DepthFormat', + Writable => 'int16u', + Notes => 'tags 0xc7e9-0xc7ee added by DNG 1.5.0.0', + Protected => 1, + WriteGroup => 'IFD0', + PrintConv => { + 0 => 'Unknown', + 1 => 'Linear', + 2 => 'Inverse', + }, + }, + 0xc7ea => { # DNG 1.5 + Name => 'DepthNear', + Writable => 'rational64u', + Protected => 1, + WriteGroup => 'IFD0', + }, + 0xc7eb => { # DNG 1.5 + Name => 'DepthFar', + Writable => 'rational64u', + Protected => 1, + WriteGroup => 'IFD0', + }, + 0xc7ec => { # DNG 1.5 + Name => 'DepthUnits', + Writable => 'int16u', + Protected => 1, + WriteGroup => 'IFD0', + PrintConv => { + 0 => 'Unknown', + 1 => 'Meters', + }, + }, + 0xc7ed => { # DNG 1.5 + Name => 'DepthMeasureType', + Writable => 'int16u', + Protected => 1, + WriteGroup => 'IFD0', + PrintConv => { + 0 => 'Unknown', + 1 => 'Optical Axis', + 2 => 'Optical Ray', + }, + }, + 0xc7ee => { # DNG 1.5 + Name => 'EnhanceParams', + Writable => 'string', + Protected => 1, + WriteGroup => 'IFD0', + }, 0xea1c => { #13 Name => 'Padding', Binary => 1, @@ -3867,7 +4068,7 @@ my %sampleFormat = ( # tags in the range 0xfde8-0xfe58 have been observed in PS7 files # generated from RAW images. They are all strings with the - # tag name at the start of the string. To accomodate these types + # tag name at the start of the string. To accommodate these types # of tags, all tags with values above 0xf000 are handled specially # by ProcessExif(). 0xfde8 => { @@ -4012,8 +4213,8 @@ my %subSecConv = ( my $v; if (defined $val[1] and $val[1]=~/^(\d+)/) { my $subSec = $1; - # be careful here just in case the time already contains a timezone (contrary to spec) - undef $v unless ($v = $val[0]) =~ s/( \d{2}:\d{2}:\d{2})/$1\.$subSec/; + # be careful here just in case the time already contains sub-seconds or a timezone (contrary to spec) + undef $v unless ($v = $val[0]) =~ s/( \d{2}:\d{2}:\d{2})(?!\.\d+)/$1\.$subSec/; } if (defined $val[2] and $val[0]!~/[-+]/ and $val[2]=~/^([-+])(\d{1,2}):(\d{2})/) { $v = ($v || $val[0]) . sprintf('%s%.2d:%.2d', $1, $2, $3); @@ -4035,14 +4236,17 @@ my %subSecConv = ( Desire => { 2 => 'ExifImageWidth', 3 => 'ExifImageHeight', + 4 => 'RawImageCroppedSize', # (FujiFilm RAF images) }, # use ExifImageWidth/Height only for Canon and Phase One TIFF-base RAW images ValueConv => q{ - return "$val[2]x$val[3]" if $val[2] and $val[3] and + return $val[4] if $val[4]; + return "$val[2] $val[3]" if $val[2] and $val[3] and $$self{TIFF_TYPE} =~ /^(CR2|Canon 1D RAW|IIQ|EIP)$/; - return "$val[0]x$val[1]" if IsFloat($val[0]) and IsFloat($val[1]); + return "$val[0] $val[1]" if IsFloat($val[0]) and IsFloat($val[1]); return undef; }, + PrintConv => '$val =~ tr/ /x/; $val', }, Megapixels => { Require => 'ImageSize', @@ -4522,7 +4726,8 @@ my %subSecConv = ( 7 => 'LensFocalRange', 8 => 'LensSpec', 9 => 'LensType2', - 10 => 'LensFocalLength', # (for Pentax to check for converter) + 10 => 'LensType3', + 11 => 'LensFocalLength', # (for Pentax to check for converter) }, Notes => q{ attempt to identify the actual lens from all lenses with a given LensType. @@ -4540,15 +4745,21 @@ my %subSecConv = ( PrintConv => q{ my $pcv; # use LensType2 instead of LensType if available and valid (Sony E-mount lenses) - if ($val[9] and $val[9] & 0x8000) { + # (0x8000 or greater; 0 for several older/3rd-party E-mount lenses) + if (defined $val[9] and ($val[9] & 0x8000 or $val[9] == 0)) { $val[0] = $val[9]; $prt[0] = $prt[9]; + # Particularly GM lenses: often LensType2=0 but LensType3 is available and valid: use LensType3. + if ($val[9] == 0 and $val[10] & 0x8000) { + $val[0] = $val[10]; + $prt[0] = $prt[10]; + } $pcv = $$self{TAG_INFO}{LensType2}{PrintConv}; } my $lens = Image::ExifTool::Exif::PrintLensID($self, $prt[0], $pcv, $prt[8], @val); # check for use of lens converter (Pentax K-3) - if ($val[10] and $val[1] and $lens) { - my $conv = $val[1] / $val[10]; + if ($val[11] and $val[1] and $lens) { + my $conv = $val[1] / $val[11]; $lens .= sprintf(' + %.1fx converter', $conv) if $conv > 1.1; } return $lens; @@ -4762,7 +4973,7 @@ sub ConvertExifText($$;$$) $type = $1; $str = $et->Decode($str, 'JIS', 'Unknown'); } else { - $tag = $asciiFlex if $asciiFlex and $asciiFlex ne 1; + $tag = $asciiFlex if $asciiFlex and $asciiFlex ne '1'; $et->Warn('Invalid EXIF text encoding' . ($tag ? " for $tag" : '')); $str = $id . $str; } @@ -4945,6 +5156,27 @@ sub PrintCFAPattern($) return $rtnVal . ']'; } +#------------------------------------------------------------------------------ +# Print Opcode List +# Inputs: 0) value, 1) flag for inverse conversion, 2) conversion hash reference +# Returns: converted value +sub PrintOpcode($$$) +{ + my ($val, $inv, $conv) = @_; + return undef if $inv; # (can't do inverse conversion) + return '' unless length $$val > 4; + my $num = unpack('N', $$val); + my $pos = 4; + my ($i, @ops); + for ($i=0; $i<$num; ++$i) { + $pos + 16 <= length $$val or push(@ops, '<err>'), last; + my ($op, $ver, $flags, $len) = unpack("x${pos}N4", $$val); + push @ops, $$conv{$op} || "[opcode $op]"; + $pos += 16 + $len; + } + return join ', ', @ops; +} + #------------------------------------------------------------------------------ # Print conversion for lens info # Inputs: 0) string of values (min focal, max focal, min F, max F) @@ -4992,12 +5224,44 @@ sub GetLensInfo($;$) return @a; } +#------------------------------------------------------------------------------ +# Match lens in list of possbilities based on value of LensModel +# Inputs: 0) reference to list of possible models, 1) LensModel string +# - updates list on return; guaranteed not to remove all list entries +sub MatchLensModel($$) +{ + my ($try, $lensModel) = @_; + if (@$try > 1 and $lensModel) { + my (@filt, $pat); + # filter by focal length + if ($lensModel =~ /((\d+-)?\d+mm)/) { + my $focal = $1; + @filt = grep /$focal/, @$try; + @$try = @filt if @filt and @filt < @$try; + } + # filter by aperture + if (@$try > 1 and $lensModel =~ m{(?:F/?|1:)(\d+(\.\d+)?)}i) { + my $fnum = $1; + @filt = grep m{(F/?|1:)$fnum(\b|[A-Z])}i, @$try; + @$try = @filt if @filt and @filt < @$try; + } + # filter by model version, and other lens parameters + foreach $pat ('I+', 'USM') { + next unless @$try > 1 and $lensModel =~ /\b($pat)\b/; + my $val = $1; + @filt = grep /\b$val\b/, @$try; + @$try = @filt if @filt and @filt < @$try; + } + } +} + #------------------------------------------------------------------------------ # Attempt to identify the specific lens if multiple lenses have the same LensType # Inputs: 0) ExifTool object ref, 1) LensType print value, 2) PrintConv hash ref, # 3) LensSpec print value, 4) LensType numerical value, 5) FocalLength, # 6) MaxAperture, 7) MaxApertureValue, 8) MinFocalLength, 9) MaxFocalLength, # 10) LensModel, 11) LensFocalRange, 12) LensSpec +my %sonyEtype; sub PrintLensID($$@) { my ($et, $lensTypePrt, $printConv, $lensSpecPrt, $lensType, $focalLength, @@ -5032,12 +5296,27 @@ sub PrintLensID($$@) ($shortFocal, $longFocal) = ($1, $2 || $1); } if ($$et{Make} eq 'SONY') { - # Patch for Metabones or other adapters on Sony E-mount cameras (ref Jos Roost) - # Metabones Canon EF to E-mount adapters add 0xef00, 0xbc00 or 0x7700 to the - # high byte for 2-byte Canon LensType values, so we need to adjust for these. - # Offset 0xef00 is also used by Sigma MC-11, Fotodiox and Viltrox EF-E adapters. - # Have to exclude A-mount Sigma Filtermatic with 'odd' LensType=0xff00. - if ($lensType != 0xffff and $lensType != 0xff00) { + if ($lensType eq 65535) { + # handle Sony E-type lenses when LensType2 isn't valid (NEX/ILCE models only) + if ($$et{Model} =~ /NEX|ILCE/) { + unless (%sonyEtype) { + my ($index, $i, %did, $lens); + require Image::ExifTool::Sony; + foreach (sort keys %Image::ExifTool::Sony::sonyLensTypes2) { + ($lens = $Image::ExifTool::Sony::sonyLensTypes2{$_}) =~ s/ or .*//; + next if $did{$lens}; + ($i, $index) = $index ? ("65535.$index", $index + 1) : (65535, 1); + $did{$sonyEtype{$i} = $lens} = 1; + } + } + $printConv = \%sonyEtype; + } + } elsif ($lensType != 0xff00) { + # Patch for Metabones or other adapters on Sony E-mount cameras (ref Jos Roost) + # Metabones Canon EF to E-mount adapters add 0xef00, 0xbc00 or 0x7700 to the + # high byte for 2-byte Canon LensType values, so we need to adjust for these. + # Offset 0xef00 is also used by Sigma MC-11, Fotodiox and Viltrox EF-E adapters. + # Have to exclude A-mount Sigma Filtermatic with 'odd' LensType=0xff00. require Image::ExifTool::Minolta; if ($Image::ExifTool::Minolta::metabonesID{$lensType & 0xff00}) { $lensType -= ($lensType >= 0xef00 ? 0xef00 : $lensType >= 0xbc00 ? 0xbc00 : 0x7700); @@ -5054,7 +5333,8 @@ sub PrintLensID($$@) $lensTypePrt = $$printConv{$lensType} if $$printConv{$lensType}; } } - } elsif ($shortFocal and $longFocal) { + # (Min/MaxFocalLength may report the current focal length for Tamron zoom lenses) + } elsif ($shortFocal and $longFocal and (not $lensModel or $lensModel !~ /^TAMRON.*-\d+mm/)) { # Canon (and some other makes) include makernote information # which allows better lens identification require Image::ExifTool::Canon; @@ -5090,7 +5370,7 @@ sub PrintLensID($$@) # excluding any part between () at the end, and preceded by a space (the space # ensures that e.g. Zeiss Loxia 21mm having LensSpec "E 21mm F2.8" will not be # identified as "Sony FE 21mm F2.8 (SEL28F20 + SEL075UWC)") - $lensSpecPrt and $lens =~ / \Q$lensSpecPrt\E( \(|$)/ and @best = ( $lens ), last; + $lensSpecPrt and $lens =~ / \Q$lensSpecPrt\E( \(| GM$|$)/ and @best = ( $lens ), last; # exactly-matching Sony lens should have been found above, so only add non-Sony lenses push @best, $lens unless $lens =~ /^Sony /; next; @@ -5150,9 +5430,12 @@ sub PrintLensID($$@) } return join(' or ', @user); } - # return the best match(es) from the possible lenses - return join(' or ', @best) if @best; - return join(' or ', @matches) if @matches; + # return the best match(es) from the possible lenses, after checking against LensModel + @best = @matches unless @best; + if (@best) { + MatchLensModel(\@best, $lensModel); + return join(' or ', @best); + } $lens = $$printConv{$lensType}; return $lensModel if $lensModel and $lens =~ / or /; # (eg. Sony NEX-5N) return $lens; @@ -5344,6 +5627,32 @@ sub ExtractImage($$$$) return $et->ValidateImage(\$image, $tag); } +#------------------------------------------------------------------------------ +# Utility routine to return tag ID string for warnings +# Inputs: 0) Tag ID, 1) [optional] TagInfo ref +# Returns: "tag 0xXXXX NAME" +sub TagName($;$) +{ + my ($tagID, $tagInfo) = @_; + my $tagName = $tagInfo ? ' '.$$tagInfo{Name} : ''; + return sprintf('tag 0x%.4x%s', $tagID, $tagName); +} + +#------------------------------------------------------------------------------ +# Get class name of next IFD offset for HtmlDump output +# Inputs: 0) ExifTool ref, 1) current class ID +# Returns: 0) new IFD offset name, 1) new class ID including "Offset_" for new offset +# 2) new "Offset_" ID +sub NextOffsetName($;$) +{ + my ($et, $id) = @_; + $$et{OffsetNum} = defined $$et{OffsetNum} ? $$et{OffsetNum} + 1 : 0; + my $offName = 'o' . $$et{OffsetNum}; + my $sid = "Offset_$offName"; + $id = (defined $id ? "$id " : '') . $sid; + return ($offName, $id, $sid); +} + #------------------------------------------------------------------------------ # Process EXIF directory # Inputs: 0) ExifTool object reference @@ -5364,9 +5673,10 @@ sub ProcessExif($$$) my $raf = $$dirInfo{RAF}; my $verbose = $et->Options('Verbose'); my $validate = $et->Options('Validate'); + my $saveFormat = $et->Options('SaveFormat'); my $htmlDump = $$et{HTML_DUMP}; my $success = 1; - my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo); + my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName); my $inMakerNotes = $$tagTablePtr{GROUPS}{0} eq 'MakerNotes'; my $isExif = ($tagTablePtr eq \%Image::ExifTool::Exif::Main); @@ -5437,11 +5747,15 @@ sub ProcessExif($$$) } } } - unless ($success) { - $et->Warn("Bad $dir directory"); - return 0; + if ($success) { + $numEntries = Get16u($dataPt, $dirStart); + } else { + $et->Warn("Bad $dir directory", $inMakerNotes); + return 0 unless $inMakerNotes and $dirLen >= 14; + $dirSize = $dirLen; + $numEntries = int(($dirSize - 2) / 12); # read what we can + Set16u($numEntries, $dataPt, $dirStart); } - $numEntries = Get16u($dataPt, $dirStart); $dirSize = 2 + 12 * $numEntries; $dirEnd = $dirStart + $dirSize; } @@ -5463,6 +5777,7 @@ sub ProcessExif($$$) } } if ($htmlDump) { + $offName = $$dirInfo{OffsetName}; my $longName = $dir eq 'MakerNotes' ? ($$dirInfo{Name} || $dir) : $dir; if (defined $makerAddr) { my $hdrLen = $dirStart + $dataPos + $base - $makerAddr; @@ -5470,14 +5785,17 @@ sub ProcessExif($$$) } unless ($$dirInfo{NoDumpEntryCount}) { $et->HDump($dirStart + $dataPos + $base, 2, "$longName entries", - "Entry count: $numEntries"); + "Entry count: $numEntries", undef, $offName); } my $tip; + my $id = $offName; if ($bytesFromEnd >= 4) { my $nxt = ($dir =~ /^(.*?)(\d+)$/) ? $1 . ($2 + 1) : 'Next IFD'; - $tip = sprintf("$nxt offset: 0x%.4x", Get32u($dataPt, $dirEnd)); + my $off = Get32u($dataPt, $dirEnd); + $tip = sprintf("$nxt offset: 0x%.4x", $off); + ($nextOffName, $id) = NextOffsetName($et, $offName) if $off; } - $et->HDump($dirEnd + $dataPos + $base, 4, "Next IFD", $tip, 0); + $et->HDump($dirEnd + $dataPos + $base, 4, "Next IFD", $tip, 0, $id); } # patch for Canon EOS 40D firmware 1.0.4 bug (incorrect directory counts) @@ -5487,7 +5805,7 @@ sub ProcessExif($$$) my $fmt = Get16u($dataPt, $entry + 2); if ($fmt < 1 or $fmt > 13) { $et->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]", - "Bad format type: $fmt", 1); + "Bad format type: $fmt", 1, $offName); # adjust the number of directory entries --$numEntries; $dirEnd -= 12; @@ -5515,7 +5833,7 @@ sub ProcessExif($$$) $format = $$mapFmt{$format}; } else { $et->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]", - "Bad format type: $format", 1); + "Bad format type: $format", 1, $offName); # warn unless the IFD was just padded with zeros if ($format or $validate) { $et->Warn("Bad format ($format) for $dir entry $index", $inMakerNotes); @@ -5532,7 +5850,9 @@ sub ProcessExif($$$) my $valueDataLen = $dataLen; my $valuePtr = $entry + 8; # pointer to value within $$dataPt my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID); - my ($origFormStr, $bad, $rational); + my ($origFormStr, $bad, $rational, $subOffName); + # save the EXIF format codes if requested + $$et{SaveFormat}{$saveFormat = $formatStr} = 1 if $saveFormat; # hack to patch incorrect count in Kodak SubIFD3 tags if ($count < 2 and ref $$tagTablePtr{$tagID} eq 'HASH' and $$tagTablePtr{$tagID}{FixCount}) { $offList or ($offList, $offHash) = GetOffList($dataPt, $dirStart, $dataPos, @@ -5550,22 +5870,22 @@ sub ProcessExif($$$) my $readSize = $size; if ($size > 4) { if ($size > 0x7fffffff) { - $et->Warn(sprintf("Invalid size (%u) for %s tag 0x%.4x", $size, $dir, $tagID), $inMakerNotes); + $et->Warn(sprintf("Invalid size (%u) for %s %s",$size,$dir,TagName($tagID,$tagInfo)), $inMakerNotes); ++$warnCount; next; } $valuePtr = Get32u($dataPt, $valuePtr); if ($validate and not $inMakerNotes) { - $et->Warn(sprintf('Odd offset for %s tag 0x%.4x', $dir, $tagID), 1) if $valuePtr & 0x01; + $et->Warn(sprintf('Odd offset for %s %s',$dir,TagName($tagID,$tagInfo)), 1) if $valuePtr & 0x01; if ($valuePtr < 8 || ($valuePtr + $size > length($$dataPt) and $valuePtr + $size > $$et{VALUE}{FileSize})) { - $et->Warn(sprintf("Invalid offset for %s tag 0x%.4x", $dir, $tagID)); + $et->Warn(sprintf('Invalid offset for %s %s',$dir,TagName($tagID,$tagInfo))); ++$warnCount; next; } if ($valuePtr + $size > $dirStart + $dataPos and $valuePtr < $dirEnd + $dataPos + 4) { - $et->Warn(sprintf("Value for %s tag 0x%.4x overlaps IFD", $dir, $tagID)); + $et->Warn(sprintf('Value for %s %s overlaps IFD', $dir, TagName($tagID,$tagInfo))); } } # fix valuePtr if necessary @@ -5798,7 +6118,7 @@ sub ProcessExif($$$) # (avoids long delays when processing some corrupted files) if ($count > 100000 and $formatStr !~ /^(undef|string|binary)$/) { my $tagName = $tagInfo ? $$tagInfo{Name} : sprintf('tag 0x%.4x', $tagID); - if ($tagName ne 'TransferFunction' or $count ne 196608) { + if ($tagName ne 'TransferFunction' or $count != 196608) { my $minor = $count > 2000000 ? 0 : 2; next if $et->Warn("Ignoring $dirName $tagName with excessive count", $minor); } @@ -5806,9 +6126,7 @@ sub ProcessExif($$$) # convert according to specified format $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize,\$rational); # re-code if necessary - if ($strEnc and $formatStr eq 'string' and defined $val) { - $val = $et->Decode($val, $strEnc); - } + $val = $et->Decode($val, $strEnc) if $strEnc and $formatStr eq 'string' and defined $val; } if ($verbose) { @@ -5834,7 +6152,8 @@ sub ProcessExif($$$) "Format: $fstr\nSize: $size bytes\n"; if ($size > 4) { my $offPt = Get32u($dataPt,$entry+8); - my $actPt = $valuePtr + $valueDataPos + $base - ($$et{EXIF_POS} || 0); + # (test this with ../pics/{CanonEOS-1D_XMarkIII.hif,PanasonicDC-G9.rw2}) + my $actPt = $valuePtr + $valueDataPos + $base - ($$et{EXIF_POS} || 0) + ($$et{BASE_FUDGE} || 0); $tip .= sprintf("Value offset: 0x%.4x\n", $offPt); # highlight tag name (red for bad size) my $style = ($bad or not defined $tval) ? 'V' : 'H'; @@ -5862,7 +6181,7 @@ sub ProcessExif($$$) } elsif ($tagInfo and Image::ExifTool::IsInt($tval)) { if ($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) { $tval = sprintf('0x%.4x', $tval); - my $actPt = $val + $base - ($$et{EXIF_POS} || 0); + my $actPt = $val + $base - ($$et{EXIF_POS} || 0) + ($$et{BASE_FUDGE} || 0); if ($actPt != $val) { $tval .= sprintf("\nActual offset: 0x%.4x", $actPt); my $sign = $actPt < $val ? '-' : ''; @@ -5874,7 +6193,10 @@ sub ProcessExif($$$) } } $tip .= "Value: $tval"; - $et->HDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1); + my $id = $offName; + my $sid; + ($subOffName, $id, $sid) = NextOffsetName($et, $offName) if $tagInfo and $$tagInfo{SubIFD}; + $et->HDump($entry+$dataPos+$base, 12, "$dname $colName", $tip, 1, $id); next if $valueDataLen < 0; # don't process bad pointer entry if ($size > 4) { my $exifDumpPos = $valuePtr + $valueDataPos + $base; @@ -5887,7 +6209,7 @@ sub ProcessExif($$$) } } # add value data block (underlining maker notes data) - $et->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag); + $et->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag, $sid); } } else { if ($tagID <= $lastID and not $inMakerNotes) { @@ -6062,6 +6384,7 @@ sub ProcessExif($$$) TagInfo => $tagInfo, SubIFD => $$tagInfo{SubIFD}, Subdir => $subdir, + OffsetName => $subOffName, ); # (remember: some cameras incorrectly write maker notes in IFD0) if ($$tagInfo{MakerNotes}) { @@ -6187,6 +6510,7 @@ sub ProcessExif($$$) $et->SetGroup($tagKey, $dirName) if $$tagTablePtr{SET_GROUP1}; # save original components of rational numbers (used when copying) $$et{RATIONAL}{$tagKey} = $rational if defined $rational; + $$et{TAG_EXTRA}{$tagKey}{G6} = $saveFormat if $saveFormat; } } @@ -6208,6 +6532,7 @@ sub ProcessExif($$$) # increment IFD number my $ifdNum = $newDirInfo{DirName} =~ s/(\d+)$// ? $1 : 0; $newDirInfo{DirName} .= $ifdNum + 1; + $newDirInfo{OffsetName} = $nextOffName; # must validate SubIFD1 because the nextIFD pointer is invalid for some RAW formats if ($newDirInfo{DirName} ne 'SubIFD1' or ValidateIFD(\%newDirInfo)) { $$et{INDENT} =~ s/..$//; # keep indent the same @@ -6241,7 +6566,7 @@ EXIF and TIFF meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FITS.pm b/src/Image-ExifTool/lib/Image/ExifTool/FITS.pm new file mode 100644 index 00000000..d5eca932 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/FITS.pm @@ -0,0 +1,148 @@ +#------------------------------------------------------------------------------ +# File: FITS.pm +# +# Description: Read Flexible Image Transport System metadata +# +# Revisions: 2018/03/07 - P. Harvey Created +# +# References: 1) https://fits.gsfc.nasa.gov/fits_standard.html +#------------------------------------------------------------------------------ + +package Image::ExifTool::FITS; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.00'; + +# FITS tags (ref 1) +%Image::ExifTool::FITS::Main = ( + GROUPS => { 2 => 'Image' }, + NOTES => q{ + This table lists some standard Flexible Image Transport System (FITS) tags, + but ExifTool will extract any other tags found. See + L<https://fits.gsfc.nasa.gov/fits_standard.html> for the specification. + }, + TELESCOP => 'Telescope', + BACKGRND => 'Background', + INSTRUME => 'Instrument', + OBJECT => 'Object', + OBSERVER => 'Observer', + DATE => { Name => 'CreateDate', Groups => { 2 => 'Time' } }, + AUTHOR => { Name => 'Author', Groups => { 2 => 'Author' } }, + REFERENC => 'Reference', + 'DATE-OBS'=> { Name => 'ObservationDate', Groups => { 2 => 'Time' } }, + 'TIME-OBS'=> { Name => 'ObservationTime', Groups => { 2 => 'Time' } }, + 'DATE-END'=> { Name => 'ObservationDateEnd', Groups => { 2 => 'Time' } }, + 'TIME-END'=> { Name => 'ObservationTimeEnd', Groups => { 2 => 'Time' } }, +); + +#------------------------------------------------------------------------------ +# Read information in a FITS document +# Inputs: 0) ExifTool ref, 1) dirInfo ref +# Returns: 1 on success, 0 if this wasn't a valid FITS file +sub ProcessFITS($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $tag, $continue); + + return 0 unless $raf->Read($buff, 80) == 80 and $buff =~ /^SIMPLE = {20}T/; + $et->SetFileType(); + my $tagTablePtr = GetTagTable('Image::ExifTool::FITS::Main'); + + for (;;) { + $raf->Read($buff, 80) == 80 or $et->Warn('Truncated FITS header'), last; + my $key = substr($buff, 0, 8); + $key =~ s/ +$//; # remove trailing space from key + if ($key eq 'CONTINUE') { + defined $continue or $et->WarnOnce('Unexpected FITS CONTINUE keyword'), next; + } else { + if (defined $continue) { + # the previous value wasn't continued, so store with the trailing '&' + $et->HandleTag($tagTablePtr, $tag, $continue . '&'); + undef $continue; + } + last if $key eq 'END'; + # make sure the key is valid + $key =~ /^[-_A-Z0-9]*$/ or $et->Warn('Format error in FITS header'), last; + next unless substr($buff,8,2) eq '= '; # ignore comment lines + # save tag name (avoiding potential conflict with ExifTool variables) + $tag = $Image::ExifTool::specialTags{$key} ? "_$key" : $key; + # add to tag table if necessary + unless ($$tagTablePtr{$tag}) { + my $name = ucfirst lc $tag; # make tag name lower case with leading capital + $name =~ s/_(.)/\U$1/g; # remove all '_' and capitalize subsequent letter + AddTagToTable($tagTablePtr, $tag, { Name => $name }); + } + } + my $val = substr($buff, 10); + # parse quoted values + if ($val =~ /^'(.*?)'(.*)/) { + ($val, $buff) = ($1, $2); + while ($buff =~ /^('.*?)'(.*)/) { # handle escaped quotes + $val .= $1; + $buff = $2; + } + $val =~ s/ +$//; # remove trailing spaces + if (defined $continue) { + $val = $continue . $val; + undef $continue; + } + # check for possible continuation, removing trailing '&' + $val =~ s/\&$// and $continue = $val, next; + } elsif (defined $continue) { + $et->WarnOnce('Invalid FITS CONTINUE value'); + next; + } else { + $val =~ s/ *(\/.*)?$//; # remove trailing spaces and comment + next unless length $val; # ignore undefined values + $val =~ s/^ +//; # remove leading spaces + # re-format floating-point values to use 'e' + $val =~ tr/DE/e/ if $val =~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?([ED]([+-]?\d+))?$/; + } + $et->HandleTag($tagTablePtr, $tag, $val); + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::FITS - Read Flexible Image Transport System metadata + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read meta +information from FITS (Flexible Image Transport System) images. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://fits.gsfc.nasa.gov/fits_standard.html> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/FITS Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FLAC.pm b/src/Image-ExifTool/lib/Image/ExifTool/FLAC.pm index a2d7675a..6c0359e6 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/FLAC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/FLAC.pm @@ -284,7 +284,7 @@ information from Free Lossless Audio Codec (FLAC) audio files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FLIF.pm b/src/Image-ExifTool/lib/Image/ExifTool/FLIF.pm new file mode 100644 index 00000000..c65e7ef9 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/FLIF.pm @@ -0,0 +1,353 @@ +#------------------------------------------------------------------------------ +# File: FLIF.pm +# +# Description: Read/write FLIF meta information +# +# Revisions: 2016/10/11 - P. Harvey Created +# 2016/10/14 - PH Added write support +# +# References: 1) http://flif.info/ +# 2) https://github.com/FLIF-hub/FLIF/blob/master/doc/metadata +#------------------------------------------------------------------------------ + +package Image::ExifTool::FLIF; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.02'; + +my %flifMap = ( + EXIF => 'FLIF', + XMP => 'FLIF', + ICC_Profile => 'FLIF', + IFD0 => 'EXIF', + IFD1 => 'IFD0', + ExifIFD => 'IFD0', + GPS => 'IFD0', + SubIFD => 'IFD0', + GlobParamIFD => 'IFD0', + PrintIM => 'IFD0', + InteropIFD => 'ExifIFD', + MakerNotes => 'ExifIFD', +); + +# FLIF tags +%Image::ExifTool::FLIF::Main = ( + GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, + VARS => { HEX_ID => 0 }, + NOTES => q{ + Information extracted from Free Lossless Image Format files. See + L<http://flif.info/> for more information. + }, +# +# header information +# + 0 => { + Name => 'ImageType', + PrintConv => { + '1' => 'Grayscale (non-interlaced)', + '3' => 'RGB (non-interlaced)', + '4' => 'RGBA (non-interlaced)', + 'A' => 'Grayscale (interlaced)', + 'C' => 'RGB (interlaced)', + 'D' => 'RGBA (interlaced)', + 'Q' => 'Grayscale Animation (non-interlaced)', + 'S' => 'RGB Animation (non-interlaced)', + 'T' => 'RGBA Animation (non-interlaced)', + 'a' => 'Grayscale Animation (interlaced)', + 'c' => 'RGB Animation (interlaced)', + 'd' => 'RGBA Animation (interlaced)', + }, + }, + 1 => { + Name => 'BitDepth', + PrintConv => { + '0' => 'Custom', + '1' => 8, + '2' => 16, + }, + }, + 2 => 'ImageWidth', + 3 => 'ImageHeight', + 4 => 'AnimationFrames', + 5 => { + Name => 'Encoding', + PrintConv => { + 0 => 'FLIF16', + }, + }, +# +# metadata chunks +# + iCCP => { + Name => 'ICC_Profile', + SubDirectory => { + TagTable => 'Image::ExifTool::ICC_Profile::Main', + }, + }, + eXif => { + Name => 'EXIF', + SubDirectory => { + TagTable => 'Image::ExifTool::Exif::Main', + ProcessProc => \&Image::ExifTool::ProcessTIFF, + WriteProc => \&Image::ExifTool::WriteTIFF, + Start => 6, # (skip "Exif\0\0" header) + Header => "Exif\0\0", + }, + }, + eXmp => { + Name => 'XMP', + SubDirectory => { + TagTable => 'Image::ExifTool::XMP::Main', + }, + }, + # tRko - list of truncation offsets + # \0 - FLIF16-format image data +); + +#------------------------------------------------------------------------------ +# Read variable-length FLIF integer +# Inputs: 0) raf reference, 1) number to add to returned value +# Returns: integer, or undef on EOF +sub GetVarInt($;$) +{ + my ($raf, $add) = @_; + my ($val, $buff); + for ($val=0; ; $val<<=7) { + $raf->Read($buff, 1) or return undef; + my $byte = ord($buff); + $val |= ($byte & 0x7f); + last unless $byte & 0x80; + } + return $val + ($add || 0); +} + +#------------------------------------------------------------------------------ +# Construct variable-length FLIF integer +# Inputs: 0) integer +# Returns: FLIF variable-length integer byte stream +sub SetVarInt($) +{ + my $val = shift; + my $buff = ''; + my $high = 0; + for (;;) { + $buff = chr(($val & 0x7f) | $high) . $buff; + last unless $val >>= 7; + $high = 0x80; + } + return $buff; +} + +#------------------------------------------------------------------------------ +# Read FLIF header +# Inputs: 0) RAF ref +# Returns: Scalar context: binary header block +# List context: header values (4 or 5 elements: type,depth,width,height[,frames]) +# or undef if this isn't a valid FLIF file header +sub ReadFLIFHeader($) +{ + my $raf = shift; + my ($buff, @vals); + + # verify this is a valid FLIF file + return () unless $raf->Read($buff, 6) == 6 and $buff =~ /^FLIF([0-\x6f])([0-2])/; + + # decode header information ("FLIF" chunk) + push @vals, $1, $2; # type, depth + push @vals, GetVarInt($raf,+1), GetVarInt($raf,+1); # width, height (+1 each) + push @vals, GetVarInt($raf,+2) if $vals[0] gt 'H'; # frames (+2) + + return () unless defined $vals[-1]; + return @vals if wantarray; # return the decoded header values + + # return the binary header block + my $hdrLen = $raf->Tell(); + return () unless $raf->Seek(0,0) and $raf->Read($buff, $hdrLen) == $hdrLen; + return $buff; +} + +#------------------------------------------------------------------------------ +# WriteFLIF : Write FLIF image +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid FLIF file, or -1 if +# an output file was specified and a write error occurred +sub WriteFLIF($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $soi, @addTags, %doneTag); + + # verify FLIF header and copy it to the output file + $buff = ReadFLIFHeader($raf) or return 0; + my $outfile = $$dirInfo{OutFile}; + Write($outfile, $buff) or return -1; + + $et->InitWriteDirs(\%flifMap); + my $tagTablePtr = GetTagTable('Image::ExifTool::FLIF::Main'); + + # loop through the FLIF chunks + for (;;) { + my ($tag, $size, $inflated); + # read new tag (or soi) unless we already hit the soi (start of image) + if (not defined $soi) { + $raf->Read($buff, 4) == 4 or $et->Error('Unexpected EOF'), last; + if ($buff lt ' ') { + $soi = $buff; # we have hit the start of image (no more metadata) + # make list of new tags to add + foreach $tag ('eXif', 'eXmp', 'iCCP') { + push @addTags, $tag if $$et{ADD_DIRS}{$$tagTablePtr{$tag}{Name}} and not $doneTag{$tag}; + } + } + } + if (not defined $soi) { + $tag = $buff; + $size = GetVarInt($raf); # read the data size + } elsif (@addTags) { + $tag = shift @addTags; + ($buff, $size) = ('', 0); # create metadata from scratch + } else { + # finish copying file (no more metadata to add) + Write($outfile, $soi) or return -1; + Write($outfile, $buff) or return -1 while $raf->Read($buff, 65536); + last; # all done! + } + my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); + if ($tagInfo and $$tagInfo{SubDirectory} and $$et{EDIT_DIRS}{$$tagInfo{Name}}) { + $doneTag{$tag} = 1; # prevent adding this back again later + unless (defined $soi) { + $raf->Read($buff, $size) == $size or $et->Error("Truncated FLIF $tag chunk"), last; + } + # rewrite the compressed data + if (eval { require IO::Uncompress::RawInflate } and eval { require IO::Compress::RawDeflate } ) { + if (length $buff == 0) { + $inflated = $buff; # (creating from scratch, so no need to inflate) + } elsif (not IO::Uncompress::RawInflate::rawinflate(\$buff => \$inflated)) { + $et->Error("Error inflating FLIF $tag chunk"), last; + } + my $subdir = $$tagInfo{SubDirectory}; + my %subdirInfo = ( + DirName => $$tagInfo{Name}, + DataPt => \$inflated, + DirStart => length($inflated) ? $$subdir{Start} : undef, + ReadOnly => 1, # (used only by WriteXMP) + ); + my $subTable = GetTagTable($$subdir{TagTable}); + $inflated = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc}); + if (defined $inflated) { + next unless length $inflated; # (delete directory if length is zero) + $inflated = $$subdir{Header} . $inflated if $$subdir{Header}; # (add back header if necessary) + unless (IO::Compress::RawDeflate::rawdeflate(\$inflated => \$buff)) { + $et->Error("Error deflating FLIF $tag chunk"), last; + } + } + } else { + $et->WarnOnce('Install IO::Compress::RawDeflate to write FLIF metadata'); + } + Write($outfile, $tag, SetVarInt(length $buff), $buff) or return -1; + } elsif (not defined $soi) { + Write($outfile, $tag, SetVarInt($size)) or return -1; + Image::ExifTool::CopyBlock($raf, $outfile, $size) or return -1; + } + } + return 1; +} + +#------------------------------------------------------------------------------ +# Extract information from an FLIF file +# Inputs: 0) ExifTool object reference, 1) DirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid FLIF file +sub ProcessFLIF($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $tag, $inflated); + + # verify this is a valid FLIF file and read the header + my @vals = ReadFLIFHeader($raf) or return 0; + + $et->SetFileType(); + my $tagTablePtr = GetTagTable('Image::ExifTool::FLIF::Main'); + my $verbose = $et->Options('Verbose'); + + # save the header information + $et->VPrint(0, "FLIF header:\n") if $verbose; + for ($tag=0; defined $vals[$tag]; ++$tag) { + $et->HandleTag($tagTablePtr, $tag, $vals[$tag]); + } + + # loop through the FLIF chunks + for (;;) { + $raf->Read($tag, 4) == 4 or $et->Warn('Unexpected EOF'), last; + my $byte = ord substr($tag, 0, 1); + # all done if we arrived at the image chunk + $byte < 32 and $et->HandleTag($tagTablePtr, 5, $byte), last; + my $size = GetVarInt($raf); + $et->VPrint(0, "FLIF $tag ($size bytes):\n") if $verbose; + if ($$tagTablePtr{$tag}) { + $raf->Read($buff, $size) == $size or $et->Warn("Truncated FLIF $tag chunk"), last; + $et->VerboseDump(\$buff, Addr => $raf->Tell() - $size) if $verbose > 2; + # inflate the compressed data + if (eval { require IO::Uncompress::RawInflate }) { + if (IO::Uncompress::RawInflate::rawinflate(\$buff => \$inflated)) { + $et->HandleTag($tagTablePtr, $tag, $inflated, + DataPt => \$inflated, + Size => length $inflated, + Extra => ' inflated', + ); + } else { + $et->Warn("Error inflating FLIF $tag chunk"); + } + } else { + $et->WarnOnce('Install IO::Uncompress::RawInflate to decode FLIF metadata'); + } + } else { + $raf->Seek($size, 1) or $et->Warn('Seek error'), last; + } + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::FLIF - Read/write FLIF meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains routines required by Image::ExifTool to read and write +meta information in FLIF (Free Lossless Image Format) images. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<http://flif.info/> + +=item L<https://github.com/FLIF-hub/FLIF/blob/master/doc/metadata> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/FLIF Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FLIR.pm b/src/Image-ExifTool/lib/Image/ExifTool/FLIR.pm index f238bb67..519109fc 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/FLIR.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/FLIR.pm @@ -5,12 +5,12 @@ # # Revisions: 2013/03/28 - P. Harvey Created # -# References: 1) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4898.0.html +# References: 1) https://exiftool.org/forum/index.php/topic,4898.0.html # 2) http://www.nuage.ch/site/flir-i7-some-analysis/ # 3) http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/Streaming_format_ThermoVision.pdf # 4) http://support.flir.com/DocDownload/Assets/62/English/1557488%24A.pdf # 5) http://code.google.com/p/dvelib/source/browse/trunk/flirPublicFormat/fpfConverter/Fpfimg.h?spec=svn3&r=3 -# 6) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5538.0.html +# 6) https://exiftool.org/forum/index.php/topic,5538.0.html # JD) Jens Duttke private communication # # Glossary: FLIR = Forward Looking Infra Red @@ -24,7 +24,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::GPS; -$VERSION = '1.17'; +$VERSION = '1.18'; sub ProcessFLIR($$;$); sub ProcessFLIRText($$$); @@ -64,7 +64,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); Name => 'ImageTemperatureMax', %temperatureInfo, Notes => q{ - these temperatures may be in Celcius, Kelvin or Fahrenheit, but there is no + these temperatures may be in Celsius, Kelvin or Fahrenheit, but there is no way to tell which }, }, @@ -378,7 +378,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); NOTES => q{ FLIR camera information. The Planck tags are variables used in the temperature calculation. See - L<http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=4898.msg23972#msg23972> + L<https://exiftool.org/forum/index.php?topic=4898.msg23972#msg23972> for details. }, 0x00 => { @@ -446,6 +446,8 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); 0x21c => { Name => 'FilterSerialNumber',Format => 'string[32]' }, 0x308 => { Name => 'PlanckO', Format => 'int32s' }, #1 0x30c => { Name => 'PlanckR2', %float8g }, #1 + 0x310 => { Name => 'RawValueRangeMin', Format => 'int16u', Groups => { 2 => 'Image' } }, #forum10060 + 0x312 => { Name => 'RawValueRangeMax', Format => 'int16u', Groups => { 2 => 'Image' } }, #forum10060 0x338 => { Name => 'RawValueMedian', Format => 'int16u', Groups => { 2 => 'Image' } }, 0x33c => { Name => 'RawValueRange', Format => 'int16u', Groups => { 2 => 'Image' } }, 0x384 => { @@ -713,7 +715,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); ); # humidity meter information -# (ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5325.0.html) +# (ref https://exiftool.org/forum/index.php/topic,5325.0.html) # The %Image::ExifTool::UserDefined hash defines new tags to be added to existing tables. %Image::ExifTool::FLIR::MeterLink = ( GROUPS => { 0 => 'APP1', 2 => 'Image' }, @@ -752,7 +754,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); 96 => { Name => 'Reading1Value', Format => 'double', - # convert Kelvin -> Celcius and kg/kg -> g/kg + # convert Kelvin -> Celsius and kg/kg -> g/kg ValueConv => q{ return $val - 273.15 if $$self{Reading1Units} == 0x0d and $$self{Reading1Description} != 11; return $val *= 1000 if $$self{Reading1Units} == 0x24; @@ -792,7 +794,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); 196 => { Name => 'Reading2Value', Format => 'double', - # convert Kelvin -> Celcius and kg/kg -> g/kg + # convert Kelvin -> Celsius and kg/kg -> g/kg ValueConv => q{ return $val - 273.15 if $$self{Reading2Units} == 0x0d and $$self{Reading2Description} != 11; return $val *= 1000 if $$self{Reading2Units} == 0x24; @@ -831,7 +833,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); 296 => { Name => 'Reading3Value', Format => 'double', - # convert Kelvin -> Celcius and kg/kg -> g/kg + # convert Kelvin -> Celsius and kg/kg -> g/kg ValueConv => q{ return $val - 273.15 if $$self{Reading3Units} == 0x0d and $$self{Reading3Description} != 11; return $val *= 1000 if $$self{Reading3Units} == 0x24; @@ -871,7 +873,7 @@ my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' ); 396 => { Name => 'Reading4Value', Format => 'double', - # convert Kelvin -> Celcius and kg/kg -> g/kg + # convert Kelvin -> Celsius and kg/kg -> g/kg ValueConv => q{ return $val - 273.15 if $$self{Reading4Units} == 0x0d and $$self{Reading4Description} != 11; return $val *= 1000 if $$self{Reading4Units} == 0x24; @@ -1339,7 +1341,7 @@ sub GetImageType($$$) sub UnescapeFLIR($) { my $char = shift; - return $char unless length $char eq 4; # escaped ASCII char (eg. '\\') + return $char unless length $char == 4; # escaped ASCII char (eg. '\\') my $val = hex $char; return chr($val) if $val < 0x80; # simple ASCII return pack('C0U', $val) if $] >= 5.006001; @@ -1398,7 +1400,6 @@ sub ProcessMeasInfo($$$) my $dirStart = $$dirInfo{DirStart} || 0; my $dataPos = $$dirInfo{DataPos}; my $dirEnd = $dirStart + $$dirInfo{DirLen}; - my $verbose = $et->Options('Verbose'); my $pos = $dirStart + 12; return 0 if $pos > $dirEnd; @@ -1593,7 +1594,7 @@ Systems Inc. thermal image files (FFF, FPF and JPEG format). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -1602,7 +1603,7 @@ under the same terms as Perl itself. =over 4 -=item L<http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4898.0.html> +=item L<https://exiftool.org/forum/index.php/topic,4898.0.html> =item L<http://www.nuage.ch/site/flir-i7-some-analysis/> @@ -1612,7 +1613,7 @@ under the same terms as Perl itself. =item L<http://code.google.com/p/dvelib/source/browse/trunk/flirPublicFormat/fpfConverter/Fpfimg.h?spec=svn3&r=3> -=item L<http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5538.0.html> +=item L<https://exiftool.org/forum/index.php/topic,5538.0.html> =back diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Fixup.pm b/src/Image-ExifTool/lib/Image/ExifTool/Fixup.pm index beb3e114..318088ea 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Fixup.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Fixup.pm @@ -354,7 +354,7 @@ linear list when ApplyFixups() is called. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Flash.pm b/src/Image-ExifTool/lib/Image/ExifTool/Flash.pm index de3f63f0..e351e325 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Flash.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Flash.pm @@ -418,7 +418,7 @@ Record: for ($rec=0; ; ++$rec) { my $num = Get32u($dataPt, $pos); $$dirInfo{Pos} = $pos + 4; my ($i, @vals); - # add array index to compount tag name + # add array index to compound tag name my $structName = $$dirInfo{StructName}; for ($i=0; $i<$num; ++$i) { $$dirInfo{StructName} = $structName . $i if defined $structName; @@ -721,7 +721,7 @@ will add AMF3 support. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FlashPix.pm b/src/Image-ExifTool/lib/Image/ExifTool/FlashPix.pm index 220decaa..db8f1c1f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/FlashPix.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/FlashPix.pm @@ -21,7 +21,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::ASF; # for GetGUID() -$VERSION = '1.36'; +$VERSION = '1.38'; sub ProcessFPX($$); sub ProcessFPXR($$$); @@ -125,7 +125,7 @@ my @dirEntryType = qw(INVALID STORAGE STREAM LOCKBYTES PROPERTY ROOT); # list of code pages used by Microsoft # (ref http://msdn.microsoft.com/en-us/library/dd317756(VS.85).aspx) my %codePage = ( - 037 => 'IBM EBCDIC US-Canada', + 37 => 'IBM EBCDIC US-Canada', 437 => 'DOS United States', 500 => 'IBM EBCDIC International', 708 => 'Arabic (ASMO 708)', @@ -313,7 +313,8 @@ my %fpxFileType = ( from DOC, PPT, XLS (Microsoft Word, PowerPoint and Excel) documents, VSD (Microsoft Visio) drawings, and FLA (Macromedia/Adobe Flash project) files since these are based on the same file format as FlashPix (the Windows - Compound Binary File format). See + Compound Binary File format). Note that ExifTool identifies any + unrecognized Windows Compound Binary file as a FlashPix (FPX) file. See L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix specification. }, @@ -1085,7 +1086,7 @@ my %fpxFileType = ( 0x0807 => 'German (Swiss)', 0x0408 => 'Greek', 0x0409 => 'English (US)', - 0x0809 => 'English (British)', + 0x0809 => 'English (British)', 0x0c09 => 'English (Australian)', 0x040a => 'Spanish (Castilian)', 0x080a => 'Spanish (Mexican)', @@ -1108,7 +1109,7 @@ my %fpxFileType = ( 0x0415 => 'Polish', 0x0416 => 'Portuguese (Brazilian)', 0x0816 => 'Portuguese', - 0x0417 => 'Rhaeto-Romanic', + 0x0417 => 'Rhaeto-Romanic', 0x0418 => 'Romanian', 0x0419 => 'Russian', 0x041a => 'Croato-Serbian (Latin)', @@ -1175,11 +1176,11 @@ my %fpxFileType = ( VARS => { NO_ID => 1 }, CommentBy => { Groups => { 2 => 'Author' }, - Notes => 'enable Duplicates option to extract all entries', + Notes => 'enable L<Duplicates|../ExifTool.html#Duplicates> option to extract all entries', }, LastSavedBy => { Groups => { 2 => 'Author' }, - Notes => 'enable Duplicates option to extract history of up to 10 entries', + Notes => 'enable L<Duplicates|../ExifTool.html#Duplicates> option to extract history of up to 10 entries', }, DOP => { SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::DOP' } }, ModifyDate => { @@ -1439,7 +1440,7 @@ sub ReadFPXValue($$$$$;$$) my $charset = $Image::ExifTool::charsetName{"cp$codePage"}; if ($charset) { $val = $et->Decode($val, $charset); - } elsif ($codePage eq 1200) { # UTF-16, little endian + } elsif ($codePage == 1200) { # UTF-16, little endian $val = $et->Decode($val, 'UCS2', 'II'); } } @@ -1577,14 +1578,16 @@ sub ProcessDocumentTable($) my $key = 'TableOffsets' . ($i ? " ($i)" : ''); my $offsets = $$value{$key}; last unless defined $offsets; - my $doc = $$extra{$key}{G3} if $$extra{$key}; + my $doc; + $doc = $$extra{$key}{G3} if $$extra{$key}; $doc = '' unless $doc; # get DocFlags for this sub-document my ($docFlags, $docTable); for ($j=0; ; ++$j) { my $key = 'DocFlags' . ($j ? " ($j)" : ''); last unless defined $$value{$key}; - my $tmp = $$extra{$key}{G3} if $$extra{$key}; + my $tmp; + $tmp = $$extra{$key}{G3} if $$extra{$key}; $tmp = '' unless $tmp; if ($tmp eq $doc) { $docFlags = $$value{$key}; @@ -1597,7 +1600,8 @@ sub ProcessDocumentTable($) for ($j=0; ; ++$j) { my $key = $tag . ($j ? " ($j)" : ''); last unless defined $$value{$key}; - my $tmp = $$extra{$key}{G3} if $$extra{$key}; + my $tmp; + $tmp = $$extra{$key}{G3} if $$extra{$key}; $tmp = '' unless $tmp; if ($tmp eq $doc) { $docTable = \$$value{$key}; @@ -1642,14 +1646,14 @@ sub ProcessCommentBy($$$) my $pos = $$dirInfo{DirStart}; my $end = $$dirInfo{DirLen} + $pos; $et->VerboseDir($$dirInfo{DirName}); - while ($pos + 2 < $end) { - my $len = Get16u($dataPt, $pos); - $pos += 2; - last if $pos + $len * 2 > $end; - my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2'); - $pos += $len * 2; - $et->HandleTag($tagTablePtr, CommentBy => $author); - } + while ($pos + 2 < $end) { + my $len = Get16u($dataPt, $pos); + $pos += 2; + last if $pos + $len * 2 > $end; + my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2'); + $pos += $len * 2; + $et->HandleTag($tagTablePtr, CommentBy => $author); + } return 1; } @@ -1665,24 +1669,24 @@ sub ProcessLastSavedBy($$$) my $end = $$dirInfo{DirLen} + $pos; return 0 if $pos + 6 > $end; $et->VerboseDir($$dirInfo{DirName}); - my $num = Get16u($dataPt, $pos+2); - $pos += 6; - while ($num >= 2) { - last if $pos + 2 > $end; - my $len = Get16u($dataPt, $pos); - $pos += 2; - last if $pos + $len * 2 > $end; - my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2'); - $pos += $len * 2; - last if $pos + 2 > $end; - $len = Get16u($dataPt, $pos); - $pos += 2; - last if $pos + $len * 2 > $end; - my $path = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2'); - $pos += $len * 2; - $et->HandleTag($tagTablePtr, LastSavedBy => "$author ($path)"); - $num -= 2; - } + my $num = Get16u($dataPt, $pos+2); + $pos += 6; + while ($num >= 2) { + last if $pos + 2 > $end; + my $len = Get16u($dataPt, $pos); + $pos += 2; + last if $pos + $len * 2 > $end; + my $author = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2'); + $pos += $len * 2; + last if $pos + 2 > $end; + $len = Get16u($dataPt, $pos); + $pos += 2; + last if $pos + $len * 2 > $end; + my $path = $et->Decode(substr($$dataPt, $pos, $len*2), 'UCS2'); + $pos += $len * 2; + $et->HandleTag($tagTablePtr, LastSavedBy => "$author ($path)"); + $num -= 2; + } return 1; } @@ -1995,7 +1999,7 @@ sub ProcessFPXR($$$) $et->Warn("Unlisted FPXR segment (index $index)") if $index != 255; } - } elsif ($type ne 3) { # not a "Reserved" segment + } elsif ($type != 3) { # not a "Reserved" segment $et->Warn("Unknown FPXR segment (type $type)"); @@ -2220,7 +2224,7 @@ sub ProcessFPX($$) my $rSib = Get32u(\$dir, $pos + 0x48); # right sibling my $chld = Get32u(\$dir, $pos + 0x4c); # child directory - # save information about object hierachy + # save information about object hierarchy my ($obj, $sub); $obj = $hier{$index} or $obj = $hier{$index} = { }; $$obj{Left} = $lSib unless $lSib == FREE_SECT; @@ -2366,7 +2370,7 @@ JPEG images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Font.pm b/src/Image-ExifTool/lib/Image/ExifTool/Font.pm index aeeb1d09..02d14d20 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Font.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Font.pm @@ -19,7 +19,7 @@ use strict; use vars qw($VERSION %ttLang); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.08'; +$VERSION = '1.09'; sub ProcessOTF($$); @@ -80,7 +80,7 @@ my %ttCharset = ( %ttLang = ( # Macintosh language codes (also used by QuickTime.pm) # oddities: - # 49 - Cyrllic version 83 - Roman + # 49 - Cyrillic version 83 - Roman # 50 - Arabic version 84 - Arabic # 146 - with dot above Macintosh => { @@ -88,20 +88,20 @@ my %ttCharset = ( 1 => 'fr', 25 => 'pl', 49 => 'az', 73 => 'kn', 130 => 'ca', 2 => 'de', 26 => 'hu', 50 => 'az', 74 => 'ta', 131 => 'la', 3 => 'it', 27 => 'et', 51 => 'hy', 75 => 'te', 132 => 'qu', - 4 => 'nl', 28 => 'lv', 52 => 'ka', 76 => 'si', 133 => 'gn', + 4 => 'nl-NL', 28 => 'lv', 52 => 'ka', 76 => 'si', 133 => 'gn', 5 => 'sv', 29 => 'smi', 53 => 'ro', 77 => 'my', 134 => 'ay', 6 => 'es', 30 => 'fo', 54 => 'ky', 78 => 'km', 135 => 'tt', 7 => 'da', 31 => 'fa', 55 => 'tg', 79 => 'lo', 136 => 'ug', 8 => 'pt', 32 => 'ru', 56 => 'tk', 80 => 'vi', 137 => 'dz', 9 => 'no', 33 => 'zh-CN', 57 => 'mn-MN', 81 => 'id', 138 => 'jv', - 10 => 'he', 34 => 'nl', 58 => 'mn-CN', 82 => 'tl', 139 => 'su', + 10 => 'he', 34 => 'nl-BE', 58 => 'mn-CN', 82 => 'tl', 139 => 'su', 11 => 'ja', 35 => 'ga', 59 => 'ps', 83 => 'ms-MY', 140 => 'gl', 12 => 'ar', 36 => 'sq', 60 => 'ku', 84 => 'ms-BN', 141 => 'af', 13 => 'fi', 37 => 'ro', 61 => 'ks', 85 => 'am', 142 => 'br', - 14 => 'iu', 38 => 'cs', 62 => 'sd', 86 => 'ti', 144 => 'gd', - 15 => 'is', 39 => 'sk', 63 => 'bo', 87 => 'om', 145 => 'vg', + 14 => 'el', 38 => 'cs', 62 => 'sd', 86 => 'ti', 144 => 'gd', + 15 => 'is', 39 => 'sk', 63 => 'bo', 87 => 'om', 145 => 'gv', 16 => 'mt', 40 => 'sl', 64 => 'ne', 88 => 'so', 146 => 'ga', - 17 => 'tr', 41 => 'yi', 65 => 'sa', 89 => 'sw', 147 => 'rar', + 17 => 'tr', 41 => 'yi', 65 => 'sa', 89 => 'sw', 147 => 'to', 18 => 'hr', 42 => 'sr', 66 => 'mr', 90 => 'rw', 148 => 'el', 19 => 'zh-TW', 43 => 'mk', 67 => 'bn', 91 => 'rn', 149 => 'kl', 20 => 'ur', 44 => 'bg', 68 => 'as', 92 => 'ny', 150 => 'az', @@ -117,7 +117,7 @@ my %ttCharset = ( # 0x048c - no ISO equivalent # 0x081a/0x83c - sr-SP # 0x0c0a - modern? - # 0x2409 - Carribean country code not found in ISO 3166-1 + # 0x2409 - Caribbean country code not found in ISO 3166-1 Windows => { 0x0401 => 'ar-SA', 0x0438 => 'fo', 0x0481 => 'mi', 0x1409 => 'en-NZ', 0x0402 => 'bg', 0x0439 => 'hi', 0x0482 => 'oc', 0x140a => 'es-CR', @@ -615,7 +615,7 @@ types are OTF, TTF, TTC, DFONT, PFA, PFB, PFM, AFM, ACFM and AMFM. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FotoStation.pm b/src/Image-ExifTool/lib/Image/ExifTool/FotoStation.pm index a959eabe..75c7fc30 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/FotoStation.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/FotoStation.pm @@ -243,7 +243,7 @@ write information from the FotoWare FotoStation trailer. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/FujiFilm.pm b/src/Image-ExifTool/lib/Image/ExifTool/FujiFilm.pm index 41210e7d..d4a3e0e8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/FujiFilm.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/FujiFilm.pm @@ -4,7 +4,7 @@ # Description: Read/write FujiFilm maker notes and RAF images # # Revisions: 11/25/2003 - P. Harvey Created -# 11/14/2007 - PH Added abilty to write RAF images +# 11/14/2007 - PH Added ability to write RAF images # # References: 1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html # 2) http://homepage3.nifty.com/kamisaka/makernote/makernote_fuji.htm (2007/09/11) @@ -14,11 +14,12 @@ # 6) http://forums.dpreview.com/forums/readflat.asp?forum=1012&thread=31350384 # and http://forum.photome.de/viewtopic.php?f=2&t=353&p=742#p740 # 7) Kai Lappalainen private communication -# 8) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5223.0.html +# 8) https://exiftool.org/forum/index.php/topic,5223.0.html # 9) Zilvinas Brobliauskas private communication # 10) Albert Shan private communication -# 11) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,8377.0.html -# 12) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,9607.0.html +# 11) https://exiftool.org/forum/index.php/topic,8377.0.html +# 12) https://exiftool.org/forum/index.php/topic,9607.0.html +# 13) https://exiftool.org/forum/index.php/topic=10481.0.html # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication #------------------------------------------------------------------------------ @@ -30,12 +31,13 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.63'; +$VERSION = '1.78'; sub ProcessFujiDir($$$); sub ProcessFaceRec($$$); # the following RAF version numbers have been tested for writing: +# (as of ExifTool 11.70, this lookup is no longer used if the version number is numerical) my %testedRAF = ( '0100' => 'E550, E900, F770, S5600, S6000fd, S6500fd, HS10/HS11, HS30, S200EXR, X100, XF1, X-Pro1, X-S1, XQ2 Ver1.00, X-T100, GFX 50R, XF10', '0101' => 'X-E1, X20 Ver1.01, X-T3', @@ -49,11 +51,14 @@ my %testedRAF = ( '0144' => 'X100T Ver1.44', '0159' => 'S2Pro Ver1.00', '0200' => 'X10 Ver2.00', + '0201' => 'X-H1 Ver2.01', '0212' => 'S3Pro Ver2.12', '0216' => 'S3Pro Ver2.16', # (NC) '0218' => 'S3Pro Ver2.18', + '0240' => 'X-E1 Ver2.40', '0264' => 'F700 Ver2.00', '0266' => 'S9500 Ver1.01', + '0261' => 'X-E1 Ver2.61', '0269' => 'S9500 Ver1.02', '0271' => 'S3Pro Ver2.71', # UV/IR model? '0300' => 'X-E2', @@ -83,22 +88,34 @@ my %faceCategories = ( Name => 'Version', Writable => 'undef', }, - 0x0010 => { #PH (how does this compare to actual serial number?) + 0x0010 => { #PH/IB Name => 'InternalSerialNumber', Writable => 'string', Notes => q{ - this number is unique, and contains the date of manufacture, but doesn't - necessarily correspond to the camera body number -- this needs to be checked + this number is unique for most models, and contains the camera model ID and + the date of manufacture }, # eg) "FPX20017035 592D31313034060427796060110384" # "FPX 20495643 592D313335310701318AD010110047" (F40fd) - # yymmdd + # HHHHHHHHHHHHyymmdd + # HHHHHHHHHHHH = camera body number in hex + # yymmdd = date of manufacture PrintConv => q{ - return $val unless $val=~/^(.*)(\d{2})(\d{2})(\d{2})(.{12})$/; - my $yr = $2 + ($2 < 70 ? 2000 : 1900); - return "$1 $yr:$3:$4 $5"; + if ($val =~ /^(.*?\s*)([0-9a-fA-F]*)(\d{2})(\d{2})(\d{2})(.{12})\s*\0*$/s + and $4 >= 1 and $4 <= 12 and $5 >= 1 and $5 <= 31) + { + my $yr = $3 + ($3 < 70 ? 2000 : 1900); + my $sn = pack 'H*', $2; + return "$1$sn $yr:$4:$5 $6"; + } else { + # handle a couple of models which use a slightly different format + $val =~ s/\b(592D(3[0-9])+)/pack("H*",$1).' '/e; + } + return $val; }, - PrintConvInv => '$_=$val; s/ (19|20)(\d{2}):(\d{2}):(\d{2}) /$2$3$4/; $_', + # (this inverse conversion doesn't work in all cases, so it is best to write + # the ValueConv value if an authentic internal serial number is required) + PrintConvInv => '$_=$val; s/(\S+) (19|20)(\d{2}):(\d{2}):(\d{2}) /unpack("H*",$1)."$3$4$5"/e; $_', }, 0x1000 => { Name => 'Quality', @@ -128,6 +145,8 @@ my %faceCategories = ( Writable => 'int16u', PrintConv => { 0x0 => 'Auto', + 0x1 => 'Auto (white priority)', #forum10890 + 0x2 => 'Auto (ambiance priority)', #forum10890 0x100 => 'Daylight', 0x200 => 'Cloudy', 0x300 => 'Daylight Fluorescent', @@ -248,10 +267,22 @@ my %faceCategories = ( 16 => 'Commander', 0x8000 => 'Not Attached', #10 (X-T2) (or external flash off) 0x8120 => 'TTL', #10 (X-T2) + 0x8320 => 'TTL Auto - Did not fire', 0x9840 => 'Manual', #10 (X-T2) + 0x9860 => 'Flash Commander', #13 0x9880 => 'Multi-flash', #10 (X-T2) 0xa920 => '1st Curtain (front)', #10 (EF-X500 flash) + 0xaa20 => 'TTL Slow - 1st Curtain (front)', #13 + 0xab20 => 'TTL Auto - 1st Curtain (front)', #13 + 0xad20 => 'TTL - Red-eye Flash - 1st Curtain (front)', #13 + 0xae20 => 'TTL Slow - Red-eye Flash - 1st Curtain (front)', #13 + 0xaf20 => 'TTL Auto - Red-eye Flash - 1st Curtain (front)', #13 0xc920 => '2nd Curtain (rear)', #10 + 0xca20 => 'TTL Slow - 2nd Curtain (rear)', #13 + 0xcb20 => 'TTL Auto - 2nd Curtain (rear)', #13 + 0xcd20 => 'TTL - Red-eye Flash - 2nd Curtain (rear)', #13 + 0xce20 => 'TTL Slow - Red-eye Flash - 2nd Curtain (rear)', #13 + 0xcf20 => 'TTL Auto - Red-eye Flash - 2nd Curtain (rear)', #13 0xe920 => 'High Speed Sync (HSS)', #10 }, }, @@ -273,6 +304,7 @@ my %faceCategories = ( PrintConv => { 0 => 'Auto', 1 => 'Manual', + 65535 => 'Movie', #forum10766 }, }, 0x1022 => { #8/forum6579 @@ -344,6 +376,7 @@ my %faceCategories = ( 0x1a => 'Portrait 2', #PH (NC, T500, maybe "Smile & Shoot"?) 0x1b => 'Dog Face Detection', #7 0x1c => 'Cat Face Detection', #7 + 0x30 => 'HDR', #forum10799 0x40 => 'Advanced Filter', 0x100 => 'Aperture-priority AE', 0x200 => 'Shutter speed priority AE', @@ -435,6 +468,17 @@ my %faceCategories = ( PrintConv => '$val > 0 ? "+$val" : $val', PrintConvInv => '$val + 0', }, + # 0x104b - BWAdjustment for Green->Magenta (forum10800) + 0x104d => { #forum9634 + Name => 'CropMode', + Writable => 'int16u', + PrintConv => { # (perhaps this is a bit mask?) + 0 => 'n/a', + 1 => 'Full-frame on GFX', #IB + 2 => 'Sports Finder Mode', # (mechanical shutter) + 4 => 'Electronic Shutter 1.25x Crop', # (continuous high) + }, + }, 0x1050 => { #forum6109 Name => 'ShutterType', Writable => 'int16u', @@ -474,9 +518,9 @@ my %faceCategories = ( SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::DriveSettings' }, }, # (0x1150-0x1152 exist only for Pro Low-light and Pro Focus PictureModes) - # 0x1150 - Pro Low-light - val=1; Pro Focus - val=2 (ref 7) - # 0x1151 - Pro Low-light - val=4 (number of pictures taken?); Pro Focus - val=2,3 (ref 7) - # 0x1152 - Pro Low-light - val=1,3,4 (stacked pictures used?); Pro Focus - val=1,2 (ref 7) + # 0x1150 - Pro Low-light - val=1; Pro Focus - val=2 (ref 7); HDR - val=128 (forum10799) + # 0x1151 - Pro Low-light - val=4 (number of pictures taken?); Pro Focus - val=2,3 (ref 7); HDR - val=3 (forum10799) + # 0x1152 - Pro Low-light - val=1,3,4 (stacked pictures used?); Pro Focus - val=1,2 (ref 7); HDR - val=3 (forum10799) 0x1153 => { #forum7668 Name => 'PanoramaAngle', Writable => 'int16u', @@ -577,6 +621,8 @@ my %faceCategories = ( 0x501 => 'Pro Neg. Hi', #PH (X-Pro1) 0x600 => 'Classic Chrome', #forum6109 0x700 => 'Eterna', #12 + 0x800 => 'Classic Negative', #forum10536 + 0x900 => 'Bleach Bypass', #forum10890 }, }, 0x1402 => { #2 @@ -584,7 +630,7 @@ my %faceCategories = ( Writable => 'int16u', PrintHex => 1, PrintConv => { - 0x000 => 'Auto (100-400%)', + 0x000 => 'Auto', 0x001 => 'Manual', #(ref http://forum.photome.de/viewtopic.php?f=2&t=353) 0x100 => 'Standard (100%)', 0x200 => 'Wide1 (230%)', @@ -595,6 +641,7 @@ my %faceCategories = ( 0x1403 => { #2 (only valid for manual DR, ref 6) Name => 'DevelopmentDynamicRange', Writable => 'int16u', + # (shows 200, 400 or 800 for HDR200,HDR400,HDR800, ref forum10799) }, 0x1404 => { #2 Name => 'MinFocalLength', @@ -614,13 +661,22 @@ my %faceCategories = ( }, # 0x1408 - values: '0100', 'S100', 'VQ10' # 0x1409 - values: same as 0x1408 - # 0x140a - values: 0, 1, 3, 5, 7 (bit 2=red-eye detection, ref 11) + # 0x140a - values: 0, 1, 3, 5, 7 (bit 2=red-eye detection, ref 11/13) 0x140b => { #6 Name => 'AutoDynamicRange', Writable => 'int16u', PrintConv => '"$val%"', PrintConvInv => '$val=~s/\s*\%$//; $val', }, + 0x104e => { #forum10800 (X-Pro3) + Name => 'ColorChromeFXBlue', + Writable => 'int32s', + PrintConv => { + 0 => 'Off', + 32 => 'Weak', # (NC) + 64 => 'Strong', + }, + }, 0x1422 => { #8 Name => 'ImageStabilization', Writable => 'int16u', @@ -629,6 +685,7 @@ my %faceCategories = ( 0 => 'None', 1 => 'Optical', #PH 2 => 'Sensor-shift', #PH + 3 => 'OIS Lens', #forum9815 (optical+sensor?) 512 => 'Digital', #PH },{ 0 => 'Off', @@ -643,6 +700,8 @@ my %faceCategories = ( PrintConv => { 0 => 'Unrecognized', 0x100 => 'Portrait Image', + 0x103 => 'Night Portrait', #forum10651 + 0x105 => 'Backlit Portrait', #forum10651 0x200 => 'Landscape Image', 0x300 => 'Night Scene', 0x400 => 'Macro', @@ -677,7 +736,11 @@ my %faceCategories = ( 0x1444 => { #12 (X-T3, only exists if DRangePriority is 'Auto') Name => 'DRangePriorityAuto', Writable => 'int16u', - PrintConv => { 1 => 'Weak', 2 => 'Strong' }, + PrintConv => { + 1 => 'Weak', + 2 => 'Strong', + 3 => 'Plus', #forum10799 + }, }, 0x1445 => { #12 (X-T3, only exists if DRangePriority is 'Fixed') Name => 'DRangePriorityFixed', @@ -687,12 +750,41 @@ my %faceCategories = ( 0x1446 => { #12 Name => 'FlickerReduction', Writable => 'int32u', + # seen values: Off=0x0000, On=0x2100,0x3100 PrintConv => q{ - my $on = ((($val >> 12) & 0xff) == 3) ? 'On' : 'Off'; + my $on = ((($val >> 8) & 0x0f) == 1) ? 'On' : 'Off'; return sprintf('%s (0x%.4x)', $on, $val); }, PrintConvInv => '$val=~/(0x[0-9a-f]+)/i; hex $1', }, + 0x3803 => { #forum10037 + Name => 'VideoRecordingMode', + Groups => { 2 => 'Video' }, + Writable => 'int32u', + PrintHex => 1, + PrintConv => { + 0x00 => 'Normal', + 0x10 => 'F-log', + 0x20 => 'HLG', + }, + }, + 0x3804 => { #forum10037 + Name => 'PeripheralLighting', + Groups => { 2 => 'Video' }, + Writable => 'int16u', + PrintConv => { 0 => 'Off', 1 => 'On' }, + }, + # 0x3805 - int16u: seen 1 + 0x3806 => { #forum10037 + Name => 'VideoCompression', + Groups => { 2 => 'Video' }, + Writable => 'int16u', + PrintConv => { + 1 => 'Log GOP', + 2 => 'All Intra', + }, + }, + # 0x3810 - int32u: related to video codec (ref forum10037) 0x3820 => { #PH (HS20EXR MOV) Name => 'FrameRate', Writable => 'int16u', @@ -708,6 +800,17 @@ my %faceCategories = ( Writable => 'int16u', Groups => { 2 => 'Video' }, }, + 0x3824 => { #forum10480 (X series) + Name => 'FullHDHighSpeedRec', + Writable => 'int32u', + Groups => { 2 => 'Video' }, + PrintConv => { 1 => 'Off', 2 => 'On' }, + }, + 0x4005 => { #forum9634 + Name => 'FaceElementSelected', # (could be face or eye) + Writable => 'int16u', + Count => 4, + }, 0x4100 => { #PH Name => 'FacesDetected', Writable => 'int16u', @@ -813,9 +916,10 @@ my %faceCategories = ( Name => 'FocusMode2', Mask => 0x000000ff, PrintConv => { - 0 => 'AF-M', - 1 => 'AF-S', - 2 => 'AF-C', + 0x00 => 'AF-M', + 0x01 => 'AF-S', + 0x02 => 'AF-C', + 0x11 => 'AF-S (Auto)', }, }, 0.2 => { @@ -977,9 +1081,30 @@ my %faceCategories = ( Groups => { 1 => 'RAF2' }, # (so RAF2 shows up in family 1 list) Count => 2, Notes => 'including borders', - ValueConv => 'my @v=reverse split(" ",$val);"@v"', + ValueConv => 'my @v=reverse split(" ",$val);"@v"', # reverse to show width first PrintConv => '$val=~tr/ /x/; $val', }, + 0x110 => { + Name => 'RawImageCropTopLeft', + Format => 'int16u', + Count => 2, + Notes => 'top margin first, then left margin', + }, + 0x111 => { + Name => 'RawImageCroppedSize', + Format => 'int16u', + Count => 2, + Notes => 'including borders', + ValueConv => 'my @v=reverse split(" ",$val);"@v"', # reverse to show width first + PrintConv => '$val=~tr/ /x/; $val', + }, + 0x115 => { + Name => 'RawImageAspectRatio', + Format => 'int16u', + Count => 2, + ValueConv => 'my @v=reverse split(" ",$val);"@v"', # reverse to show width first + PrintConv => '$val=~tr/ /:/; $val', + }, 0x121 => [ { Name => 'RawImageSize', @@ -1367,9 +1492,10 @@ sub WriteRAF($$) return 1; } # check to make sure this version of RAF has been tested - unless ($testedRAF{$ver}) { - $et->Warn("RAF version $ver not yet tested", 1); - } + #(removed in ExifTool 11.70) + #unless ($testedRAF{$ver}) { + # $et->Warn("RAF version $ver not yet tested", 1); + #} # read the embedded JPEG unless ($raf->Seek($jpos, 0) and $raf->Read($jpeg, $jlen) == $jlen) { $et->Error('Error reading RAF meta information'); @@ -1532,7 +1658,7 @@ FujiFilm maker notes in EXIF information, and to read/write FujiFilm RAW =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/GE.pm b/src/Image-ExifTool/lib/Image/ExifTool/GE.pm index 9e8b7ab5..d321dd17 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/GE.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/GE.pm @@ -68,7 +68,7 @@ General Imaging maker notes. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/GIF.pm b/src/Image-ExifTool/lib/Image/ExifTool/GIF.pm index dda3d08d..8a4d33cb 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/GIF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/GIF.pm @@ -20,7 +20,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.16'; +$VERSION = '1.17'; # road map of directory locations in GIF images my %gifMap = ( @@ -42,7 +42,7 @@ my %gifMap = ( Comment => { # for documentation only -- flag as writable for the docs, but # it won't appear in the TagLookup because there is no WRITE_PROC - Writable => 1, + Writable => 2, }, Duration => { Notes => 'duration of a single animation iteration', @@ -67,12 +67,12 @@ my %gifMap = ( 'XMP Data/XMP' => { #2 Name => 'XMP', IncludeLengthBytes => 1, # length bytes are included in the data - Writable => 1, + Writable => 2, SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, }, 'ICCRGBG1/012' => { #4 Name => 'ICC_Profile', - Writable => 1, + Writable => 2, SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' }, }, 'MIDICTRL/Jon' => { #5 @@ -466,7 +466,7 @@ Block: } elsif ($a == 0xf9 and $length == 4) { # graphic control extension last unless $raf->Read($buff, $length) == $length; - # sum the indivual delay times + # sum the individual delay times my $delay = Get16u(\$buff, 1); $delayTime += $delay; $verbose and printf $out "Graphic Control: delay=%.2f\n", $delay / 100; @@ -532,7 +532,7 @@ write GIF meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/GIMP.pm b/src/Image-ExifTool/lib/Image/ExifTool/GIMP.pm index bcba96b8..9c70d7fc 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/GIMP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/GIMP.pm @@ -228,7 +228,7 @@ sub ProcessXCF($$) # skip over precision for XCV version 4 or later $raf->Seek(4, 1) if $$et{XCFVersion} =~ /^v0*(\d+)/ and $1 >= 4; - + # loop through image properties for (;;) { $raf->Read($buff, 8) == 8 or last; @@ -270,7 +270,7 @@ GIMP software. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/GPS.pm b/src/Image-ExifTool/lib/Image/ExifTool/GPS.pm index a1c8131f..313e056d 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/GPS.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/GPS.pm @@ -12,7 +12,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool::Exif; -$VERSION = '1.50'; +$VERSION = '1.51'; my %coordConv = ( ValueConv => 'Image::ExifTool::GPS::ToDegrees($val)', @@ -96,13 +96,13 @@ my %coordConv = ( Name => 'GPSAltitudeRef', Writable => 'int8u', Notes => q{ - ExifTool will also accept a signed number when writing this tag, beginning - with "+" for above sea level, or "-" for below + ExifTool will also accept number when writing this tag, with negative + numbers indicating below sea level }, PrintConv => { OTHER => sub { my ($val, $inv) = @_; - return undef unless $inv and $val =~ /^([-+])/; + return undef unless $inv and $val =~ /^([-+0-9])/; return($1 eq '-' ? 1 : 0); }, 0 => 'Above Sea Level', @@ -383,11 +383,11 @@ my %coordConv = ( my $alt = $val[0]; $alt = $val[2] unless defined $alt; return undef unless defined $alt and IsFloat($alt); - return ($val[1] || $val[3]) ? -$alt : $alt; + return(($val[1] || $val[3]) ? -$alt : $alt); }, PrintConv => q{ $val = int($val * 10) / 10; - return ($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level"; + return(($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level"); }, }, GPSDestLatitude => { @@ -459,7 +459,7 @@ sub ToDMS($$;$$) unless (length $val) { # don't convert an empty value - return $val if $doPrintConv and $doPrintConv eq 1; # avoid hiding existing tag when extracting + return $val if $doPrintConv and $doPrintConv eq '1'; # avoid hiding existing tag when extracting return undef; # avoid writing empty value } if ($ref) { @@ -534,6 +534,7 @@ sub ToDMS($$;$$) sub ToDegrees($;$) { my ($val, $doSign) = @_; + return '' if $val =~ /\b(inf|undef)\b/; # ignore invalid values # extract decimal or floating point values out of any other garbage my ($d, $m, $s) = ($val =~ /((?:[+-]?)(?=\d|\.\d)\d*(?:\.\d*)?(?:[Ee][+-]\d+)?)/g); return '' unless defined $d; @@ -563,7 +564,7 @@ GPS (Global Positioning System) meta information in EXIF data. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/GeoTiff.pm b/src/Image-ExifTool/lib/Image/ExifTool/GeoTiff.pm index 80aacc41..042b31a9 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/GeoTiff.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/GeoTiff.pm @@ -603,7 +603,7 @@ my %epsg_vertcs = ( 20499 => 'Ain el Abd Bahrain Grid', 20538 => 'Afgooye UTM zone 38N', 20539 => 'Afgooye UTM zone 39N', - 20700 => 'Lisbon Portugese Grid', + 20700 => 'Lisbon Portuguese Grid', 20822 => 'Aratu UTM zone 22S', 20823 => 'Aratu UTM zone 23S', 20824 => 'Aratu UTM zone 24S', @@ -2240,7 +2240,7 @@ coordinates. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Geotag.pm b/src/Image-ExifTool/lib/Image/ExifTool/Geotag.pm index a0628def..f74ffbb2 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Geotag.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Geotag.pm @@ -11,6 +11,8 @@ # 2012/05/08 - PH Read Winplus Beacon .TXT files # 2015/05/30 - PH Read Bramor gEO log files # 2016/07/13 - PH Added ability to geotag date/time only +# 2019/07/02 - PH Added ability to read IMU CSV files +# 2019/11/10 - PH Also write pitch to CameraElevationAngle # # References: 1) http://www.topografix.com/GPX/1/1/ # 2) http://www.gpsinformation.org/dale/nmea.htm#GSA @@ -24,7 +26,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:Public); -$VERSION = '1.56'; +$VERSION = '1.61'; sub JITTER() { return 2 } # maximum time jitter @@ -52,6 +54,7 @@ my %xmlTag = ( vdop => 'vdop', # GPX pdop => 'pdop', # GPX sat => 'nsats', # GPX + atemp => 'atemp', # GPX (Garmin 550t) when => 'time', # KML coordinates => 'coords', # KML coord => 'coords', # KML, as written by Google Location History @@ -77,6 +80,7 @@ my %fixInfoKeys = ( track => [ 'track', 'speed' ], alt => [ 'alt' ], orient => [ 'dir', 'pitch', 'roll' ], + atemp => [ 'atemp' ], ); my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key @@ -127,7 +131,7 @@ sub LoadTrackLog($$;$) local ($_, $/, *EXIFTOOL_TRKFILE); my ($et, $val) = @_; my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm); - my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea); + my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings); my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp); unless (eval { require Time::Local }) { @@ -205,7 +209,7 @@ sub LoadTrackLog($$;$) $format = 'XML'; # check for NMEA sentence # (must ONLY start with ones that have timestamps! eg. not GSA or PTNTHPR!) - } elsif (/^\$([A-Z]{2}(RMC|GGA|GLL|ZDA)|PMGNTRK),/) { + } elsif (/^.*\$([A-Z]{2}(RMC|GGA|GLL|ZDA)|PMGNTRK),/) { $format = 'NMEA'; $nmeaStart = $2 || $1; # save type of first sentence } elsif (/^A(FLA|XSY|FIL)/) { @@ -214,7 +218,7 @@ sub LoadTrackLog($$;$) next; } elsif (/^HFDTE(\d{2})(\d{2})(\d{2})/) { my $year = $3 + ($3 >= 70 ? 1900 : 2000); - $dateFlarm = Time::Local::timegm(0,0,0,$1,$2-1,$year-1900); + $dateFlarm = Time::Local::timegm(0,0,0,$1,$2-1,$year); $nmeaStart = 'B' ; $format = 'IGC'; next; @@ -225,6 +229,10 @@ sub LoadTrackLog($$;$) $format = 'Winplus'; } elsif (/^\s*\d+\s+.*\sypr\s*$/ and (@tmp=split) == 12) { $format = 'Bramor'; + } elsif (/\bDate\b/i and /\bTime\b/ and ',') { + @csvHeadings = split ','; + $format = 'CSV'; + next; } else { # search only first 50 lines of file for a valid fix last if ++$skipped > 50; @@ -253,6 +261,8 @@ sub LoadTrackLog($$;$) # validate altitude undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/; $$has{alt} = 1 if $$fix{alt}; # set "has altitude" flag if appropriate + } elsif ($tag eq 'atemp') { + $$has{atemp} = 1; } } } @@ -292,6 +302,8 @@ sub LoadTrackLog($$;$) # validate altitude undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/; $$has{alt} = 1 if $$fix{alt}; # set "has altitude" flag if appropriate + } elsif ($tag eq 'atemp') { + $$has{atemp} = 1; } } } @@ -352,7 +364,7 @@ sub LoadTrackLog($$;$) /^TP,D,\s*([-+]?\d+\.\d*),\s*([-+]?\d+\.\d*),\s*(\d+)\/(\d+)\/(\d{4}),\s*(\d+):(\d+):(\d+)/ or next; $$fix{lat} = $1; $$fix{lon} = $2; - $time = Time::Local::timegm($8,$7,$6,$4,$3-1,$5-1900); + $time = Time::Local::timegm($8,$7,$6,$4,$3-1,$5); DoneFix: $isDate = 1; $$points{$time} = $fix; push @fixTimes, $time; @@ -372,17 +384,57 @@ DoneFix: $isDate = 1; next unless @d == 3 and @t == 3; @$fix{qw(lat lon alt track dir pitch roll)} = @parts[2,3,4,5,8,9,10]; # (add the seconds afterwards in case some models have decimal seconds) - $time = Time::Local::timegm(0,$t[1],$t[0],$d[0],$d[1]-1,$d[2]-1900) + $t[2]; + $time = Time::Local::timegm(0,$t[1],$t[0],$d[0],$d[1]-1,$d[2]) + $t[2]; # set necessary flags for extra available information @$has{qw(alt track orient)} = (1,1,1); goto DoneFix; # save this fix +# +# CSV format output of GPS/IMU POS system +# + } elsif ($format eq 'CSV') { + my @vals = split ','; + my ($label, $date, $secs); + foreach $label (@csvHeadings) { + my $val = shift @vals; + last unless defined $val; + if ($label =~ /^Date/i) { + if ($val =~ m{^(\d{2})/(\d{2})/(\d{4})$}) { + $date = Time::Local::timegm(0,0,0,$1,$2-1,$3); + } + } elsif ($label =~ /^Time/i) { + if ($val =~ /^(\d{1,2}):(\d{2}):(\d{2}(\.\d+)?)/) { + $secs = (($1 * 60) + $2) * 60 + $3; + } + } elsif ($label =~ /^(Pos)?Lat/) { + $$fix{lat} = $val; + } elsif ($label =~ /^(Pos)?Lon/) { + $$fix{lon} = $val; + } elsif ($label =~ /^(Pos)?Alt/) { + $$fix{alt} = $val; + } elsif ($label =~ /^(Angle)?Heading/) { + $$fix{track} = $val; + } elsif ($label =~ /^(Angle)?Pitch/) { + $$fix{pitch} = $val; + } elsif ($label =~ /^(Angle)?Roll/) { + $$fix{roll} = $val; + } + } + if ($date and defined $secs and defined $$fix{lat} and defined $$fix{lon}) { + $time = $date + $secs; + $$has{alt} = 1 if defined $$fix{alt}; + $$has{track} = 1 if defined $$fix{track}; + $$has{orient} = 1 if defined $$fix{pitch}; + goto DoneFix; + } + next; } my (%fix, $secs, $date, $nmea); if ($format eq 'NMEA') { # ignore unrecognized NMEA sentences # (first 2 characters: GP=GPS, GL=GLONASS, GA=Gallileo, GN=combined, BD=Beidou) - next unless /^\$([A-Z]{2}(RMC|GGA|GLL|GSA|ZDA)|PMGNTRK|PTNTHPR),/; - $nmea = $2 || $1; + next unless /^(.*)\$([A-Z]{2}(RMC|GGA|GLL|GSA|ZDA)|PMGNTRK|PTNTHPR),/; + $nmea = $3 || $2; + $_ = substr($_, length($1)) if length($1); } # # IGC (flarm) (ref 4) @@ -418,7 +470,7 @@ DoneFix: $isDate = 1; $fix{track} = $12 if length $12; my $year = $15 + ($15 >= 70 ? 1900 : 2000); $secs = (($1 * 60) + $2) * 60 + $3; - $date = Time::Local::timegm(0,0,0,$13,$14-1,$year-1900); + $date = Time::Local::timegm(0,0,0,$13,$14-1,$year); # # NMEA GGA sentence (no date) # @@ -461,7 +513,7 @@ DoneFix: $isDate = 1; # $GPZDA,hhmmss.ss,DD,MM,YYYY,tzh,tzm (hhmmss in UTC) /^\$[A-Z]{2}ZDA,(\d{2})(\d{2})(\d{2}(\.\d*)?),(\d+),(\d+),(\d+)/ or next; $secs = (($1 * 60) + $2) * 60 + $3; - $date = Time::Local::timegm(0,0,0,$5,$6-1,$7-1900); + $date = Time::Local::timegm(0,0,0,$5,$6-1,$7); # # Magellan eXplorist PMGNTRK (Proprietary MaGellaN TRacK) sentence (optional date) # @@ -477,7 +529,7 @@ DoneFix: $isDate = 1; next if $13 > 31 or $14 > 12 or $15 > 99; # validate day/month/year # optional date is available in PMGNTRK sentence my $year = $15 + ($15 >= 70 ? 1900 : 2000); - $date = Time::Local::timegm(0,0,0,$13,$14-1,$year-1900); + $date = Time::Local::timegm(0,0,0,$13,$14-1,$year); } # # Honeywell HMR3000 PTNTHPR (Heading Pitch Roll) sentence (no date) @@ -666,7 +718,7 @@ sub GetTime($) { my $timeStr = shift; $timeStr =~ /^(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d+)(\.\d+)?(.*)/ or return undef; - my $time = Time::Local::timegm($6,$5,$4,$3,$2-1,$1-1900); + my $time = Time::Local::timegm($6,$5,$4,$3,$2-1,$1); $time += $7 if $7; # add fractional seconds my $tz = $8; # adjust for time zone (otherwise assume UTC) @@ -831,7 +883,7 @@ sub SetGeoValues($$;$) last; } if ($tz) { - $time = Time::Local::timegm($sec,$min,$hr,$day,$mon-1,$year-1900); + $time = Time::Local::timegm($sec,$min,$hr,$day,$mon-1,$year); # use timezone from date/time value if ($tz ne 'Z') { my $tzmin = $t1 * 60 + $t2; @@ -839,7 +891,7 @@ sub SetGeoValues($$;$) } } else { # assume local timezone - $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$year-1900); + $time = Image::ExifTool::TimeLocal($sec,$min,$hr,$day,$mon-1,$year); } # add fractional seconds $time += $fs if $fs and $fs ne '.'; @@ -934,7 +986,7 @@ sub SetGeoValues($$;$) # loop through available fix information categories # (pos, track, alt, orient) my ($category, $key); -Category: foreach $category (qw{pos track alt orient}) { +Category: foreach $category (qw{pos track alt orient atemp}) { next unless $$has{$category}; my ($f, $p0b, $p1b, $f0b); # loop through specific fix information keys @@ -1055,10 +1107,20 @@ Category: foreach $category (qw{pos track alt orient}) { } @r = $et->SetNewValue(GPSImgDirection => $$tFix{dir}, %opts); @r = $et->SetNewValue(GPSImgDirectionRef => (defined $$tFix{dir} ? 'T' : undef), %opts); + @r = $et->SetNewValue(CameraElevationAngle => $$tFix{pitch}, %opts); # Note: GPSPitch and GPSRoll are non-standard, and must be user-defined @r = $et->SetNewValue(GPSPitch => $$tFix{pitch}, %opts); @r = $et->SetNewValue(GPSRoll => $$tFix{roll}, %opts); } + if ($$has{atemp}) { + my $tFix = $fix; + if (not defined $$fix{atemp} and defined $iExt) { + # (not all fixes have atemp, so try interpolating specifically for this) + my $p = FindFix($et,'atemp',$times,$points,$iExt,$iDir,$geoMaxExtSecs); + $tFix = $p if $p; + } + @r = $et->SetNewValue(AmbientTemperature => $$tFix{atemp}, %opts); + } unless ($xmp) { my ($latRef, $lonRef); $latRef = ($$fix{lat} > 0 ? 'N' : 'S') if defined $$fix{lat}; @@ -1075,15 +1137,16 @@ Category: foreach $category (qw{pos track alt orient}) { @r = $et->SetNewValue(GPSDateTime => "$gpsDate $gpsTime", %opts); } } else { - my %opts; + my %opts = ( IgnorePermanent => 1 ); $opts{Replace} = 2 if defined $val; # remove existing new values $opts{Group} = $writeGroup if $writeGroup; # reset any GPS values we might have already set foreach (qw(GPSLatitude GPSLatitudeRef GPSLongitude GPSLongitudeRef GPSAltitude GPSAltitudeRef GPSDateStamp GPSTimeStamp GPSDateTime - GPSTrack GPSTrackRef GPSSpeed GPSSpeedRef - GPSImgDirection GPSImgDirectionRef GPSPitch GPSRoll)) + GPSTrack GPSTrackRef GPSSpeed GPSSpeedRef GPSImgDirection + GPSImgDirectionRef GPSPitch GPSRoll CameraElevationAngle + AmbientTemperature)) { my @r = $et->SetNewValue($_, undef, %opts); } @@ -1267,7 +1330,8 @@ This module is used by Image::ExifTool This module loads GPS track logs, interpolates to determine position based on time, and sets new GPS values for geotagging images. Currently supported formats are GPX, NMEA RMC/GGA/GLL, KML, IGC, Garmin XML and TCX, Magellan -PMGNTRK, Honeywell PTNTHPR, Winplus Beacon text, and Bramor gEO log files. +PMGNTRK, Honeywell PTNTHPR, Winplus Beacon text, IMU CSV, and Bramor gEO log +files. Methods in this module should not be called directly. Instead, the Geotag feature is accessed by writing the values of the ExifTool Geotag, Geosync @@ -1276,12 +1340,12 @@ in the tag name documentation). =head1 NOTES -To take advantage of attitude information in the PTNTHPR NMEA sentence, two -user-defined tags, GPSPitch and GPSRoll, must be active. +To take advantage of attitude information in the PTNTHPR NMEA sentence, the +user-defined tag GPSRoll, must be active. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/GoPro.pm b/src/Image-ExifTool/lib/Image/ExifTool/GoPro.pm new file mode 100644 index 00000000..4cd985a0 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/GoPro.pm @@ -0,0 +1,711 @@ +#------------------------------------------------------------------------------ +# File: GoPro.pm +# +# Description: Read information from GoPro videos +# +# Revisions: 2018/01/12 - P. Harvey Created +# +# References: 1) https://github.com/gopro/gpmf-parser +# 2) https://github.com/stilldavid/gopro-utils +#------------------------------------------------------------------------------ + +package Image::ExifTool::GoPro; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); +use Image::ExifTool::QuickTime; + +$VERSION = '1.03'; + +sub ProcessGoPro($$$); +sub ProcessString($$$); +sub ScaleValues($$); +sub AddUnits($$$); +sub ConvertSystemTime($$); + +# GoPro data types that have ExifTool equivalents (ref 1) +my %goProFmt = ( # format codes + # 0x00 - container (subdirectory) + 0x62 => 'int8s', # 'b' + 0x42 => 'int8u', # 'B' + 0x63 => 'string', # 'c' (possibly null terminated) + 0x73 => 'int16s', # 's' + 0x53 => 'int16u', # 'S' + 0x6c => 'int32s', # 'l' + 0x4c => 'int32u', # 'L' + 0x66 => 'float', # 'f' + 0x64 => 'double', # 'd' + 0x46 => 'undef', # 'F' (4-char ID) + 0x47 => 'undef', # 'G' (16-byte uuid) + 0x6a => 'int64s', # 'j' + 0x4a => 'int64u', # 'J' + 0x71 => 'fixed32s', # 'q' + 0x51 => 'fixed64s', # 'Q' + 0x55 => 'undef', # 'U' (16-byte date) + 0x3f => 'undef', # '?' (complex structure) +); + +# sizes of format codes if different than what FormatSize() would return +my %goProSize = ( + 0x46 => 4, + 0x47 => 16, + 0x55 => 16, +); + +# tagInfo elements to add units to PrintConv value +my %addUnits = ( + AddUnits => 1, + PrintConv => 'Image::ExifTool::GoPro::AddUnits($self, $val, $tag)', +); + +# Tags found in the GPMF box of Hero6 mp4 videos (ref PH), and +# the gpmd-format timed metadata of Hero5 and Hero6 videos (ref 1) +%Image::ExifTool::GoPro::GPMF = ( + PROCESS_PROC => \&ProcessGoPro, + GROUPS => { 2 => 'Camera' }, + NOTES => q{ + Tags extracted from the GPMF box of GoPro MP4 videos, the APP6 "GoPro" + segment of JPEG files, and from the "gpmd" timed metadata if the + L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option is enabled. Many more tags exist, but are + currently unknown and extracted only with the L<Unknown|../ExifTool.html#Unknown> (-u) option. Please + let me know if you discover the meaning of any of these unknown tags. See + L<https://github.com/gopro/gpmf-parser> for details about this format. + }, + ACCL => { #2 (gpmd) + Name => 'Accelerometer', + Notes => 'accelerator readings in m/s2', + Binary => 1, + }, + ALLD => 'AutoLowLightDuration', #1 (gpmd) (untested) + # APTO (GPMF) - seen: 'RAW', 'DYNM' (fmt c) + ATTD => { #PH (Karma) + Name => 'Attitude', + # UNIT=s,rad,rad,rad,rad/s,rad/s,rad/s, + # TYPE=LffffffB + # SCAL=1000 1 1 1 1 1 1 1 + Binary => 1, + }, + ATTR => { #PH (Karma) + Name => 'AttitudeTarget', + # UNIT=s,rad,rad,rad, + # TYPE=Jffff + # SCAL=1000 1 1 1 1 + Binary => 1, + }, + AUDO => 'AudioSetting', #PH (GPMF - seen: 'WIND', fmt c) + # AUPT (GPMF) - seen: 'N','Y' (fmt c) + BPOS => { #PH (Karma) + Name => 'Controller', + Unknown => 1, + # UNIT=deg,deg,m,deg,deg,m,m,m + # TYPE=lllfffff + # SCAL=10000000 10000000 1000 1 1 1 1 1 + %addUnits, + }, + # BRID (GPMF) - seen: 0 (fmt B) + # BROD (GPMF) - seen: 'ASK','' (fmt c) + CASN => 'CameraSerialNumber', #PH (GPMF - seen: 'C3221324545448', fmt c) + # CINF (GPMF) - seen: 0x67376be7709bc8876a8baf3940908618 (fmt B) (Camera INFormation?) + # CMOD (GPMF) - seen: 12,13,17 [13 time-laps video, 17 JPEG] (fmt B) + CYTS => { #PH (Karma) + Name => 'CoyoteStatus', + # UNIT=s,,,,,rad,rad,rad,, + # TYPE=LLLLLfffBB + # SCAL=1000 1 1 1 1 1 1 1 1 1 + Binary => 1, + }, + CSEN => { #PH (Karma) + Name => 'CoyoteSense', + # UNIT=s,rad/s,rad/s,rad/s,g,g,g,,,, + # TYPE=LffffffLLLL + # SCAL=1000 1 1 1 1 1 1 1 1 1 1 + Binary => 1, + }, + DEVC => { #PH (gpmd,GPMF, fmt \0) + Name => 'DeviceContainer', + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' }, + }, + # DVID (GPMF) - DeviceID; seen: 1 (fmt L), HLMT (fmt F) + DVID => { Name => 'DeviceID', Unknown => 1 }, #2 (gpmd) + # DVNM (GPMF) seen: 'Video Global Settings' (fmt c), 'Highlights' (fmt c) + # DVNM (gpmd) seen: 'Camera' (Hero5), 'Hero6 Black' (Hero6), 'GoPro Karma v1.0' (Karma) + DVNM => 'DeviceName', #PH (n/c) + DZOM => { #PH (GPMF - seen: 'Y', fmt c) + Name => 'DigitalZoom', + PrintConv => { N => 'No', Y => 'Yes' }, + }, + # DZST (GPMF) - seen: 0 (fmt L) (something to do with digital zoom maybe?) + EISA => { #PH (GPMF) - seen: 'Y','N', 'HS EIS' (fmt c) [N was for a time-lapse video] + Name => 'ElectronicImageStabilization', + }, + # EISE (GPMF) - seen: 'Y' (fmt c) + EMPT => { Name => 'Empty', Unknown => 1 }, #2 (gpmd) + ESCS => { #PH (Karma) + Name => 'EscapeStatus', + # UNIT=s,rpm,rpm,rpm,rpm,rpm,rpm,rpm,rpm,degC,degC,degC,degC,V,V,V,V,A,A,A,A,,,,,,,,, + # TYPE=JSSSSSSSSssssSSSSSSSSSSSSSSSSB + # (no SCAL!) + Unknown => 1, + %addUnits, + }, + # EXPT (GPMF) - seen: '', 'AUTO' (fmt c) + FACE => 'FaceDetected', #PH (gpmd) + FCNM => 'FaceNumbers', #PH (gpmd) (faces counted per frame, ref 1) + FMWR => 'FirmwareVersion', #PH (GPMF - seen: HD6.01.01.51.00, fmt c) + FWVS => 'OtherFirmware', #PH (NC) (gpmd - seen: '1.1.11.0', Karma) + GLPI => { #PH (gpmd, Karma) + Name => 'GPSPos', + # UNIT=s,deg,deg,m,m,m/s,m/s,m/s,deg + # TYPE=LllllsssS + # SCAL=1000 10000000 10000000 1000 1000 100 100 100 100 + RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GLPI' }, + }, + GPRI => { #PH (gpmd, Karma) + Name => 'GPSRaw', + # UNIT=s,deg,deg,m,m,m,m/s,deg,, + # TYPE=JlllSSSSBB + # SCAL=1000000,10000000,10000000,1000,100,100,100,100,1,1 + Unknown => 1, + RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPRI' }, + }, + GPS5 => { #2 (gpmd) + Name => 'GPSInfo', + # SCAL=10000000,10000000,1000,1000,100 + RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPS5' }, + }, + GPSF => { #2 (gpmd) + Name => 'GPSMeasureMode', + PrintConv => { + 2 => '2-Dimensional Measurement', + 3 => '3-Dimensional Measurement', + }, + }, + GPSP => { #2 (gpmd) + Name => 'GPSHPositioningError', + Description => 'GPS Horizontal Positioning Error', + ValueConv => '$val / 100', # convert from cm to m + }, + GPSU => { #2 (gpmd) + Name => 'GPSDateTime', + Groups => { 2 => 'Time' }, + # (HERO5 writes this in 'c' format, HERO6 writes 'U') + ValueConv => '$val =~ s/^(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/20$1:$2:$3 $4:$5:/; $val', + PrintConv => '$self->ConvertDateTime($val)', + }, + GYRO => { #2 (gpmd) + Name => 'Gyroscope', + Notes => 'gyroscope readings in rad/s', + Binary => 1, + }, + # HFLG (APP6) - seen: 0 + ISOE => 'ISOSpeeds', #PH (gpmd) + ISOG => { #2 (gpmd) + Name => 'ImageSensorGain', + Binary => 1, + }, + KBAT => { #PH (gpmd) (Karma) + Name => 'BatteryStatus', + # UNIT=A,Ah,J,degC,V,V,V,V,s,%,,,,,% + # TYPE=lLlsSSSSSSSBBBb + # SCAL=1000,1000,0.00999999977648258,100,1000,1000,1000,1000,0.0166666675359011,1,1,1,1,1,1 + RawConv => '$val', # necessary to use scaled value instead of raw data as subdir data + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::KBAT' }, + }, + # LINF (GPMF) - seen: LAJ7061916601668 (fmt c) (Lens INFormation?) + LNED => { #PH (Karma) + Name => 'LocalPositionNED', + # UNIT=s,m,m,m,m/s,m/s,m/s + # TYPE=Lffffff + # SCAL=1000 1 1 1 1 1 1 + Binary => 1, + }, + MAGN => 'Magnetometer', #1 (gpmd) (units of uT) + MINF => { #PH (GPMF - seen: HERO6 Black, fmt c) + Name => 'Model', + Groups => { 2 => 'Camera' }, + Description => 'Camera Model Name', + }, + # MTYP (GPMF) - seen: 0,1,11 [1 for time-lapse video, 11 for JPEG] (fmt B) + # MUID (GPMF) - seen: 3882563431 2278071152 967805802 411471936 0 0 0 0 (fmt L) + OREN => { #PH (GPMF - seen: 'U', fmt c) + Name => 'AutoRotation', + PrintConv => { + U => 'Up', + D => 'Down', # (NC) + A => 'Auto', # (NC) + }, + }, + # (most of the "P" tags are ProTune settings - PH) + PHDR => 'HDRSetting', #PH (APP6 - seen: 0) + PIMN => 'AutoISOMin', #PH (GPMF - seen: 100, fmt L) + PIMX => 'AutoISOMax', #PH (GPMF - seen: 1600, fmt L) + # PRAW (APP6) - seen: 0, 'N' (fmt c) + PRES => 'PhotoResolution', #PH (APP6 - seen: '12MP_W') + PRTN => { #PH (GPMF - seen: 'N', fmt c) + Name => 'ProTune', + PrintConv => { + N => 'Off', + Y => 'On', # (NC) + }, + }, + PTCL => 'ColorMode', #PH (GPMF - seen: 'GOPRO', fmt c' APP6: 'FLAT') + PTEV => 'ExposureCompensation', #PH (GPMF - seen: '0.0', fmt c) + PTSH => 'Sharpness', #PH (GPMF - seen: 'HIGH', fmt c) + PTWB => 'WhiteBalance', #PH (GPMF - seen: 'AUTO', fmt c) + RATE => 'Rate', #PH (GPMF - seen: '0_5SEC', fmt c; APP6 - seen: '4_1SEC') + RMRK => { #2 (gpmd) + Name => 'Comments', + ValueConv => '$self->Decode($val, "Latin")', + }, + SCAL => { #2 (gpmd) scale factor for subsequent data + Name => 'ScaleFactor', + Unknown => 1, + }, + SCPR => { #PH (Karma) [stream was empty] + Name => 'ScaledPressure', + # UNIT=s,Pa,Pa,degC + # TYPE=Lffs + # SCAL=1000 0.00999999977648258 0.00999999977648258 100 + %addUnits, + }, + SHUT => { #2 (gpmd) + Name => 'ExposureTimes', + PrintConv => q{ + my @a = split ' ', $val; + $_ = Image::ExifTool::Exif::PrintExposureTime($_) foreach @a; + return join ' ', @a; + }, + }, + SIMU => { #PH (Karma) + Name => 'ScaledIMU', + # UNIT=s,g,g,g,rad/s,rad/s,rad/s,T,T,T + # TYPE=Lsssssssss + # SCAL=1000 1000 1000 1000 1000 1000 1000 1000 1000 1000 + %addUnits, + }, + SIUN => { #2 (gpmd - seen : 'm/s2','rad/s') + Name => 'SIUnits', + Unknown => 1, + ValueConv => '$self->Decode($val, "Latin")', + }, + # SMTR (GPMF) - seen: 'N' (fmt c) + STMP => { #1 (gpmd) + Name => 'TimeStamp', + ValueConv => '$val / 1e6', + }, + STRM => { #2 (gpmd,GPMF, fmt \0) + Name => 'NestedSignalStream', + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' }, + }, + STNM => { #2 (gpmd) + Name => 'StreamName', + Unknown => 1, + ValueConv => '$self->Decode($val, "Latin")', + }, + SYST => { #PH (Karma) + Name => 'SystemTime', + # UNIT=s,s + # TYPE=JJ + # SCAL=1000000 1000 + # save system time calibrations for later + RawConv => q{ + my @v = split ' ', $val; + if (@v == 2) { + my $s = $$self{SystemTimeList}; + $s or $s = $$self{SystemTimeList} = [ ]; + push @$s, \@v; + } + return $val; + }, + }, + # TICK => { Name => 'InTime', Unknown => 1, ValueConv => '$val/1000' }, #1 (gpmd) + TMPC => { #2 (gpmd) + Name => 'CameraTemperature', + PrintConv => '"$val C"', + }, + # TOCK => { Name => 'OutTime', Unknown => 1, ValueConv => '$val/1000' }, #1 (gpmd) + TSMP => { Name => 'TotalSamples', Unknown => 1 }, #2 (gpmd) + TYPE => { Name => 'StructureType', Unknown => 1 }, #2 (gpmd,GPMF - eg 'LLLllfFff', fmt c) + UNIT => { #2 (gpmd) alternative units + Name => 'Units', + Unknown => 1, + ValueConv => '$self->Decode($val, "Latin")', + }, + VFOV => { #PH (GPMF - seen: 'W', fmt c) + Name => 'FieldOfView', + PrintConv => { + W => 'Wide', + S => 'Super View', # (NC, not seen) + L => 'Linear', # (NC, not seen) + }, + }, + # VLTA (GPMF) - seen: 78 ('N') (fmt B -- wrong format?) + VFRH => { #PH (Karma) + Name => 'VisualFlightRulesHUD', + BinaryData => 1, + # UNIT=m/s,m/s,m,m/s,deg,% + # TYPE=ffffsS + }, + # VLTE (GPMF) - seen: 'Y','N' (fmt c) + WBAL => 'ColorTemperatures', #PH (gpmd) + WRGB => { #PH (gpmd) + Name => 'WhiteBalanceRGB', + Binary => 1, + }, +); + +# GoPro GPS5 tags (ref 2) (Hero5,Hero6) +%Image::ExifTool::GoPro::GPS5 = ( + PROCESS_PROC => \&ProcessString, + GROUPS => { 1 => 'GoPro', 2 => 'Location' }, + VARS => { HEX_ID => 0, ID_LABEL => 'Index' }, + 0 => { # (unit='deg') + Name => 'GPSLatitude', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 1 => { # (unit='deg') + Name => 'GPSLongitude', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 2 => { # (unit='m') + Name => 'GPSAltitude', + PrintConv => '"$val m"', + }, + 3 => 'GPSSpeed', # (unit='m/s') + 4 => 'GPSSpeed3D', # (unit='m/s') +); + +# GoPro GPRI tags (ref PH) (Karma) +%Image::ExifTool::GoPro::GPRI = ( + PROCESS_PROC => \&ProcessString, + GROUPS => { 1 => 'GoPro', 2 => 'Location' }, + VARS => { HEX_ID => 0, ID_LABEL => 'Index' }, + 0 => { # (unit='s') + Name => 'GPSDateTimeRaw', + Groups => { 2 => 'Time' }, + ValueConv => \&ConvertSystemTime, # convert to date/time based on SystemTime clock + PrintConv => '$self->ConvertDateTime($val)', + }, + 1 => { # (unit='deg') + Name => 'GPSLatitudeRaw', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 2 => { # (unit='deg') + Name => 'GPSLongitudeRaw', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 3 => { + Name => 'GPSAltitudeRaw', # (NC) + PrintConv => '"$val m"', + }, + # (unknown tags must be defined so that ProcessString() will iterate through all values) + 4 => { Name => 'GPRI_Unknown4', Unknown => 1, Hidden => 1, PrintConv => '"$val m"' }, + 5 => { Name => 'GPRI_Unknown5', Unknown => 1, Hidden => 1, PrintConv => '"$val m"' }, + 6 => 'GPSSpeedRaw', # (NC) # (unit='m/s' -- should convert to other units?) + 7 => 'GPSTrackRaw', # (NC) # (unit='deg') + 8 => { Name => 'GPRI_Unknown8', Unknown => 1, Hidden => 1 }, # (no units) + 9 => { Name => 'GPRI_Unknown9', Unknown => 1, Hidden => 1 }, # (no units) +); + +# GoPro GLPI tags (ref PH) (Karma) +%Image::ExifTool::GoPro::GLPI = ( + PROCESS_PROC => \&ProcessString, + GROUPS => { 1 => 'GoPro', 2 => 'Location' }, + VARS => { HEX_ID => 0, ID_LABEL => 'Index' }, + 0 => { # (unit='s') + Name => 'GPSDateTime', + Groups => { 2 => 'Time' }, + ValueConv => \&ConvertSystemTime, # convert to date/time based on SystemTime clock + PrintConv => '$self->ConvertDateTime($val)', + }, + 1 => { # (unit='deg') + Name => 'GPSLatitude', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 2 => { # (unit='deg') + Name => 'GPSLongitude', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 3 => { # (unit='m') + Name => 'GPSAltitude', # (NC) + PrintConv => '"$val m"', + }, + # (unknown tags must be defined so that ProcessString() will iterate through all values) + 4 => { Name => 'GLPI_Unknown4', Unknown => 1, Hidden => 1, PrintConv => '"$val m"' }, + 5 => { Name => 'GPSSpeedX', PrintConv => '"$val m/s"' }, # (NC) + 6 => { Name => 'GPSSpeedY', PrintConv => '"$val m/s"' }, # (NC) + 7 => { Name => 'GPSSpeedZ', PrintConv => '"$val m/s"' }, # (NC) + 8 => { Name => 'GPSTrack' }, # (unit='deg') +); + +# GoPro KBAT tags (ref PH) +%Image::ExifTool::GoPro::KBAT = ( + PROCESS_PROC => \&ProcessString, + GROUPS => { 1 => 'GoPro', 2 => 'Camera' }, + VARS => { HEX_ID => 0, ID_LABEL => 'Index' }, + NOTES => 'Battery status information found in GoPro Karma videos.', + 0 => { Name => 'BatteryCurrent', PrintConv => '"$val A"' }, + 1 => { Name => 'BatteryCapacity', PrintConv => '"$val Ah"' }, + 2 => { Name => 'KBAT_Unknown2', PrintConv => '"$val J"', Unknown => 1, Hidden => 1 }, + 3 => { Name => 'BatteryTemperature', PrintConv => '"$val C"' }, + 4 => { Name => 'BatteryVoltage1', PrintConv => '"$val V"' }, + 5 => { Name => 'BatteryVoltage2', PrintConv => '"$val V"' }, + 6 => { Name => 'BatteryVoltage3', PrintConv => '"$val V"' }, + 7 => { Name => 'BatteryVoltage4', PrintConv => '"$val V"' }, + 8 => { Name => 'BatteryTime', PrintConv => 'ConvertDuration(int($val + 0.5))' }, # (NC) + 9 => { Name => 'KBAT_Unknown9', PrintConv => '"$val %"', Unknown => 1, Hidden => 1, }, + 10 => { Name => 'KBAT_Unknown10', Unknown => 1, Hidden => 1 }, # (no units) + 11 => { Name => 'KBAT_Unknown11', Unknown => 1, Hidden => 1 }, # (no units) + 12 => { Name => 'KBAT_Unknown12', Unknown => 1, Hidden => 1 }, # (no units) + 13 => { Name => 'KBAT_Unknown13', Unknown => 1, Hidden => 1 }, # (no units) + 14 => { Name => 'BatteryLevel', PrintConv => '"$val %"' }, +); + +# GoPro fdsc tags written by the Hero5 and Hero6 (ref PH) +%Image::ExifTool::GoPro::fdsc = ( + GROUPS => { 2 => 'Camera' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + NOTES => q{ + Tags extracted from the MP4 "fdsc" timed metadata when the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> + (-ee) option is used. + }, + 0x08 => { Name => 'FirmwareVersion', Format => 'string[15]' }, + 0x17 => { Name => 'SerialNumber', Format => 'string[16]' }, + 0x57 => { Name => 'OtherSerialNumber', Format => 'string[15]' }, # (NC) + 0x66 => { + Name => 'Model', + Description => 'Camera Model Name', + Format => 'string[16]', + }, + # ... + # after this there are lots of interesting values also found in the GPMF box, + # but this block is lacking tag ID's and any directory structure, so the + # value offsets are therefore presumably firmware dependent :( +); + +#------------------------------------------------------------------------------ +# Convert system time to date/time string +# Inputs: 0) system time value, 1) ExifTool ref +# Returns: EXIF-format date/time string with milliseconds +sub ConvertSystemTime($$) +{ + my ($val, $et) = @_; + my $s = $$et{SystemTimeList} or return '<uncalibrated>'; + unless ($$et{SystemTimeListSorted}) { + $s = $$et{SystemTimeList} = [ sort { $$a[0] <=> $$b[0] } @$s ]; + $$et{SystemTimeListSorted} = 1; + } + my ($i, $j) = (0, $#$s); + # perform binary search to find this system time value + while ($j - $i > 1) { + my $t = int(($i + $j) / 2); + ($val < $$s[$t][0] ? $j : $i) = $t; + } + if ($i == $j or $$s[$j][0] == $$s[$i][0]) { + $val = $$s[$i][1]; + } else { + # interpolate between values + $val = $$s[$i][1] + ($$s[$j][1] - $$s[$i][1]) * ($val - $$s[$i][0]) / ($$s[$j][0] - $$s[$i][0]); + } + # (a bit tricky to remove fractional seconds then add them back again after + # the date/time conversion while avoiding round-off errors which could + # put the seconds out by 1...) + my ($t, $f) = ("$val" =~ /^(\d+)(\.\d+)/); + return Image::ExifTool::ConvertUnixTime($t, $$et{OPTIONS}{QuickTimeUTC}) . $f; +} + +#------------------------------------------------------------------------------ +# Scale values by last 'SCAL' constants +# Inputs: 0) value or list of values, 1) string of scale factors +# Returns: nothing, but updates values +sub ScaleValues($$) +{ + my ($val, $scl) = @_; + return unless $val and $scl; + my @scl = split ' ', $scl or return; + my @scaled; + my $v = (ref $val eq 'ARRAY') ? $val : [ $val ]; + foreach $val (@$v) { + my @a = split ' ', $val; + $a[$_] /= $scl[$_ % @scl] foreach 0..$#a; + push @scaled, join(' ', @a); + } + $_[0] = @scaled > 1 ? \@scaled : $scaled[0]; +} + +#------------------------------------------------------------------------------ +# Add units to values for human-readable output +# Inputs: 0) ExifTool ref, 1) value, 2) tag key +# Returns: converted value +sub AddUnits($$$) +{ + my ($et, $val, $tag) = @_; + if ($et and $$et{TAG_EXTRA}{$tag} and $$et{TAG_EXTRA}{$tag}{Units}) { + my $u = $$et{TAG_EXTRA}{$tag}{Units}; + $u = [ $u ] unless ref $u eq 'ARRAY'; + my @a = split ' ', $val; + if (@$u == @a) { + my $i; + for ($i=0; $i<@a; ++$i) { + $a[$i] .= ' ' . $$u[$i] if $$u[$i]; + } + $val = join ' ', @a; + } + } + return $val; +} + +#------------------------------------------------------------------------------ +# Process string of values (or array of strings) to extract as separate tags +# Inputs: 0) ExifTool object ref, 1) directory information ref, 2) tag table ref +# Returns: 1 on success +sub ProcessString($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dataPt = $$dirInfo{DataPt}; + my @list = ref $$dataPt eq 'ARRAY' ? @{$$dataPt} : ( $$dataPt ); + my ($string, $val); + $et->VerboseDir('GoPro structure'); + foreach $string (@list) { + my @val = split ' ', $string; + my $i = 0; + foreach $val (@val) { + $et->HandleTag($tagTablePtr, $i, $val); + $$tagTablePtr{++$i} or $i = 0; + } + } + return 1; +} + +#------------------------------------------------------------------------------ +# Process GoPro metadata (gpmd samples, GPMF box, or APP6) (ref PH/1/2) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub ProcessGoPro($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $base = $$dirInfo{Base}; + my $pos = $$dirInfo{DirStart} || 0; + my $dirEnd = $pos + ($$dirInfo{DirLen} || (length($$dataPt) - $pos)); + my $verbose = $et->Options('Verbose'); + my $unknown = $verbose || $et->Options('Unknown'); + my ($size, $type, $unit, $scal, $setGroup0); + + $et->VerboseDir($$dirInfo{DirName} || 'GPMF', undef, $dirEnd-$pos) if $verbose; + if ($pos) { + my $parent = $$dirInfo{Parent}; + $setGroup0 = $$et{SET_GROUP0} = 'APP6' if $parent and $parent eq 'APP6'; + } else { + # set group0 to "QuickTime" unless group1 is being changed (to Track#) + $setGroup0 = $$et{SET_GROUP0} = 'QuickTime' unless $$et{SET_GROUP1}; + } + + for (; $pos+8<=$dirEnd; $pos+=($size+3)&0xfffffffc) { + my ($tag,$fmt,$len,$count) = unpack("x${pos}a4CCn", $$dataPt); + $size = $len * $count; + $pos += 8; + last if $pos + $size > $dirEnd; + my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); + last if $tag eq "\0\0\0\0"; # stop at null tag + next unless $size or $verbose; # don't save empty values unless verbose + my $format = $goProFmt{$fmt} || 'undef'; + my ($val, $i, $j, $p, @v); + if ($fmt == 0x3f and defined $type) { + # decode structure with format given by previous 'TYPE' + for ($i=0; $i<$count; ++$i) { + my (@s, $l); + for ($j=0, $p=0; $j<length($type); ++$j, $p+=$l) { + my $b = Get8u(\$type, $j); + my $f = $goProFmt{$b} or last; + $l = $goProSize{$b} || Image::ExifTool::FormatSize($f) or last; + last if $p + $l > $len; + my $s = ReadValue($dataPt, $pos+$i*$len+$p, $f, undef, $l); + last unless defined $s; + push @s, $s; + } + push @v, join ' ', @s if @s; + } + $val = @v > 1 ? \@v : $v[0]; + } elsif (($format eq 'undef' or $format eq 'string') and $count > 1 and $len > 1) { + # unpack multiple undef/string values as a list + my $a = $format eq 'undef' ? 'a' : 'A'; + $val = [ unpack("x${pos}".("$a$len" x $count), $$dataPt) ]; + } else { + $val = ReadValue($dataPt, $pos, $format, undef, $size); + } + # save TYPE, UNIT/SIUN and SCAL values for later + $type = $val if $tag eq 'TYPE'; + $unit = $val if $tag eq 'UNIT' or $tag eq 'SIUN'; + $scal = $val if $tag eq 'SCAL'; + + unless ($tagInfo) { + next unless $unknown; + my $name = Image::ExifTool::QuickTime::PrintableTagID($tag); + $tagInfo = { Name => "GoPro_$name", Description => "GoPro $name", Unknown => 1 }; + $$tagInfo{SubDirectory} = { TagTable => 'Image::ExifTool::GoPro::GPMF' } if not $fmt; + AddTagToTable($tagTablePtr, $tag, $tagInfo); + } + # apply scaling if available to last tag in this container + ScaleValues($val, $scal) if $scal and $tag ne 'SCAL' and $pos+$size+3>=$dirEnd; + my $key = $et->HandleTag($tagTablePtr, $tag, $val, + DataPt => $dataPt, + Base => $base, + Start => $pos, + Size => $size, + TagInfo => $tagInfo, + Format => $format, + Extra => $verbose ? ", type='".($fmt ? chr($fmt) : '\0')."' size=$len count=$count" : undef, + ); + # save units for adding in print conversion if specified + $$et{TAG_EXTRA}{$key}{Units} = $unit if $$tagInfo{AddUnits} and $key; + } + delete $$et{SET_GROUP0} if $setGroup0; + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::GoPro - Read information from GoPro videos + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to decode +metadata from GoPro MP4 videos. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://github.com/gopro/gpmf-parser> + +=item L<https://github.com/stilldavid/gopro-utils> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/GoPro Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/H264.pm b/src/Image-ExifTool/lib/Image/ExifTool/H264.pm index cbd2c5d7..bdc0e775 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/H264.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/H264.pm @@ -64,7 +64,7 @@ my $parsePictureTiming; # flag to enable parsing of picture timing information ( Information (SEI). I<[Yes, this description is confusing, but nothing compared to the challenge of actually decoding the data!]> This information may exist at regular intervals through the entire video, but only the first - occurrence is extracted unless the ExtractEmbedded (-ee) option is used (in + occurrence is extracted unless the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option is used (in which case subsequent occurrences are extracted as sub-documents). }, # (Note: all these are explained in IEC 61834-4, but it costs money so it is useless to me) @@ -458,7 +458,7 @@ my $parsePictureTiming; # flag to enable parsing of picture timing information ( ValueConv => '$val == 0xff ? undef : $val', PrintConv => q{ my $foc = ($val & 0x7e) / (($val & 0x01) ? 40 : 400); - return ($val & 0x80 ? 'Manual' : 'Auto') . " ($foc)"; + return(($val & 0x80 ? 'Manual' : 'Auto') . " ($foc)"); }, }, ); @@ -1108,7 +1108,7 @@ information from H.264 video streams. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/HP.pm b/src/Image-ExifTool/lib/Image/ExifTool/HP.pm index ade99eee..6ef602a8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/HP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/HP.pm @@ -119,7 +119,7 @@ sub ProcessTDHD($$$); NOTES => q{ These tags are extracted from the APP6 "TDHD" segment of Photosmart R837 JPEG images. Many other unknown tags exist in is data, and can be seen with - the Unknown (-u) option. + the L<Unknown|../ExifTool.html#Unknown> (-u) option. }, # (all subdirectories except TDHD and LSLV are automatically recognized # by their "type" word of 0x10001) @@ -250,7 +250,7 @@ Hewlett-Packard maker notes. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/HTML.pm b/src/Image-ExifTool/lib/Image/ExifTool/HTML.pm index 695948f4..1f75e20e 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/HTML.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/HTML.pm @@ -20,7 +20,7 @@ use Image::ExifTool::PostScript; use Image::ExifTool::XMP qw(EscapeXML UnescapeXML); require Exporter; -$VERSION = '1.15'; +$VERSION = '1.16'; @ISA = qw(Exporter); @EXPORT_OK = qw(EscapeHTML UnescapeHTML); @@ -363,11 +363,11 @@ sub EscapeChar($) #------------------------------------------------------------------------------ # Escape any special characters for HTML -# Inputs: 0) UTF-8 string to be escaped +# Inputs: 0) string to be escaped, 1) optional string encoding (default 'UTF8') # Returns: escaped string -sub EscapeHTML($) +sub EscapeHTML($;$) { - my $str = shift; + my ($str, $enc) = @_; # escape XML characters $str = EscapeXML($str); # escape other special characters if they exist @@ -382,19 +382,26 @@ sub EscapeHTML($) } # suppress warnings local $SIG{'__WARN__'} = sub { 1 }; - # escape any non-ascii characters for HTML - $str =~ s/([\xc2-\xf7][\x80-\xbf]+)/EscapeChar($1)/sge; + if ($enc and $enc ne 'UTF8') { + $str = Image::ExifTool::Decode(undef, $str, $enc, undef, 'UTF8'); + $str =~ s/([\xc2-\xf7][\x80-\xbf]+)/EscapeChar($1)/sge; + $str = Image::ExifTool::Decode(undef, $str, 'UTF8', undef, $enc); + } else { + # escape any non-ascii characters for HTML + $str =~ s/([\xc2-\xf7][\x80-\xbf]+)/EscapeChar($1)/sge; + } } return $str; } #------------------------------------------------------------------------------ # Unescape all HTML character references -# Inputs: 0) string to be unescaped +# Inputs: 0) string to be unescaped, 1) optional string encoding (default 'UTF8') # Returns: unescaped string -sub UnescapeHTML($) +sub UnescapeHTML($;$) { - return UnescapeXML(shift, \%entityNum); + my ($str, $enc) = @_; + return UnescapeXML($str, \%entityNum, $enc); } #------------------------------------------------------------------------------ @@ -548,7 +555,7 @@ meta information from HTML documents. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/HtmlDump.pm b/src/Image-ExifTool/lib/Image/ExifTool/HtmlDump.pm index 349f8f64..7e6503e0 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/HtmlDump.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/HtmlDump.pm @@ -13,9 +13,9 @@ use vars qw($VERSION); use Image::ExifTool; # only for FinishTiffDump() use Image::ExifTool::HTML qw(EscapeHTML); -$VERSION = '1.34'; +$VERSION = '1.37'; -sub DumpTable($$$;$$$$$); +sub DumpTable($$$;$$$$$$); sub Open($$$;@); sub Write($@); @@ -32,6 +32,7 @@ _END_PART_1_ # Note: Don't change font-weight style because it can affect line height my $htmlHeader2 = <<_END_PART_2_; </title> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css"> <!-- /* character style ID's */ @@ -111,7 +112,6 @@ function GetElementsByClass(classname, tagname) { } } } - delete list; return found; } @@ -171,7 +171,9 @@ function high(e,on) { // un-highlight current objects if (hlist) { for (var i=0; i<hlist.length; ++i) { - hlist[i].style.background = 'transparent'; + for (var j=0; j<hlist[i].length; ++j) { + hlist[i][j].style.background = 'transparent'; + } } hlist = null; } @@ -190,20 +192,25 @@ function high(e,on) { } } // highlight anchor elements with the same name - hlist = document.getElementsByName(targ.name); + hlist = new Array; + hlist.push(document.getElementsByName(targ.name)); + // is this an IFD pointer? + var pos = targ.className.indexOf('Offset_'); + if (pos > 0) { + // add elements from this IFD to our highlight list + hlist.push(document.getElementsByClassName(targ.className.substr(pos+7))); + } // use class name to highlight span elements if necessary for (var i=0; i<mspan.length; ++i) { if (mspan[i] != targ.name) continue; - var slist = GetElementsByClass(targ.name, 'span'); - // add elements from hlist collection to our array - for (var j=0; j<hlist.length; ++j) { - slist[slist.length] = hlist[j]; - } - hlist = slist; + // add these span elements to our highlight list + hlist.push(GetElementsByClass(targ.name, 'span')); break; } - for (var j=0; j<hlist.length; ++j) { - hlist[j].style.background = '#ffcc99'; + for (var i=0; i<hlist.length; ++i) { + for (var j=0; j<hlist[i].length; ++j) { + hlist[i][j].style.background = '#ffcc99'; + } } } } @@ -236,7 +243,7 @@ sub new # Add information to dump # Inputs: 0) HTML dump hash ref, 1) absolute offset in file, 2) data size, # 3) comment string, 4) tool tip (or SAME to use previous tip), -# 5) bit flags (see below) +# 5) bit flags (see below), 6) IFD name # Bits: 0x01 - print at start of line # 0x02 - print red address # 0x04 - maker notes data ('M'-class span) @@ -244,9 +251,9 @@ sub new # 0x10 - allow double references # 0x100 - (reserved) # Notes: Block will be shown in 'unused' color if comment string begins with '[' -sub Add($$$$;$) +sub Add($$$$;$$) { - my ($self, $start, $size, $msg, $tip, $flag) = @_; + my ($self, $start, $size, $msg, $tip, $flag, $ifd) = @_; my $block = $$self{Block}; $$block{$start} or $$block{$start} = [ ]; my $htip; @@ -263,7 +270,7 @@ sub Add($$$$;$) $htip .= "<br>($size bytes)" unless $htip =~ /<br>Size:/; ++$self->{TipNum}; } - push @{$$block{$start}}, [ $size, $msg, $htip, $flag, $self->{TipNum} ]; + push @{$$block{$start}}, [ $size, $msg, $htip, $flag, $self->{TipNum}, $ifd ]; } #------------------------------------------------------------------------------ @@ -351,7 +358,7 @@ sub Print($$;$$$$$) } my $parms; foreach $parms (@$parmList) { - my ($len, $msg, $tip, $flag, $tipNum) = @$parms; + my ($len, $msg, $tip, $flag, $tipNum, $ifd) = @$parms; next unless $len > 0; $flag = 0 unless defined $flag; # generate same name for all blocks indexed by this tooltip @@ -367,8 +374,10 @@ sub Print($$;$$$$$) ++$index; } if ($flag & 0x14) { + my $class = $flag & 0x04 ? "$name M" : $name; + $class .= " $ifd" if $ifd; my %bkg = ( - Class => $flag & 0x04 ? "$name M" : $name, + Class => $class, Start => $start - $dataPos, End => $start - $dataPos + $len, ); @@ -428,7 +437,7 @@ sub Print($$;$$$$$) $flag |= 0x100 unless $flag & 0x01 or $nextFlag & 0x01; } $self->DumpTable($start-$dataPos, \$buff, $msg, $name, - $flag, $len, $pos-$dataPos); + $flag, $len, $pos-$dataPos, $ifd); undef $buff; $pos = $end if $pos < $end; } @@ -558,10 +567,10 @@ sub Open($$$;@) # Dump a block of data in HTML table form # Inputs: 0) HtmlDump object ref, 1) data position, 2) block pointer, # 3) message, 4) object name, 5) flag, 6) full block length (actual -# data may be shorter), 7) data end position -sub DumpTable($$$;$$$$$) +# data may be shorter), 7) data end position, 8) IFD name +sub DumpTable($$$;$$$$$$) { - my ($self, $pos, $blockPt, $msg, $name, $flag, $len, $endPos) = @_; + my ($self, $pos, $blockPt, $msg, $name, $flag, $len, $endPos, $ifd) = @_; $len = length $$blockPt unless defined $len; $endPos = 0 unless $endPos; my ($f0, $dblRef, $id); @@ -588,7 +597,8 @@ sub DumpTable($$$;$$$$$) } ++$id unless $dblRef; } - $name = "<a name=$name class=$id>"; + my $class = $ifd ? "'$id $ifd'" : $id; + $name = "<a name=$name class=$class>"; $msg and $msg = "$name$msg</a>"; } else { $name = ''; @@ -653,7 +663,8 @@ sub DumpTable($$$;$$$$$) if ($dblRef and $p >= $endPos) { $dblRef = 0; ++$id; - $name =~ s/class=\w\b/class=$id/; + my $class = $ifd ? "'$id $ifd'" : $id; + $name =~ s/class=\w\b/class=$class/; $f0 = ''; $self->Open('fgd', $f0, 0); } @@ -885,7 +896,7 @@ page. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/ICC_Profile.pm b/src/Image-ExifTool/lib/Image/ExifTool/ICC_Profile.pm index d3017c8c..1affb5bd 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/ICC_Profile.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/ICC_Profile.pm @@ -61,7 +61,7 @@ my %manuSig = ( #6 'AAMA' => 'Aamazing Technologies, Inc.', 'ACER' => 'Acer Peripherals', 'ACLT' => 'Acolyte Color Research', - 'ACTI' => 'Actix Sytems, Inc.', + 'ACTI' => 'Actix Systems, Inc.', 'ADAR' => 'Adara Technology, Inc.', 'ADBE' => 'Adobe Systems Inc.', 'ADI ' => 'ADI Systems, Inc.', @@ -1264,7 +1264,7 @@ data created on one device into another device's native color space. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/ID3.pm b/src/Image-ExifTool/lib/Image/ExifTool/ID3.pm index 8c369044..39bba5d6 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/ID3.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/ID3.pm @@ -16,7 +16,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.51'; +$VERSION = '1.53'; sub ProcessID3v2($$$); sub ProcessPrivate($$$); @@ -964,11 +964,20 @@ sub PrintGenre($) $genre{$1} or $genre{$1} = "Unknown ($1)"; } $val =~ s/\((\d+)\)/\($genre{$1}\)/g; - $val =~ s/(^|\/)(\d+)(?=\/|$)/$1$genre{$2}$3/g; + $val =~ s/(^|\/)(\d+)(?=\/|$)/$1$genre{$2}/g; $val =~ s/^\(([^)]+)\)\1?$/$1/; # clean up by removing brackets and duplicates return $val; } +#------------------------------------------------------------------------------ +# Get Genre ID +# Inputs: 0) Genre name +# Returns: genre ID number, or undef +sub GetGenreID($) +{ + return Image::ExifTool::ReverseLookup(shift, \%genre); +} + #------------------------------------------------------------------------------ # Decode ID3 string # Inputs: 0) ExifTool object reference @@ -1554,7 +1563,7 @@ other types of audio files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/IPTC.pm b/src/Image-ExifTool/lib/Image/ExifTool/IPTC.pm index 76bbaa60..1df01886 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/IPTC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/IPTC.pm @@ -15,7 +15,7 @@ use strict; use vars qw($VERSION $AUTOLOAD %iptcCharset); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.56'; +$VERSION = '1.57'; %iptcCharset = ( "\x1b%G" => 'UTF8', @@ -1050,6 +1050,7 @@ sub ProcessIPTC($$$) my $dirLen = $$dirInfo{DirLen} || 0; my $dirEnd = $pos + $dirLen; my $verbose = $et->Options('Verbose'); + my $validate = $et->Options('Validate'); my $success = 0; my ($lastRec, $recordPtr, $recordName); @@ -1153,6 +1154,9 @@ sub ProcessIPTC($$$) last; } if (not defined $lastRec or $lastRec != $rec) { + if ($validate and defined $lastRec and $rec < $lastRec) { + $et->Warn("IPTC doesn't conform to spec: Records out of sequence",1) + } my $tableInfo = $tagTablePtr->{$rec}; unless ($tableInfo) { $et->WarnOnce("Unrecognized IPTC record $rec (ignored)"); @@ -1183,9 +1187,26 @@ sub ProcessIPTC($$$) # (could use $$recordPtr{FORMAT} if no Format below, but don't do this to # be backward compatible with improperly written PhotoMechanic tags) $format = $$tagInfo{Format} if $tagInfo; - # use logic to determine format if not specified - unless ($format) { + if (not $format) { + # guess at "int" format if not specified $format = 'int' if $len <= 4 and $len != 3 and $val =~ /[\0-\x08]/; + } elsif ($validate) { + my ($fmt,$min,$max); + if ($format =~ /(.*)\[(\d+)(,(\d+))?\]/) { + $fmt = $1; + $min = $2; + $max = $4 || $2; + } else { + $fmt = $format; + $min = $max = 1; + } + my $siz = Image::ExifTool::FormatSize($fmt) || 1; + $min *= $siz; $max *= $siz; + if ($len < $min or $len > $max) { + my $should = ($min == $max) ? $min : ($len < $min ? "$min min" : "$max max"); + my $what = ($len < $siz * $min) ? 'short' : 'long'; + $et->Warn("IPTC $$tagInfo{Name} too $what ($len bytes; should be $should)", 1); + } } if ($format) { if ($format =~ /^int/) { @@ -1197,7 +1218,10 @@ sub ProcessIPTC($$$) } } } elsif ($format =~ /^string/) { - $val =~ s/\0+$//; # some braindead softwares add null terminators + # some braindead softwares add null terminators + if ($val =~ s/\0+$// and $validate) { + $et->Warn("IPTC $$tagInfo{Name} improperly terminated", 1); + } if ($rec == 1) { # handle CodedCharacterSet tag $xlat = HandleCodedCharset($et, $val) if $tag == 90; @@ -1207,9 +1231,11 @@ sub ProcessIPTC($$$) TranslateCodedString($et, \$val, \$xlat, 1); } } elsif ($format =~ /^digits/) { - $val =~ s/\0+$//; + if ($val =~ s/\0+$// and $validate) { + $et->Warn("IPTC $$tagInfo{Name} improperly terminated", 1); + } } elsif ($format !~ /^undef/) { - warn("Invalid IPTC format: $format"); + warn("Invalid IPTC format: $format"); # (this would be a programming error) } } $verbose and $et->VerboseInfo($tag, $tagInfo, @@ -1253,7 +1279,7 @@ image files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/ISO.pm b/src/Image-ExifTool/lib/Image/ExifTool/ISO.pm new file mode 100644 index 00000000..eeb20aa5 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/ISO.pm @@ -0,0 +1,206 @@ +#------------------------------------------------------------------------------ +# File: ISO.pm +# +# Description: Read information from ISO 9660 disk images +# +# Revisions: 2016-04-07 - P. Harvey created +# +# References: 1) http://wiki.osdev.org/ISO_9660 +#------------------------------------------------------------------------------ + +package Image::ExifTool::ISO; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.01'; + +# trim trailing spaces and ignore tag if empty +my %rawStr = ( + RawConv => sub { + my $val = shift; + $val =~ s/ +$//; + return length($val) ? $val : undef; + }, +); + +# tag info for date/time tags +my %dateInfo = ( + Format => 'undef[17]', + Groups => { 2 => 'Time' }, + ValueConv => q{ + return undef if $val !~ /[^0\0 ]/; # ignore if empty + if ($val =~ s/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.)/$1:$2:$3 $4:$5:$6.$7/s) { + $val .= TimeZoneString(unpack('c', $8) * 15); + } + return $val; + }, + PrintConv => '$self->ConvertDateTime($val)', +); + +# lookup for volume descriptor types +my %volumeDescriptorType = ( + 0 => 'Boot Record', + 1 => 'Primary Volume', + 2 => 'Supplementary Volume', + 3 => 'Volume Partition', + 255 => 'Terminator', +); + +# ISO tags +%Image::ExifTool::ISO::Main = ( + GROUPS => { 2 => 'Other' }, + NOTES => 'Tags extracted from ISO 9660 disk images.', + 0 => { + Name => 'BootRecord', + SubDirectory => { TagTable => 'Image::ExifTool::ISO::BootRecord' }, + }, + 1 => { + Name => 'PrimaryVolume', + SubDirectory => { TagTable => 'Image::ExifTool::ISO::PrimaryVolume' }, + }, +); + +%Image::ExifTool::ISO::BootRecord = ( + GROUPS => { 2 => 'Other' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + # 0 => { Name => 'VolumeType', PrintConv => \%volumeDescriptorType }, # (0 for boot record) + # 1 => { Name => 'Identifier', Format => 'undef[5]' }, # (always "CD001") + # 6 => 'VolumeDesriptorVersion', # (always 1) + # always extract BootSystem, even if empty, as an indication that this is bootable + 7 => { Name => 'BootSystem', Format => 'string[32]', ValueConv => '$val=~s/ +$//; $val' }, + 39 => { Name => 'BootIdentifier', Format => 'string[32]', %rawStr }, +); + +%Image::ExifTool::ISO::PrimaryVolume = ( + GROUPS => { 2 => 'Other' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + # 0 => { Name => 'VolumeType', PrintConv => \%volumeDescriptorType }, # (1 for primary volume) + # 1 => { Name => 'Identifier', Format => 'undef[5]' }, # (always "CD001") + # 6 => 'VolumeDesriptorVersion', # (always 1) + 8 => { Name => 'System', Format => 'string[32]', %rawStr }, + 40 => { Name => 'VolumeName', Format => 'string[32]', %rawStr }, + 80 => { Name => 'VolumeBlockCount', Format => 'int32u' }, + 120 => { Name => 'VolumeSetDiskCount', Format => 'int16u', Unknown => 1 }, + 124 => { Name => 'VolumeSetDiskNumber', Format => 'int16u', Unknown => 1 }, + 128 => { Name => 'VolumeBlockSize', Format => 'int16u' }, + 132 => { Name => 'PathTableSize', Format => 'int32u', Unknown => 1 }, + 140 => { Name => 'PathTableLocation', Format => 'int32u', Unknown => 1 }, + 174 => { + Name => 'RootDirectoryCreateDate', + Format => 'undef[7]', + Groups => { 2 => 'Time' }, + ValueConv => q{ + my @a = unpack('C6c', $val); + $a[0] += 1900; + $a[6] = TimeZoneString($a[6] * 15); + return sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d%s', @a); + }, + PrintConv => '$self->ConvertDateTime($val)', + }, + 190 => { Name => 'VolumeSetName', Format => 'string[128]', %rawStr }, + 318 => { Name => 'Publisher', Format => 'string[128]', %rawStr }, + 446 => { Name => 'DataPreparer', Format => 'string[128]', %rawStr }, + 574 => { Name => 'Software', Format => 'string[128]', %rawStr }, + 702 => { Name => 'CopyrightFileName', Format => 'string[38]', %rawStr }, + 740 => { Name => 'AbstractFileName', Format => 'string[36]', %rawStr }, + 776 => { Name => 'BibligraphicFileName',Format => 'string[37]', %rawStr }, + 813 => { Name => 'VolumeCreateDate', %dateInfo }, + 830 => { Name => 'VolumeModifyDate', %dateInfo }, + 847 => { Name => 'VolumeExpirationDate',%dateInfo }, + 864 => { Name => 'VolumeEffectiveDate', %dateInfo }, + #881 => 'FileStructureVersion', # (always 1) +); + +# ISO Composite tags +%Image::ExifTool::ISO::Composite = ( + GROUPS => { 2 => 'Other' }, + VolumeSize => { + Require => { + 0 => 'ISO:VolumeBlockCount', + 1 => 'ISO:VolumeBlockSize', + }, + ValueConv => '$val[0] * $val[1]', + PrintConv => \&Image::ExifTool::ConvertFileSize, + }, +); + +# add our composite tags +Image::ExifTool::AddCompositeTags('Image::ExifTool::ISO'); + +#------------------------------------------------------------------------------ +# Extract information from an ISO 9660 disk image +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid ISO 9660 image +sub ProcessISO($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $tagTablePtr); + + # verify this is a valid ISO file + return 0 unless $raf->Seek(32768, 0); + + while ($raf->Read($buff, 2048) == 2048) { + last unless $buff =~ /^[\0-\x03\xff]CD001/; + unless ($tagTablePtr) { + $et->SetFileType(); # set the FileType tag + SetByteOrder('II'); # read little-endian values only + $tagTablePtr = GetTagTable('Image::ExifTool::ISO::Main'); + } + my $type = unpack('C', $buff); + $et->VPrint(0, "Volume descriptor type $type ($volumeDescriptorType{$type})\n"); + last if $type == 255; # stop at terminator + next unless $$tagTablePtr{$type}; + my $subTablePtr = GetTagTable($$tagTablePtr{$type}{SubDirectory}{TagTable}); + my %dirInfo = ( + DataPt => \$buff, + DataPos => $raf->Tell() - 2048, + DirStart => 0, + DirLen => length($buff), + ); + $et->ProcessDirectory(\%dirInfo, $subTablePtr); + } + return $tagTablePtr ? 1 : 0; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::ISO - Read information from ISO 9660 disk images + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read +information from ISO 9660 disk images. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<http://wiki.osdev.org/ISO_9660> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/ISO Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/ITC.pm b/src/Image-ExifTool/lib/Image/ExifTool/ITC.pm index e877580e..226250ec 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/ITC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/ITC.pm @@ -191,7 +191,7 @@ information (including artwork images) from iTunes Cover Flow files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Import.pm b/src/Image-ExifTool/lib/Image/ExifTool/Import.pm index 763c3058..a7376489 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Import.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Import.pm @@ -345,7 +345,7 @@ stored as hash lookups of tag name/value for each SourceFile. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/InDesign.pm b/src/Image-ExifTool/lib/Image/ExifTool/InDesign.pm index b18642b1..cc1ad9d5 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/InDesign.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/InDesign.pm @@ -258,7 +258,7 @@ them and the LargeFileSupport option is enabled. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/JPEG.pm b/src/Image-ExifTool/lib/Image/ExifTool/JPEG.pm index 8419370d..56af7c17 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/JPEG.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/JPEG.pm @@ -11,7 +11,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.26'; +$VERSION = '1.30'; sub ProcessOcad($$$); sub ProcessJPEG_HDR($$$); @@ -63,6 +63,13 @@ sub ProcessJPEG_HDR($$$); Name => 'FLIR', Condition => '$$valPt =~ /^FLIR\0/', SubDirectory => { TagTable => 'Image::ExifTool::FLIR::FFF' }, + }, { + Name => 'RawThermalImage', # (from Parrot Bebop-Pro Thermal drone) + Condition => '$$valPt =~ /^PARROT\0(II\x2a\0|MM\0\x2a)/', + Groups => { 0 => 'APP1', 1 => 'Parrot', 2 => 'Preview' }, + Notes => 'thermal image from Parrot Bebop-Pro Thermal drone', + RawConv => 'substr($val, 7)', + Binary => 1, }], APP2 => [{ Name => 'ICC_Profile', @@ -110,6 +117,10 @@ sub ProcessJPEG_HDR($$$); Name => 'RMETA', Condition => '$$valPt =~ /^RMETA\0/', SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::RMETA' }, + }, { + Name => 'SamsungUniqueID', + Condition => '$$valPt =~ /ssuniqueid\0/', + SubDirectory => { TagTable => 'Image::ExifTool::Samsung::APP5' }, }, { Name => 'PreviewImage', # (eg. BenQ DC E1050) Notes => 'continued from APP4', @@ -130,11 +141,16 @@ sub ProcessJPEG_HDR($$$); Name => 'GoPro', Condition => '$$valPt =~ /^GoPro\0/', SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' }, + # also seen Motorola APP6 "MMIMETA\0", with sub-types: AL3A,ALED,MMI0,MOTD,QC3A }], APP7 => [{ Name => 'Pentax', Condition => '$$valPt =~ /^PENTAX \0/', SubDirectory => { TagTable => 'Image::ExifTool::Pentax::Main' }, + }, { + Name => 'Huawei', + Condition => '$$valPt =~ /^HUAWEI\0\0/', + SubDirectory => { TagTable => 'Image::ExifTool::Unknown::Main' }, }, { Name => 'Qualcomm', Condition => '$$valPt =~ /^\x1aQualcomm Camera Attributes/', @@ -181,7 +197,7 @@ sub ProcessJPEG_HDR($$$); APP14 => { Name => 'Adobe', Condition => '$$valPt =~ /^Adobe/', - Writable => 1, # (for docs only) + Writable => 2, # (for docs only) SubDirectory => { TagTable => 'Image::ExifTool::JPEG::Adobe' }, }, APP15 => { @@ -194,7 +210,7 @@ sub ProcessJPEG_HDR($$$); Name => 'Comment', # note: flag as writable for documentation, but it won't show up # in the TagLookup as writable because there is no WRITE_PROC - Writable => 1, + Writable => 2, }, SOF => { Name => 'StartOfFrame', @@ -231,10 +247,17 @@ sub ProcessJPEG_HDR($$$); Name => 'Samsung', Condition => '$$valPt =~ /QDIOBS$/', SubDirectory => { TagTable => 'Image::ExifTool::Samsung::Trailer' }, + }, { + Name => 'EmbeddedVideo', + Notes => 'extracted only when ExtractEmbedded option is used', + Condition => '$$valPt =~ /^.{4}ftyp/s', + }, { + Name => 'Insta360', + Condition => '$$valPt =~ /8db42d694ccc418790edff439fe026bf$/', }, { Name => 'PreviewImage', Condition => '$$valPt =~ /^\xff\xd8\xff/', - Writable => 1, # (for docs only) + Writable => 2, # (for docs only) }], ); @@ -248,6 +271,7 @@ sub ProcessJPEG_HDR($$$); 0xc4a5 => { Name => 'PrintIM', # must set Writable here so this tag will be saved with MakerNotes option + # (but it isn't actually writable because there is no WRITE_PROC) Writable => 'undef', Description => 'Print Image Matching', SubDirectory => { @@ -598,7 +622,7 @@ segments are included in the Image::ExifTool module itself. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/JPEGDigest.pm b/src/Image-ExifTool/lib/Image/ExifTool/JPEGDigest.pm index 4b2171f8..947584d3 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/JPEGDigest.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/JPEGDigest.pm @@ -283,7 +283,7 @@ my %PrintConv = ( #JD '42bfe52476bf07f1ed0e6451903cc9ee:111111' => 'Adobe Lightroom, Quality 85% - 92%', '4c3c425b4024b68c0de03904a825bc35:111111' => 'Adobe Lightroom, Quality 93% - 100%', - # Tested with Adobe Photoshop CS2 Version 9.0.2 (Win) - "Save as..." (RGB/CYMK) + # Tested with Adobe Photoshop CS2 Version 9.0.2 (Win) - "Save as..." (RGB/CMYK) '683506a889c78d9bc230a0c7ee5f62f3:221111' => 'Adobe Photoshop, Quality 0', 'bc490651af6592cd1dbbbc4fa2cfa1fb:221111' => 'Adobe Photoshop, Quality 1', 'ce4286d9f07999524c3c7472b065c5ab:221111' => 'Adobe Photoshop, Quality 2', @@ -2590,7 +2590,7 @@ estimated JPEG quality if requested. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/JSON.pm b/src/Image-ExifTool/lib/Image/ExifTool/JSON.pm new file mode 100644 index 00000000..80db6c1a --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/JSON.pm @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------ +# File: JSON.pm +# +# Description: Read JSON files +# +# Notes: Set ExifTool MissingTagValue to "null" to ignore JSON nulls +# +# Revisions: 2017/03/13 - P. Harvey Created +#------------------------------------------------------------------------------ + +package Image::ExifTool::JSON; +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); +use Image::ExifTool::Import; + +$VERSION = '1.01'; + +sub ProcessTag($$$$%); + +%Image::ExifTool::JSON::Main = ( + GROUPS => { 0 => 'JSON', 1 => 'JSON', 2 => 'Other' }, + NOTES => q{ + No JSON tags have been pre-defined, but ExifTool will read any existing + tags from basic JSON-formatted files. + }, +); + +#------------------------------------------------------------------------------ +# Store a tag value +# Inputs: 0) ExifTool ref, 1) tag table, 2) tag ID, 3) value, 4) tagInfo flags +sub FoundTag($$$$%) +{ + my ($et, $tagTablePtr, $tag, $val, %flags) = @_; + + # avoid conflict with special table entries + $tag .= '!' if $Image::ExifTool::specialTags{$tag}; + + AddTagToTable($tagTablePtr, $tag, { + Name => Image::ExifTool::MakeTagName($tag), + %flags, + }) unless $$tagTablePtr{$tag}; + + $et->HandleTag($tagTablePtr, $tag, $val); +} + +#------------------------------------------------------------------------------ +# Process a JSON tag +# Inputs: 0) ExifTool ref, 1) tag table, 2) tag ID, 3) value, 4) tagInfo flags +# - expands structures into flattened tags as required +sub ProcessTag($$$$%) +{ + local $_; + my ($et, $tagTablePtr, $tag, $val, %flags) = @_; + + if (ref $val eq 'HASH') { + if ($et->Options('Struct')) { + FoundTag($et, $tagTablePtr, $tag, $val, %flags, Struct => 1); + return unless $et->Options('Struct') > 1; + } + foreach (sort keys %$val) { + ProcessTag($et, $tagTablePtr, $tag . ucfirst, $$val{$_}, %flags, Flat => 1); + } + } elsif (ref $val eq 'ARRAY') { + foreach (@$val) { + ProcessTag($et, $tagTablePtr, $tag, $_, %flags, List => 1); + } + } elsif (defined $val) { + FoundTag($et, $tagTablePtr, $tag, $val, %flags); + } +} + +#------------------------------------------------------------------------------ +# Extract meta information from a JSON file +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a recognized JSON file +sub ProcessJSON($$) +{ + local $_; + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my $structOpt = $et->Options('Struct'); + my (%database, $key, $tag); + + # read information from JSON file into database structure + my $err = Image::ExifTool::Import::ReadJSON($raf, \%database, + $et->Options('MissingTagValue'), $et->Options('Charset')); + + return 0 if $err or not %database; + + $et->SetFileType(); + + my $tagTablePtr = GetTagTable('Image::ExifTool::JSON::Main'); + + # remove any old tag definitions in case they change flags + foreach $key (TagTableKeys($tagTablePtr)) { + delete $$tagTablePtr{$key}; + } + + # extract tags from JSON database + foreach $key (sort keys %database) { + foreach $tag (sort keys %{$database{$key}}) { + my $val = $database{$key}{$tag}; + # (ignore SourceFile if generated automatically by ReadJSON) + next if $tag eq 'SourceFile' and defined $val and $val eq '*'; + ProcessTag($et, $tagTablePtr, $tag, $val); + } + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::JSON - Read JSON files + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool read +information from JSON files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/JSON Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/JVC.pm b/src/Image-ExifTool/lib/Image/ExifTool/JVC.pm index db890f4a..60ae19ed 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/JVC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/JVC.pm @@ -117,7 +117,7 @@ notes. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Jpeg2000.pm b/src/Image-ExifTool/lib/Image/ExifTool/Jpeg2000.pm index 6c7fe2f2..36e3e117 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Jpeg2000.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Jpeg2000.pm @@ -874,7 +874,7 @@ files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Kodak.pm b/src/Image-ExifTool/lib/Image/ExifTool/Kodak.pm index aa3ef8a2..2a6f88b8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Kodak.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Kodak.pm @@ -25,7 +25,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.44'; +$VERSION = '1.47'; sub ProcessKodakIFD($$$); sub ProcessKodakText($$$); @@ -375,6 +375,8 @@ sub WriteKodakIFD($$$); %Image::ExifTool::Kodak::Type5 = ( GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + WRITE_PROC => \&Image::ExifTool::WriteBinaryData, + CHECK_PROC => \&Image::ExifTool::CheckBinaryData, NOTES => q{ These tags are used by the CX4200, CX4210, CX4230, CX4300, CX4310, CX6200 and CX6230. @@ -442,6 +444,8 @@ sub WriteKodakIFD($$$); %Image::ExifTool::Kodak::Type6 = ( GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + WRITE_PROC => \&Image::ExifTool::WriteBinaryData, + CHECK_PROC => \&Image::ExifTool::CheckBinaryData, NOTES => 'These tags are used by the DX3215 and DX3700.', WRITABLE => 1, FIRST_ENTRY => 0, @@ -784,6 +788,8 @@ sub WriteKodakIFD($$$); Name => 'PreviewImageSize', Writable => 'int16u', Count => 2, + PrintConv => '$val =~ tr/ /x/; $val', + PrintConvInv => '$val =~ tr/x/ /; $val', }, # 0x03 int32u - ranges from about 33940 to 40680 # 0x04 int32u - always 18493 @@ -2659,6 +2665,7 @@ my %sceneModeUsed = ( 'Image Number' => 'ImageNumber', 'ISO' => 'ISO', 'ISO Speed' => 'ISO', + 'Lens' => { Name => 'Lens', Priority => 0 }, 'Max Aperture' => { Name => 'MaxAperture', ValueConv => '$val=~s/^f//i; $val', @@ -3003,7 +3010,7 @@ my %sceneModeUsed = ( PROCESS_PROC => \&ProcessPose, NOTES => q{ Streamed orientation information from the PixPro 4KVR360, extracted as - sub-documents when the Duplicates option is used. + sub-documents when the L<Duplicates|../ExifTool.html#Duplicates> option is used. }, Accelerometer => { }, # up, back, left? units of g AngularVelocity => { } # left, up, ccw? units? @@ -3245,7 +3252,7 @@ interpret Kodak maker notes EXIF meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/KyoceraRaw.pm b/src/Image-ExifTool/lib/Image/ExifTool/KyoceraRaw.pm index b02fd9f0..f4300520 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/KyoceraRaw.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/KyoceraRaw.pm @@ -152,7 +152,7 @@ meta information from Kyocera Contax N Digital RAW images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/LNK.pm b/src/Image-ExifTool/lib/Image/ExifTool/LNK.pm index 2ddd497a..6f9fa96a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/LNK.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/LNK.pm @@ -699,7 +699,7 @@ information MS Shell Link (Windows shortcut) files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/cs.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/cs.pm index 7546dc9f..5773b2ef 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/cs.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/cs.pm @@ -1570,7 +1570,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/de.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/de.pm index d6d434fb..d3533176 100755 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/de.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/de.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::de; use strict; use vars qw($VERSION); -$VERSION = '1.33'; +$VERSION = '1.35'; %Image::ExifTool::Lang::de::Translate = ( 'AEAperture' => 'AE-Blende', @@ -693,6 +693,7 @@ $VERSION = '1.33'; 'AFPointsInFocus' => { Description => 'AF-Punkte im Fokus', PrintConv => { + '(none)' => '(Keine)', 'All' => 'Alle', 'All 11 Points' => 'Alle 11 Punkte', 'Bottom' => 'Unten', @@ -1182,6 +1183,7 @@ $VERSION = '1.33'; 'No flash & flash' => 'Kein Blitz & Blitz', 'Off' => 'Aus', 'On' => 'Ein', + 'Pre-shot' => 'Vorauslösung', 'WB' => 'Weißabgleich', 'WB2' => 'Weißabgleich 2', }, @@ -1675,7 +1677,7 @@ $VERSION = '1.33'; }, 'CanonImageType' => 'Canon-Bildtyp', 'CanonImageWidth' => 'Canon-Bildbreite', - 'CanonModelID' => 'Canon-Modell', + 'CanonModelID' => 'Canon-Modell ID', 'Caption' => 'Bildtext', 'Caption-Abstract' => 'Beschreibung/Zusammenfassung', 'CaptionWriter' => 'Bildtextautor', @@ -1700,7 +1702,7 @@ $VERSION = '1.33'; }, 'Category' => 'Kategorie', 'CenterAFArea' => { - Description => 'AF-Messfeldgröße', + Description => 'AF-Messfeld Mitte', PrintConv => { 'Normal Zone' => 'Normal', 'Wide Zone' => 'Groß', @@ -1714,7 +1716,7 @@ $VERSION = '1.33'; }, }, 'CenterWeightedAreaSize' => { - Description => 'Messfeldgröße', + Description => 'Messfeldgröße Mitte', PrintConv => { 'Average' => 'Durchschnitt', }, @@ -1789,9 +1791,9 @@ $VERSION = '1.33'; 'On' => 'Ein', }, }, - 'ColorAdjustment' => 'Farbkorrektur', + 'ColorAdjustment' => 'Farbeinstellung', 'ColorAdjustmentMode' => { - Description => 'Farbtonkorrektur Modus', + Description => 'Farbeinstellung Modus', PrintConv => { 'Off' => 'Aus', 'On' => 'Ein', @@ -1808,9 +1810,10 @@ $VERSION = '1.33'; 'On' => 'Ein', }, }, - 'ColorBalanceBlue' => 'Farbbalance Blau', - 'ColorBalanceGreen' => 'Farbbalance Grün', - 'ColorBalanceRed' => 'Farbbalance Rot', + 'ColorBalanceBlue' => 'Farbabgleich Blau', + 'ColorBalanceGreen' => 'Farbabgleich Grün', + 'ColorBalanceRed' => 'Farbangleich Rot', + 'ColorBalanceVersion' => 'Farbabgleich Version', 'ColorBitDepth' => 'Farbtiefe', 'ColorBoostType' => { PrintConv => { @@ -3209,7 +3212,8 @@ $VERSION = '1.33'; 'Night View/Portrait' => 'Abendszene/Porträt', 'Pet' => 'Haustiere', 'Portrait' => 'Porträt', - 'Program' => 'Programm', + 'Program' => 'Programmautomatik', + 'Program AE' => 'Programmautomatik', 'Program-shift' => 'Programm-Shift', 'Program-shift A' => 'Programmverschiebung A', 'Program-shift S' => 'Programmverschiebung S', @@ -3249,8 +3253,8 @@ $VERSION = '1.33'; 'Night view/portrait' => 'Abendszene/Porträt', 'Not Defined' => 'Nicht definiert', 'Portrait' => 'Porträt', - 'Program' => 'Programm', - 'Program AE' => 'Normal-Programm', + 'Program' => 'Programmautomatik', + 'Program AE' => 'Programmautomatik', 'Shutter Priority' => 'Verschlusspriorität', 'Shutter speed priority AE' => 'Verschlusspriorität', 'Sports' => 'Sport', @@ -3531,6 +3535,7 @@ $VERSION = '1.33'; 'F1/Studio Portrait' => 'F1/Studio-Porträt', 'F1a/Studio Portrait Enhanced Saturation' => 'F1a/Studio-Porträt Erweiterte Sättigung', 'F1b/Studio Portrait Smooth Skin Tone (ASTIA)' => 'F1b/Studio-Porträt Weiche Hauttöne', + 'F1b/Studio Portrait Smooth Skin Tone (Astia)' => 'F1b/Studio-Porträt Weiche Hauttöne', 'F1c/Studio Portrait Increased Sharpness' => 'F1c/Studio-Porträt Erhöhte Schärfe', 'F3/Studio Portrait Ex' => 'F3/Studio Porträt Ex', 'n/a' => '(nicht gesetzt)', @@ -3643,9 +3648,9 @@ $VERSION = '1.33'; 'On' => 'Ein', }, }, - 'FineTuneOptCenterWeighted' => 'Feinabst. der Bel.Messung Mittenbetonte Messung', - 'FineTuneOptMatrixMetering' => 'Feinabst. der Bel.Messung Matrixmessung', - 'FineTuneOptSpotMetering' => 'Feinabst. der Bel.Messung Spotmessung', + 'FineTuneOptCenterWeighted' => 'Feinabstimmung Mittenbetonte Messung', + 'FineTuneOptMatrixMetering' => 'Feinabstimmung Matrixmessung', + 'FineTuneOptSpotMetering' => 'Feinabstimmung Spotmessung', 'FirmwareRevision' => 'Firmware-Revision', 'FirmwareRevision2' => 'Firmware-Revision 2', 'FirmwareVersion' => 'Firmware-Version', @@ -5479,6 +5484,7 @@ $VERSION = '1.33'; 'ManufactureDate' => 'Herstellungsdatum', 'Marked' => 'Markiert', 'MasterDocumentID' => 'ID des Originaldokuments', + 'MatrixMetering' => 'Mehrfeldmessung', 'MaxAperture' => 'Größte Blende', 'MaxApertureAtCurrentFocal' => 'Größte Blende bei aktueller Brennweite', 'MaxApertureAtMaxFocal' => 'Größte Blende bei größter Brennweite', @@ -5505,6 +5511,7 @@ $VERSION = '1.33'; 'MeasurementObserver' => 'Messung nach', 'MediaBlackPoint' => 'Medium-Schwarzpunkt', 'MediaWhitePoint' => 'Medium-Weißpunkt', + 'Medium' => 'Mittelgroß', 'MenuButtonDisplayPosition' => { Description => 'Positionsanzeige Menuetaste', PrintConv => { @@ -5526,7 +5533,7 @@ $VERSION = '1.33'; Description => 'Belichtungsmessung', PrintConv => { 'Center-weighted' => 'Mittenbetont', - 'Matrix' => 'Matrixmessung', + 'Matrix' => 'Mehrfeldmessung', 'Spot' => 'Spotmessung', }, }, @@ -5590,7 +5597,7 @@ $VERSION = '1.33'; }, }, 'MinoltaMakerNote' => 'Minolta-Herstellerinformationen', - 'MinoltaModelID' => 'Minolta-Modell', + 'MinoltaModelID' => 'Minolta-Modell ID', 'MinoltaQuality' => { Description => 'Minolta-Bildqualität', PrintConv => { @@ -5620,6 +5627,7 @@ $VERSION = '1.33'; }, 'Model' => 'Kameramodell', 'Model2' => 'Kameramodell (2)', + 'ModelID' => 'Modell ID', 'ModelingFlash' => { Description => 'Einstelllicht', PrintConv => { @@ -6119,7 +6127,7 @@ $VERSION = '1.33'; 'Full' => 'Voll', }, }, - 'PentaxModelID' => 'Pentax-Modell', + 'PentaxModelID' => 'Pentax-Modell ID', 'PentaxVersion' => 'Pentax-Version', 'People' => 'Menschen', 'Permits' => { @@ -6296,7 +6304,7 @@ $VERSION = '1.33'; 'Pink' => 'Rosa', 'Portrait' => 'Porträt', 'Portrait 2' => 'Porträt 2', - 'Program' => 'Programm', + 'Program' => 'Programmautomatik', 'Program (HyP)' => 'Programmautomatik (Hyper-Programm)', 'Program AE' => 'Programmautomatik', 'Program Av Shift' => 'Av Shift-Belichtungsprogramm', @@ -6584,7 +6592,7 @@ $VERSION = '1.33'; 'Province-State' => 'Bundesland/Kanton', 'Publisher' => 'Herausgeber', 'Quality' => { - Description => 'Bildqualität', + Description => 'Qualität', PrintConv => { 'Best' => 'Optimal', 'Better' => 'Besser', @@ -6602,6 +6610,7 @@ $VERSION = '1.33'; 'n/a' => '(nicht gesetzt)', }, }, + 'Quality2' => 'Qualität 2', 'QualityMode' => { PrintConv => { 'Fine' => 'Fein', @@ -7119,7 +7128,7 @@ $VERSION = '1.33'; 'Off' => 'Aus', 'Pet' => 'Haustiere', 'Portrait' => 'Porträt', - 'Program' => 'Programm', + 'Program' => 'Programmautomatik', 'Self Portrait' => 'Selbstporträt', 'Self Portrait+Self Timer' => 'Selbstporträt+Selbstauslöser', 'Shutter Priority' => 'Verschlusspriorität', @@ -7151,7 +7160,7 @@ $VERSION = '1.33'; 'Night Landscape' => 'Landschaft bei Nacht', 'Night Portrait' => 'Nachtporträt', 'Portrait' => 'Porträt', - 'Program' => 'Programm', + 'Program' => 'Programmautomatik', 'Shutter Priority' => 'Verschlusspriorität', 'Snow' => 'Schnee', 'Sunset' => 'Sonnenuntergang', @@ -7494,7 +7503,7 @@ $VERSION = '1.33'; 'Night Scenery' => 'Nachtszene', 'Pet' => 'Haustiere', 'Portrait' => 'Porträt', - 'Program' => 'Programm', + 'Program' => 'Programmautomatik', 'Self Portrait' => 'Selbstportait', 'Shutter Priority' => 'Verschlusspriorität', 'Snow' => 'Schnee', @@ -7704,7 +7713,7 @@ $VERSION = '1.33'; Description => 'Unterdatei-Typ', PrintConv => { 'Alternate reduced-resolution image' => 'Alternatives Bild in reduzierter Auflösung', - 'Full-resolution Image' => 'Bild in voller Auflösung', + 'Full-resolution image' => 'Bild in voller Auflösung', 'Reduced-resolution image' => 'Bild in reduzierter Auflösung', 'Single page of multi-page image' => 'Einzelbild eines mehrseitigen Bildes', 'Single page of multi-page reduced-resolution image' => 'Einzelbild eines mehrseitigen Bildes in reduzierter Auflösung', @@ -8691,14 +8700,15 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 ACKNOWLEDGEMENTS -Thanks to Jens Duttke and Herbert Kauer for providing this translation. +Thanks to Jens Duttke, Herbert Kauer and Jobi for providing this +translation. =head1 SEE ALSO diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_ca.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_ca.pm index 6e3dbb6c..cba7f0e0 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_ca.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_ca.pm @@ -989,7 +989,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_gb.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_gb.pm index 6b07082b..ddf6d53a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_gb.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/en_gb.pm @@ -1032,7 +1032,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/es.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/es.pm index 7c57959b..26c01a7f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/es.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/es.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::es; use strict; use vars qw($VERSION); -$VERSION = '1.15'; +$VERSION = '1.16'; %Image::ExifTool::Lang::es::Translate = ( 'AEAperture' => 'Aperture AE', @@ -176,6 +176,7 @@ $VERSION = '1.15'; 'ActionAdvised' => { Description => 'Acción Aconsejada', PrintConv => { + 'Object Append' => 'Añadir Objeto', 'Object Kill' => 'Destruir Objecto', 'Object Reference' => 'Referencia Objecto', 'Object Replace' => 'Reemplazar Objecto', @@ -870,6 +871,7 @@ $VERSION = '1.15'; }, }, 'ContrastSetting' => 'Ajustes de Contraste', + 'Copyright' => 'Copyright Perfil', 'CopyrightNotice' => 'Aviso Copyright', 'Country' => 'País', 'Country-PrimaryLocationCode' => 'Código País ISO', @@ -4003,7 +4005,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/fi.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/fi.pm index 0ef21068..bfb57e86 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/fi.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/fi.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::fi; use strict; use vars qw($VERSION); -$VERSION = '1.02'; +$VERSION = '1.04'; %Image::ExifTool::Lang::fi::Translate = ( 'AEAperture' => 'AE-aukko', @@ -147,6 +147,7 @@ $VERSION = '1.02'; 'ActionAdvised' => { Description => 'Suositettava toiminto', PrintConv => { + 'Object Append' => 'Objektiliitäntä', 'Object Kill' => 'Objektin tuhonta', 'Object Reference' => 'Objektiviite', 'Object Replace' => 'Objektin korvaus', @@ -238,6 +239,7 @@ $VERSION = '1.02'; 'On' => 'Päällä', }, }, + 'AutoBracketingSet' => 'Haarukointisarja', 'AutoDistortionControl' => 'Automaattinen vääristymäkorjaus', 'AutoExposureBracketing' => 'Automaattinen valotuksen haarukointi', 'AutoFP' => 'Automaattinen FP', @@ -335,6 +337,7 @@ $VERSION = '1.02'; 'BurstMode' => { Description => 'Sarjatapa', PrintConv => { + 'Auto Exposure Bracketing (AEB)' => 'Ääretön', 'Infinite' => 'Ääretön', 'Off' => 'Pois', 'On' => 'Matala/korkea laatu', @@ -442,6 +445,7 @@ $VERSION = '1.02'; 'ColorBalanceBlue' => 'Väritasapaino sininen', 'ColorBalanceGreen' => 'Väritasapaino vihreä', 'ColorBalanceRed' => 'Väritasapaino punainen', + 'ColorBalanceVersion' => 'Väritasapainon versio', 'ColorBoostData' => 'Väritehostusdata', 'ColorBoostLevel' => 'Väritehostustaso', 'ColorBoostType' => 'Väritehostustyyppi', @@ -508,6 +512,7 @@ $VERSION = '1.02'; }, }, 'ColorMoireReduction' => 'Värimoareen vaimennus', + 'ColorMoireReductionMode' => 'Värimoareen vaimennustapa', 'ColorPalette' => 'Väripaletti', 'ColorProfile' => 'Väriprofiili', 'ColorRepresentation' => 'Väriesitys', @@ -665,6 +670,7 @@ $VERSION = '1.02'; 'DefaultCropOrigin' => 'Oletusrajauksen alkuperä', 'DefaultCropSize' => 'Oletusrajauskoko', 'DefaultScale' => 'Oletusasteikko', + 'DelayTime' => 'Viiveaika', 'DeletedImageCount' => 'Poistettujen kuvien määrä', 'Description' => 'Deskriptio', 'Destination' => 'Kohde', @@ -923,6 +929,7 @@ $VERSION = '1.02'; 'FileIndex' => 'Tiedostoindeksi', 'FileInfo' => 'Tiedostoinfot', 'FileInfoVersion' => 'Tiedostoinfojen versio', + 'FileName' => 'Tiedostonimi', 'FileNumber' => 'Tiedoston numero', 'FileNumberMemory' => 'Tiedostonumeromuisti', 'FileNumberSequence' => 'Tiedostojen numerojärjestys', @@ -946,9 +953,11 @@ $VERSION = '1.02'; 'Dynamic (B&W)' => 'Dynaaminen (M&V)', 'Dynamic (color)' => 'Dynaaminen (väri)', 'F0/Standard (PROVIA)' => 'F0/vakio', + 'F0/Standard (Provia)' => 'F0/vakio', 'F1/Studio Portrait' => 'F1/studiomuotokuva', 'F1a/Studio Portrait Enhanced Saturation' => 'F1a/studiomuotokuva laajennettu värikylläisyys', 'F1b/Studio Portrait Smooth Skin Tone (ASTIA)' => 'F1b/studiomuotokuva pehmeä ihonväri', + 'F1b/Studio Portrait Smooth Skin Tone (Astia)' => 'F1b/studiomuotokuva pehmeä ihonväri', 'F1c/Studio Portrait Increased Sharpness' => 'F1c/studiomuotokuva lisätty terävyys', 'F3/Studio Portrait Ex' => 'F3/studiomuotokuva Ex', 'Nature (color)' => 'Luonnollinen (väri)', @@ -1013,6 +1022,7 @@ $VERSION = '1.02'; 'FlashEnergy' => 'Salaman teho', 'FlashExposureBracketValue' => 'Salamavalotuksen haarukoinnin arvo', 'FlashExposureComp' => 'Salaman kirkkauden säätö', + 'FlashExposureComp2' => 'Salaman kirkkauden säätö 2', 'FlashFired' => { Description => 'Salama lauennut', PrintConv => { @@ -1105,6 +1115,7 @@ $VERSION = '1.02'; 'FocusArea' => 'Tarkennusalue', 'FocusAreaSelection' => 'Tarkennusalueen valinta', 'FocusContinuous' => 'Jatkuva tarkennus', + 'FocusDistance' => 'Tarkennusetäisyys', 'FocusDistanceLower' => 'Lähitarkennus', 'FocusDistanceUpper' => 'Kaukotarkennus', 'FocusMode' => { @@ -1605,6 +1616,7 @@ $VERSION = '1.02'; 'MaskedAreas' => 'Maskilliset alueet', 'MasterDocumentID' => 'Alkuperäisdokumentin ID', 'MasterGain' => 'Yleisvahvistus', + 'MatrixMetering' => 'Matriisimittaus', 'Matteing' => 'Mattaus', 'MaxAperture' => 'Suurin aukko', 'MaxApertureAtCurrentFocal' => 'Suurin aukko nykyisellä polttovälillä', @@ -1662,6 +1674,7 @@ $VERSION = '1.02'; 'Model' => 'Malli', 'Model2' => 'Kuvasyötelaitteen malli (2)', 'ModelAndVersion' => 'Malli ja versio', + 'ModelID' => 'Mallin ID', 'ModelTiePoint' => 'Sidospistemalli-tagi', 'ModelTransform' => 'Muuntomalli-tagi', 'ModelingFlash' => 'Mallinnussalama', @@ -2021,6 +2034,7 @@ $VERSION = '1.02'; 'n/a' => 'Ei asetettu', }, }, + 'Quality2' => 'Laatu 2', 'QualityMode' => { Description => 'Kuvalaatu', PrintConv => { @@ -2153,7 +2167,13 @@ $VERSION = '1.02'; }, }, 'ResolutionMode' => 'Resoluutiomuoto', - 'ResolutionUnit' => 'X- ja Y-resoluution yksikkö', + 'ResolutionUnit' => { + Description => 'X- ja Y-resoluution yksikkö', + PrintConv => { + 'None' => 'Ei mitään', + 'inches' => 'Tuuma', + }, + }, 'RetouchHistory' => 'Korjailuhistoria', 'ReverseIndicators' => 'Käänteiset ilmaisimet', 'RevisionNumber' => 'Revision numero', @@ -2218,6 +2238,10 @@ $VERSION = '1.02'; 'Saturation' => { Description => 'Värikylläisyys', PrintConv => { + '+1 (medium high)' => 'Korkeahko', + '+2 (high)' => 'Korkea', + '-1 (medium low)' => 'Matalahko', + '0 (normal)' => 'Vakio', 'Film Simulation' => 'Filminsimulaatio', 'High' => 'Korkea', 'Low' => 'Matala', @@ -2422,6 +2446,13 @@ $VERSION = '1.02'; 'Sharpness' => { Description => 'Terävyys', PrintConv => { + '+1 (medium hard)' => 'Kovahko', + '+2 (hard)' => 'Kova', + '+3 (very hard)' => 'Kova 2', + '-1 (medium soft)' => 'Pehmeähkö', + '-2 (soft)' => 'Pehmeä 2', + '-3 (very soft)' => 'Pehmeä', + '0 (normal)' => 'Vakio', 'Film Simulation' => 'Filminsimulaatio', 'Hard' => 'Kova', 'Hard2' => 'Kova 2', @@ -2473,6 +2504,7 @@ $VERSION = '1.02'; 'SpecialInstructions' => 'Ohjeet', 'SpecialMode' => 'Erikoistapa', 'SpectralSensitivity' => 'Spektraalinen herkkyys', + 'Sport' => 'Urheilu', 'SpotFocusPointX' => 'Pistetarkennuksen piste X', 'SpotFocusPointY' => 'Pistetarkennuksen piste Y', 'SpotMeteringMode' => 'Pistemittaustapa', @@ -2743,6 +2775,10 @@ $VERSION = '1.02'; 'Custom WB 4' => 'Mukautettu valkotasapaino 4', 'Custom WB 5400K' => 'Mukautettu valkotasapaino 5400 K', 'Custom WB 8000K' => 'Mukautettu valkotasapaino 8000 K', + 'One Touch WB 1' => 'Mukautettu valkotasapaino 1', + 'One Touch WB 2' => 'Mukautettu valkotasapaino 2', + 'One Touch WB 3' => 'Mukautettu valkotasapaino 3', + 'One Touch WB 4' => 'Mukautettu valkotasapaino 4', }, }, 'WhiteBalanceAdj' => 'Väritasapainon säätö', @@ -2801,7 +2837,13 @@ $VERSION = '1.02'; 'XPosition' => 'X-sijainti', 'XResolution' => 'Kuvan vaakaresoluutio', 'YCbCrCoefficients' => 'Väriavaruuden muunnon matriisikertoimet', - 'YCbCrPositioning' => 'Y:n ja C:n sijoitus', + 'YCbCrPositioning' => { + Description => 'Y:n ja C:n sijoitus', + PrintConv => { + 'Centered' => 'Keskitetty', + 'Co-sited' => 'Vierekkäin', + }, + }, 'YCbCrSubSampling' => 'Suhteen Y - C subsamplaus', 'YClipPathUnits' => 'Y-leikepolkuyksiköt', 'YPosition' => 'Y-sijainti', @@ -2836,7 +2878,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/fr.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/fr.pm index 6deeada7..34b7abc7 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/fr.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/fr.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::fr; use strict; use vars qw($VERSION); -$VERSION = '1.32'; +$VERSION = '1.34'; %Image::ExifTool::Lang::fr::Translate = ( 'AEAperture' => 'Ouverture AE', @@ -372,6 +372,7 @@ $VERSION = '1.32'; 'ActionAdvised' => { Description => 'Action conseillée', PrintConv => { + 'Object Append' => 'Ajout d\'objet', 'Object Kill' => 'Destruction d\'objet', 'Object Reference' => 'Référence d\'objet', 'Object Replace' => 'Remplacement d\'objet', @@ -903,6 +904,7 @@ $VERSION = '1.32'; 'On' => 'Activé', }, }, + 'ColorBalanceVersion' => 'Version de la Balance des couleurs', 'ColorBooster' => { PrintConv => { 'Off' => 'Désactivé', @@ -4749,7 +4751,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/it.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/it.pm index e7026836..ec9bd8bb 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/it.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/it.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::it; use strict; use vars qw($VERSION); -$VERSION = '1.13'; +$VERSION = '1.14'; %Image::ExifTool::Lang::it::Translate = ( 'A100DataOffset' => 'Offset dati A100', @@ -1249,6 +1249,7 @@ $VERSION = '1.13'; 'Off' => 'Spento', }, }, + 'ColorBalanceVersion' => 'Versione Bilanciamento Colore', 'ColorBooster' => { PrintConv => { 'Off' => 'Spento', @@ -2394,6 +2395,7 @@ $VERSION = '1.13'; PrintConv => { 'Aperture Priority' => 'Priorità diaframma', 'Aperture-priority AE' => 'Priorità diaframma', + 'Auto' => 'Esposizione automatica', 'Auto bracket' => 'A forcella automatica', 'Fireworks' => 'Fuochi artificiali', 'Landscape' => 'Orizzontale', @@ -4846,6 +4848,7 @@ $VERSION = '1.13'; }, }, 'ObjectTypeReference' => 'Riferimento Tipo Oggetto', + 'OffsetSchema' => 'Schema Offset', 'OldSubfileType' => { Description => 'Vecchio tipo sotto-file', PrintConv => { @@ -7057,7 +7060,7 @@ $VERSION = '1.13'; 'SubfileType' => { Description => 'Tipo sotto-file', PrintConv => { - 'Full-resolution Image' => 'Immagine con risoluzione originale', + 'Full-resolution image' => 'Immagine con risoluzione originale', 'Reduced-resolution image' => 'Immagine a risoluzione ridotta', 'Single page of multi-page image' => 'Singola pagina di un\'immagine multi-pagina', 'Single page of multi-page reduced-resolution image' => 'Singola pagina di un\'immagine multi-pagina a risoluzione ridotta', @@ -7711,9 +7714,9 @@ $VERSION = '1.13'; }, 'WBAdjLighting' => { PrintConv => { + 'Daylight (cloudy)' => 'Luce del giorno (2)', 'Daylight (direct sunlight)' => 'Luce del giorno (0)', 'Daylight (shade)' => 'Luce del giorno (1)', - 'Daylight (cloudy)' => 'Luce del giorno (2)', 'None' => 'Nessuno', }, }, @@ -7900,7 +7903,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/ja.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/ja.pm index 574fd6d4..0a6e2ecf 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/ja.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/ja.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::ja; use strict; use vars qw($VERSION); -$VERSION = '1.23'; +$VERSION = '1.25'; %Image::ExifTool::Lang::ja::Translate = ( 'AEAperture' => 'AE絞り', @@ -633,6 +633,7 @@ $VERSION = '1.23'; 'On' => 'オン', }, }, + 'AutoBracketingSet' => 'オートブラケット設定', 'AutoExposureBracketing' => { Description => 'フラッシュãƒã‚¤ã‚¢ã‚¹', PrintConv => { @@ -820,6 +821,7 @@ $VERSION = '1.23'; 'BurstMode' => { Description => 'ブラストモード', PrintConv => { + 'Auto Exposure Bracketing (AEB)' => 'ç„¡é™', 'Infinite' => 'ç„¡é™', 'Off' => 'オフ', 'On' => 'オン', @@ -2190,6 +2192,7 @@ $VERSION = '1.23'; 'FlashEnergy' => 'フラッシュ強度', 'FlashExposureBracketValue' => 'フラッシュ露出ブラケット値', 'FlashExposureComp' => 'フラッシュ露出補正', + 'FlashExposureComp2' => 'フラッシュ露出補正', 'FlashExposureCompSet' => 'ストロボ露出補正設定', 'FlashExposureLock' => { PrintConv => { @@ -3352,6 +3355,7 @@ $VERSION = '1.23'; 'MaskedAreas' => 'マスク領域', 'MasterDocumentID' => 'マスタ文書ID', 'MasterGain' => 'マスターゲイン', + 'MatrixMetering' => '分割測光', 'Matteing' => 'マッãƒãƒ³ã‚°', 'MaxAperture' => '最大絞り', 'MaxApertureAtCurrentFocal' => 'ç¾åœ¨ç„¦ç‚¹è·é›¢ã®æœ€å¤§çµžã‚Š', @@ -3472,6 +3476,7 @@ $VERSION = '1.23'; }, 'Model' => 'ç”»åƒå…¥åŠ›æ©Ÿå™¨ãƒ¢ãƒ‡ãƒ«', 'Model2' => 'ç”»åƒå…¥åŠ›æ©Ÿå™¨ãƒ¢ãƒ‡ãƒ«(2)', + 'ModelID' => 'モデルID', 'ModelTiePoint' => 'モデル拘æŸãƒã‚¤ãƒ³ãƒˆã‚¿ã‚°', 'ModelTransform' => 'モデル変化タグ', 'ModelingFlash' => { @@ -4215,6 +4220,7 @@ $VERSION = '1.23'; 'n/a' => '未設定', }, }, + 'Quality2' => 'å“質', 'QualityMode' => { Description => 'å“質モード', PrintConv => { @@ -4877,7 +4883,8 @@ $VERSION = '1.23'; 'Soft2' => 'ソフト2', 'n/a' => '該当無ã—', }, - }, 'SharpnessFactor' => 'シャープãƒã‚¹è¦å› ', + }, + 'SharpnessFactor' => 'シャープãƒã‚¹è¦å› ', 'SharpnessFaithful' => 'シャープãƒã‚¹å¿ å®Ÿè¨­å®š', 'SharpnessFrequency' => { PrintConv => { @@ -5061,6 +5068,7 @@ $VERSION = '1.23'; 'SpecialInstructions' => '手順', 'SpecialMode' => 'スペシャルモード', 'SpectralSensitivity' => 'スペクトル感度', + 'Sport' => 'スãƒãƒ¼ãƒ„', 'SpotFocusPointX' => 'スãƒãƒƒãƒˆãƒ•ã‚©ãƒ¼ã‚«ã‚¹ãƒã‚¤ãƒ³ãƒˆX', 'SpotFocusPointY' => 'スãƒãƒƒãƒˆãƒ•ã‚©ãƒ¼ã‚«ã‚¹ãƒã‚¤ãƒ³ãƒˆY', 'SpotMeterLinkToAFPoint' => { @@ -5693,6 +5701,10 @@ $VERSION = '1.23'; 'Custom WB 4' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹4', 'Custom WB 5400K' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹5400K', 'Custom WB 8000K' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹8000K', + 'One Touch WB 1' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹1', + 'One Touch WB 2' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹2', + 'One Touch WB 3' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹3', + 'One Touch WB 4' => 'カスタムホワイトãƒãƒ©ãƒ³ã‚¹4', }, }, 'WhiteBalanceAdj' => { @@ -5829,7 +5841,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/ko.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/ko.pm index f4ec5d01..b7349a67 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/ko.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/ko.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::ko; use strict; use vars qw($VERSION); -$VERSION = '1.06'; +$VERSION = '1.07'; %Image::ExifTool::Lang::ko::Translate = ( 'AELock' => { @@ -256,6 +256,7 @@ $VERSION = '1.06'; 'Off' => '꺼ì§', }, }, + 'AutoBracketingSet' => 'ìžë™ 브ë¼ì¼€íŒ… 설정', 'AutoExposureBracketing' => { PrintConv => { 'Off' => '꺼ì§', @@ -429,6 +430,7 @@ $VERSION = '1.06'; 'On' => '켜ì§', }, }, + 'ColorBalanceVersion' => '컬러 밸런스 버전', 'ColorBooster' => { PrintConv => { 'Off' => '꺼ì§', @@ -1469,6 +1471,7 @@ $VERSION = '1.06'; 'MakerNotes' => '제조업체 ì •ë³´', 'ManualFlashOutput' => '내장 플래시 ìˆ˜ë™ ì¶œë ¥', 'ManualFocusDistance' => 'ìˆ˜ë™ ì´ˆì  ê±°ë¦¬', + 'MatrixMetering' => '멀티 패턴 측광', 'MaxAperture' => '최대 렌즈 조리개', 'MaxApertureAtMaxFocal' => '최대 ì´ˆì ê¸¸ì´ì—ì„œ 최대 조리개', 'MaxApertureAtMinFocal' => '최소 ì´ˆì ê¸¸ì´ì—ì„œ 최대 조리개', @@ -2313,7 +2316,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/nl.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/nl.pm index 4cf8b003..b8fd6b43 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/nl.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/nl.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::nl; use strict; use vars qw($VERSION); -$VERSION = '1.11'; +$VERSION = '1.12'; %Image::ExifTool::Lang::nl::Translate = ( 'AEBAutoCancel' => { @@ -201,6 +201,7 @@ $VERSION = '1.11'; 'ActionAdvised' => { Description => 'Actie advies', PrintConv => { + 'Object Append' => 'Object toevoegen', 'Object Kill' => 'Object verwijderen', 'Object Reference' => 'Object referentie', 'Object Replace' => 'Object vervangen', @@ -335,6 +336,7 @@ $VERSION = '1.11'; 'Off' => 'Uit', }, }, + 'AutoBracketingSet' => 'Inst. voor auto bracketing', 'AutoExposureBracketing' => { PrintConv => { 'Off' => 'Uit', @@ -1996,6 +1998,7 @@ $VERSION = '1.11'; }, }, 'MasterDocumentID' => 'ID van hoofddocument', + 'MatrixMetering' => 'Matrixmeting', 'MaxAperture' => 'Maximale lensopening', 'MaxApertureValue' => 'Grootste diafragma', 'MaxContinuousRelease' => 'Max. aant. continuopnamen', @@ -3058,9 +3061,9 @@ $VERSION = '1.11'; }, 'WBAdjLighting' => { PrintConv => { + 'Daylight (cloudy)' => 'Daglicht (2)', 'Daylight (direct sunlight)' => 'Daglicht (0)', 'Daylight (shade)' => 'Daglicht (1)', - 'Daylight (cloudy)' => 'Daglicht (2)', 'Flash' => 'Flits', 'None' => 'Geen', }, @@ -3204,7 +3207,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/pl.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/pl.pm index 0e59a51d..342bffe6 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/pl.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/pl.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::pl; use strict; use vars qw($VERSION); -$VERSION = '1.10'; +$VERSION = '1.12'; %Image::ExifTool::Lang::pl::Translate = ( 'A100DataOffset' => 'PrzesuniÄ™cie danych A100', @@ -1064,7 +1064,7 @@ $VERSION = '1.10'; 'SubfileType' => { Description => 'Typ podsekcji', PrintConv => { - 'Full-resolution Image' => 'Obraz w peÅ‚nej rozdzielczoÅ›ci', + 'Full-resolution image' => 'Obraz w peÅ‚nej rozdzielczoÅ›ci', 'Reduced-resolution image' => 'Obraz o zredukowanej rozdzielczoÅ›ci', 'Single page of multi-page image' => 'Jedna strona obrazu wielostronicowego', 'Single page of multi-page reduced-resolution image' => 'Jedna strona obrazu wielostronicowego o zredukowanej rozdzielczoÅ›ci', @@ -1258,7 +1258,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/ru.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/ru.pm index ae4a8b33..bcea992a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/ru.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/ru.pm @@ -11,608 +11,4820 @@ package Image::ExifTool::Lang::ru; use strict; use vars qw($VERSION); -$VERSION = '1.04'; +$VERSION = '1.08'; %Image::ExifTool::Lang::ru::Translate = ( + 'A100DataOffset' => 'Смещение данных (Sony A100)', + 'ABDate' => 'AB – Дата', + 'ABLabel' => 'AB – Метка', + 'ABRelatedNames' => 'AB – Похожие имена', + 'AB_UID' => 'AB – Уникальный ID', + 'AFAdjustment' => 'Регулировка автофокуÑа', + 'AIBuildNumber' => 'AI – Ðомер Ñборки', + 'AIColorModel' => 'AI – Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ', + 'AIColorUsage' => 'AI – ИÑпользование цвета', + 'AICreatorVersion' => 'AI – ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'AIFileFormat' => 'AI – Формат файла', + 'AINumLayers' => 'AI – КоличеÑтво Ñлоёв', + 'AIRulerUnits' => { + Description => 'AI – Единицы линейки', + PrintConv => { + 'Centimeters' => 'Сантиметры', + 'Inches' => 'Дюймы', + 'Millimeters' => 'Милиметры', + 'Picas' => 'Пики', + 'Pixels' => 'ПикÑели', + 'Points' => 'Точки', + }, + }, + 'AITargetResolution' => 'AI – Целевое разрешение', + 'APEVersion' => 'ВерÑÐ¸Ñ APE', + 'ARMIdentifier' => 'Идентификатор ARM', + 'ARMVersion' => 'ВерÑÐ¸Ñ ARM', + 'ATSCContent' => { + Description => 'Контент ATSC', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'About' => 'Об', + 'AbsoluteAltitude' => 'ÐбÑÐ¾Ð»ÑŽÑ‚Ð½Ð°Ñ Ð²Ñ‹Ñота', + 'Abstract' => 'Краткое опиÑание', + 'AbstractFileName' => 'Файл Ñ Ð°Ð±Ñтрактной информацией', + 'Acceleration' => 'УÑкорение', + 'AccelerationVector' => 'Вектор уÑкорениÑ', + 'Accelerometer' => 'ÐкÑелерометр', + 'AccelerometerTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð°ÐºÑелерометра', + 'AccelerometerX' => 'ÐкÑелерометр – X', + 'AccelerometerY' => 'ÐкÑелерометр – Y', + 'AccelerometerZ' => 'ÐкÑелерометр – Z', + 'AccessDate' => 'Дата поÑледнего доÑтупа', + 'Acknowledged' => 'БлагодарноÑти', + 'Action' => 'ДейÑтвие', + 'ActionAdvised' => { + Description => 'Рекомендуемое дейÑтвие', + PrintConv => { + 'Object Append' => 'Добавить объект', + 'Object Kill' => 'Уничтожить объект', + 'Object Reference' => 'Сделать ÑÑылку на объект', + 'Object Replace' => 'Заменить объект', + }, + }, 'ActiveArea' => 'ÐÐºÑ‚Ð¸Ð²Ð½Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ', + 'Actor' => 'Ðктёр', + 'Address' => 'ÐдреÑÑ', + 'AdoptedNeutral' => 'ПринÑтый как нейтральный', + 'Adult' => 'Ð”Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых', + 'AdultContentWarning' => { + Description => 'Предупреждение о Ñодержании Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых', + PrintConv => { + 'Adult Content Warning Required' => 'ТребуетÑÑ', + 'Not Required' => 'Ðе требуетÑÑ', + 'Unknown' => 'Ðе задано', + }, + }, + 'AdvancedSceneMode' => { + Description => 'РаÑширенный режим Ñцены', + PrintConv => { + 'Architecture' => 'Ðрхитектура', + 'Bleach Bypass' => 'Удержание Ñеребра', + 'Cinema' => 'Кино', + 'Color Select' => 'Выбранный цвет', + 'Creative Macro' => 'ТворчеÑкий макро', + 'Creative Night Scenery' => 'ТворчеÑкий ночной пейзаж', + 'Creative Portrait' => 'ТворчеÑкий портрет', + 'Creative Scenery' => 'ТворчеÑкий пейзаж', + 'Creative Sports' => 'ТворчеÑкий Ñпорт', + 'Cross Process' => 'КроÑÑпроцеÑÑ', + 'Dynamic Art' => 'Динамика', + 'Dynamic Monochrome' => 'Динамичное монохромное', + 'Elegant' => 'Элегантный', + 'Expressive' => 'Выразительный', + 'Fantasy' => 'ФÑнтези', + 'Flower' => 'Цветок', + 'HDR Art' => 'HDR', + 'HDR B&W' => 'Чёрно-Белый HDR', + 'Handheld Night Shot' => 'ÐÐ¾Ñ‡Ð½Ð°Ñ Ñъёмка Ñ Ñ€ÑƒÐºÐ¸', + 'High Dynamic' => 'Ð’Ñ‹ÑÐ¾ÐºÐ°Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÐºÐ°', + 'High Key' => 'Ð’ выÑоком ключе', + 'Illuminations' => 'Свеча', + 'Impressive Art' => 'ВпечатлÑющий', + 'Indoor Portrait' => 'Внутренний портрет', + 'Indoor Sports' => 'Спорт в помещении', + 'Low Key' => 'Ð’ низком ключе', + 'Miniature' => 'Миниатюра', + 'Monochrome' => 'Монохромный', + 'Nature' => 'Природа', + 'Objects' => 'Объекты', + 'Old Days' => 'Старые времена', + 'Outdoor Portrait' => 'Ðаружный портрет', + 'Outdoor Sports' => 'Спорт на открытом воздухе', + 'Pure' => 'ЧиÑтый', + 'Retro' => 'Ретро', + 'Rough Monochrome' => 'Грубый монохромный', + 'Sepia' => 'СепиÑ', + 'Silhouette' => 'СилуÑÑ‚', + 'Silky Monochrome' => 'ШелковиÑтый монохромный', + 'Soft' => 'ÐœÑгкий', + 'Star' => 'Звёзды', + 'Sunshine' => 'Солнечный Ñвет', + 'Toy Effect' => 'Эффект ломографии', + 'Toy Pop' => 'Ð›Ð¾Ð¼Ð¾Ð³Ñ€Ð°Ñ„Ð¸Ñ Ñ Ð²Ñ‹Ð´ÐµÐ»ÐµÐ½Ð¸ÐµÐ¼ цвета', + }, + }, + 'AdventRevision' => 'Проверка поÑвлениÑ', + 'AdventScale' => 'МаÑштаб поÑвлениÑ', + 'AffineA' => 'Ðфинное преобразование A', + 'AffineB' => 'Ðфинное преобразование B', + 'AffineC' => 'Ðфинное преобразование C', + 'AffineD' => 'Ðфинное преобразование D', + 'AffineTransformMat' => 'Матрица Ðфинного преобразованиÑ', + 'AffineX' => 'Ðфинное преобразование X', + 'AffineY' => 'Ðфинное преобразование Y', + 'AlarmUID' => 'Уникальный ID Ñигнала', 'Album' => 'Ðльбом', + 'AlbumArtist' => 'ИÑполнитель альбома', + 'AliasLayerMetadata' => 'ПÑевдоним метаданных ÑлоÑ', + 'Alignment' => 'Выравнивание', + 'AllColorFlatField1' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¿Ð»Ð¾Ñкого Ð¿Ð¾Ð»Ñ â€“ Ð’Ñе цвета 1', + 'AllColorFlatField2' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¿Ð»Ð¾Ñкого Ð¿Ð¾Ð»Ñ â€“ Ð’Ñе цвета 2', + 'AllColorFlatField3' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¿Ð»Ð¾Ñкого Ð¿Ð¾Ð»Ñ â€“ Ð’Ñе цвета 3', + 'AllDayEvent' => 'Событие на веÑÑŒ день', + 'Alpha' => { + Description => 'Ðльфа-канал', + PrintConv => { + 'Alpha Exists (W color component)' => 'Ðльфа-канал приÑутÑтвует (цветной компонент W)', + 'Alpha Exists (color not premultiplied)' => 'Ðльфа-канал приÑутÑтвует (не предварительно умноженный цвет)', + 'Alpha Exists (color premultiplied)' => 'Ðльфа-канал приÑутÑтвует (предварительно умноженный цвет)', + 'No Alpha Plane' => 'Ðльфа-канал отÑутÑтвует', + }, + }, + 'AlphaByteCount' => 'Размер альфа-канала (байт)', + 'AlphaChannelsNames' => 'ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ð°Ð»ÑŒÑ„Ð°-каналов', + 'AlphaDataDiscard' => { + Description => 'Отброшенные данные альфа-канала', + PrintConv => { + 'Flexbits Discarded' => 'Гибкие биты отброшены', + 'Full Resolution' => 'Полное разрешение', + 'HighPass Frequency Data Discarded' => 'Данные выÑоких чаÑтот отброшены', + 'Highpass and LowPass Frequency Data Discarded' => 'Данные выÑоких и низких чаÑтот отброшены', + }, + }, + 'AlphaIdentifiers' => 'Идентификаторы альфа-канала', + 'AlphaMask' => 'МаÑка Ðльфа-канала', + 'AlphaOffset' => 'Смещение альфа-канала', + 'AlternateDuotoneColors' => 'Ðльтернативные цвета Duotone', + 'AlternateSpotColors' => 'Ðльтернативные плашечные цвета', + 'AmbientInfrared' => 'Внешний инфракраÑный Ñвет', + 'AmbientLight' => 'Внешнее оÑвещение', + 'AmbientTemperature' => 'Температура окружающей Ñреды', + 'AmbientTemperatureFahrenheit' => 'Температура окружающей Ñреды по Фаренгейту', 'AnalogBalance' => 'Ðналоговый Ð±Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾', - 'AntiAliasStrength' => 'ОтноÑÐ¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñила Ñглаживающего фильтра ÑенÑора', + 'AngleInfoRoll' => 'Угол Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ (крен)', + 'AngleInfoYaw' => 'Угол поворота (рыÑкание)', + 'AnimationControl' => 'Управление анимацией', + 'AnimationFrames' => 'Кадры анимации', + 'AnimationIterations' => 'Повторений анимации', + 'AnimationPlays' => 'Проигрывание анимации', + 'Anniversary' => 'Годовщина', + 'Annotation' => 'ÐннотациÑ', + 'AnnotationUsageRights' => 'Права на иÑпользование Ðннотации', + 'Annotations' => 'Ðннотации', + 'Announce' => 'Трекер', + 'AnnounceList1' => 'СпиÑок трекеров 1', + 'AntiAliasStrength' => 'Сила ÑглаживаниÑ', 'Aperture' => 'Диафрагма', 'ApertureValue' => 'Диафрагма', + 'AppleKeywords' => 'Apple – Ключевые Ñлова', + 'AppleMailDateReceived' => 'Apple Mail – Дата получениÑ', + 'AppleMailDateSent' => 'Apple Mail – Дата отправки', + 'AppleMailFlagged' => 'Apple Mail – Отмечено флажком', + 'AppleMailIsRemoteAttachment' => 'Apple Mail – Ðаличие удалённого вложениÑ', + 'AppleMailMessageID' => 'Apple Mail – ID ÑообщениÑ', + 'AppleMailPriority' => 'Apple Mail – Приоритет', + 'AppleMailRead' => 'Apple Mail – Прочитано', + 'AppleMailRepliedTo' => 'Apple Mail – Отвечено', + 'Application' => 'Приложение', + 'ApplicationData' => 'Данные об уÑтройÑтве', + 'ApplicationNotes' => 'ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'ApplicationRecordVersion' => 'ВерÑÐ¸Ñ Application Record', + 'AppointmentSequence' => 'ПоÑледовательноÑÑ‚ÑŒ назначениÑ', + 'ApproximateFocusDistance' => 'Приблизительное раÑÑтоÑние фокуÑировки', + 'ArchivedFileName' => 'Ðазвание заархивированного файла', 'Artist' => 'ИÑполнитель', - 'AsShotICCProfile' => 'ICC профиль Ñнимка', + 'ArtistLen' => 'ИÑполнитель Len', + 'AsShotICCProfile' => 'ICC-профиль при Ñъёмке', 'AsShotNeutral' => 'Ðейтральный цвет при Ñъёмке', - 'AsShotPreProfileMatrix' => 'ÐŸÑ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° Ñнимка', - 'AsShotProfileName' => 'Ð˜Ð¼Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ, аÑÑоциированного Ñо Ñнимком', - 'AsShotWhiteXY' => 'Ðейтральный цвет x,y', + 'AsShotPreProfileMatrix' => 'Предварительный профиль матрицы при Ñъёмке', + 'AsShotProfileName' => 'Ðазвание Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ Ð¿Ñ€Ð¸ Ñъёмке', + 'AsShotWhiteXY' => 'XY белого при Ñъёмке', + 'Ascender' => 'ÐадÑтрочный интервал', + 'Ascent' => 'ÐадÑтрочный интервал', + 'AspectRatio' => 'Соотношение Ñторон', + 'AssetID' => 'ID актива', + 'Association' => 'ÐÑÑоциациÑ', + 'AssumedDisplaySize' => 'Размер отображаемого ÑтереоизображениÑ', + 'AssumedDistanceView' => 'РаÑÑтоÑние от позиции проÑмотра до диÑплеÑ', + 'Attachment' => 'Вложение', + 'Attendee' => 'УчаÑтник', + 'Attitude' => 'Положение', + 'AttitudeTarget' => 'Целевое положение', + 'Audiences' => 'ÐудиториÑ', + 'AudioBitrate' => 'Битрейт аудио', + 'AudioBitsPerSample' => 'Ð‘Ð¸Ñ‚Ð¾Ð²Ð°Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ð° аудио', + 'AudioBytes' => 'Ðудио байтов', + 'AudioChannels' => 'КоличеÑтво аудиоканалов', + 'AudioCodec' => 'Кодек аудио', + 'AudioCodecID' => 'ID аудиокодека', + 'AudioData' => 'Ðудиоданные', + 'AudioDuration' => 'ПродолжительноÑÑ‚ÑŒ аудио', + 'AudioEncoding' => { + Description => 'Кодирование звука', + PrintConv => { + 'Device-specific sound' => 'ЗавиÑÑщий от уÑтройÑтва звук', + 'G.711 A-law logarithmic PCM' => 'G.711 A-law логарифмичеÑкий PCM', + 'G.711 mu-law logarithmic PCM' => 'G.711 mu-law логарифмичеÑкий PCM', + 'Nellymoser 16kHz Mono' => 'Nellymoser 16 кГц, моно', + 'Nellymoser 8kHz Mono' => 'Nellymoser 8kHz, моно', + 'PCM-BE (uncompressed)' => 'PCM-BE (без ÑжатиÑ)', + 'PCM-LE (uncompressed)' => 'PCM-LE (без ÑжатиÑ)', + }, + }, + 'AudioFileSize' => 'Размер аудио файла', + 'AudioFormat' => 'Формат аудио', + 'AudioFrameSize' => 'Размер аудио фрейма', + 'AudioLayer' => 'Уровень аудио', + 'AudioMimeType' => 'MIME-тип аудио', + 'AudioMode' => 'Режим аудио', + 'AudioOutcue' => 'Заключительные Ñлова аудио', + 'AudioSampleRate' => 'ЧаÑтота диÑкретизации звука', + 'AudioSampleSize' => 'КоличеÑтво бит на канал', + 'AudioSamplingRate' => 'ЧаÑтота диÑкретизации', + 'AudioSamplingResolution' => 'РазрÑдноÑÑ‚ÑŒ аудио', + 'AudioSetting' => 'ÐаÑтройка звука', + 'AudioSize' => 'Размер аудиофайла', + 'AudioType' => { + Description => 'Тип аудио', + PrintConv => { + 'Mono Actuality' => 'Событие – Моно', + 'Mono Music' => 'Музыка – Моно', + 'Mono Question and Answer Session' => 'ВопроÑÑ‹ и ответы – Моно', + 'Mono Raw Sound' => 'ÐÐµÐ¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð½Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ – Моно', + 'Mono Response to a Question' => 'Ответ на Ð²Ð¾Ð¿Ñ€Ð¾Ñ â€“ Моно', + 'Mono Scener' => 'ОбÑтоÑтельÑтва ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ â€“ Моно', + 'Mono Voicer' => 'ГолоÑÐ¾Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ – Моно', + 'Mono Wrap' => 'Итог ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ â€“ Моно', + 'Stereo Actuality' => 'Событие – Стерео', + 'Stereo Music' => 'Музыка – Стерео', + 'Stereo Question and Answer Session' => 'ВопроÑÑ‹ и ответы – Стерео', + 'Stereo Raw Sound' => 'ÐÐµÐ¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚Ð°Ð½Ð½Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ – Стерео', + 'Stereo Response to a Question' => 'Ответ на Ð²Ð¾Ð¿Ñ€Ð¾Ñ â€“ Стерео', + 'Stereo Scener' => 'ОбÑтоÑтельÑтва ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ â€“ Стерео', + 'Stereo Voicer' => 'ГолоÑÐ¾Ð²Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑŒ – Стерео', + 'Stereo Wrap' => 'Итог ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ â€“ Стерео', + 'Text Only' => 'Только текÑÑ‚', + }, + }, + 'AuthenticationTime' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – Ð’Ñ€ÐµÐ¼Ñ Ð°ÑƒÑ‚ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ð¸', + 'AuthenticationType' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – Тип аутентификации', 'Author' => 'Ðвтор', + 'AuthorLen' => 'Ðвтор Len', 'AuthorsPosition' => 'ДолжноÑÑ‚ÑŒ автора', + 'AutoFocus' => { + Description => 'ÐвтофокуÑ', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'AutoISOMax' => 'МакÑимально значение автоматичеÑкого ISO', + 'AutoISOMin' => 'Минимальное значение автоматичеÑкого ISO', + 'AutoLowLightDuration' => 'ÐвтоÑъёмка при низком оÑвещении – ПродолжительноÑÑ‚ÑŒ', + 'AutoRotation' => { + Description => 'ÐвтоматичеÑкий поворот', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑки', + 'Down' => 'Вниз', + 'Up' => 'Вверх', + }, + }, + 'AutoSaveFilePath' => 'Путь к файлу автоÑохранениÑ', + 'AutoSaveFormat' => 'Формат автоÑохранениÑ', + 'AvgBitrate' => 'Средний битрейт', + 'AvgPacketSize' => 'Средний размер пакета', + 'AvgWidth' => 'СреднÑÑ ÑˆÐ¸Ñ€Ð¸Ð½Ð° глифа', + 'AxisDistanceX' => 'ДиÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð¿Ð¾ оÑи X', + 'AxisDistanceY' => 'ДиÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð¿Ð¾ оÑи Y', + 'AxisDistanceZ' => 'ДиÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð¿Ð¾ оÑи Z', + 'BMPVersion' => { + Description => 'ВерÑÐ¸Ñ BMP', + PrintConv => { + 'AVI BMP structure?' => 'Структура AVI BMP?', + }, + }, + 'BWFilter' => 'Чёрно-Белый фильтр', + 'BW_HalftoningInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ тонировании – Чёрно-Белое', + 'BW_TransferFunc' => 'Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñа – Чёрно-Белое', + 'Background' => 'Фон', + 'BackgroundColor' => 'Цвет фона', + 'BackgroundColorIndicator' => { + Description => 'Цвет фона', + PrintConv => { + 'Specified Background Color' => 'Указан', + 'Unspecified Background Color' => 'Ðе указан', + }, + }, + 'BackgroundColorValue' => 'Значение фонового цвета', + 'BackupTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ·ÐµÑ€Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'BadFaxLines' => 'КоличеÑтво битых Ñтрок', + 'BaseViewpointNum' => 'Ðомер базовой точки проÑмотра', 'BaselineExposure' => 'Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ ÑкÑпозициÑ', - 'BaselineNoise' => 'Базовый шум', + 'BaselineExposureOffset' => 'Сдвиг базовой ÑкÑпозиции', + 'BaselineLength' => 'Длина базовой линии', + 'BaselineNoise' => 'Базовый уровень шума', 'BaselineSharpness' => 'Ð‘Ð°Ð·Ð¾Ð²Ð°Ñ Ñ‡Ñ‘Ñ‚ÐºÐ¾ÑÑ‚ÑŒ', + 'BatteryCapacity' => 'ÐмкоÑÑ‚ÑŒ аккумулÑтора', + 'BatteryCurrent' => 'Ток аккумулÑтора', + 'BatteryLevel' => 'Уровень зарÑда аккумулÑтора', + 'BatteryTemperature' => 'Температура аккумулÑтора', + 'BatteryTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ от аккумулÑтора', + 'BatteryType' => 'Тип аккумулÑтора', + 'BatteryVoltage' => 'ÐапрÑжение аккумулÑтора', + 'BatteryVoltage1' => 'ÐапрÑжение аккумулÑтора 1', + 'BatteryVoltage2' => 'ÐапрÑжение аккумулÑтора 2', + 'BatteryVoltage3' => 'ÐапрÑжение аккумулÑтора 3', + 'BatteryVoltage4' => 'ÐапрÑжение аккумулÑтора 4', + 'BatteryVoltageAvg' => 'ÐапрÑжение аккумулÑтора (Ñреднее)', 'BayerGreenSplit' => 'Разделение зелёных каналов в матрице Байера', - 'BestQualityScale' => 'МаÑштаб Ñ Ð½Ð°Ð¸Ð»ÑƒÑ‡ÑˆÐ¸Ð¼ качеÑтвом', + 'BayerPattern' => 'Фильтр Байера', + 'BestQualityScale' => 'Оптимальный маÑштаб', + 'BibligraphicFileName' => 'Файл Ñ Ð±Ð¸Ð±Ð»Ð¸Ð¾Ð³Ñ€Ð°Ñ„Ð¸Ñ‡ÐµÑкой информацией', + 'BinaryFilter' => 'Бинарный фильтр', + 'Birthday' => 'День рождениÑ', + 'BitDepth' => { + Description => 'Ð‘Ð¸Ñ‚Ð¾Ð²Ð°Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ð°', + PrintConv => { + 'Custom' => 'Ð—Ð°Ð´Ð°Ð½Ð½Ð°Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»ÐµÐ¼', + }, + }, + 'Bitrate' => 'Битрейт', + 'BitsPerComponent' => 'КоличеÑтво бит на компонент', + 'BitsPerExtendedRunLength' => 'КоличеÑтво бит на раÑширенную длину Ñерий', + 'BitsPerPixel' => 'КоличеÑтво бит на пикÑель', + 'BitsPerRunLength' => 'КоличеÑтво бит на длину Ñерий', 'BitsPerSample' => 'КоличеÑтво бит на компонент', 'BlackLevel' => 'Уровень чёрного', - 'BlackLevelDeltaH' => 'Горизонтальное раÑпределение ÑƒÑ€Ð¾Ð²Ð½Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾', - 'BlackLevelDeltaV' => 'Вертикальное раÑпределение ÑƒÑ€Ð¾Ð²Ð½Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾', - 'BlackLevelRepeatDim' => 'Размер матрицы уровней чёрного', + 'BlackLevelBlue' => 'Уровень чёрного – Синий', + 'BlackLevelData' => 'Данные ÑƒÑ€Ð¾Ð²Ð½Ñ Ñ‡ÐµÑ€Ð½Ð¾Ð³Ð¾', + 'BlackLevelDeltaH' => 'Уровень чёрного – Дельта H', + 'BlackLevelDeltaV' => 'Уровень чёрного – Дельта V', + 'BlackLevelGreen' => 'Уровень чёрного – Зелёный', + 'BlackLevelRed' => 'Уровень чёрного – КраÑный', + 'BlackLevelRepeatDim' => 'Уровень чёрного – Размер шаблона повторений', + 'BlacksAdj' => 'Регулировка ÑƒÑ€Ð¾Ð²Ð½Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾', + 'BlockSizeMax' => 'МакÑимальный размер блока', + 'BlockSizeMin' => 'Минимальный размер блока', + 'BlocksPerFrame' => 'Блоков на кадр', + 'BlueBalance' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ñинего', + 'BlueEndpoint' => 'ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° Синего', + 'BlueMask' => 'МаÑка Синего', + 'BluePrimary' => 'ОÑновной Ñиний', + 'BlueX' => 'Синий по X', + 'BlueY' => 'Синий по Y', + 'BookName' => 'Ðазвание книги', + 'BookTitle' => 'Ðазвание книги', + 'BookType' => 'Тип книги', + 'BookVersion' => 'ВерÑÐ¸Ñ ÐºÐ½Ð¸Ð³Ð¸', + 'BootIdentifier' => 'Идентификатор загрузки', + 'BootLoaderVersion' => 'ВерÑÐ¸Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·Ñ‡Ð¸ÐºÐ°', + 'BootSystem' => 'СиÑтема загрузки', + 'BorderColor' => 'Цвет границы', + 'BorderInformation' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ границе', + 'BoundingBox' => 'Габаритный прÑмоугольник', + 'Brain' => 'Модуль Brain', + 'BrandingImageID' => 'Бренд – ID изображениÑ', + 'BrandingName' => 'Бренд – Ðазвание', + 'BreakChar' => 'Символ определÑющий границы Ñлов', 'Brightness' => 'ЯркоÑÑ‚ÑŒ', + 'BrightnessAdj' => 'Регулировка ÑркоÑти', + 'BrightnessValue' => 'Значение ÑркоÑти', + 'BurstID' => 'ID Ñерии Ñнимков', + 'BurstPrimary' => 'Первый кадр Ñерии', + 'BurstUUID' => 'Уникальный ID Ð´Ð»Ñ Ñерии Ñнимков', + 'BusyStatus' => 'СоÑтоÑние занÑтоÑти', 'By-line' => 'Ðвтор', + 'By-lineTitle' => 'Титул автора', + 'ByteLength' => 'Длина в байтах', + 'ByteOrder' => { + Description => 'ПорÑдок байтов', + PrintConv => { + 'Big-endian' => 'ПорÑдок от Ñтаршего к младшему', + 'Little-endian' => 'ПорÑдок от младшего к Ñтаршему', + }, + }, + 'BytesPerLine' => 'КоличеÑтво байт на Ñтроку', + 'BytesPerMinute' => 'Байт в минуту', + 'CDDBDiscPlayTime' => 'CDDB – Ð’Ñ€ÐµÐ¼Ñ Ð²Ð¾ÑÐ¿Ñ€Ð¾Ð¸Ð·Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¸Ñка', + 'CDDBDiscTracks' => 'CDDB – Треки на диÑке', + 'CDEType' => 'Тип CDE', 'CFALayout' => { - Description => 'Структура CFA', + Description => 'Макет CFA', + PrintConv => { + 'Even columns offset down 1/2 row' => 'Чётные Ñтолбцы Ñмещены вниз на 1/2 Ñтроки', + 'Even columns offset up 1/2 row' => 'Чётные Ñтолбцы Ñмещены вверх 1/2 Ñтроки', + 'Even rows offset down by 1/2 row, even columns offset left by 1/2 column' => 'Чётные Ñтроки Ñмещены вниз на 1/2 Ñтроки, чётные Ñтолбцы Ñмещены влево на 1/2 Ñтолбца', + 'Even rows offset down by 1/2 row, even columns offset right by 1/2 column' => 'Чётные Ñтроки Ñмещены вниз на 1/2 Ñтроки, чётные Ñтолбцы Ñмещены вправо на 1/2 Ñтолбца', + 'Even rows offset left 1/2 column' => 'Чётные Ñтроки Ñмещены влево на 1/2 Ñтолбца', + 'Even rows offset right 1/2 column' => 'Чётные Ñтроки Ñмещены вправо на 1/2 Ñтолбца', + 'Even rows offset up by 1/2 row, even columns offset left by 1/2 column' => 'Чётные Ñтроки Ñмещены вверх на 1/2 Ñтроки, чётные Ñтолбцы Ñмещены влево на 1/2 Ñтолбца', + 'Even rows offset up by 1/2 row, even columns offset right by 1/2 column' => 'Чётные Ñтроки Ñмещены вверх на 1/2 Ñтроки, чётные Ñтолбцы Ñмещены вправо на 1/2 Ñтолбца', + 'Rectangular' => 'ПрÑÐ¼Ð¾ÑƒÐ³Ð¾Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½Ð¾Ð²ÐºÐ°', + }, + }, + 'CFAPattern' => { + Description => 'Шаблон CFA', + PrintConv => { + '[Blue,Green][Green,Red]' => '[Синий, Зелёный][Зелёный, КраÑный]', + '[Green,Blue][Red,Green]' => '[Зелёный, Синий][КраÑный, Зелёный]', + '[Green,Red][Blue,Green]' => '[Зелёный, КраÑный][Синий, Зелёный]', + '[Red,Green][Green,Blue]' => '[КраÑный, Зелёный][Зелёный, Синий]', + 'n/a' => 'Ðет данных', + }, + }, + 'CFAPattern2' => 'Шаблон CFA 2', + 'CFAPlaneColor' => 'Цветовые плоÑкоÑти CFA', + 'CFARepeatPatternDim' => 'Шаблон Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð¸Ñ CFA', + 'CIP3DataFile' => 'CIP3 – Файл данных', + 'CIP3Sheet' => 'CIP3 – ЛиÑÑ‚', + 'CIP3Side' => 'CIP3 – Сторона', + 'CMYKEquivalent' => 'Эквивалент CMYK', + 'CPUVersions' => 'ВерÑии CPU', + 'CR2CFAPattern' => { + Description => 'CR2 – Шаблон CFA', PrintConv => { - 'Even columns offset down 1/2 row' => 'Смещённое раÑположение A: чётные Ñтолбцы Ñмещены вниз на полпикÑела', - 'Even columns offset up 1/2 row' => 'Смещённое раÑположение B: чётные Ñтолбцы Ñмещены вверх на полпикÑела', - 'Even rows offset left 1/2 column' => 'Смещённое раÑположение D: чётные Ñтроки Ñмещены влево на полпикÑела', - 'Even rows offset right 1/2 column' => 'Смещённое раÑположение C: чётные Ñтроки Ñмещены вправо на полпикÑела', - 'Rectangular' => 'ПрÑмоугольное (или квадратное) раÑположение Ñлементов', + '[Blue,Green][Green,Red]' => '[Синий, Зеленый][Зеленый, КраÑный]', + '[Green,Blue][Red,Green]' => '[Зеленый, Синий][КраÑный, Зеленый]', + '[Green,Red][Blue,Green]' => '[Зеленый, КраÑный][Синий, Зеленый]', + '[Red,Green][Green,Blue]' => '[КраÑный, Зеленый][Зеленый, Синий]', }, }, - 'CFAPattern' => 'CFA карта', + 'CacheControl' => 'Контроль кешированиÑ', + 'CacheVersion' => 'ВерÑÐ¸Ñ ÐºÑша', + 'CalendarColor' => 'Цвет календарÑ', + 'CalendarDescription' => 'ОпиÑание календарÑ', + 'CalendarID' => 'ID календарÑ', + 'CalendarName' => 'Ðазвание календарÑ', + 'CalendarScale' => 'ÐšÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ð½Ð°Ñ ÑиÑтема', + 'CalibratedFocalLength' => 'Откалирброванное фокуÑное раÑÑтоÑние', + 'CalibratedOpticalCenterX' => 'Откалирброванный оптичеÑкий центр по X', + 'CalibratedOpticalCenterY' => 'Откалирброванный оптичеÑкий центр по Y', 'CalibrationIlluminant1' => { - Description => 'Калибровочный иллюминант â„–1', + Description => 'Калибровочное оÑвещение 1', PrintConv => { - 'Cloudy' => 'ОблачноÑÑ‚ÑŒ', - 'Cool White Fluorescent' => 'ФлуореÑцентный белый холодный (W 3800 - 4500K)', - 'Day White Fluorescent' => 'ФлуореÑцентный белый дневной', - 'Daylight' => 'Дневной Ñвет', - 'Daylight Fluorescent' => 'ФлуореÑцентный белый дневного Ñвета (D 5700 - 7100K)', - 'Fine Weather' => 'ЯÑÐ½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð°', - 'Flash' => 'Ð’Ñпышка', - 'Fluorescent' => 'ФлуореÑцентный', - 'ISO Studio Tungsten' => 'ISO Ð´Ð»Ñ Ñтудийных ламп накаливаниÑ', - 'Other' => 'другой иÑточник Ñвета', - 'Shade' => 'Тень', - 'Standard Light A' => 'Стандартный Ñвет A', - 'Standard Light B' => 'Стандартный Ñвет B', - 'Standard Light C' => 'Стандартный Ñвет C', - 'Tungsten (Incandescent)' => 'Лампа Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (Ñркий Ñвет)', - 'Unknown' => 'неизвеÑтно', - 'Warm White Fluorescent' => 'ФлуореÑцентный теплый белый (L 2600 - 3250K)', - 'White Fluorescent' => 'ФлуореÑцентный белый (WW 3250 - 3800K)', + 'Cloudy' => 'Облачно (6500 К)', + 'Cool White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Холодный Ñвет (4150 К)', + 'D50' => 'D50 (5000 К)', + 'D55' => 'D55 (5500 К)', + 'D65' => 'D65 (6500 К)', + 'D75' => 'D75 (7500 К)', + 'Day White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Дневной белый (5050 К)', + 'Daylight' => 'Дневной Ñвет (5500 К)', + 'Daylight Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° дневного Ñвета (6400 К)', + 'Fine Weather' => 'ЯÑÐ½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð° (5500 К)', + 'Flash' => 'Ð’Ñпышка (5500 К)', + 'Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° (4150 К)', + 'ISO Studio Tungsten' => 'Ð¡Ñ‚ÑƒÐ´Ð¸Ð¹Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (3200 К)', + 'Other' => 'Другой иÑточник Ñвета', + 'Shade' => 'Тень (7500 К)', + 'Standard Light A' => 'Стандартное оÑвещение A (2850 К)', + 'Standard Light B' => 'Стандартное оÑвещение B (5500 К)', + 'Standard Light C' => 'Стандартное оÑвещение C (6500 К)', + 'Tungsten (Incandescent)' => 'Лампа Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (2850 К)', + 'Unknown' => 'ÐеизвеÑтно', + 'Warm White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Тёплый Ñвет (2925 К)', + 'White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Белый Ñвет (3525 К)', }, }, 'CalibrationIlluminant2' => { - Description => 'Калибровочный иллюминант â„–2', + Description => 'Калибровочное оÑвещение 2', PrintConv => { - 'Cloudy' => 'ОблачноÑÑ‚ÑŒ', - 'Cool White Fluorescent' => 'ФлуореÑцентный белый холодный (W 3800 - 4500K)', - 'Day White Fluorescent' => 'ФлуореÑцентный белый дневной', - 'Daylight' => 'Дневной Ñвет', - 'Daylight Fluorescent' => 'ФлуореÑцентный белый дневного Ñвета (D 5700 - 7100K)', - 'Fine Weather' => 'ЯÑÐ½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð°', - 'Flash' => 'Ð’Ñпышка', - 'Fluorescent' => 'ФлуореÑцентный', - 'ISO Studio Tungsten' => 'ISO Ð´Ð»Ñ Ñтудийных ламп накаливаниÑ', - 'Other' => 'другой иÑточник Ñвета', - 'Shade' => 'Тень', - 'Standard Light A' => 'Стандартный Ñвет A', - 'Standard Light B' => 'Стандартный Ñвет B', - 'Standard Light C' => 'Стандартный Ñвет C', - 'Tungsten (Incandescent)' => 'Лампа Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (Ñркий Ñвет)', - 'Unknown' => 'неизвеÑтно', - 'Warm White Fluorescent' => 'ФлуореÑцентный теплый белый (L 2600 - 3250K)', - 'White Fluorescent' => 'ФлуореÑцентный белый (WW 3250 - 3800K)', + 'Cloudy' => 'Облачно (6500 К)', + 'Cool White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Холодный Ñвет (4150 К)', + 'D50' => 'D50 (5000 К)', + 'D55' => 'D55 (5500 К)', + 'D65' => 'D65 (6500 К)', + 'D75' => 'D75 (7500 К)', + 'Day White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Дневной белый (5050 К)', + 'Daylight' => 'Дневной Ñвет (5500 К)', + 'Daylight Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° дневного Ñвета (6400 К)', + 'Fine Weather' => 'ЯÑÐ½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð° (5500 К)', + 'Flash' => 'Ð’Ñпышка (5500 К)', + 'Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° (4150 К)', + 'ISO Studio Tungsten' => 'Ð¡Ñ‚ÑƒÐ´Ð¸Ð¹Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (3200 К)', + 'Other' => 'Другой иÑточник Ñвета', + 'Shade' => 'Тень (7500 К)', + 'Standard Light A' => 'Стандартное оÑвещение A (2850 К)', + 'Standard Light B' => 'Стандартное оÑвещение B (5500 К)', + 'Standard Light C' => 'Стандартное оÑвещение C (6500 К)', + 'Tungsten (Incandescent)' => 'Лампа Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (2850 К)', + 'Unknown' => 'ÐеизвеÑтное', + 'Warm White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Тёплый Ñвет (2925 К)', + 'White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Белый Ñвет (3525 К)', + }, + }, + 'CallForImage' => 'Звонок по изображению', + 'CamReverse' => 'Камера заднего вида', + 'CameraArrangementInterval' => 'Интервал раÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹', + 'CameraCalibration1' => 'ÐšÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° фотокамеры 1', + 'CameraCalibration2' => 'ÐšÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° фотокамеры 2', + 'CameraCalibrationSig' => 'Сигнатура калибровки камеры', + 'CameraDateTime' => 'Дата и Ð’Ñ€ÐµÐ¼Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹', + 'CameraElevationAngle' => 'Угол обзора камеры', + 'CameraFilename' => 'Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ñозданное камерой', + 'CameraID' => 'ID камеры', + 'CameraLabel' => 'Ðазвание камеры', + 'CameraMakeModel' => 'Модель камеры', + 'CameraModel' => 'Модель камеры', + 'CameraModelID' => 'ID модели камеры', + 'CameraOperator' => 'Кинооператор', + 'CameraOrientation' => { + Description => 'ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹', + PrintConv => { + 'Horizontal (normal)' => 'ГоризонтальнаÑ', + 'Rotate 180' => 'Поверот на 180°', + 'Rotate 270 CW' => 'Поворот на 270° по чаÑовой Ñтрелке', + 'Rotate 90 CW' => 'Поворот на 90° по чаÑовой Ñтрелке', }, }, - 'CameraCalibration1' => 'ÐšÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° фотоаппарата â„–1', - 'CameraCalibration2' => 'ÐšÐ°Ð»Ð¸Ð±Ñ€Ð¾Ð²Ð¾Ñ‡Ð½Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° фотоаппарата â„–2', - 'CameraCalibrationSig' => 'Сигнатура калибровки фотоаппарата', - 'CameraSerialNumber' => 'Серийный номер фотоаппарата', - 'Caption-Abstract' => 'ПодпиÑÑŒ', + 'CameraPitch' => 'Тангаж камеры (Ðаклон)', + 'CameraRoll' => 'Крен камеры (Вращение)', + 'CameraSerialNumber' => 'Серийный номер камеры', + 'CameraTemperature' => 'Температура камеры', + 'CameraType' => 'Тип камеры', + 'CameraYaw' => 'РыÑкание камеры (Поворот)', + 'CanSeekOnTime' => 'ВозможноÑÑ‚ÑŒ навигации по времени', + 'CanSeekToEnd' => 'ВозможноÑÑ‚ÑŒ перейти к концу', + 'CapHeight' => 'Ð’Ñ‹Ñота пропиÑных букв', + 'Caption' => 'Заголовок', + 'Caption-Abstract' => 'Подробное опиÑание', 'CaptionWriter' => 'Ðвтор подпиÑи', + 'CaptureSoftware' => 'ЗапиÑÑŒ изображений выполнен в', + 'CaptureXResolution' => 'Разрешение захвата по X', + 'CaptureXResolutionUnit' => { + Description => 'Единицы Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð·Ð°Ñ…Ð²Ð°Ñ‚Ð° по X', + PrintConv => { + '0.01 mm' => '0.01 мм', + '0.1 mm' => '0.1 мм', + '10 cm' => '10 Ñм', + '10 m' => '10 м', + '100 m' => '100 м', + 'cm' => 'Ñм', + 'km' => 'км', + 'm' => 'м', + 'mm' => 'мм', + 'um' => 'мкм', + }, + }, + 'CaptureYResolution' => 'Разрешение захвата по Y', + 'CaptureYResolutionUnit' => { + Description => 'Единицы Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð·Ð°Ñ…Ð²Ð°Ñ‚Ð° по Y', + PrintConv => { + '0.01 mm' => '0.01 мм', + '0.1 mm' => '0.1 мм', + '10 cm' => '10 Ñм', + '10 m' => '10 м', + '100 m' => '100 м', + 'cm' => 'Ñм', + 'km' => 'км', + 'm' => 'м', + 'mm' => 'мм', + 'um' => 'мкм', + }, + }, + 'CatalogSets' => 'Ðаборы каталога', 'Categories' => 'Категории', - 'Category' => 'Категории', + 'Category' => 'Группа', + 'CellLength' => 'Строк в матрице дизеринга или полутонированиÑ', + 'CellWidth' => 'Колонок в матрице дизеринга или полутонированиÑ', + 'ChannelMode' => { + Description => 'Режим канала', + PrintConv => { + 'Dual Channel' => 'Двухканальное', + 'Joint Stereo' => 'Объединённое Ñтерео', + 'Single Channel' => 'Моно', + 'Stereo' => 'Стерео', + }, + }, + 'ChannelUsage' => 'ИÑпользование канала', + 'Channels' => 'Каналов', + 'Chapter' => 'ЧаÑÑ‚ÑŒ', + 'ChapterCount' => 'КоличеÑтво глав', + 'ChapterName' => 'Ðазвание главы', + 'ChapterNumber' => 'Ðомер главы', + 'CharacterSet' => 'Ðабор Ñимволов', + 'Characters' => 'КоличеÑтво Ñимволов', + 'CharactersWithSpaces' => 'КоличеÑтво Ñимволов, Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ Ð¿Ñ€Ð¾Ð±ÐµÐ»Ñ‹', 'ChromaBlurRadius' => 'Ð Ð°Ð´Ð¸ÑƒÑ ÑÐ³Ð»Ð°Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð½Ð¾Ñти', - 'City' => 'Город', + 'ChromaticAberrationCorrParams' => 'Параметры коррекции хроматичеÑкой аберрации', + 'ChromaticAberrationCorrection' => { + Description => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñ…Ñ€Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкой аберрации', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкаÑ', + 'No correction params available' => 'ÐедоÑтупна', + 'Off' => 'Ðе включена', + 'On' => 'Включена', + }, + }, + 'Chromaticities' => 'ОÑновные цвета и Точка белого', + 'CircleOfConfusion' => 'Круг нерезкоÑти', + 'City' => 'Город проиÑÑ…Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…', + 'Class' => 'КлаÑÑ', + 'Classification' => 'КлаÑÑификации', + 'ClassifyState' => 'КлаÑÐ¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñтруктуры', + 'CleanFaxData' => { + Description => 'Ðаличие битых Ñтрок', + PrintConv => { + 'Clean' => 'Без битых Ñтрок', + 'Regenerated' => 'Битые Ñтроки воÑÑтановлены', + 'Unclean' => 'Битые Ñтроки не воÑÑтановлены', + }, + }, + 'ClipPath' => 'Обтравочный контур', + 'ClippingLimit' => 'ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° копирование', + 'ClippingPathName' => 'Ðазвание обтравочного контура', + 'CodePage' => { + Description => 'ÐšÐ¾Ð´Ð¾Ð²Ð°Ñ Ñтраница', + PrintConv => { + 'Windows Latin 1 (Western European)' => 'Windows Latin 1 (ЗападноевропейÑкаÑ)', + }, + }, + 'CodecFlavorID' => 'ID кодека Flavor', + 'CodedCharacterSet' => 'Кодовый набор Ñимволов', + 'CodedFrameSize' => 'Размер кодированного кадра', + 'CodestreamRegistration' => 'РегиÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÐºÐ¾Ð´Ð¾Ð²Ð¾Ð³Ð¾ потока', + 'CodingMethods' => { + Description => 'Метод ÑжатиÑ', + PrintConv => { + 'Baseline JPEG' => 'Базовое JPEG', + 'JBIG color' => 'Цветное JBIG', + 'Modified Huffman' => 'Одномерное – ÐœÐ¾Ð´Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð¥Ð°Ñ„Ñ„Ð¼Ð°Ð½Ð°', + 'Modified MR' => 'Двумерное – Modified Modified READ', + 'Modified Read' => 'Двумерное – Modified READ', + 'Unspecified compression' => 'ÐеизвеÑтное Ñжатие', + }, + }, + 'Collection' => 'КоллекциÑ', + 'CollectionName' => 'Ðазвание коллекции', + 'CollectionURI' => 'URI коллекции', + 'Collections' => 'Коллекции', + 'ColorAdjustmentMode' => { + Description => 'Режим регулировки цвета', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'ColorCalibrationMatrix' => 'Матрица калибровки цвета', + 'ColorCharacterization' => 'Спецификации цвета', + 'ColorClass' => { + Description => 'Цветовой клаÑÑ', + PrintConv => { + '0 (None)' => '0 (Ðе указан)', + '1 (Winner)' => '1 (Лучшее)', + '2 (Winner alt)' => '2 (Лучшее Alt)', + '3 (Superior)' => '3 (Хорошее)', + '4 (Superior alt)' => '4 (Хорошее Alt)', + '5 (Typical)' => '5 (Обычноеl)', + '6 (Typical alt)' => '6 (Обычное Alt)', + '7 (Extras)' => '7 (ЭкÑтра)', + '8 (Trash)' => '8 (Хлам)', + }, + }, + 'ColorComponents' => 'Цветовых компонентов', + 'ColorCorrection' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð°', 'ColorEffect' => { PrintConv => { 'Sepia' => 'СепиÑ', }, }, 'ColorFilter' => 'Цветовой фильтр', - 'ColorMatrix1' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° â„–1', - 'ColorMatrix2' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° â„–2', + 'ColorGroup' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð°', + 'ColorHalftoningInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ тонировании – Цветное', + 'ColorMap' => 'Карта цветов', + 'ColorMatrix1' => 'Матрица Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð² 1', + 'ColorMatrix2' => 'Матрица Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð² 2', 'ColorMode' => { - Description => 'ТворчеÑкийСтиль', + Description => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ', PrintConv => { 'Autumn Leaves' => 'ОÑенние лиÑÑ‚ÑŒÑ', - 'B&W' => 'Черно-белое', + 'B&W' => 'Чёрно-белое', + 'Bitmap' => 'МонохромнаÑ', + 'Black & White' => 'Чёрно-белый', 'Clear' => 'Прозрачный', + 'Color Palette' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð°', 'Deep' => 'Глубокий', + 'Duotone' => 'ДвуцветнаÑ', + 'Embed Adobe RGB' => 'Ð’Ñтроенный Adobe RGB', + 'Evening' => 'Вечер', + 'Grayscale' => 'Ð’ градациÑÑ… Ñерого', + 'Indexed' => 'ИндекÑированные цвета', + 'Indexed Color' => 'ИндекÑированный цвет', 'Landscape' => 'Пейзаж', 'Light' => 'Бледный', + 'Multichannel' => 'МногоканальнаÑ', + 'Natural' => 'Ðатуральный', + 'Natural color' => 'Ðатуральный цвет', + 'Natural sRGB' => 'Ðатуральный sRGB', + 'Natural+ sRGB' => 'Ðатуральный+ sRGB', 'Neutral' => 'Ðейтральный', + 'Night Portrait' => 'Ðочной портрет', + 'Night Scene' => 'ÐÐ¾Ñ‡Ð½Ð°Ñ Ñцена', 'Night View' => 'Ðочной вид', - 'Night View/Portrait' => 'Ðочной портрет', + 'Night View/Portrait' => 'Ðочной вид/портрет', 'Portrait' => 'Портрет', - 'Standard' => 'Стандартное', + 'RGB Color' => 'Цвет RGB', + 'Sepia' => 'СепиÑ', + 'Solarization' => 'СолÑризациÑ', + 'Standard' => 'Стандартный', 'Sunset' => 'Закат', 'Vivid' => 'Яркий цвет', + 'Vivid color' => 'Яркий цвет', + 'n/a' => 'Ðет данных', + }, + }, + 'ColorNoiseReduction' => 'Щумодав – Уменьшение цветных шумов', + 'ColorPalette' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð°', + 'ColorPlanes' => 'Цветовые плоÑкоÑти', + 'ColorPrimaries' => 'Праймериз цвета', + 'ColorRepresentation' => { + Description => 'Цветовое предÑтавление', + PrintConv => { + '3 Components, Frame Sequential in Multiple Objects' => '3 компонента. ПоÑледовательноÑÑ‚ÑŒ кадров в неÑкольких объектах', + '3 Components, Frame Sequential in One Object' => '3 компонента. ПоÑледовательноÑÑ‚ÑŒ кадров в одном объекте', + '3 Components, Line Sequential' => '3 компонента. ПоÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñтрока', + '3 Components, Pixel Sequential' => '3 компонента. ПоÑледовательноÑÑ‚ÑŒ пикÑелей', + '3 Components, Single Frame' => '3 компонента. Один кадр', + '3 Components, Special Interleaving' => '3 компонента. Специальное чередование', + '4 Components, Frame Sequential in Multiple Objects' => '4 компонента. ПоÑледовательноÑÑ‚ÑŒ кадров в неÑкольких объектах', + '4 Components, Frame Sequential in One Object' => '4 компонента. ПоÑледовательноÑÑ‚ÑŒ кадров в одном объекте', + '4 Components, Line Sequential' => '4 компонента. ПоÑÐ»ÐµÐ´Ð¾Ð²Ð°Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñтрока', + '4 Components, Pixel Sequential' => '4 компонента. ПоÑледовательноÑÑ‚ÑŒ пикÑелей', + '4 Components, Single Frame' => '4 компонента. Один кадр', + '4 Components, Special Interleaving' => '4 компонента. Специальное чередование', + 'Monochrome, Single Frame' => 'Монохромное. Один кадр', + 'No Image, Single Frame' => 'Ðет изображениÑ. Один кадр', }, }, + 'ColorResolutionDepth' => 'Глубина цвета', + 'ColorResponseUnit' => 'Единицы цветовой чувÑтвительноÑти', + 'ColorSamplersResource' => 'РеÑÑƒÑ€Ñ Ð±Ñ€Ð°Ð·Ñ†Ð¾Ð² цвета', + 'ColorSamplersResource2' => 'РеÑÑƒÑ€Ñ Ð±Ñ€Ð°Ð·Ñ†Ð¾Ð² цвета 2', + 'ColorSequence' => 'ПоÑледовательноÑÑ‚ÑŒ цветов', 'ColorSpace' => { - Description => 'Данные о цветовой Ñреде', + Description => 'Цветовое проÑтранÑтво', + PrintConv => { + 'BT 2020 Constant Luminance' => 'ПоÑтоÑÐ½Ð½Ð°Ñ ÑркоÑÑ‚ÑŒ BT 2020', + 'Calibrated RGB' => 'Калиброванный RGB', + 'Device CMYK' => 'УÑтройÑтво CMYK', + 'Device RGB' => 'УÑтройÑтво RGB', + 'Embedded Color Profile' => 'Ð’Ñтроенный цветовой профиль', + 'Grayscale' => 'Оттенки Ñерого', + 'ICC Profile' => 'ICC-профиль', + 'Linked Color Profile' => 'СвÑзанный цветовой профиль', + 'Uncalibrated' => 'Ðекалиброванное', + 'Undefined' => 'Ðе определено', + 'Windows Color Space' => 'Цветовое проÑтранÑтво Windows', + }, + }, + 'ColorSpecApproximation' => { + Description => 'Ð¡Ð¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð° – ÐппрокÑимациÑ', + PrintConv => { + 'Accurate' => 'ТочнаÑ', + 'Exceptional Quality' => 'Лучшее качеÑтво', + 'Not Specified' => 'Ðе указана', + 'Poor Quality' => 'Ðизкое качеÑтво', + 'Reasonable Quality' => 'Приемлемое качеÑтво', + }, + }, + 'ColorSpecData' => 'Ð¡Ð¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð° – Данные', + 'ColorSpecMethod' => { + Description => 'Ð¡Ð¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð° – Метод', PrintConv => { - 'ICC Profile' => 'Профиль ICC', - 'Uncalibrated' => 'Ðе калиброванный', + 'Any ICC' => 'Любой ICC', + 'Enumerated' => 'ПеречиÑлимый', + 'Restricted ICC' => 'Ограниченный ICC', + 'Vendor Color' => 'Цвет поÑтавщика', }, }, + 'ColorSpecPrecedence' => 'Ð¡Ð¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð° – Precedence', + 'ColorTable' => 'Таблица цвета', 'ColorTemperature' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð°', + 'ColorTemperatureAdj' => 'Регулировка температуры цвета', + 'ColorTemperatures' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð°', + 'ColorTransferFuncs' => 'Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñа – Цветное', + 'ColorType' => { + Description => 'Тип цвета', + PrintConv => { + 'Grayscale' => 'Ð“Ñ€Ð°Ð´Ð°Ñ†Ð¸Ñ Ñерого', + 'Grayscale with Alpha' => 'Ð“Ñ€Ð°Ð´Ð°Ñ†Ð¸Ñ Ñерого Ñ Ðльфа-каналом', + 'Palette' => 'Палитра', + 'RGB with Alpha' => 'RGB Ñ Ðльфа-каналом', + }, + }, 'ColorimetricReference' => 'КолориметричеÑкий Ñталон', + 'Colorimetry' => 'КолориметриÑ', + 'Colors' => 'Цвета', + 'Command' => 'Команда', + 'CommandLineArguments' => 'Ðргументы командной Ñтроки', 'Comment' => 'Комментарий', - 'ComponentsConfiguration' => 'Значение каждого компонента', - 'CompressedBitsPerPixel' => 'Режим ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + 'CommentLen' => 'Комментарий Len', + 'CommentTime' => 'Ð’Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð¼Ð¼ÐµÐ½Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'Comments' => 'Комментарии', + 'CommonNetworkRelLink' => 'ÐžÐ±Ñ‰Ð°Ñ Ñеть Rel Link', + 'CommonPathSuffix' => 'Ð¡ÑƒÑ„Ñ„Ð¸ÐºÑ Ð¾Ð±Ñ‰ÐµÐ³Ð¾ пути', + 'Company' => 'ОрганизациÑ', + 'CompatibleBrands' => 'СовмеÑтимые марки', + 'CompatibleFontName' => 'Ðазвание ÑовмеÑтимого шрифта', + 'ComponentDefinition' => 'Определение компонента', + 'ComponentMapping' => 'СопоÑтавление компонентов', + 'ComponentsConfiguration' => { + Description => 'ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð¾Ð²', + PrintConv => { + 'Alpha (matte)' => 'Ðльфа-канал (маÑка)', + 'Alpha, B, G, R' => 'Ðльфа-канал, B, G, R', + 'Blue (B)' => 'Синий (B)', + 'Chrominance (Cb, Cr, subsampled by two)' => 'ЦветноÑÑ‚ÑŒ (Cb, Cr, ÑубдиÑÐºÑ€ÐµÑ‚Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° два)', + 'Composite video' => 'Композитное видео', + 'Depth (Z)' => 'Глубина (Z)', + 'Green (G)' => 'Зелёный (G)', + 'Luminance (Y)' => 'ЯркоÑÑ‚ÑŒ (Y)', + 'R, G, B, Alpha' => 'R, G, B, Ðльфа-канал', + 'Red (R)' => 'КраÑный (R)', + 'User-defined 2 component element' => '2-компонентный Ñлемент определÑемый пользователем', + 'User-defined 3 component element' => '3-компонентный Ñлемент определÑемый пользователем', + 'User-defined 4 component element' => '4-компонентный Ñлемент определÑемый пользователем', + 'User-defined 5 component element' => '5-компонентный Ñлемент определÑемый пользователем', + 'User-defined 6 component element' => '6-компонентный Ñлемент определÑемый пользователем', + 'User-defined 7 component element' => '7-компонентный Ñлемент определÑемый пользователем', + 'User-defined 8 component element' => '8-компонентный Ñлемент определÑемый пользователем', + 'User-defined single component' => 'Один компонент определÑемый пользователем', + }, + }, + 'Composer' => 'Композитор', + 'CompositeImage' => { + Description => 'СоÑтавное изображение', + PrintConv => { + 'Composite Image Captured While Shooting' => 'Полученное во Ð²Ñ€ÐµÐ¼Ñ Ñъёмки', + 'General Composite Image' => 'Созданное в редакторе', + 'Not a Composite Image' => 'Ðет', + 'Unknown' => 'ГеизвеÑтно', + }, + }, + 'CompositeImageCount' => 'СоÑтавное изображение – КоличеÑтво', + 'CompositeImageExposureTimes' => 'СоÑтавное изображение – Выдержка', + 'Composition' => 'КомпозициÑ', + 'CompositionOptions' => 'Варианты композиции', + 'Compressed' => { + Description => 'Сжатый', + PrintConv => { + 'False' => 'Ðет', + 'True' => 'Да', + }, + }, + 'CompressedBitsPerPixel' => 'Сжатых бит на пикÑель', + 'CompressedSize' => 'Сжатый размер', 'Compression' => { - Description => 'Схема ÑжатиÑ', + Description => 'Метод ÑжатиÑ', PrintConv => { + '4-Bit RLE' => '4-битное RLE', + '8-Bit RLE' => '8-битное RLE', + 'Bitfields' => 'Битовые полÑ', + 'Fractal' => 'Фрактальное', 'JPEG' => 'JPEG Ñжатие', - 'Uncompressed' => 'без ÑжатиÑ', + 'JPEG (old-style)' => 'JPEG (Ñтарый Ñтиль)', + 'Modified Huffman' => 'Модифицированное кодирование Хаффмана', + 'Modified Modified READ' => 'Modified Modified READ (MMR)', + 'Modified READ' => 'Modified READ (MR)', + 'None' => 'Без ÑжатиÑ', + 'RLE Encoding' => 'Кодирование RLE', + 'Uncompressed' => 'ÐеÑжатый', + 'ZIP with prediction' => 'ZIP Ñ Ð¿Ñ€ÐµÐ´Ñказанием', + 'ZIP without prediction' => 'ZIP без предÑказаниÑ', + }, + }, + 'CompressionFactor' => 'КоÑффициент ÑжатиÑ', + 'CompressionLevel' => 'Уровень ÑжатиÑ', + 'CompressionType' => 'Тип ÑжатиÑ', + 'CompressorName' => 'Ðазвание компреÑÑора', + 'ConditionalFEC' => 'КомпенÑÐ°Ñ†Ð¸Ñ ÑкÑпозиции при Ñъёмке Ñо вÑпышкой', + 'Confidence' => 'КонфидециальноÑÑ‚ÑŒ', + 'ConfidenceLevel' => 'Интервал раÑÐ¿Ð¾Ð·Ð½Ð°Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†Ð°', + 'ConfidenceMime' => 'MIME-тип конфидециального изображениÑ', + 'ConfirmedObjectSize' => 'Подтверждённый размер объекта', + 'ConsecutiveBadFaxLines' => 'КоличеÑтво поÑледовательных битых Ñтрок', + 'ConstrainedCropHeight' => 'ÐŸÑ€Ð¾Ð¿Ð¾Ñ€Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾Ð±Ñ€ÐµÐ·ÐºÐ° – Ð’Ñ‹Ñота', + 'ConstrainedCropWidth' => 'ÐŸÑ€Ð¾Ð¿Ð¾Ñ€Ñ†Ð¸Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ð¾Ð±Ñ€ÐµÐ·ÐºÐ° – Ширина', + 'Contact' => 'Контакт', + 'ContainerVersion' => 'ВерÑÐ¸Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð°', + 'ContentDisposition' => 'РаÑпорÑжение Ñодержимым', + 'ContentIdentifier' => 'Идентификатор контента', + 'ContentLanguage' => 'Язык контента', + 'ContentLocationCode' => 'Контент – Код Ñтраны', + 'ContentLocationName' => 'Контент – Страна', + 'ContentProtected' => { + Description => 'Контент защищен', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'ContentProtectedPercent' => 'Контент защищен – Процент', + 'ContentRating' => { + Description => 'ВозраÑтной рейтинг контента', + PrintConv => { + 'Adult Supervision Recommended' => 'Под наблюдением взроÑлых', + 'Adults Only' => 'Только Ð´Ð»Ñ Ð²Ð·Ñ€Ð¾Ñлых', + 'All Ages' => 'Ð”Ð»Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾ возраÑта', + 'No Rating' => 'ВозраÑÑ‚Ð½Ð°Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð° не указана', + 'Older Children' => 'Старшим детÑм', + 'Older Teens' => 'Старшим подроÑткам', + 'Younger Teens' => 'Младшим подроÑткам', }, }, + 'ContentScriptType' => 'Язык Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñценариев', + 'ContentStyleType' => 'Язык таблицы Ñтилей', + 'ContentType' => 'MIME-тип документа', + 'ContiguousCodestream' => 'Смежный кодовый поток', 'Contrast' => { Description => 'КонтраÑтноÑÑ‚ÑŒ', PrintConv => { - 'High' => 'Резко', - 'Low' => 'ÐœÑгко', - 'Normal' => 'Стандарт', + 'High' => 'Ð’Ñ‹ÑокаÑ', + 'Low' => 'ÐизкаÑ', + 'Normal' => 'СтандартнаÑ', + }, + }, + 'ContrastAdj' => 'Регулировка контраÑта', + 'Contributor' => 'Соавтор', + 'Controller' => 'Контроллер', + 'ConvergenceAngle' => 'Угол ÑхождениÑ', + 'ConvergenceBaseImage' => { + Description => 'СходимоÑÑ‚ÑŒ базового изображениÑ', + PrintConv => { + 'Equivalent for Both Viewpoints' => 'Эквивалент Ð´Ð»Ñ Ð¾Ð±ÐµÐ¸Ñ… точек проÑмотра', + 'Left Viewpoint' => 'Ð›ÐµÐ²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° проÑмотра', + 'Right Viewpoint' => 'ÐŸÑ€Ð°Ð²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° проÑмотра', + }, + }, + 'ConvergenceDistance' => 'РаÑÑтоÑние ÑходимоÑти', + 'Converter' => 'Конвертер', + 'Copyright' => 'ÐвторÑкое право', + 'CopyrightFileName' => 'Ðазвание файла авторÑкого права', + 'CopyrightFlag' => { + Description => 'Флаг авторÑкого права', + PrintConv => { + 'False' => 'Ðет', + 'True' => 'ЕÑÑ‚ÑŒ', + }, + }, + 'CopyrightLen' => 'ÐвторÑкое право Len', + 'CopyrightNotice' => 'ÐвторÑкое право', + 'CopyrightOwner' => 'Правообладатель', + 'CopyrightOwnerID' => 'PLUS-ID правообладателÑ', + 'CopyrightOwnerImageID' => 'ID Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ñвоенный правообладателем', + 'CopyrightOwnerName' => 'Ð˜Ð¼Ñ Ð¿Ñ€Ð°Ð²Ð¾Ð¾Ð±Ð»Ð°Ð´Ð°Ñ‚ÐµÐ»Ñ', + 'CopyrightRegistrationNumber' => 'РегиÑтрационный номер авторÑкого права', + 'CopyrightStatus' => { + Description => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + PrintConv => { + 'Protected' => 'Защищено', + 'Public Domain' => 'Ð’Ñеобщее доÑтоÑние', + 'Unknown' => 'Ðе указано', }, }, - 'Copyright' => 'Владелец копирайта', - 'CopyrightNotice' => 'Уведомление об авторÑких правах', + 'CountInfo' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ подщёте', 'Country' => 'Страна', + 'Country-PrimaryLocationCode' => 'Код Ñтраны', 'Country-PrimaryLocationName' => 'Страна', - 'CreateDate' => 'Дата ÑозданиÑ', + 'CountryCode' => 'Код Ñтраны', + 'CoverArt' => 'Обложка', + 'CoverArtMIMEType' => 'MIME тип обложки', + 'CoverArtType' => 'Тип обложки', + 'Coverage' => 'Охват', + 'CreateDate' => 'Дата оцифровки', + 'CreatedBy' => 'Создан', 'CreationDate' => 'Дата ÑозданиÑ', - 'Credit' => 'ФамилиÑ', - 'CurrentICCProfile' => 'Текущий ICC профиль', - 'CurrentPreProfileMatrix' => 'Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð¿Ñ€ÐµÐ´Ð²Ð°Ñ€Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð°', + 'CreationTime' => 'Ð’Ñ€ÐµÐ¼Ñ ÑозданиÑ', + 'CreativeStyleWasChanged' => { + Description => 'ТворчеÑкий Ñтиль был изменён', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'Creator' => 'Создатель', + 'CreatorAppID' => { + Description => 'ID Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñоздавшего файл', + PrintConv => { + 'Unknown' => 'ÐеизвеÑтное', + }, + }, + 'CreatorAppVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'CreatorBuildNumber' => 'Приложение – Ðомер Ñборки', + 'CreatorBuildNumber2' => 'Приложение – Ðомер Ñборки 2', + 'CreatorMajorVersion' => 'Приложение – ÐœÐ°Ð¶Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'CreatorMinorVersion' => 'Приложение – ÐœÐ¸Ð½Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'CreatorOpenWithUIOptions' => 'Открыт Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°Ð¼Ð¸ пользовательÑкого интерфейÑа', + 'CreatorSoftware' => 'Создан в приложении', + 'CreatorTool' => 'Создано в', + 'CreatorVersion' => 'ВерÑÐ¸Ñ Ð¸Ñходного приложениÑ', + 'Credit' => 'ПоÑтавщик', + 'CreditLineRequired' => { + Description => 'Политика кредитованиÑ', + PrintConv => { + 'Credit Adjacent To Image' => 'Кредит Ñ€Ñдом Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸ÐµÐ¼', + 'Credit in Credits Area' => 'Кредит в облаÑти кредитов', + 'Credit on Image' => 'Кредит на изображение', + 'Not Required' => 'Кредит не требуетÑÑ', + }, + }, + 'CropArea' => 'ОблаÑÑ‚ÑŒ кадрированиÑ', + 'CropBottom' => 'Обрезка Ñнизу', + 'CropH' => 'Ð’Ñ‹Ñота кадрированиÑ', + 'CropLeft' => 'Обрезка Ñлева', + 'CropRight' => 'Обрезка Ñправа', + 'CropRotation' => 'Поворот рамки кадрированиÑ', + 'CropTop' => 'Обрезка Ñверху', + 'CropW' => 'Ширина кадрированиÑ', + 'CropX' => 'Координаты ÐºÐ°Ð´Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ оÑи X', + 'CropXCommonOffset' => { + Description => 'Обрезка по X – Общее Ñмещение', + PrintConv => { + 'Common Offset Setting' => 'ÐžÐ±Ñ‰Ð°Ñ Ð½Ð°Ñтройка ÑмещениÑ', + 'Individual Offset Setting' => 'Ð˜Ð½Ð´Ð¸Ð²Ð¸Ð´ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ Ð½Ð°Ñтройка ÑмещениÑ', + }, + }, + 'CropXOffset' => 'Обрезка по X – Смещение', + 'CropXOffset2' => 'Обрезка по X – Смещение 2', + 'CropXSize' => 'Размер обрезки по X', + 'CropXViewpointNumber' => 'Обрезка по X – Ðомер точки проÑмотра', + 'CropXViewpointNumber2' => 'Обрезка по X – Ðомер точки проÑмотра 2', + 'CropY' => 'Координаты ÐºÐ°Ð´Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾ оÑи Y', + 'CropYCommonOffset' => { + Description => 'Обрезка по Y – Общее Ñмещение', + PrintConv => { + 'Common Offset Setting' => 'ÐžÐ±Ñ‰Ð°Ñ Ð½Ð°Ñтройка ÑмещениÑ', + 'Individual Offset Setting' => 'Ð˜Ð½Ð´Ð¸Ð²Ð¸Ð´ÑƒÐ°Ð»ÑŒÐ½Ð°Ñ Ð½Ð°Ñтройка ÑмещениÑ', + }, + }, + 'CropYOffset' => 'Обрезка по Y – Смещение', + 'CropYOffset2' => 'Обрезка по Y – Смещение 2', + 'CropYSize' => 'Размер обрезки по Y', + 'CropYViewpointNumber' => 'Обрезка по Y – Ðомер точки проÑмотра', + 'CropYViewpointNumber2' => 'Обрезка по Y – Ðомер точки проÑмотра 2', + 'CroppedAreaImageHeightPixels' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð²Ñ‹Ñота Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² пикÑелÑÑ…', + 'CroppedAreaImageWidthPixels' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² пикÑелÑÑ…', + 'CroppedAreaLeftPixels' => 'ÐžÐ±Ñ€ÐµÐ·Ð°Ð½Ð½Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ Ñлева в пикÑелÑÑ…', + 'CroppedAreaTopPixels' => 'ÐžÐ±Ñ€ÐµÐ·Ð°Ð½Ð½Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ Ñверху в пикÑелÑÑ…', + 'Cropping' => { + Description => 'Кадрирование', + PrintConv => { + 'Off' => 'Ðе включено', + 'On' => 'Включено', + }, + }, + 'Cross-Reference' => 'ПерекреÑÑ‚Ð½Ð°Ñ ÑÑылка', + 'CueSheet' => 'Файл разметки (Cue Sheet)', + 'CurrentICCProfile' => 'Текущий ICC-профиль', + 'CurrentIPTCDigest' => 'Хеш Ñумма текущего IPTC', + 'CurrentPreProfileMatrix' => 'Текущий предварительный профиль матрицы', + 'CurrentVersion' => 'Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'CursorSize' => 'Размер курÑора', + 'Curve0x' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 0x', + 'Curve0y' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 0y', + 'Curve1x' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 1x', + 'Curve1y' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 1y', + 'Curve2x' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 2x', + 'Curve2y' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 2y', + 'Curve3x' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 3x', + 'Curve3y' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 3y', + 'Curve4x' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 4x', + 'Curve4y' => 'ÐšÑ€Ð¸Ð²Ð°Ñ 4y', + 'Custom1' => 'Дополнительное поле 1', + 'Custom10' => 'Дополнительное поле 10', + 'Custom2' => 'Дополнительное поле 2', + 'Custom3' => 'Дополнительное поле 3', + 'Custom4' => 'Дополнительное поле 4', + 'Custom5' => 'Дополнительное поле 5', + 'Custom6' => 'Дополнительное поле 6', + 'Custom7' => 'Дополнительное поле 7', + 'Custom8' => 'Дополнительное поле 8', + 'Custom9' => 'Дополнительное поле 9', 'CustomRendered' => { - Description => 'Обработка Ñнимков по перÑональным наÑтройкам', + Description => 'ПользовательÑкий рендеринг', PrintConv => { - 'Custom' => '"ПроцеÑÑ, наÑтроенный пользователем"', - 'Normal' => 'Ðормальный процеÑÑ', + 'Custom' => 'ПользовательÑкий', + 'Normal' => 'Обычный', + 'Panorama' => 'Панорама', + 'Portrait' => 'Портрет', + }, + }, + 'D-RangeOptimizerHighlight' => 'ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого диапазона – Света', + 'D-RangeOptimizerMode' => { + Description => 'ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого диапазона – Режим', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкий', + 'Manual' => 'Ручной', + 'Off' => 'Ðе включён', }, }, + 'D-RangeOptimizerShadow' => 'ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого диапазона – Тени', + 'D-RangeOptimizerValue' => 'ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого диапазона – Значение', + 'DCContinent' => 'DC – Континент', + 'DCCoordinatePrecision' => 'DC – ТочноÑÑ‚ÑŒ координат', + 'DCCoordinateUncertaintyInMeters' => 'DC – ПогрешноÑÑ‚ÑŒ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚ (м)', + 'DCCountry' => 'DC – Страна', + 'DCCountryCode' => 'DC – Код Ñтраны', + 'DCCounty' => 'DC – Район', + 'DCDecimalLatitude' => 'DC – ГеографичеÑÐºÐ°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð° меÑта находки', + 'DCDecimalLongitude' => 'DC – ГеографичеÑÐºÐ°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð° меÑта находки', + 'DCEvent' => 'Событие/Явление', + 'DCFootprintSRS' => 'DC – Footprint SRS', + 'DCFootprintSpatialFit' => 'DC – Footprint Spatial Fit', + 'DCFootprintWKT' => 'DC – Footprint WKT', + 'DCGeodeticDatum' => 'DC – ГеографичеÑÐºÐ°Ñ ÑиÑтема координат', + 'DCGeoreferenceProtocol' => 'DC – ОпиÑание метода Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¾Ñ€Ð´Ð¸Ð½Ð°Ñ‚', + 'DCGeoreferenceRemarks' => 'DC – Комментарии к геопривÑзке', + 'DCGeoreferenceSources' => 'DC – ИÑточники геопривÑзки', + 'DCGeoreferenceVerificationStatus' => 'DC – Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ¸ геопривÑзки', + 'DCGeoreferencedBy' => 'DC – Люди Ñоздавшие геопривÑзку', + 'DCGeoreferencedDate' => 'DC – Дата геопривÑзки', + 'DCHigherGeography' => 'DC – Крупные географичеÑкие объекты', + 'DCHigherGeographyID' => 'DC – ID географичеÑкого региона', + 'DCIsland' => 'DC – ОÑтров', + 'DCIslandGroup' => 'DC – Группа оÑтровов', + 'DCLocality' => 'DC – ОпиÑание меÑта находки', + 'DCLocationAccordingTo' => 'DC – ИÑточник данных о меÑтоположении', + 'DCLocationID' => 'DC – ID набора данных о меÑтоположении', + 'DCLocationRemarks' => 'DC – Комментарии к опиÑанию меÑтоположениÑ', + 'DCMaximumDepthInMeters' => 'DC – МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ð° (м)', + 'DCMaximumDistanceAboveSurfaceInMeters' => 'DC – МакÑимальное диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð°Ð´ поверхноÑтью (м)', + 'DCMaximumElevationInMeters' => 'DC – МакÑимальное выÑота (м)', + 'DCMinimumDepthInMeters' => 'DC – ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ð° (м)', + 'DCMinimumDistanceAboveSurfaceInMeters' => 'DC – Минимальное диÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ð½Ð°Ð´ поверхноÑтью (м)', + 'DCMinimumElevationInMeters' => 'DC – ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота (м)', + 'DCMunicipality' => 'DC – Район', + 'DCPointRadiusSpatialFit' => 'DC – Point Radius Spatial Fit', + 'DCStateProvince' => 'DC – ОблаÑÑ‚ÑŒ', + 'DCTermsLocation' => 'DC – МеÑтоположение', + 'DCVerbatimCoordinateSystem' => 'DC – СиÑтема координат по первоиÑточнику', + 'DCVerbatimCoordinates' => 'DC – Координаты меÑта находки по первоиÑточнику', + 'DCVerbatimDepth' => 'DC – ОпиÑание глубины по первоиÑточнику', + 'DCVerbatimElevation' => 'DC – ОпиÑание выÑоты по первоиÑточнику', + 'DCVerbatimLatitude' => 'DC – Широта меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ первоиÑточнику', + 'DCVerbatimLocality' => 'DC – ОпиÑание меÑта по первоиÑточнику', + 'DCVerbatimLongitude' => 'DC – Долгота меÑÑ‚Ð¾Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ первоиÑточнику', + 'DCVerbatimSRS' => 'DC – SRS по первоиÑточнику', + 'DCWaterBody' => 'DC – Водоём', + 'DNGAdobeData' => 'DNG – Данные Adobe', 'DNGBackwardVersion' => 'СовмеÑÑ‚Ð¸Ð¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ DNG', - 'DNGLensInfo' => 'Минимальное фокуÑное раÑÑтоÑние', + 'DNGLensInfo' => 'DNG – Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± объективе', + 'DNGPrivateData' => 'DNG – Данные производителÑ', 'DNGVersion' => 'ВерÑÐ¸Ñ DNG', + 'DOF' => 'Глубина резкоÑти', + 'DPP' => 'Digital Photo Professional (DPP)', + 'DPXFileSize' => 'Размер файла DPX', + 'DRMCommerceID' => 'DRM – КоммерчеÑкий ID', + 'DRMServerID' => 'DRM – ID Ñервера', + 'DRM_E-BookBaseID' => 'DRM – ID базы Ñлектронных книг', + 'DTVContent' => { + Description => 'Контент DTV', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'DataCompressionMethod' => 'Метод ÑÐ¶Ð°Ñ‚Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…', + 'DataDump' => 'Вывод данных', + 'DataLocation' => { + Description => 'РаÑположение данных', + PrintConv => { + 'Downloaded Separately' => 'СкачиваетÑÑ Ð¾Ñ‚Ð´ÐµÐ»ÑŒÐ½Ð¾', + 'Local Music File' => 'Локальный музыкальный файл', + }, + }, + 'DataOffset' => 'Смещение данных', + 'DataOffsets' => 'Ð¡Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ…', + 'DataPreparer' => 'Подготовка данных', + 'DataReference' => 'СÑылка на данные', + 'DataSign' => { + Description => 'ПодпиÑÑŒ данных', + PrintConv => { + 'Signed' => 'ПодпиÑан', + 'Unsigned' => 'ÐеподпиÑан', + }, + }, + 'DataSize' => 'Размер данных', + 'DataType' => { + Description => 'Тип данных', + PrintConv => { + 'Artwork' => 'Обложка', + }, + }, + 'DataWindow' => 'Окно данных', + 'DatabaseName' => 'Ðазвание базы данных', + 'Date' => 'Дата', + 'DateAcquired' => 'Дата приобретениÑ', 'DateCreated' => 'Дата ÑозданиÑ', - 'DateTimeOriginal' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð´Ð°Ñ‚Ð° и времÑ', + 'DateIdentified' => 'Дата определениÑ', + 'DateSent' => 'Дата отправлениÑ', + 'DateTime' => 'Дата и времÑ', + 'DateTimeCompleted' => 'Дата завершениÑ', + 'DateTimeCreated' => 'Дата и Ð²Ñ€ÐµÐ¼Ñ ÑозданиÑ', + 'DateTimeDue' => 'Срок Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°Ñ‡Ð¸', + 'DateTimeEnd' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ ÑобытиÑ', + 'DateTimeOriginal' => 'Дата Ñъёмки', + 'DateTimeStamp' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑобытиÑ', + 'DateTimeStart' => 'Дата начала ÑобытиÑ', + 'DayOfWeek' => { + Description => 'День недели', + PrintConv => { + 'Friday' => 'ПÑтница', + 'Monday' => 'Понедельник', + 'Saturday' => 'Суббота', + 'Sunday' => 'ВоÑкреÑенье', + 'Thursday' => 'Четверг', + 'Tuesday' => 'Вторник', + 'Wednesday' => 'Среда', + }, + }, + 'Decode' => 'Декодирование', + 'DefaultAlarm' => 'Сигнал по-умолчанию', + 'DefaultBlackRender' => { + Description => 'Обработка чёрного по-умолчанию', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкаÑ', + 'None' => 'Ðе обрабатывать', + }, + }, + 'DefaultChar' => 'Символ замены', 'DefaultCropOrigin' => 'Положение обрезанного Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾-умолчанию', 'DefaultCropSize' => 'Размер обрезанного Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾-умолчанию', - 'DefaultScale' => 'Стандартный маÑштаб', - 'DeviceSettingDescription' => 'ОпиÑание наÑтроек уÑтройÑтва', - 'DigitalZoom' => 'Цифровой зум', - 'DigitalZoomRatio' => 'Показатель цифрового зума', - 'Directory' => '"Файл, размещение"', - 'DriveMode' => 'Режим ÑпуÑка', + 'DefaultImageColor' => 'Цвет Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾-умолчанию', + 'DefaultScale' => 'МаÑÑштаб по-умолчанию', + 'DefaultStyle' => 'Стиль по-умолчанию', + 'DefaultUserCrop' => 'ОблаÑÑ‚ÑŒ обрезки по-умолчанию', + 'DefineQuantizationTable' => 'Определение таблиц квантованиÑ', + 'Delay' => 'Задержка', + 'DelayTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ð´ÐµÑ€Ð¶ÐºÐ¸', + 'DependentImage1EntryNumber' => 'ЗавиÑимое изображение 1 – Ðомер входа', + 'DependentImage2EntryNumber' => 'ЗавиÑимое изображение 2 – Ðомер входа', + 'Depth' => 'Глубина цвета', + 'DepthImage' => 'Глубина изображениÑ', + 'DepthMapTiff' => 'Карта глубины Tiff', + 'Descender' => 'ПодÑтрочный интервал', + 'Description' => 'ОпиÑание', + 'Designer' => 'Дизайнер', + 'DesignerURL' => 'URL дизайнера', + 'Destination' => 'Ðазначение', + 'DeviceID' => 'ID уÑтройÑтва', + 'DeviceName' => 'Ðазвание уÑтройÑтва', + 'DeviceSettingDescription' => 'ОпиÑание предуÑтановок камеры', + 'DewarpData' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð¾Ð¿Ñ‚Ð¸Ñ‡ÐµÑкого иÑÐºÐ°Ð¶ÐµÐ½Ð¸Ñ â€“ Данные', + 'DewarpFlag' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð¾Ð¿Ñ‚Ð¸Ñ‡ÐµÑкого иÑÐºÐ°Ð¶ÐµÐ½Ð¸Ñ â€“ Флаг', + 'DictionaryShortName' => 'Сокращенное название ÑловарÑ', + 'DigitalCreationDate' => 'Дата оцифровки файла', + 'DigitalCreationDateTime' => 'Дата и Ð²Ñ€ÐµÐ¼Ñ Ð¾Ñ†Ð¸Ñ„Ñ€Ð¾Ð²ÐºÐ¸ файла', + 'DigitalCreationTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ†Ð¸Ñ„Ñ€Ð¾Ð²ÐºÐ¸ файла', + 'DigitalSignature' => 'Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ', + 'DigitalZoom' => { + Description => 'Цифровой зум', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'DigitalZoomOn' => { + Description => 'Цифровой зум', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'DigitalZoomRatio' => 'КоÑффициент цифрового увеличениÑ', + 'Director' => 'Директор', + 'Directory' => 'Каталог', + 'DirectoryNumber' => 'Ðомер каталога', + 'DisallowCounterProposal' => 'Запретить вÑтречное предложение', + 'Disclaimer' => 'Отказ от ответÑтвенноÑти', + 'DisplayWindow' => 'Окно отображениÑ', + 'DisplayXResolution' => 'Разрешение Ñкрана по X', + 'DisplayXResolutionUnit' => { + Description => 'Единицы Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ñкрана по X', + PrintConv => { + '0.01 mm' => '0.01 мм', + '0.1 mm' => '0.1 мм', + '10 cm' => '10 Ñм', + '10 m' => '10 м', + '100 m' => '100 м', + 'cm' => 'Ñм', + 'km' => 'км', + 'm' => 'м', + 'mm' => 'мм', + 'um' => 'мкм', + }, + }, + 'DisplayYResolution' => 'Разрешение Ñкрана по Y', + 'DisplayYResolutionUnit' => { + Description => 'Единицы Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ñкрана по Y', + PrintConv => { + '0.01 mm' => '0.01 мм', + '0.1 mm' => '0.1 мм', + '10 cm' => '10 Ñм', + '10 m' => '10 м', + '100 m' => '100 м', + 'cm' => 'Ñм', + 'km' => 'км', + 'm' => 'м', + 'mm' => 'мм', + 'um' => 'мкм', + }, + }, + 'DisplayedUnitsX' => { + Description => 'Отображаемые единицы по X', + PrintConv => { + 'cm' => 'Сантиметры', + 'inches' => 'Дюймы', + }, + }, + 'DisplayedUnitsY' => { + Description => 'Отображаемые единицы по Y', + PrintConv => { + 'cm' => 'Сантиметры', + 'inches' => 'Дюймы', + }, + }, + 'Dispose' => 'Управление ÑлоÑми', + 'DistortionCompensation' => { + Description => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð´Ð¸ÑторÑии', + PrintConv => { + 'Off' => 'Ðе включена', + 'On' => 'Включена', + 'n/a' => 'Ðет данных', + }, + }, + 'DistortionCorrParams' => 'Параметры коррекции диÑторÑии', + 'DistortionCorrection' => { + Description => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð´Ð¸ÑторÑии', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкаÑ', + 'Auto fixed by lens' => 'ÐвтоматичеÑÐºÐ°Ñ Ð¿Ð¾ объективу', + 'No correction params available' => 'Ðе доÑтупна', + 'Off' => 'Ðе включена', + }, + }, + 'DistortionCorrectionAlreadyApplied' => 'Применена ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð´Ð¸ÑторÑии', + 'Distribution' => 'ОпиÑание', + 'DittoKey' => { + Description => 'Ключь Ditto', + PrintConv => { + 'New' => 'Заново', + 'Same' => 'Так же', + }, + }, + 'DjVuVersion' => 'ВерÑÐ¸Ñ DjVu', + 'DoNotForwardMeeting' => 'Ðе передвигать вÑтречу', + 'DocClass' => 'СоÑтоÑние документа', + 'DocRights' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð°Ð²Ñ‚Ð¾Ñ€Ñкого права', + 'DocType' => 'Тип документа', + 'Document' => 'Документ', + 'DocumentAncestors' => 'Предки документа', + 'DocumentHistory' => 'ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°', + 'DocumentName' => 'Ðазвание документа', + 'DocumentNotes' => 'Комментарии к документу', + 'DocumentUsageRights' => 'Права на иÑпользование Документа', + 'DotRange' => 'Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚Ð° ÑоответÑтвующих точке', + 'DriveMode' => { + Description => 'Режим ÑпуÑка', + PrintConv => { + 'Continuous Shooting' => 'Ð¡ÐµÑ€Ð¸Ð¹Ð½Ð°Ñ Ñъёмка', + 'Self-timer Operation' => 'Съёмка Ñ Ð°Ð²Ñ‚Ð¾ÑпуÑком', + 'Single-frame Shooting' => 'ÐŸÐ¾ÐºÐ°Ð´Ñ€Ð¾Ð²Ð°Ñ Ñъёмка', + }, + }, + 'DriveSerialNumber' => 'Серийный номер привода', + 'DriveType' => { + Description => 'Тип накопителÑ', + PrintConv => { + 'Fixed Disk' => 'УÑтановленный диÑк', + 'Invalid Root Path' => 'Ðеверный корневой путь', + 'Ram Disk' => 'Ram диÑк', + 'Remote Drive' => 'Удаленный диÑк', + 'Removable Media' => 'Съемный диÑк', + 'Unknown' => 'ÐеизвеÑтный', + }, + }, + 'DuotoneHalftoningInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ тонировании – Двуцветное', + 'DuotoneImageInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ двухцветном изображении', + 'DuotoneTransferFuncs' => 'Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñа – Двуцветное', + 'Duration' => 'ПродолжительноÑÑ‚ÑŒ', 'DynamicRangeOptimizer' => { - Description => 'Оптим.Д-диапаз.', - PrintConv => { - 'Advanced Auto' => 'Улучш.авто', - 'Advanced Lv1' => 'Улучш.уровень1', - 'Advanced Lv2' => 'Улучш.уровень2', - 'Advanced Lv3' => 'Улучш.уровень3', - 'Advanced Lv4' => 'Улучш.уровень4', - 'Advanced Lv5' => 'Улучш.уровень5', - 'Auto' => 'Ðвто', - 'Off' => 'Отключено', - 'Standard' => 'Стандартное', + Description => 'ÐžÐ¿Ñ‚Ð¸Ð¼Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð¸Ð½Ð°Ð¼Ð¸Ñ‡ÐµÑкого диапазона', + PrintConv => { + 'Advanced Auto' => 'РаÑширеннаÑ. ÐвтоматичеÑкаÑ', + 'Advanced Lv1' => 'РаÑширеннаÑ. Уровень 1', + 'Advanced Lv2' => 'РаÑширеннаÑ. Уровень 2', + 'Advanced Lv3' => 'РаÑширеннаÑ. Уровень 3', + 'Advanced Lv4' => 'РаÑширеннаÑ. Уровень 4', + 'Advanced Lv5' => 'РаÑширеннаÑ. Уровень 5', + 'Auto' => 'ÐвтоматичеÑкаÑ', + 'Off' => 'Ðе включена', + 'Standard' => 'СтандартнаÑ', + }, + }, + 'EPSOptions' => 'Параметры EPS', + 'EXRVersion' => 'ВерÑÐ¸Ñ EXR', + 'EarliestAgeOrLowestStage' => 'Самый ранний век/Ðизший ÑруÑ', + 'EarliestEonOrLowestEonothem' => 'Самый ранний Ñон/ÐÐ¸Ð·ÑˆÐ°Ñ Ñонотема', + 'EarliestEpochOrLowestSeries' => 'Ð¡Ð°Ð¼Ð°Ñ Ñ€Ð°Ð½Ð½ÑÑ Ñпоха/Ðизший отдел', + 'EarliestEraOrLowestErathem' => 'Ð¡Ð°Ð¼Ð°Ñ Ñ€Ð°Ð½Ð½ÑÑ Ñра/ÐÐ¸Ð·ÑˆÐ°Ñ Ñратема', + 'EarliestPeriodOrLowestSystem' => 'Самый ранний период/ÐÐ¸Ð·ÑˆÐ°Ñ ÑиÑтема', + 'EdgeNoiseReduction' => 'Щумоподавление – Уменьшение контурных шумов', + 'EditStatus' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'Edition' => 'Издание', + 'EditorialUpdate' => { + Description => 'Тип обновлениÑ', + PrintConv => { + 'Additional language' => 'Дополнительный Ñзык', + }, + }, + 'EffectiveBW' => 'Эффективный Чёрно-Белый', + 'EffectsVisible' => 'ВидимоÑÑ‚ÑŒ Ñффектов', + 'ElectronicImageStabilization' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ ÑÑ‚Ð°Ð±Ð¸Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + 'EmbeddedFileName' => 'Ðазвание вÑтроенного файла', + 'EmbeddedFileUsageRights' => 'Права на иÑпользование вÑтроенных файлов', + 'EmbeddedImage' => 'Ð’Ñтроенное изображение', + 'EmbeddedImageColorSpace' => 'Ð’Ñтроенное изображение – Цветовое проÑтранÑтво', + 'EmbeddedImageFilter' => 'Ð’Ñтроенное изображение – Фильтр', + 'EmbeddedImageHeight' => 'Ð’Ñтроенное изображение – Ð’Ñ‹Ñота', + 'EmbeddedImageWidth' => 'Ð’Ñтроенное изображение – Ширина', + 'EmbeddedJPG' => 'Ð’Ñтроенный JPG', + 'EmbeddedPNG' => 'Ð’Ñтроенный PNG', + 'EmbeddedVideo' => 'Ð’Ñтроенное видео', + 'EmbeddedXMPDigest' => 'Хеш-Ñумма вÑтроенного XMP', + 'Emphasis' => { + Description => 'Ðкцент', + PrintConv => { + 'None' => 'Ðет', + }, + }, + 'EncodeTime' => 'Ð’Ñ€ÐµÐ¼Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'EncodedBy' => 'Закодировал', + 'EncodedUsing' => 'Закодировано Ñ Ð¸Ñпользованием', + 'Encoder' => 'Кодер', + 'EncoderOptions' => 'ÐаÑтройки кодера', + 'EncoderVersion' => 'ВерÑÐ¸Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ñ‰Ð¸ÐºÐ°', + 'Encoding' => 'Кодирование', + 'EncodingProcess' => { + Description => 'ПроцеÑÑ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + PrintConv => { + 'Baseline DCT, Huffman coding' => 'Базовое DCT, кодирование Хаффмана', + 'Extended sequential DCT, Huffman coding' => 'РаÑширенное поÑледовательное DCT, кодирование Хаффмана', + 'Extended sequential DCT, arithmetic coding' => 'РаÑширенное поÑледовательное DCT, арифметичеÑкое кодирование', + 'Lossless, Differential Huffman coding' => 'Без потерь, дифференциальное кодирование Хаффмана', + 'Lossless, Huffman coding' => 'Без потерь, кодирование Хаффмана', + 'Lossless, arithmetic coding' => 'Без потерь, арифметичеÑкое кодирование', + 'Lossless, differential arithmetic coding' => 'Без потерь, дифференциальное арифметичеÑкое кодирование', + 'Progressive DCT, Huffman coding' => 'ПрогреÑÑивное DCT, кодирование Хаффмана', + 'Progressive DCT, arithmetic coding' => 'ПрогреÑÑивное DCT, арифметичеÑкое кодирование', + 'Progressive DCT, differential Huffman coding' => 'ПрогреÑÑивное DCT, дифференциальное кодирование Хаффмана', + 'Progressive DCT, differential arithmetic coding' => 'ПрогреÑÑивное DCT, дифференциальное арифметичеÑкое кодирование', + 'Sequential DCT, differential Huffman coding' => 'ПоÑледовательное DCT, Дифференциальное кодирование Хаффмана', + 'Sequential DCT, differential arithmetic coding' => 'ПоÑледовательное DCT, дифференциальное арифметичеÑкое кодирование', + }, + }, + 'EncodingScheme' => 'Схема кодированиÑ', + 'Encryption' => { + Description => 'Шифрование', + PrintConv => { + 'None' => 'Ðет', + 'Old Mobipocket' => 'Старый Mobipocket', }, }, - 'ExifImageHeight' => 'ДопуÑÑ‚Ð¸Ð¼Ð°Ñ Ð²Ñ‹Ñота Ñнимка', - 'ExifImageWidth' => 'ДопуÑÑ‚Ð¸Ð¼Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° Ñнимка', - 'ExifOffset' => 'Exif IFD указатель', - 'ExifVersion' => 'Exif верÑиÑ', - 'ExposureCompensation' => '"ЭкÑпозициÑ, калибровка"', - 'ExposureIndex' => '"ЭкÑпозициÑ, показатель"', + 'EncryptionKey' => 'Ключ шифрованиÑ', + 'EndPoints' => 'Конечные точки', + 'EndTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ', + 'EndUser' => 'Конечный пользователь', + 'EndUserID' => 'PLUS-ID пользователÑ', + 'EndUserName' => 'Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ', + 'EnvelopeNumber' => 'Ðомер конверта', + 'EnvelopePriority' => { + Description => 'Приоритет конверта', + PrintConv => { + '0 (reserved)' => '0 (Ð’ резерве)', + '1 (most urgent)' => '1 (Ðеотложное)', + '5 (normal urgency)' => '5 (Обычное)', + '8 (least urgent)' => '8 (Ðе Ñрочное)', + '9 (user-defined priority)' => '9 (ПользовательÑкий приоритет)', + }, + }, + 'EnvelopeRecordVersion' => 'ВерÑÐ¸Ñ Envelope Record', + 'EnvironmentMap' => { + Description => 'Карта окружениÑ', + PrintConv => { + 'Cube' => 'Куб', + 'Latitude/Longitude' => 'Широта/Долгота', + }, + }, + 'EquipmentInstitution' => 'Оборудование учреждениÑ', + 'EquipmentManufacturer' => 'Производитель оборудованиÑ', + 'Error' => 'Ошибка', + 'EscChar' => 'Escape-Ñимвол', + 'EscapeStatus' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿Ñ€Ð¾Ð±ÐµÐ³Ð°', + 'Event' => 'Событие', + 'EventDate' => 'Дата ÑобытиÑ', + 'EventDay' => 'День(и) ÑобытиÑ', + 'EventEarliestDate' => 'Дата начала ÑобытиÑ', + 'EventEndDayOfYear' => 'День года Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ ÑобытиÑ', + 'EventFieldNotes' => 'Полевые заметки о Ñобытии', + 'EventFieldNumber' => 'Ðомер полевых заметок о Ñобытии', + 'EventHabitat' => 'Ðреал ÑобытиÑ', + 'EventID' => 'ID ÑобытиÑ', + 'EventLatestDate' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ ÑобытиÑ', + 'EventMonth' => 'МеÑÑц ÑобытиÑ', + 'EventNumber' => 'Ðомер ÑобытиÑ', + 'EventParentEventID' => 'ID оÑновного ÑобытиÑ', + 'EventRemarks' => 'Комментарии к Ñобытию', + 'EventSampleSizeUnit' => 'Событие – Единицы размера', + 'EventSampleSizeValue' => 'Событие – Размер образца', + 'EventSamplingEffort' => 'Событие – Затраченные уÑилиÑ', + 'EventSamplingProtocol' => 'Событие – Метод иÑÑледованиÑ', + 'EventStartDayOfYear' => 'День года начала ÑобытиÑ', + 'EventTime' => 'Ð’Ñ€ÐµÐ¼Ñ ÑобытиÑ', + 'EventVerbatimEventDate' => 'Дата ÑÐ¾Ð±Ñ‹Ñ‚Ð¸Ñ Ð¿Ð¾ первоиÑточнику', + 'EventYear' => 'Год ÑобытиÑ', + 'ExceptionDateTimes' => 'Дата иÑключениÑ', + 'ExclusiveCoverage' => 'ЭкÑклюзивный репортаж', + 'ExcursionTolerance' => { + Description => 'Выход за пределы диапазона', + PrintConv => { + 'Allowed' => 'ДопуÑкаетÑÑ', + 'Not Allowed' => 'Ðе допуÑкаетÑÑ', + }, + }, + 'ExifByteOrder' => { + Description => 'Exif – ПорÑдок байтов', + PrintConv => { + 'Big-endian (Motorola, MM)' => 'ПорÑдок от Ñтаршего к младшему (Motorola, MM)', + 'Little-endian (Intel, II)' => 'ПорÑдок от младшего к Ñтаршему (Intel, II)', + }, + }, + 'ExifCameraInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ камере из Exif', + 'ExifImageHeight' => 'Exif – Ð’Ñ‹Ñота изображениÑ', + 'ExifImageWidth' => 'Exif – Ширина изображениÑ', + 'ExifInfo2' => 'Exif – Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ 2', + 'ExifOffset' => 'Смещение Exif Sub IFD', + 'ExifToolVersion' => 'ВерÑÐ¸Ñ ExifTool', + 'ExifUnicodeByteOrder' => { + Description => 'Exif – ПорÑдок байтов Unicode', + PrintConv => { + 'Big-endian (Motorola, MM)' => 'ПорÑдок от Ñтаршего к младшему (Motorola, MM)', + 'Little-endian (Intel, II)' => 'ПорÑдок от младшего к Ñтаршему (Intel, II)', + }, + }, + 'ExifVersion' => 'ВерÑÐ¸Ñ Exif', + 'ExpandFilm' => 'Expand – Плёнка', + 'ExpandFilterLens' => 'Expand – Фильтр объектива', + 'ExpandFlashLamp' => 'Expand – Ð’Ñпышка', + 'ExpandLens' => 'Expand – Объектив', + 'ExpandScanner' => 'Expand – Сканер', + 'ExpandSoftware' => 'Expand – Приложение', + 'ExpirationDate' => 'Дата иÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ Ñрока', + 'ExpirationSpan' => 'Срок дейÑÑ‚Ð²Ð¸Ñ Ð¸ÑтечениÑ', + 'ExpirationTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¸ÑÑ‚ÐµÑ‡ÐµÐ½Ð¸Ñ Ñрока', + 'Expires' => 'Дата уÑÑ‚Ð°Ñ€ÐµÐ²Ð°Ð½Ð¸Ñ Ð´Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°', + 'Exposure' => 'ЭкÑпозициÑ', + 'ExposureCompensation' => 'КомпенÑÐ°Ñ†Ð¸Ñ ÑкÑпозиции', + 'ExposureIndex' => 'Ð˜Ð½Ð´ÐµÐºÑ ÑкÑпозиции', + 'ExposureLockUsed' => 'ИÑпользование блокировки параметров ÑкÑпозиции', 'ExposureMode' => { - Description => '"ЭкÑпозициÑ, режим"', + Description => 'Режим ÑкÑпозиции', PrintConv => { 'Auto' => 'ÐвтоÑкÑпозициÑ', - 'Auto bracket' => 'ÐвтобрÑкетинг', + 'Auto bracket' => 'Ðвтобрекетинг', 'Manual' => 'Ð ÑƒÑ‡Ð½Ð°Ñ ÑкÑпозициÑ', }, }, 'ExposureProgram' => { - Description => 'ЭкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð½Ð°Ñ', + Description => 'Программа ÑкÑпозиции', PrintConv => { - 'Action (High speed)' => 'Экшен/боевик', - 'Aperture-priority AE' => 'Приоритет диафрагмы', - 'Bulb' => 'Лампа', - 'Creative (Slow speed)' => 'ТворчеÑÐºÐ°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð°', + 'Action (High speed)' => 'Спорт', + 'Aperture-priority AE' => 'ÐвтоÑкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¾Ð¼ Диафрагмы', + 'Bulb' => 'Выдержка от руки', + 'Creative (Slow speed)' => 'ТворчеÑкаÑ', 'Landscape' => 'Пейзаж', - 'Manual' => '"ЭкÑпозициÑ, ручнаÑ"', + 'Manual' => 'РучнаÑ', + 'Not Defined' => 'Ðе определена', 'Portrait' => 'Портрет', - 'Program AE' => 'ÐÐ¾Ñ€Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð°', - 'Shutter speed priority AE' => 'Приоритет выдержки', + 'Program AE' => 'ÐŸÑ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð½Ð°Ñ Ð°Ð²Ñ‚Ð¾ÑкÑпозициÑ', + 'Shutter speed priority AE' => 'ÐвтоÑкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¾Ð¼ Выдержки', }, }, 'ExposureTime' => 'Выдержка', - 'FNumber' => 'Диафрагма', - 'FaceOrientation' => { + 'ExposureTimes' => 'Выдержка2', + 'ExtCache' => 'Ðазвание альтернативного кÑша', + 'ExtenderStatus' => { + Description => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ ÑкÑтендера', + PrintConv => { + 'Attached' => 'Прикреплен', + 'Not attached' => 'Ðе прикреплен', + 'Removed' => 'Удалён', + }, + }, + 'ExternalLeading' => 'Внешний зазор', + 'ExtraFlags' => { + Description => 'Дополнительные флаги', + PrintConv => { + '(none)' => 'ОтÑутÑтвуют', + 'Fastest Algorithm' => 'БыÑтрый алгоритм', + 'Maximum Compression' => 'МакÑимальное Ñжатие', + }, + }, + 'ExtraSamples' => { + Description => 'ОпиÑание дополнительных компонентов', + PrintConv => { + 'Associated Alpha' => 'СвÑзаные альфа-данные', + 'Unassociated Alpha' => 'ÐеÑвÑзанные альфа-данные', + 'Unspecified' => 'Данные без указаниÑ', + }, + }, + 'FNumber' => 'Диафрагменное чиÑло', + 'FOV' => 'Поле зрениÑ', + 'FSType' => 'Тип Ð²Ð½ÐµÐ´Ñ€ÐµÐ½Ð¸Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ð° в документ', + 'FaceBalanceOrigI' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð»Ð¸Ñ†Ð° – ИÑходный I', + 'FaceBalanceOrigQ' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð»Ð¸Ñ†Ð° – ИÑходный Q', + 'FaceBalanceStrength' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð»Ð¸Ñ†Ð° – ИнтенÑивноÑÑ‚ÑŒ', + 'FaceBalanceWarmth' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð»Ð¸Ñ†Ð° – Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð°', + 'FaceDetected' => 'Обнаружение лица', + 'FaceID' => 'Идентификатор лица', + 'FaceNumbers' => 'КоличеÑтво лиц', + 'FaceOrientation' => { + PrintConv => { + 'Horizontal (normal)' => 'Положительное направление', + 'Rotate 180' => 'Поворот на 180°', + 'Rotate 270 CW' => 'Поворот на 270° по чаÑовой Ñтрелке', + 'Rotate 90 CW' => 'Поворот на 90° по чаÑовой Ñтрелке', + }, + }, + 'FacePosition' => 'Положение лица', + 'FacesDetected' => 'Обнаружены лица', + 'Far' => 'Дальнее значение карты глубины', + 'FastSeek' => { + Description => 'БыÑтрый поиÑк', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'FaxProfile' => { + Description => 'ФакÑ-профиль', + PrintConv => { + 'Extended B&W lossless, F' => 'РаÑширенный чёрно-белый без потерь, профиль F', + 'Lossless JBIG B&W, J' => 'JBIG чёрно-белый без потерь, профиль J', + 'Lossless color and grayscale, L' => 'Цветной и Ñ Ð¾Ñ‚Ñ‚ÐµÐ½ÐºÐ°Ð¼Ð¸ Ñерого без потерь, профиль L', + 'Lossy color and grayscale, C' => 'Цветной и Ñ Ð¾Ñ‚Ñ‚ÐµÐ½ÐºÐ°Ð¼Ð¸ Ñерого Ñ Ð¿Ð¾Ñ‚ÐµÑ€Ñми, профиль C', + 'Minimal B&W lossless, S' => 'Минимальный чёрно-белый без потерь, профиль S', + 'Mixed raster content, M' => 'Смешанное Ñодержимое раÑтра, профиль M', + 'Multi Profiles' => 'ÐеÑколько профилей', + 'Profile T' => 'Профиль T', + 'Unknown' => 'Ðе ÑоответÑтвует профилю факÑимильной ÑвÑзи', + }, + }, + 'FaxRecvParams' => 'Параметры Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ„Ð°ÐºÑов', + 'FaxRecvTime' => 'Требуемое Ð²Ñ€ÐµÐ¼Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ñ„Ð°ÐºÑа', + 'FaxSubAddress' => 'ÐŸÐ¾Ð´Ð°Ð´Ñ€ÐµÑ Ñ„Ð°ÐºÑа', + 'FieldOfView' => { + Description => 'Угол обзора', + PrintConv => { + 'Linear' => 'Линейный', + 'Wide' => 'Широкий', + }, + }, + 'FieldPermissions' => { + Description => 'Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° изменение Полей', + PrintConv => { + 'Allow changes to specified form fields' => 'Разрешить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² указанных полÑÑ… формы', + 'Disallow changes to all form fields' => 'Запретить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ð¾ вÑех полÑÑ… формы', + 'Disallow changes to specified form fields' => 'Запретить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² указанных полÑÑ… формы', + }, + }, + 'File1Duration' => 'Файл 1 – ПродолжительноÑÑ‚ÑŒ', + 'File1Length' => 'Файл 1 – Размер', + 'File1MD5Sum' => 'Файл 1 – Сумма MD5', + 'File1Media' => 'Файл 1 – Медиа', + 'File1Path' => 'Файл 1 – Путь', + 'File1PathUTF-8' => 'Файл 1 – Путь в кодировке UTF-8', + 'FileAccessDate' => 'Дата поÑледнего доÑтупа к файлу', + 'FileAttributes' => { + Description => 'Ðтрибуты файла', + PrintConv => { + 'Archive' => 'Ðрхивный', + 'BSD Whiteout' => 'BSD – Скрытый', + 'Block' => 'Блок', + 'Character' => 'Символ', + 'Compressed' => 'Сжатый', + 'Device' => 'УÑтройÑтво', + 'Directory' => 'Каталог', + 'Encrypted' => 'Зашифрованный', + 'Encrypted?' => 'Зашифрованные?', + 'FIFO' => 'FIFO (именованный канал)', + 'Hidden' => 'Скрытый', + 'Mux Block' => 'Блок Mux', + 'Mux Character' => 'Символ Mux', + 'Normal' => 'Без атрибутов', + 'Not Content Indexed' => 'Ðе проиндекÑированный', + 'Not indexed' => 'Ðе индекÑированный', + 'Offline' => 'Ðвтономный', + 'Read Only' => 'Только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ', + 'Read-only' => 'Только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ', + 'Regular' => 'Обычный', + 'Reparse Point' => 'Точки повторной обработки', + 'Reparse point' => 'Точки повторной обработки', + 'Set Group ID' => 'УÑтановка ID группы', + 'Set User ID' => 'УÑтановка ID пользователÑ', + 'Socket' => 'Сокет', + 'Solaris Door' => 'Дверь (в Solaris)', + 'Solaris Shadow Inode' => 'Теневой Ð¸Ð½Ð´ÐµÐºÑ Solaris', + 'Sparse' => 'Разрежённый', + 'Sparse File' => 'Разрежённый файл', + 'Symbolic Link' => 'СимволичеÑÐºÐ°Ñ ÑÑылка', + 'System' => 'СиÑтемный', + 'Temporary' => 'Временный', + 'Unknown' => 'ÐеизвеÑтный', + 'Volume' => 'Том', + 'Volume Label' => 'Метка тома', + 'VxFS Compressed' => 'Сжатый VxFS', + 'XENIX Named' => 'Именованный (в XENIX)', + }, + }, + 'FileBlockCount' => 'КоличеÑтво блоков в файле', + 'FileBlockSize' => 'Размер блока в файле', + 'FileCreateDate' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'FileDeviceID' => 'ID уÑтройÑтва файла', + 'FileDeviceNumber' => 'Ðомер уÑтройÑтва файла', + 'FileFormat' => { + Description => 'Формат файла', + PrintConv => { + 'AppleSingle (Apple Computer Inc)' => 'AppleSingle (Apple)', + 'Audio Interchange File Format AIFF (Apple Computer Inc)' => 'Ðудиофайл формата AIFF (Apple)', + 'Bit Mapped Graphics File [.BMP] (Microsoft)' => 'Битовый графичеÑкий файл [.BMP] (Microsoft)', + 'Compressed Binary File [.ZIP] (PKWare Inc)' => 'Сжатый двоичный файл [.ZIP] (ÐšÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ PKWare)', + 'Digital Audio File [.WAV] (Microsoft & Creative Labs)' => 'Ðудиофайл формата [.WAV] (Microsoft и Creative Labs)', + 'Hypertext Markup Language [.HTML] (The Internet Society)' => 'Язык гипертекÑтовой разметки [.HTML] (The Internet Society)', + 'IPTC Unstructured Character Oriented File Format (UCOFF)' => 'ÐеÑтруктурированный Ñимвольно-ориентированный формат файла IPTC (UCOFF)', + 'IPTC7901 Recommended Message Format' => 'IPTC7901 Рекомендуемый формат ÑообщениÑ', + 'Illustrator (Adobe Graphics data)' => 'Illustrator (ГрафичеÑкие данные Adobe)', + 'JPEG File Interchange (JFIF)' => 'Формат обмена файлами Ñтандарта JPEG (JFIF)', + 'MPEG 2 Audio Layer 2 (Musicom), ISO/IEC' => 'Ðудио второго ÑƒÑ€Ð¾Ð²Ð½Ñ MPEG 2 (Musicom), ISO/IEC', + 'MPEG 2 Audio Layer 3, ISO/IEC' => 'Ðудио третьего ÑƒÑ€Ð¾Ð²Ð½Ñ MPEG 2 , ISO/IEC', + 'News Industry Text Format (NITF)' => 'ТекÑтовый формат новоÑтной индуÑтрии (NITF)', + 'No ObjectData' => 'Данные объекта отÑутÑтвуют', + 'PC DOS/Windows Executable Files [.COM][.EXE]' => 'ИÑполнÑемый файл PC DOS/Windows [.COM][.EXE]', + 'RIFF Wave (Microsoft Corporation)' => 'RIFF Wave (Microsoft)', + 'Ritzaus Bureau NITF version (RBNITF DTD)' => 'Ritzaus Bureau вариант NITF (RBNITF DTD)', + 'Tagged Image File Format (Adobe/Aldus Image data)' => 'Формат файла Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ‚ÐµÐ³Ð°Ð¼Ð¸ (Adobe/Aldus данные изображениÑ)', + 'Tape Archive [.TAR]' => 'Формат файла архива [.TAR]', + 'Tidningarnas Telegrambyra NITF version (TTNITF DTD)' => 'Tidningarnas Telegrambyra вариант NITF (TTNITF DTD)', + 'United Press International ANPA 1312 variant' => 'United Press International – Вариант ANPA 1312', + 'United Press International Down-Load Message' => 'United Press International – Down-Load Message', + }, + }, + 'FileGroupID' => 'ID группы файла', + 'FileHardLinks' => 'ЖёÑткие ÑÑылки файла', + 'FileID' => 'ID файла', + 'FileInfoLen' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ файле – Len', + 'FileInfoLen2' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ файле – Len 2', + 'FileInfoVersion' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ файле – ВерÑиÑ', + 'FileInodeChangeDate' => 'Дата Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¾Ð³Ð¾ индекÑа', + 'FileInodeNumber' => 'Ðомер индекÑа файла', + 'FileModifyDate' => 'Дата Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'FileName' => 'Ðазвание файла', + 'FileNameAsDelivered' => 'Ðазвание предоÑтавленного файла', + 'FileNameLength' => 'Длина Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'FileNumber' => 'Ðомер файла', + 'FilePath' => 'Путь к файлу', + 'FilePermissions' => 'Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'FileSequence' => 'ПоÑледовательноÑÑ‚ÑŒ файлов', + 'FileSize' => 'Размер файла', + 'FileSizeBytes' => 'Размер файла в байтах', + 'FileSource' => { + Description => 'ИÑточник файла', + PrintConv => { + 'Digital Camera' => 'Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ñ„Ð¾Ñ‚Ð¾ÐºÐ°Ð¼ÐµÑ€Ð°', + 'Film Scanner' => 'Плёночный Ñканер', + 'Reflection Print Scanner' => 'Планшетный Ñканер', + 'Sigma Digital Camera' => 'Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ñ„Ð¾Ñ‚Ð¾ÐºÐ°Ð¼ÐµÑ€Ð° Sigma', + }, + }, + 'FileType' => 'Тип файла', + 'FileTypeExtension' => 'РаÑширение файла', + 'FileUserID' => 'ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'FileVersion' => 'ВерÑÐ¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð°', + 'Filename' => 'Ðазвание файла', + 'Files' => 'Файлы', + 'FillAttributes' => 'Ðттрибуты заполнениÑ', + 'FillOrder' => { + Description => 'ПорÑдок битов в байте', + PrintConv => { + 'Normal' => 'Обычный', + 'Reversed' => 'Обратный', + }, + }, + 'Filter' => { + Description => 'Фильтр', + PrintConv => { + 'Adaptive' => 'Ðдаптивный', + }, + }, + 'FinalFrameBlocks' => 'Блоков в поÑледнем кадре', + 'Firmware' => 'Прошивка', + 'FirmwareDate' => 'Дата прошивки', + 'FirmwareID' => 'ID прошивки', + 'FirmwareVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¾ÑˆÐ¸Ð²ÐºÐ¸', + 'FirmwareVersions' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¾ÑˆÐ¸Ð²ÐºÐ¸', + 'FirstChar' => 'Первый Ñимвол шрифта', + 'FirstPhotoDate' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿ÐµÑ€Ð²Ð¾Ð³Ð¾ изображениÑ', + 'FirstPublicationDate' => 'Дата первой публикации изображениÑ', + 'FixtureIdentifier' => 'Узнаваемый идентификатор', + 'Flags' => { + Description => 'Флаги', + PrintConv => { + 'Allow Download' => 'Разрешить загрузку', + 'Allow Recording' => 'Разрешить запиÑÑŒ', + 'Animation' => 'ÐнимациÑ', + 'Comment' => 'Комментарий', + 'Description' => 'ОпиÑание', + 'Extension Present' => 'ÐаÑтоÑщее времÑ', + 'ExtraFields' => 'Дополнительное поле', + 'FileName' => 'Ðазвание файлов', + 'IDList' => 'СпиÑок ID', + 'IconFile' => 'Иконка файла', + 'Limited Range' => 'Ограниченный диапазон', + 'LinkInfo' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ÑÑылке', + 'LinkToLink' => 'СÑылка на ÑÑылку', + 'Live' => 'Ð’ прÑмом Ñфире', + 'NoLinkInfo' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ ÑÑылке отÑутÑтвует', + 'NoLinkPathTracking' => 'ОтÑлеживание пути без ÑÑылки', + 'NoLinkTrack' => 'Без ÑÑылки на трек', + 'Perfect Play' => 'ВоÑпроизводить поÑле загрузки', + 'RelativePath' => 'ОтноÑительный путь', + 'RunAsUser' => 'ЗапуÑк от имени пользователÑ', + 'TargetMetadata' => 'Целевые метаданные', + 'Text' => 'ТекÑÑ‚', + 'Unicode' => 'Юникод', + 'WorkingDir' => 'Ð Ð°Ð±Ð¾Ñ‡Ð°Ñ Ð¿Ð°Ð¿ÐºÐ°', + }, + }, + 'Flash' => { + Description => 'СоÑтоÑние вÑпышки при Ñъёмке', + PrintConv => { + 'Auto, Did not fire' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка не Ñработала', + 'Auto, Did not fire, Red-eye reduction' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка не Ñработала. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз»', + 'Auto, Fired' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка Ñработала', + 'Auto, Fired, Red-eye reduction' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка Ñработала', + 'Auto, Fired, Red-eye reduction, Return detected' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка Ñработала. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз». Отражённый Ñвет обнаружен', + 'Auto, Fired, Red-eye reduction, Return not detected' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка Ñработала. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз». Отражённый Ñвет не обнаружен', + 'Auto, Fired, Return detected' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка Ñработала. Отражённый Ñвет обнаружен', + 'Auto, Fired, Return not detected' => 'ÐвтоматичеÑкий режим. Ð’Ñпышка Ñработала. Отражённый Ñвет не обнаружен', + 'Did not fire' => 'Ð’Ñпышка не Ñработала', + 'Fired' => 'Ð’Ñпышка Ñработала', + 'Fired, Red-eye reduction' => 'Ð’Ñпышка Ñработала. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз»', + 'Fired, Red-eye reduction, Return detected' => 'Ð’Ñпышка Ñработала. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз». Отражённый Ñвет обнаружен', + 'Fired, Red-eye reduction, Return not detected' => 'Ð’Ñпышка Ñработала. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз». Отражённый Ñвет не обнаружен', + 'Fired, Return detected' => 'Ð’Ñпышка Ñработала. Отражённый Ñвет обнаружен', + 'Fired, Return not detected' => 'Ð’Ñпышка Ñработала. Отражённый Ñвет не обнаружен', + 'No Flash' => 'Без вÑпышки', + 'No flash function' => 'Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñпышки не поддерживаетÑÑ', + 'Off' => 'Ðе включена', + 'Off, Did not fire' => 'Ðе включена. Ð’Ñпышка не Ñработала', + 'Off, Did not fire, Return not detected' => 'Ðе включена. Ð’Ñпышка не Ñработала. Отражённый Ñвет не обнаружен', + 'Off, No flash function' => 'Ðе включена. Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð²Ñпышки не поддерживаетÑÑ', + 'Off, Red-eye reduction' => 'Ðе включена. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз»', + 'On' => 'Включена', + 'On, Did not fire' => 'Принудительный режим. Ð’Ñпышка не Ñработала', + 'On, Fired' => 'Принудительный режим. Ð’Ñпышка Ñработала', + 'On, Red-eye reduction' => 'Принудительный режим. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз»', + 'On, Red-eye reduction, Return detected' => 'Принудительный режим. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз». Отражённый Ñвет обнаружен', + 'On, Red-eye reduction, Return not detected' => 'Принудительный режим. Включён режим ÑƒÐ¼ÐµÐ½ÑŒÑˆÐµÐ½Ð¸Ñ Ñффекта «краÑных глаз». Отражённый Ñвет не обнаружен', + 'On, Return detected' => 'Принудительный режим. Отражённый Ñвет обнаружен', + 'On, Return not detected' => 'Принудительный режим. Отражённый Ñвет не обнаружен', + }, + }, + 'FlashAttributes' => { + Description => 'Flash аттрибуты', + PrintConv => { + 'UseNetwork' => 'ИÑпользовать Ñеть', + }, + }, + 'FlashCompensation' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð²Ñпышки', + 'FlashEnergy' => 'МощноÑÑ‚ÑŒ вÑпышки', + 'FlashExposureComp' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð²Ñпышки', + 'FlashManufacturer' => 'Производитель вÑпышки', + 'FlashMode' => { + Description => 'Режим вÑпышки', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкий', + 'Disabled' => 'Ð’Ñпышка не включена', + 'Force' => 'Принудительный', + 'Red eye' => 'КраÑные глаза', + }, + }, + 'FlashModel' => 'Модель вÑпышки', + 'FlashType' => { + Description => 'Тип вÑпышки', + PrintConv => { + 'Built-In Flash' => 'Ð’ÑтроеннаÑ', + 'External' => 'ВнешнÑÑ', + }, + }, + 'FlashVersion' => 'ВерÑÐ¸Ñ Flash', + 'FlashpixVersion' => 'ВерÑÐ¸Ñ Flashpix', + 'FlickerReduce' => { + Description => 'Уменьшение мерцаниÑ', + PrintConv => { + 'Off' => 'Ðе включено', + 'On' => 'Включено', + }, + }, + 'FlightPitchDegree' => 'Тангаж полета (наклон)', + 'FlightRollDegree' => 'Крен полета (вращение)', + 'FlightXSpeed' => 'СкороÑÑ‚ÑŒ полёта по оÑи X', + 'FlightYSpeed' => 'СкороÑÑ‚ÑŒ полёта по оÑи Y', + 'FlightYawDegree' => 'РыÑкание полета (поворот)', + 'FlightZSpeed' => 'СкороÑÑ‚ÑŒ полёта по оÑи Z', + 'FocalDistance' => 'ФокуÑное раÑÑтоÑние', + 'FocalLength' => 'ФокуÑное раÑÑтоÑние', + 'FocalLength35efl' => 'ФокуÑное раÑÑтоÑние', + 'FocalLengthIn35mmFormat' => 'ФокуÑное раÑÑтоÑние Ð´Ð»Ñ 35-мм формата', + 'FocalPlaneResolutionUnit' => { + Description => 'Единицы Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð² фокальной плоÑкоÑти', + PrintConv => { + 'None' => 'Ðе указано', + 'cm' => 'Ñм', + 'inches' => 'дюймы', + 'mm' => 'мм', + 'um' => 'мкм', + }, + }, + 'FocalPlaneXResolution' => 'Разрешение в фокальной плоÑкоÑти по X', + 'FocalPlaneYResolution' => 'Разрешение в фокальной плоÑкоÑти по Y', + 'FocalPointX' => 'Точка фокуÑа по оÑи X', + 'FocalPointY' => 'Точка фокуÑа по оÑи Y', + 'FocusDistance' => 'ФокуÑное раÑÑтоÑние', + 'FocusDistance2' => 'ФокуÑное раÑÑтоÑние 2', + 'FocusMode' => 'Режим фокуÑировки', + 'FocusPos' => 'ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ñ„Ð¾ÐºÑƒÑа', + 'FontFamily' => { + Description => 'СемейÑтво шрифта', + PrintConv => { + 'Decorative' => 'Декоративный', + 'Don\'t Care' => 'Без разницы', + 'Modern' => 'Модерн', + 'Script' => 'Скрипт', + }, + }, + 'FontName' => 'Ðазвание шрифта', + 'FontSize' => 'Размер шрифта', + 'FontSubfamily' => 'Стиль шрифта', + 'FontSubfamilyID' => 'ID ÑÑ‚Ð¸Ð»Ñ ÑˆÑ€Ð¸Ñ„Ñ‚Ð°', + 'FontType' => 'Тип шрифта', + 'FontWeight' => 'Толщина шрифта', + 'Footnotes' => 'СноÑки', + 'For' => 'ДлÑ', + 'FormExtraUsageRights' => 'Права на иÑпользование Форм Extra', + 'FormFields' => 'ÐŸÐ¾Ð»Ñ Ñ„Ð¾Ñ€Ð¼', + 'FormUsageRights' => 'Права на иÑпользование Форм', + 'Format' => { + Description => 'Формат', + PrintConv => { + 'RangeInverse' => 'Диапазон инверÑии', + 'RangeLinear' => 'Диапазон линейноÑти', + }, + }, + 'FormatVersionTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð²ÐµÑ€Ñии формата', + 'FormattedName' => 'Отформатированное имÑ', + 'Formatter' => 'Форматировщик', + 'ForwardMatrix1' => 'ПрÑÐ¼Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° 1', + 'ForwardMatrix2' => 'ПрÑÐ¼Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° 2', + 'FossilSpecimen' => 'ИÑкопаемый образец', + 'FossilSpecimenMaterialSampleID' => 'ID материала иÑкопаемого образца', + 'FovCot' => 'Угол обзора и КотангенÑ', + 'FractalParameters' => 'Фрактальные параметры', + 'FragmentList' => 'СпиÑок фрагментов', + 'FragmentTable' => 'Таблица фрагментов', + 'FrameCount' => 'КоличеÑтво кадров', + 'FrameExposureTime' => 'Ð’Ñ€ÐµÐ¼Ñ ÑкÑпозиции кадра', + 'FrameID' => 'ID кадра', + 'FrameNum' => 'Ðомер кадра', + 'FrameRate' => 'ЧаÑтота кадров', + 'FrameSize' => 'Размер кадра', + 'FrameSizeMax' => 'МакÑимальный размер кадра', + 'FrameSizeMin' => 'Минимальный размер кадра', + 'FramesPerSecond' => 'Кадров в Ñекунду', + 'Free' => 'Свободный', + 'FreeBusyTime' => 'Свободное/ЗанÑтое времÑ', + 'FreeByteCounts' => 'КоличеÑтво байтов в Ñтроке неиÑпользуемых байтов', + 'FreeOffsets' => 'Смещение к Ñтроке неиÑпользуемых байтов', + 'FullName' => 'Полное название шрифта', + 'FullPanoHeightPixels' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð¿Ð¾Ð»Ð½Ð°Ñ Ð²Ñ‹Ñота до обрезки изображениÑ', + 'FullPanoWidthPixels' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð¿Ð¾Ð»Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° до обрезки изображениÑ', + 'FullScreen' => 'ПолноÑкранный', + 'GDALMetadata' => 'GDAL – Метаданные', + 'GDALNoData' => 'GDAL – ПрозрачноÑÑ‚ÑŒ', + 'GEMake' => 'GE – Сделан', + 'GEModel' => 'GE – Модель', + 'GIFApplicationExtension' => 'РаÑширение GIF-приложениÑ', + 'GIFGraphicControlExtension' => 'РаÑширение ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð³Ñ€Ð°Ñ„Ð¸ÐºÐ¾Ð¹ GIF', + 'GIFPlainTextExtension' => 'РаÑширение обычного текÑта GIF', + 'GIFTFtpPriority' => 'Приоритет GIFT Ftp', + 'GIFVersion' => 'ВерÑÐ¸Ñ GIF', + 'GLPI_Unknown4' => 'GLPI – ÐеизвеÑтный 4', + 'GPRI_Unknown4' => 'GPRI – ÐеизвеÑтный – 4', + 'GPRI_Unknown5' => 'GPRI – ÐеизвеÑтный – 5', + 'GPRI_Unknown8' => 'GPRI – ÐеизвеÑтный – 8', + 'GPRI_Unknown9' => 'GPRI – ÐеизвеÑтный – 9', + 'GPSAltitude' => 'GPS – Ð’Ñ‹Ñота', + 'GPSAltitudeRaw' => 'GPS – Ð’Ñ‹Ñота – Raw', + 'GPSAltitudeRef' => { + Description => 'GPS – Ð˜Ð½Ð´ÐµÐºÑ Ð²Ñ‹Ñоты', + PrintConv => { + 'Above Sea Level' => 'Ðад уровнем морÑ', + 'Below Sea Level' => 'Ðиже ÑƒÑ€Ð¾Ð²Ð½Ñ Ð¼Ð¾Ñ€Ñ', + }, + }, + 'GPSAreaInformation' => 'GPS – Ðазвание облаÑти', + 'GPSDOP' => 'GPS – ТочноÑÑ‚ÑŒ измерениÑ', + 'GPSDateStamp' => 'GPS – Дата и времÑ', + 'GPSDateTime' => 'GPS – Дата/ВремÑ', + 'GPSDateTimeRaw' => 'GPS – Дата/Ð’Ñ€ÐµÐ¼Ñ â€“ Raw', + 'GPSDestBearing' => 'GPS – Пеленг объекта Ñъёмки', + 'GPSDestBearingRef' => { + Description => 'GPS – Ориентир пеленга объекта Ñъёмки', + PrintConv => { + 'Magnetic North' => 'Ðа магнитный Ñеверный полюÑ', + 'True North' => 'Ðа географичеÑкий Ñеверный полюÑ', + }, + }, + 'GPSDestDistance' => 'GPS – РаÑÑтоÑние до объекта Ñъёмки', + 'GPSDestDistanceRef' => { + Description => 'GPS – Единицы Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ñ€Ð°ÑÑтоÑниÑ', + PrintConv => { + 'Kilometers' => 'Километры', + 'Miles' => 'Мили', + 'Nautical Miles' => 'МорÑкие мили', + }, + }, + 'GPSDestLatitude' => 'GPS – Широта объекта Ñъёмки', + 'GPSDestLatitudeRef' => { + Description => 'GPS – Ð˜Ð½Ð´ÐµÐºÑ ÑˆÐ¸Ñ€Ð¾Ñ‚Ñ‹ объекта Ñъёмки', + PrintConv => { + 'North' => 'Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', + 'South' => 'Ð®Ð¶Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', + }, + }, + 'GPSDestLongitude' => 'GPS – Долгота объекта Ñъёмки', + 'GPSDestLongitudeRef' => { + Description => 'GPS – Ð˜Ð½Ð´ÐµÐºÑ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ñ‹ объекта Ñъёмки', + PrintConv => { + 'East' => 'ВоÑÑ‚Ð¾Ñ‡Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', + 'West' => 'Ð—Ð°Ð¿Ð°Ð´Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', + }, + }, + 'GPSDifferential' => { + Description => 'GPS – Ð”Ð¸Ñ„Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð¿Ñ€Ð°Ð²ÐºÐ°', + PrintConv => { + 'Differential Corrected' => 'Ð”Ð¸Ñ„Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð¿Ñ€Ð°Ð²ÐºÐ° применена', + 'No Correction' => 'Измерение без дифференциальной поправки', + }, + }, + 'GPSHPositioningError' => 'GPS – Ошибка горизонтального позиционированиÑ', + 'GPSImgDirection' => 'GPS – ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹ при Ñъёмке', + 'GPSImgDirectionRef' => { + Description => 'GPS – Ориентир Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹', + PrintConv => { + 'Magnetic North' => 'Ðа магнитный Ñеверный полюÑ', + 'True North' => 'Ðа географичеÑкий Ñеверный полюÑ', + }, + }, + 'GPSInfo' => 'IFD указатель информации GPS', + 'GPSLatitude' => 'GPS – Широта', + 'GPSLatitudeRaw' => 'GPS – Широта – Raw', + 'GPSLatitudeRef' => { + Description => 'GPS – Ð˜Ð½Ð´ÐµÐºÑ ÑˆÐ¸Ñ€Ð¾Ñ‚Ñ‹', + PrintConv => { + 'North' => 'Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', + 'South' => 'Ð®Ð¶Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', + }, + }, + 'GPSLongitude' => 'GPS – Долгота', + 'GPSLongitudeRaw' => 'GPS – Долгота – Raw', + 'GPSLongitudeRef' => { + Description => 'GPS – Ð˜Ð½Ð´ÐµÐºÑ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ñ‹', + PrintConv => { + 'East' => 'ВоÑÑ‚Ð¾Ñ‡Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', + 'West' => 'Ð—Ð°Ð¿Ð°Ð´Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', + }, + }, + 'GPSLongtitude' => 'GPS – Долгота', + 'GPSMapDatum' => 'GPS – СиÑтема координат', + 'GPSMeasureMode' => { + Description => 'GPS – Режим Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ GPS', + PrintConv => { + '2-Dimensional Measurement' => '2-Ð¼ÐµÑ€Ð½Ð°Ñ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ñ', + '3-Dimensional Measurement' => '3-Ð¼ÐµÑ€Ð½Ð°Ñ Ð½Ð°Ð²Ð¸Ð³Ð°Ñ†Ð¸Ñ', + }, + }, + 'GPSPosition' => 'GPS – МеÑтоположение', + 'GPSProcessingMethod' => 'GPS – Метод вычиÑÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'GPSSatellites' => 'GPS – ИÑпользуемые Ñпутники', + 'GPSSpeed' => 'GPS – СкороÑÑ‚ÑŒ передвижениÑ', + 'GPSSpeed3D' => 'GPS – СкороÑÑ‚ÑŒ 3D', + 'GPSSpeedRaw' => 'GPS – ÑкороÑÑ‚ÑŒ – Raw', + 'GPSSpeedRef' => { + Description => 'GPS – Единицы Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ ÑкороÑти', + PrintConv => { + 'km/h' => 'Км/ч', + 'knots' => 'Узлы', + 'mph' => 'Миль/ч', + }, + }, + 'GPSSpeedX' => 'GPS – СкороÑÑ‚ÑŒ по X', + 'GPSSpeedY' => 'GPS – СкороÑÑ‚ÑŒ по Y', + 'GPSSpeedZ' => 'GPS – СкороÑÑ‚ÑŒ по Z', + 'GPSStatus' => { + Description => 'GPS – СоÑтоÑние приёмника во Ð²Ñ€ÐµÐ¼Ñ Ñъёмки', + PrintConv => { + 'Measurement Active' => 'Координаты актуальные', + 'Measurement Void' => 'Ðктуальных координат нету', + }, + }, + 'GPSTimeStamp' => 'GPS – Ð’Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿Ð¸Ñанных координат', + 'GPSTrack' => 'GPS – Трек', + 'GPSTrackRaw' => 'GPS – Трек – Raw', + 'GPSTrackRef' => { + Description => 'GPS – Ориентир направлениÑ', + PrintConv => { + 'Magnetic North' => 'Ðа магнитный Ñеверный полюÑ', + 'True North' => 'Ðа географичеÑкий Ñеверный полюÑ', + }, + }, + 'GPSVersionID' => 'GPS – ВерÑÐ¸Ñ Ñ‚ÐµÐ³Ð¾Ð²', + 'GainControl' => { + Description => 'Управление уÑилением', + PrintConv => { + 'High gain down' => 'С большим шагом вниз', + 'High gain up' => 'С большим шагом вверх', + 'Low gain down' => 'С малым шагом вниз', + 'Low gain up' => 'С малым шагом вверх', + 'None' => 'ОтÑутÑтвует', + }, + }, + 'Gamma' => 'Гамма', + 'GammaBlue' => 'Гамма Синего', + 'GammaCompensatedValue' => 'Значение гамма-компенÑации', + 'GammaGreen' => 'Гамма Зелёного', + 'GammaRed' => 'Гамма КраÑного', + 'Gapless' => { + Description => 'Без зазора', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'Gender' => 'Пол', + 'Generator' => 'Сгенерирован в', + 'GeneratorVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'Genr' => 'Жанр', + 'Genre' => 'Жанр', + 'GeoTiffAsciiParams' => 'Geo Tiff – Параметры Ascii', + 'GeoTiffDirectory' => 'Geo Tiff – Каталог', + 'GeoTiffDoubleParams' => 'Geo Tiff – Параметры дублированиÑ', + 'Geolocation' => 'ГеолокациÑ', + 'GeologicalContext' => 'ГеологичеÑкий контекÑÑ‚', + 'GeologicalContextBed' => 'Ðазвание литоÑтратиграфичеÑкого ÑлоÑ', + 'GeologicalContextFormation' => 'Ðазвание литоÑтратиграфичеÑкой Ñвиты', + 'GeologicalContextGroup' => 'Ðазвание литоÑтратиграфичеÑкой Ñерии', + 'GeologicalContextID' => 'ID геологичеÑкого контекÑта', + 'GeologicalContextMember' => 'Ðазвание литоÑтратиграфичеÑкой пачки', + 'Geosync' => 'Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ меÑтоположениÑ', + 'Geotag' => 'Журнал пройденного маршрута', + 'Geotime' => 'Дата/Ð’Ñ€ÐµÐ¼Ñ Ð¼ÐµÑтоположениÑ', + 'GimbalPitchDegree' => 'Тангаж шарнира (наклон)', + 'GimbalReverse' => 'Оборот шарнира', + 'GimbalRollDegree' => 'Крен шарнира (вращение)', + 'GimbalYawDegree' => 'РыÑкание шарнира (поворот)', + 'GlobalAltitude' => 'Ð“Ð»Ð¾Ð±Ð°Ð»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота', + 'GlobalAngle' => 'Глобальный угол', + 'GoogleBot' => 'ПоиÑковый робот Google', + 'GooglePlusUploadCode' => 'Код загрузки Google Plus', + 'Gradation' => 'ВпечатлÑющ.режим', + 'GrayPoint' => 'Точка Ñерого', + 'GrayResponseCurve' => 'ОптичеÑÐºÐ°Ñ Ð¿Ð»Ð¾Ñ‚Ð½Ð¾ÑÑ‚ÑŒ Ñерого', + 'GrayResponseUnit' => 'Единицы плотноÑти Ñерого', + 'GreenEndpoint' => 'ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° Зелёного', + 'GreenMask' => 'МаÑка Зелёного', + 'GreenPrimary' => 'ОÑновной зелёный', + 'GreenX' => 'Зелёный по X', + 'GreenY' => 'Зелёный по Y', + 'GridGuidesInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ Ñетке и направлÑющих', + 'Gyroscope' => 'ГироÑкоп', + 'HCUsage' => 'Тип информации HC-файла', + 'HDContent' => { + Description => 'Контент HD', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'HDR' => { + Description => 'ÐвтоматичеÑкий HDR', + PrintConv => { + 'Off' => 'Ðе включён', + }, + }, + 'HDRImageType' => { + Description => 'Тип HDR изображениÑ', + PrintConv => { + 'HDR Image' => 'HDR изображение', + 'Original Image' => 'Оригинальное изображение', + }, + }, + 'HDRSetting' => 'Праметры HDR', + 'HDRToningInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ HDR-тонировании', + 'HTTPHostHeader' => 'Заголовок HTTP-хоÑта', + 'HalftoneHints' => 'Ð£ÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‚Ð¾Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'HardLink' => 'ЖёÑÑ‚ÐºÐ°Ñ ÑÑылка', + 'HasAudio' => 'Имеет аудио', + 'HasColorMap' => { + Description => 'Имеет цветовую карту', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'HasCuePoints' => 'Имеет ключевые точки', + 'HasKeyFrames' => 'Имеет ключевые кадры', + 'HasMetadata' => 'Имеет метаданные', + 'HasRealMergedData' => { + Description => 'Имеет Ñовмещённые данные', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'HasVideo' => 'Имеет видео', + 'HasXFA' => { + Description => 'XFA', + PrintConv => { + 'No' => 'ОтÑутÑтвует', + 'Yes' => 'ЕÑÑ‚ÑŒ', + }, + }, + 'HeaderSize' => 'Размер заголовка', + 'HeaderVersion' => 'ВерÑÐ¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð²', + 'Headline' => 'Заголовок', + 'HeightResolution' => 'Разрешение по выÑоте (PPI)', + 'HierarchicalKeywords' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов', + 'HierarchicalKeywords1' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 1', + 'HierarchicalKeywords1Applied' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 1 – Применена', + 'HierarchicalKeywords1Children' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 1 – ДочернÑÑ', + 'HierarchicalKeywords2' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 2', + 'HierarchicalKeywords2Applied' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 2 – Применена', + 'HierarchicalKeywords2Children' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 2 – ДочернÑÑ', + 'HierarchicalKeywords3' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 3', + 'HierarchicalKeywords3Applied' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 3 – Применена', + 'HierarchicalKeywords3Children' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 3 – ДочернÑÑ', + 'HierarchicalKeywords4' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 4', + 'HierarchicalKeywords4Applied' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 4 – Применена', + 'HierarchicalKeywords4Children' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 4 – ДочернÑÑ', + 'HierarchicalKeywords5' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 5', + 'HierarchicalKeywords5Applied' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 5 – Применена', + 'HierarchicalKeywords5Children' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 5 – ДочернÑÑ', + 'HierarchicalKeywords6' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 6', + 'HierarchicalKeywords6Applied' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… Ñлов 6 – Применена', + 'HierarchicalSubject' => 'Ð˜ÐµÑ€Ð°Ñ€Ñ…Ð¸Ñ Ñ‚ÐµÐ¼', + 'HighISOMultiplierBlue' => 'Множитель ISO – Синий', + 'HighISOMultiplierGreen' => 'Множитель ISO – Зелёный', + 'HighISOMultiplierRed' => 'Множитель ISO – КраÑный', + 'HighISONoiseReduction' => { + Description => 'Шумоподавление при выÑоком ISO', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкое', + 'High' => 'Сильное', + 'Low' => 'Слабое', + 'Normal' => 'Стандартное', + 'Off' => 'Ðе включено', + 'Standard' => 'Стандартное', + 'Strong' => 'Сильное', + }, + }, + 'HighestBiostratigraphicZone' => 'Ð’Ñ‹ÑÑˆÐ°Ñ Ð±Ð¸Ð¾ÑтратиграфичеÑÐºÐ°Ñ Ð·Ð¾Ð½Ð°', + 'HighlightColorDistortReduct' => { + Description => 'Уменьшение иÑкажений Ñветлых цветов', + PrintConv => { + 'Advanced' => 'РаÑширенный', + 'Standard' => 'Стандартный', + }, + }, + 'Highlights' => 'Света', + 'HighlightsAdj' => 'Регулировка Ñветов', + 'History' => 'ИÑториÑ', + 'HistoryBufferSize' => 'Размер буфера иÑтории', + 'HostComputer' => 'Компьютер/СиÑтема', + 'HotKey' => { + Description => 'ГорÑÑ‡Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑˆÐ°', + PrintConv => { + '(none)' => 'ОтÑутÑтвует', + }, + }, + 'HowPublished' => 'Метод публикации', + 'Hue' => 'Оттенок', + 'HueAdj' => 'Регулировка оттенка', + 'HumanObservation' => 'Визуальное наблюдение', + 'HumanObservationDay' => 'День меÑÑца визуального наблюдениÑ', + 'HumanObservationEarliestDate' => 'Дата начала визуального наблюдениÑ', + 'HumanObservationEndDayOfYear' => 'День года Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ наблюдениÑ', + 'HumanObservationEventDate' => 'Дата визуального наблюдениÑ', + 'HumanObservationEventID' => 'ID визуального наблюдениÑ', + 'HumanObservationEventRemarks' => 'Комментарии к визуальному наблюдению', + 'HumanObservationEventTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ наблюдениÑ', + 'HumanObservationFieldNotes' => 'Полевые заметки о визуальном наблюдении', + 'HumanObservationFieldNumber' => 'Ðомер полевых заметок о визуальном наблюдении', + 'HumanObservationHabitat' => 'Ðреал визуального наблюдениÑ', + 'HumanObservationLatestDate' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð²Ð¸Ð·ÑƒÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ наблюдениÑ', + 'HumanObservationMonth' => 'МеÑÑц визуального наблюдениÑ', + 'HumanObservationParentEventID' => 'ID оÑновного визуального наблюдениÑ', + 'HumanObservationSampleSizeUnit' => 'Визуальное наблюдение – Единицы размера', + 'HumanObservationSampleSizeValue' => 'Визуальное наблюдение – Размер образца', + 'HumanObservationSamplingEffort' => 'Визуальное наблюдение – Затраченные уÑилиÑ', + 'HumanObservationSamplingProtocol' => 'Визуальное наблюдение – Метод иÑÑледованиÑ', + 'HumanObservationStartDayOfYear' => 'День года начала визуального наблюдениÑ', + 'HumanObservationVerbatimEventDate' => 'Дата визуального Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ñловно', + 'HumanObservationYear' => 'Год визуального наблюдениÑ', + 'Humidity' => 'ВлажноÑÑ‚ÑŒ', + 'HyperfocalDistance' => 'Гиперфокальное раÑÑтоÑние', + 'HyperlinkBase' => 'База гиперÑÑылок', + 'ICCProfileName' => 'Ðазвание ICC-профилÑ', + 'ICC_Profile' => 'ICC-профиль', + 'ICC_Untagged' => 'ICC без метки', + 'ID3Size' => 'Размер блока данных ID3', + 'IDCCreativeStyle' => { + Description => 'IDC – ТворчеÑкий Ñтиль', + PrintConv => { + 'A100 Standard' => 'Стандарт A100', + 'Autumn Leaves' => 'ОÑенние лиÑÑ‚ÑŒÑ', + 'B&W' => 'Чёрно-Белое', + 'Camera Setting' => 'ÐаÑтройка камеры', + 'Clear' => 'ЧиÑтый', + 'Deep' => 'Глубокий', + 'Landscape' => 'Пейзаж', + 'Light' => 'Светлый', + 'Neutral' => 'Ðейтральный', + 'Night View' => 'Ðочной вид', + 'Portrait' => 'Портрет', + 'Real' => 'Реальный', + 'Sepia' => 'СепиÑ', + 'Standard' => 'Стандарт', + 'Sunset' => 'Закат', + 'Vivid' => 'Яркий', + }, + }, + 'IDCPreviewImage' => 'IDC – файл предпроÑмотра', + 'IDCPreviewLength' => 'IDC – Строк в файле предпроÑмотра', + 'IDCPreviewStart' => 'IDC – Ðачало файла предпроÑмотра', + 'IDsBaseValue' => 'ОÑновные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð½Ð´Ð¸ÐºÐ°Ñ‚Ð¾Ñ€Ð¾Ð²', + 'INGRReserved' => 'Intergraph – Резерв', + 'IPTCBitsPerSample' => 'IPTC – КоличеÑтво бит на компонент', + 'IPTCDigest' => 'Хеш IPTC', + 'IPTCImageHeight' => 'IPTC – Ð’Ñ‹Ñота изображениÑ', + 'IPTCImageRotation' => { + Description => 'IPTC – Вращение изображениÑ', + PrintConv => { + '0' => 'Ðе вращать', + '180' => 'Повернуть вправо на 180°', + '270' => 'Повернуть вправо на 270°', + '90' => 'Повернуть вправо на 90°', + }, + }, + 'IPTCImageWidth' => 'IPTC – Ширина изображениÑ', + 'IPTCPictureNumber' => 'IPTC – Ðомер изображениÑ', + 'IPTCPixelHeight' => 'IPTC – Ð’Ñ‹Ñота (в пикÑелÑÑ…)', + 'IPTCPixelWidth' => 'IPTC – Ширина (в пикÑелÑÑ…)', + 'ISOSetting' => { + Description => 'ISO2', + PrintConv => { + '200 (Zone Matching High)' => '200 (СоглаÑование зон. Ð’ выÑоком ключе)', + '80 (Zone Matching Low)' => '80 (СоглаÑование зон. Ð’ низком ключе)', + 'Auto' => 'ÐвтоматичеÑки', + }, + }, + 'ISOSpeed' => 'ЧувÑтвительноÑÑ‚ÑŒ ISO', + 'ISOSpeedLatitudeyyy' => 'ISO – ФотографичеÑÐºÐ°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð° yyy', + 'ISOSpeedLatitudezzz' => 'ISO – ФотографичеÑÐºÐ°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð° zzz', + 'ISOSpeeds' => 'ISO4', + 'ISRCNumber' => 'Ðомер ISRC', + 'IT8Header' => 'IT8-заголовок', + 'IconFileName' => 'Ðазвание файла значка', + 'IconIndex' => 'Ð˜Ð½Ð´ÐµÐºÑ Ð¸ÐºÐ¾Ð½ÐºÐ¸', + 'Identification' => 'Определение', + 'IdentificationID' => 'ID определениÑ', + 'IdentificationQualifier' => 'Уточнение к определению', + 'IdentificationReferences' => 'ИÑточники иÑпользованные Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ', + 'IdentificationRemarks' => 'Комментарии к определению', + 'IdentificationVerificationStatus' => 'Код Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ', + 'IdentifiedBy' => 'Люди определившие образец', + 'Identifier' => 'Идентификатор', + 'Illumination' => { + Description => 'ПодÑветка', + PrintConv => { + 'Off' => 'Ðе включена', + 'On' => 'Включена', + }, + }, + 'Image2Description' => 'Изображение 2 – ОпиÑание', + 'Image3Description' => 'Изображение 3 – ОпиÑание', + 'Image4Description' => 'Изображение 4 – ОпиÑание', + 'Image5Description' => 'Изображение 5 – ОпиÑание', + 'Image6Description' => 'Изображение 6 – ОпиÑание', + 'Image7Description' => 'Изображение 7 – ОпиÑание', + 'Image8Description' => 'Изображение 8 – ОпиÑание', + 'Image::ExifTool::AIFF::Comment' => 'Комментарии AIFF', + 'Image::ExifTool::AIFF::Common' => 'Общее AIFF', + 'Image::ExifTool::AIFF::FormatVers' => 'ВерÑÐ¸Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð° AIFF', + 'Image::ExifTool::APE::NewHeader' => 'Ðовый заголовок APE', + 'Image::ExifTool::APE::OldHeader' => 'Старый заголовок APE', + 'Image::ExifTool::APP12::PictureInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ APP12', + 'Image::ExifTool::Apple::RunTime' => 'Apple – Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ', + 'Image::ExifTool::Audible::cvrx' => 'Обложка Audible', + 'Image::ExifTool::Audible::meta' => 'Метаданные Audible', + 'Image::ExifTool::BPG::Extensions' => 'РаÑÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ BPG', + 'Image::ExifTool::DjVu::Form' => 'Форма DjVu', + 'Image::ExifTool::DjVu::Info' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ DjVu', + 'Image::ExifTool::DjVu::Meta' => 'DjVu метаданные', + 'Image::ExifTool::FLAC::Picture' => 'Изображение FLAC', + 'Image::ExifTool::FLAC::StreamInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ потоке FLAC', + 'Image::ExifTool::Flash::Audio' => 'Flash аудио', + 'Image::ExifTool::Flash::Meta' => 'Flash метаданные', + 'Image::ExifTool::Flash::Video' => 'Flash видео', + 'Image::ExifTool::Font::Main' => 'Шрифт', + 'Image::ExifTool::Font::Name' => 'Ðазвание шрифта', + 'Image::ExifTool::Font::PFM' => 'Шрифт PFM', + 'Image::ExifTool::Font::PSInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ PostScript шрифте', + 'Image::ExifTool::FotoStation::SoftEdit' => 'FotoStation – Редактор', + 'Image::ExifTool::GE::Main' => 'General Imaging (GE)', + 'Image::ExifTool::GIF::Animation' => 'GIF анимациÑ', + 'Image::ExifTool::GIF::Extensions' => 'GIF РаÑширениÑ', + 'Image::ExifTool::GIF::MIDIControl' => 'GIF MIDIControl', + 'Image::ExifTool::GIF::Main' => 'GIF', + 'Image::ExifTool::GIF::Screen' => 'GIF Screen', + 'Image::ExifTool::GIMP::Header' => 'Заголовок GIMP', + 'Image::ExifTool::GIMP::Parasite' => 'GIMP – Паразитный Ñлемент', + 'Image::ExifTool::GIMP::Resolution' => 'GIMP – Разешение', + 'Image::ExifTool::HP::Type2' => 'HP – Тип 2', + 'Image::ExifTool::HP::Type4' => 'HP – Тип 4', + 'Image::ExifTool::HP::Type6' => 'HP – Тип 6', + 'Image::ExifTool::IPTC::ObjectData' => 'IPTC – Данные объекта', + 'Image::ExifTool::IPTC::PostObjectData' => 'IPTC – Данные Post объекта', + 'Image::ExifTool::IPTC::PreObjectData' => 'IPTC – Данные Pre объекта', + 'Image::ExifTool::ITC::Header' => 'Заголовок ITC', + 'Image::ExifTool::ITC::Item' => 'Элемент ITC', + 'Image::ExifTool::JFIF::Extension' => 'JFIF Дополнение', + 'Image::ExifTool::JVC::Text' => 'JVC – ТекÑÑ‚', + 'Image::ExifTool::Jpeg2000::ColorSpec' => 'Jpeg2000 – Ð¡Ð¿ÐµÑ†Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð°', + 'Image::ExifTool::Jpeg2000::DisplayResolution' => 'Jpeg2000 – Разрешение Ñкрана', + 'Image::ExifTool::Jpeg2000::FileType' => 'Jpeg2000 – Тип файла', + 'Image::ExifTool::Jpeg2000::ImageHeader' => 'Jpeg2000 – Заголовок изображениÑ', + 'Image::ExifTool::MPEG::Audio' => 'MPEG аудио', + 'Image::ExifTool::MPEG::Video' => 'MPEG видео', + 'Image::ExifTool::Microsoft::MP' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ Microsoft Photo', + 'Image::ExifTool::PDF::Encrypt' => 'PDF зашифрован', + 'Image::ExifTool::PDF::Info' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ PDF-файле', + 'Image::ExifTool::PDF::Pages' => 'Страниц в PDF', + 'Image::ExifTool::PDF::Root' => 'ОÑновные параметры PDF', + 'Image::ExifTool::PDF::Signature' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ PDF', + 'Image::ExifTool::PDF::TransformParams' => 'Параметры Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ PDF-файла', + 'Image::ExifTool::PNG::ImageHeader' => 'Заголовки PNG-изображениÑ', + 'Image::ExifTool::PNG::PrimaryChromaticities' => 'ОÑновные цвета PNG', + 'Image::ExifTool::PNG::StereoImage' => 'Стереоизображние PNG', + 'Image::ExifTool::PSP::Creator' => 'Создатель PSP', + 'Image::ExifTool::PSP::Image' => 'Изображение PSP', + 'Image::ExifTool::PhaseOne::SensorCalibration' => 'PhaseOne – ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора', + 'Image::ExifTool::PhotoMechanic::SoftEdit' => 'PhotoMechanic', + 'Image::ExifTool::Photoshop::Header' => 'Заголовок Photoshop', + 'Image::ExifTool::Photoshop::JPEG_Quality' => 'КачеÑтво JPEG в Photoshop', + 'Image::ExifTool::Photoshop::Layers' => 'Слои Photoshop', + 'Image::ExifTool::Photoshop::PrintScaleInfo' => 'Photoshop – МаÑштабирование при печати', + 'Image::ExifTool::Photoshop::Resolution' => 'Photoshop – Разрешение', + 'Image::ExifTool::PrintIM::Main' => 'Print Image Matching (PrintIM)', + 'Image::ExifTool::RTF::Main' => 'RTF', + 'Image::ExifTool::Rawzor::Main' => 'Rawzor', + 'Image::ExifTool::Real::Metadata' => 'Метаданные Real', + 'Image::ExifTool::Real::Metafile' => 'Метафайл Real', + 'Image::ExifTool::Real::Properties' => 'СвойÑтва Real', + 'Image::ExifTool::Sanyo::Thumbnail' => 'Миниатюра Sanyo', + 'Image::ExifTool::Stim::CropX' => 'Stim – Обрезка по X', + 'Image::ExifTool::Stim::CropY' => 'Stim – Обрезка по Y', + 'Image::ExifTool::Theora::Identification' => 'Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Theora', + 'Image::ExifTool::Torrent::Files' => 'Торрент-файлы', + 'Image::ExifTool::Torrent::Info' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ торренте', + 'Image::ExifTool::Torrent::Main' => 'Торрент', + 'Image::ExifTool::Torrent::Profiles' => 'Торрент профили', + 'Image::ExifTool::Vorbis::Comments' => 'Комментарии Vorbis', + 'Image::ExifTool::Vorbis::Identification' => 'Идентификатор Vorbis', + 'Image::ExifTool::ZIP::GZIP' => 'ZIP GZIP', + 'Image::ExifTool::ZIP::Main' => 'ZIP', + 'Image::ExifTool::ZIP::RAR' => 'ZIP RAR', + 'ImageAlterationConstraints' => { + Description => 'Ограничение на редактирование', + PrintConv => { + 'No Colorization' => 'Ðе раÑкрашивать', + 'No Cropping' => 'Ðе кадрировать', + 'No De-Colorization' => 'Ðе обеÑцвечивать', + 'No Flipping' => 'Ðе отражать', + 'No Merging' => 'Ðе объединÑÑ‚ÑŒ', + 'No Retouching' => 'Ðе ретушировать', + }, + }, + 'ImageArrangement' => { + Description => 'РаÑположение Ñтереоизображений', + PrintConv => { + 'Cross View Alignment' => 'ПереÑечное раÑположение', + 'Parallel View Alignment' => 'Параллельное раÑположение', + }, + }, + 'ImageByteCount' => 'Размер Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (байт)', + 'ImageColorIndicator' => { + Description => 'Цвет переднего плана или прозрачноÑти', + PrintConv => { + 'Specified Image Color' => 'Указан', + 'Unspecified Image Color' => 'Ðе указан', + }, + }, + 'ImageColorValue' => 'Значение цвета переднего плана или прозрачноÑти', + 'ImageCreator' => 'Создатель изображеениÑ', + 'ImageCreatorID' => 'PLUS-ID ÑÐ¾Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + 'ImageCreatorImageID' => 'ID Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ñвоенный Ñоздателем', + 'ImageCreatorName' => 'Ð˜Ð¼Ñ ÑÐ¾Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + 'ImageData' => 'Данные изображениÑ', + 'ImageDataDiscard' => { + Description => 'Отброшенные данные изображениÑ', + PrintConv => { + 'Flexbits Discarded' => 'Гибкие биты отброшены', + 'Full Resolution' => 'Полное разрешение', + 'HighPass Frequency Data Discarded' => 'Данные выÑоких чаÑтот отброшены', + 'Highpass and LowPass Frequency Data Discarded' => 'Данные выÑоких и низких чаÑтот отброшены', + }, + }, + 'ImageDepth' => 'Глубина изображениÑ', + 'ImageDescription' => 'ОпиÑание изображениÑ', + 'ImageDuplicationConstraints' => { + Description => 'Ограничение на дублирование', + PrintConv => { + 'Duplication Only as Necessary Under License' => 'Дублировать только при необходимоÑти в ÑоответÑтвии Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸ÐµÐ¹', + 'No Duplication' => 'Дублирование запрещено', + 'No Duplication Constraints' => 'ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° дублирование отÑутÑтвуют', + }, + }, + 'ImageElements' => 'Элементы изображениÑ', + 'ImageFileConstraints' => { + Description => 'ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° файл', + PrintConv => { + 'Maintain File Name' => 'ЗапрещаетÑÑ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ðµ файла', + 'Maintain File Type' => 'ЗапрещаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ тип файла', + 'Maintain ID in File Name' => 'ЗапрещаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑÑ‚ÑŒ ID в имени файла', + 'Maintain Metadata' => 'ЗапрещаетÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ðµ метаданных', + }, + }, + 'ImageFileFormatAsDelivered' => { + Description => 'ИÑходный формат файла', + PrintConv => { + 'Other' => 'Другой формат', + }, + }, + 'ImageFileName' => 'Ðазвание файла изображениÑ', + 'ImageFileSizeAsDelivered' => { + Description => 'ИÑходный размер файла', + PrintConv => { + 'Greater than 50 MB' => 'Более 50 МБ', + 'Up to 1 MB' => 'До 1 МБ', + 'Up to 10 MB' => 'До 10 МБ', + 'Up to 30 MB' => 'До 30 МБ', + 'Up to 50 MB' => 'До 50 МБ', + }, + }, + 'ImageFullHeight' => 'ÐŸÐ¾Ð»Ð½Ð°Ñ Ð²Ñ‹Ñота изображениÑ', + 'ImageFullWidth' => 'ÐŸÐ¾Ð»Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° изображениÑ', + 'ImageHeight' => 'Ð’Ñ‹Ñота изображениÑ', + 'ImageHistory' => 'ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + 'ImageID' => 'ID изображениÑ', + 'ImageLayer' => 'Слой изображениÑ', + 'ImageLength' => 'Строк в изображении', + 'ImageLimitExposureBias' => 'Лимит поправки ÑкÑпозиции', + 'ImageMimeType' => 'MIME-тип изображениÑ', + 'ImageModulationExposureBias' => 'МодулÑÑ†Ð¸Ñ Ð¿Ð¾Ð¿Ñ€Ð°Ð²ÐºÐ¸ ÑкÑпозиции', + 'ImageNumber' => 'Ðомер изображениÑ', + 'ImageOffset' => 'Смещение изображениÑ', + 'ImageOrientation' => { + Description => 'ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + PrintConv => { + 'Landscape' => 'ÐльбомнаÑ', + 'Portrait' => 'ПортретнаÑ', + 'Square' => 'КвадратнаÑ', + }, + }, + 'ImageRank' => 'Рейтинг изображениÑ', + 'ImageReadyDataSets' => 'Ðаборы данных', + 'ImageReadyVariables' => 'Переменные', + 'ImageReferencePoints' => 'Опорные точки изображениÑ', + 'ImageResolution' => 'Разрешение изображениÑ', + 'ImageRotation' => { + Description => 'Поворот/Ð ÐµÐ²ÐµÑ€Ñ Ñ‚Ð¾Ñ‡ÐµÐº проÑмотра изображениÑ', + PrintConv => { + 'None' => 'Ðет', + }, + }, + 'ImageSensorGain' => 'КоÑффициент уÑÐ¸Ð»ÐµÐ½Ð¸Ñ Ð´Ð°Ñ‚Ñ‡Ð¸ÐºÐ° изображениÑ', + 'ImageSize' => 'Размер изображениÑ', + 'ImageSourceData' => 'ИÑходные данные изображениÑ', + 'ImageStabilization' => { + PrintConv => { + 'CCD Shift' => 'ОптичеÑкий Ñтабилизатор', + 'High Sensitivity' => 'Движение объекта Ñъёмки', + 'Off' => 'Выкл', + 'Off (1)' => 'Выкл (1)', + }, + }, + 'ImageSupplier' => 'ПоÑтавщик изображениÑ', + 'ImageSupplierID' => 'PLUS-ID поÑтавщика изображениÑ', + 'ImageSupplierImageID' => 'ID Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ñвоенный поÑтавщиком', + 'ImageSupplierName' => 'Ð˜Ð¼Ñ Ð¿Ð¾Ñтавщика изображениÑ', + 'ImageToolbar' => 'Панель команд Ð´Ð»Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', + 'ImageType' => { + Description => 'Тип изображениÑ', + PrintConv => { + 'Grayscale (interlaced)' => 'Ð“Ñ€Ð°Ð´Ð°Ñ†Ð¸Ñ Ñерого (череÑÑтрочнаÑ)', + 'Grayscale (non-interlaced)' => 'Ð“Ñ€Ð°Ð´Ð°Ñ†Ð¸Ñ Ñерого (без чередованиÑ)', + 'Grayscale Animation (interlaced)' => 'ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð² градациÑÑ… Ñерого (череÑÑтрочнаÑ)', + 'Grayscale Animation (non-interlaced)' => 'ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ Ð² градациÑÑ… Ñерого (без чередованиÑ)', + 'Illustrated Image' => 'ГрафичеÑкое изображение', + 'Multimedia or Composited Image' => 'Мультимедийное или композитное изображение', + 'Other' => 'Другой тип', + 'Page' => 'Страница', + 'Photographic Image' => 'ФотографиÑ', + 'Preview' => 'ПредпроÑмотр', + 'RGB (interlaced)' => 'RGB (череÑÑтрочнаÑ)', + 'RGB (non-interlaced)' => 'RGB (без чередованиÑ)', + 'RGB Animation (interlaced)' => 'ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ RGB (череÑÑтрочнаÑ)', + 'RGB Animation (non-interlaced)' => 'ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ RGB (без чередованиÑ)', + 'RGBA (interlaced)' => 'RGBA (череÑÑтрочнаÑ)', + 'RGBA (non-interlaced)' => 'RGBA (без чередованиÑ)', + 'RGBA Animation (interlaced)' => 'ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ RGBA (череÑÑтрочнаÑ)', + 'RGBA Animation (non-interlaced)' => 'ÐÐ½Ð¸Ð¼Ð°Ñ†Ð¸Ñ RGBA (без чередованиÑ)', + 'Video' => 'Видео', + }, + }, + 'ImageUIDList' => 'СпиÑок уникальных ID изображений', + 'ImageUniqueID' => 'Уникальный ID изображениÑ', + 'ImageWidth' => 'Ширина изображениÑ', + 'Importance' => { + Description => 'ВажноÑÑ‚ÑŒ', + PrintConv => { + 'High' => 'Ð’Ñ‹ÑокаÑ', + 'Low' => 'ÐизкаÑ', + 'Normal' => 'ОбычнаÑ', + }, + }, + 'Imprint' => 'ИздательÑтво', + 'InclinationAngle' => 'Угол наклона', + 'InclinationCorrection' => { + Description => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð°ÐºÐ»Ð¾Ð½Ð°', + PrintConv => { + 'Off' => 'Ðе включена', + 'On' => 'Включена', + }, + }, + 'IncludedFileID' => 'ID вÑтроенного файла', + 'Index' => 'ИндекÑ', + 'IndexOffset' => 'Ð˜Ð½Ð´ÐµÐºÑ ÑмещениÑ', + 'Indexable' => { + Description => 'ИндекÑированный', + PrintConv => { + 'False' => 'Ðет', + 'True' => 'Да', + }, + }, + 'Indexed' => { + Description => 'ИндекÑированный', + PrintConv => { + 'Indexed' => 'Да', + 'Not indexed' => 'Ðет', + }, + }, + 'IndexedColorTableCount' => 'КоличеÑтво индекÑированных цветов', + 'InfraredIlluminator' => { + Description => 'ИнфракраÑÐ½Ð°Ñ Ð¿Ð¾Ð´Ñветка', + PrintConv => { + 'Off' => 'Ðе включена', + 'On' => 'Включена', + }, + }, + 'InitialCameraDolly' => 'ИÑходное положение вдоль линии взглÑда', + 'InitialDisplayEffect' => { + Description => 'Ðачальный Ñффект отображениÑ', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'InitialHorizontalFOVDegrees' => 'ИÑходное горизонтальное поле Ð·Ñ€ÐµÐ½Ð¸Ñ (°)', + 'InitialViewHeadingDegrees' => 'КурÑовой угол Ð´Ð»Ñ Ð¸Ñходного предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ (°)', + 'InitialViewPitchDegrees' => 'Угол продольного наклона Ð´Ð»Ñ Ð¸Ñходного предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ (°)', + 'InitialViewRollDegrees' => 'Угол поперечного наклона Ð´Ð»Ñ Ð¸Ñходного предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð¸Ñ (°)', + 'InkNames' => 'ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‡ÐµÑ€Ð½Ð¸Ð»', + 'InkSet' => { + Description => 'Ðабор чернил', + PrintConv => { + 'Not CMYK' => 'Ðе CMYK', + }, + }, + 'InputDeviceName' => 'Ðазвание уÑтройÑтва ввода', + 'InputDeviceSerialNumber' => 'Серийный номер уÑтройÑтва ввода', + 'InsertMode' => 'Режим вÑтавки', + 'InstanceType' => { + Description => 'Тип ÑобытиÑ', + PrintConv => { + 'Exception to Recurring Appointment' => 'ИÑключение Ð´Ð»Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÑющегоÑÑ ÑобытиÑ', + 'Non-recurring Appointment' => 'ÐеповторÑющиеÑÑ Ñобытие', + 'Recurring Appointment' => 'ПовторÑющиеÑÑ Ñобытие', + 'Single Instance of Recurring Appointment' => 'Событие Ñ ÐµÐ´Ð¸Ð½Ð¾ÐºÑ€Ð°Ñ‚Ð½Ñ‹Ð¼ повторением', + }, + }, + 'Institution' => 'ИнÑтитут', + 'InstructionSet' => 'Ðабор инÑтрукций', + 'Instructions' => 'ИнÑтрукции', + 'Instrument' => 'ИнÑтрумент', + 'IntendedBusyStatus' => 'Предполагаемый ÑÑ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð½ÑтоÑти', + 'IntensityStereo' => 'ИнтенÑивное Ñтерео', + 'InterchangeColorSpace' => { + Description => 'Смена цветового проÑтранÑтва', + PrintConv => { + 'CMY (K) Device Dependent' => 'Ðппаратно-завиÑимый CMY (K)', + 'RGB Device Dependent' => 'Ðппаратно-завиÑимый RGB', + }, + }, + 'IntergraphFlagRegisters' => 'Intergraph – Флаг региÑтров', + 'IntergraphMatrix' => 'Intergraph – Матрица', + 'IntergraphPacketData' => 'Intergraph – Данные пакета', + 'Interlace' => { + Description => 'ЧереÑÑÑ‚Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ñ€Ð°Ð·Ð²Ñ‘Ñ€Ñ‚ÐºÐ°', + PrintConv => { + 'Adam7 Interlace' => 'ЧереÑÑÑ‚Ñ€Ð¾Ñ‡Ð½Ð°Ñ Adam7', + 'Noninterlaced' => 'ПрогреÑÑивнаÑ', + }, + }, + 'InternalIDNumber' => 'Внутренний ID-номер', + 'InternalLeading' => 'Внутренний зазор', + 'InternalVersionNumber' => 'ВнутреннÑÑ Ð²ÐµÑ€ÑÐ¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'InteropIndex' => { + Description => 'Ð˜Ð½Ð´ÐµÐºÑ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¾Ð¹ ÑовмеÑтимоÑти', + PrintConv => { + 'R03 - DCF option file (Adobe RGB)' => 'R03 – Дополнительный файл DCF (Adobe RGB)', + 'R98 - DCF basic file (sRGB)' => 'R98 – ОÑновной файл DCF (sRGB)', + 'THM - DCF thumbnail file' => 'THM – Файл Ñ Ð¼Ð¸Ð½Ð¸Ð°Ñ‚ÑŽÑ€Ð°Ð¼Ð¸ DCF', + }, + }, + 'InteropOffset' => 'Тег взаимной ÑовмеÑтимоÑти', + 'InteropVersion' => 'ВерÑÐ¸Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¾Ð¹ ÑовмеÑтимоÑти', + 'IsBaseFont' => 'Базовый шрифт', + 'IsFixedPitch' => 'Моноширинный шрифт', + 'IsMergedHDR' => 'Объединённый HDR', + 'IsMergedPanorama' => 'ÐžÐ±ÑŠÐµÐ´Ð¸Ð½Ñ‘Ð½Ð½Ð°Ñ Ð¿Ð°Ð½Ð¾Ñ€Ð°Ð¼Ð°', + 'Italic' => 'КурÑив', + 'ItalicAngle' => 'Угол наклона шрифта', + 'ItemSubType' => 'Подтип Ñлемента', + 'Iterations' => 'Повторов', + 'JBIGOptions' => 'Параметры JBIG', + 'JFIFVersion' => 'ВерÑÐ¸Ñ JFIF', + 'JP2Signature' => 'JP2 ПодпиÑÑŒ', + 'JPEGACTables' => 'Таблицы JPEGAC', + 'JPEGDCTables' => 'Таблицы JPEGDC', + 'JPEGDigest' => 'JPEG – Хеш-Ñумма', + 'JPEGImageLength' => 'JPEG – Строк в изображении', + 'JPEGLosslessPredictors' => 'Ð—Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¸ÐºÑ‚Ð¾Ñ€Ð° JPEG без потерь', + 'JPEGPointTransforms' => 'Преобразование точек JPEG', + 'JPEGProc' => { + Description => 'JPEG-Ñжатие в Ñтаром Ñтиле', + PrintConv => { + 'Baseline' => 'Базовое поÑледовательное', + 'Lossless' => 'Без потерь Ñ ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸ÐµÐ¼ Хаффмана', + }, + }, + 'JPEGQTables' => 'Таблицы JPEGQ', + 'JPEGQuality' => { + Description => 'КачеÑтво изображениÑ', + PrintConv => { + 'Extra Fine' => 'СверхвыÑокое', + 'Fine' => 'Ð’Ñ‹Ñокое', + 'Standard' => 'Стандартное качеÑтво', + }, + }, + 'JPEGQualityEstimate' => 'JPEG – Оценка качеÑтва', + 'JPEGRestartInterval' => 'Интервал перезапуÑка JPEG', + 'JPEGTables' => 'JPEG-таблицы', + 'JSONMetadata' => 'Метаданные JSON', + 'JobID' => 'ID заданиÑ', + 'JobTitle' => 'ДолжноÑÑ‚ÑŒ', + 'Journal' => 'Журнал', + 'JpgFromRaw' => 'Jpg-файл, вÑтроенный в Raw-файл', + 'JpgFromRawLength' => 'Строк в JPG-файле, вÑтроенного в RAW-файл', + 'JpgFromRawStart' => 'Смещение JPG-файла, вÑтроенного в RAW-файл', + 'JumpToXPEP' => 'Переход к XPEP', + 'KBAT_Unknown10' => 'KBAT – ÐеизвеÑтный 10', + 'KBAT_Unknown11' => 'KBAT – ÐеизвеÑтный 11', + 'KBAT_Unknown12' => 'KBAT – ÐеизвеÑтный 12', + 'KBAT_Unknown13' => 'KBAT – ÐеизвеÑтный 13', + 'KBAT_Unknown2' => 'KBAT – ÐеизвеÑтный 2', + 'KBAT_Unknown9' => 'KBAT – ÐеизвеÑтный 9', + 'KByteSize' => 'Общий размер в килобайтах', + 'KF8CoverURI' => 'KF8 – URI обложки', + 'Key' => 'Код', + 'KeyCode' => 'Код ключа', + 'KeyFramePositions' => 'Положение ключевых кадров', + 'KeyFramesTimes' => 'Ð’Ñ€ÐµÐ¼Ñ ÐºÐ»ÑŽÑ‡ÐµÐ²Ñ‹Ñ… кадров', + 'KeywordInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ ключевых Ñловах', + 'Keywords' => 'Ключевые Ñлова', + 'Label' => 'Метка', + 'LameBitrate' => 'Lame – Битрейт', + 'LameLowPassFilter' => 'Lame – Фильтр нижних чаÑтот', + 'LameMethod' => { + Description => 'Lame – Метод кодированиÑ', + PrintConv => { + 'ABR' => 'ABR – Средний битрейт', + 'ABR (2-pass)' => 'ABR – Средний битрейт (2 прохода)', + 'CBR' => 'CBR – ПоÑтоÑнный битрейт', + 'CBR (2-pass)' => 'CBR – ПоÑтоÑнный битрейт (2 прохода)', + 'VBR' => 'VBR – переменный битрейт', + 'VBR (new/mtrh)' => 'VBR – переменный битрейт (новый/mtrh)', + 'VBR (old/rh)' => 'VBR – переменный битрейт (Ñтарый/rh)', + }, + }, + 'LameQuality' => 'Lame – КачеÑтво', + 'LameStereoMode' => { + Description => 'Lame – Режим Ñтерео', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкий', + 'Dual Channels' => 'Двуканальный режим', + 'Forced Joint Stereo' => 'Принудительное объединённое Ñтерео', + 'Intensity Stereo' => 'ИнтенÑивное Ñтерео', + 'Joint Stereo' => 'Объединённое Ñтерео', + 'Mono' => 'Моно', + 'Stereo' => 'Стерео', + }, + }, + 'LameVBRQuality' => 'Lame – КачеÑтво переменного битрейта', + 'Language' => 'Язык', + 'LanguageIdentifier' => 'Идентификатор Ñзыка', + 'LargestValidInteriorRectHeight' => 'МакÑимально Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð°Ñ Ð²Ñ‹Ñота прÑмоугольника', + 'LargestValidInteriorRectLeft' => 'ОтÑтуп Ñлева Ð´Ð»Ñ Ð¼Ð°ÐºÑимально возможного прÑмоугольника', + 'LargestValidInteriorRectTop' => 'ОтÑтуп Ñверху Ð´Ð»Ñ Ð¼Ð°ÐºÑимально возможного прÑмоугольника', + 'LargestValidInteriorRectWidth' => 'МакÑимально Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° прÑмоугольника', + 'LastAuthor' => 'ПоÑледнее редактирование Ñделал', + 'LastBackupDate' => 'Дата поÑледнего резервного копированиÑ', + 'LastChar' => 'ПоÑледний Ñимвол шрифта', + 'LastKeyFrameTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего ключевого кадра', + 'LastKeywordIPTC' => 'ПоÑледнее ключевое Ñлово IPTC', + 'LastKeywordXMP' => 'ПоÑледнее ключевое Ñлово XMP', + 'LastModifiedBy' => 'ПоÑледнее изменение Ñделал', + 'LastPhotoDate' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ñледнего изображениÑ', + 'LastPrinted' => 'Дата поÑледней печати', + 'LastTimeStamp' => 'ПоÑледнÑÑ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð½Ð°ÌÑ Ð¼ÐµÑ‚ÐºÐ°', + 'LastUpdateTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ñледнего обновлениÑ', + 'LateralChromaticAberrationCorrectionAlreadyApplied' => 'Применена ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ñ…Ñ€Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑкой аберрации', + 'LatestAgeOrHighestStage' => 'ПоÑледний век/Ð’Ñ‹Ñший ÑруÑ', + 'LatestEonOrHighestEonothem' => 'ПоÑледний Ñон/Ð’Ñ‹ÑÑˆÐ°Ñ Ñонотема', + 'LatestEpochOrHighestSeries' => 'ПоÑледнÑÑ Ñпоха/Ð’Ñ‹Ñший отдел', + 'LatestEraOrHighestErathem' => 'ПоÑледнÑÑ Ñра/Ð’Ñ‹ÑÑˆÐ°Ñ Ñратема', + 'LatestPeriodOrHighestSystem' => 'ПоÑледний период/Ð’Ñ‹ÑÑˆÐ°Ñ ÑиÑтема', + 'Latitude' => 'Широта', + 'LayerBlendModes' => { + Description => 'Режим Ð½Ð°Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ñлоёв', + PrintConv => { + 'Color' => 'ЦветноÑÑ‚ÑŒ', + 'Color Burn' => 'Затемнение оÑновы', + 'Color Dodge' => 'ОÑветление оÑновы', + 'Darken' => 'Затемнение', + 'Darker Color' => 'Темнее', + 'Difference' => 'Разница', + 'Dissolve' => 'Затухание', + 'Divide' => 'Разделить', + 'Exclusion' => 'ИÑключение', + 'Hard Light' => 'ЖёÑткий Ñвет', + 'Hard Mix' => 'ЖёÑткое Ñмешение', + 'Hue' => 'Цветовой тон', + 'Lighten' => 'Замена Ñветлым', + 'Lighter Color' => 'Светлее', + 'Linear Burn' => 'Линейный затемнитель', + 'Linear Dodge' => 'Линейный оÑветлитель', + 'Linear Light' => 'Линейный Ñвет', + 'Luminosity' => 'ЯркоÑÑ‚ÑŒ', + 'Multiply' => 'Умножение', + 'Normal' => 'Обычный', + 'Overlay' => 'Перекрытие', + 'Pass Through' => 'ПропуÑтить', + 'Pin Light' => 'Точечный Ñвет', + 'Saturation' => 'ÐаÑыщенноÑÑ‚ÑŒ', + 'Screen' => 'Экран', + 'Soft Light' => 'ÐœÑгкий Ñвет', + 'Subtract' => 'Вычитание', + 'Vivid Light' => 'Яркий Ñвет', + }, + }, + 'LayerComps' => 'Композиции Ñлоёв', + 'LayerCount' => 'КоличеÑтво Ñлоёв', + 'LayerGroupsEnabledID' => 'ID включенных групп Ñлоёв', + 'LayerIDs' => 'ID Ñлоёв', + 'LayerModifyDates' => 'Дата Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑлоÑ', + 'LayerNames' => 'ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ñлоёв', + 'LayerOpacities' => 'ÐепрозрачноÑÑ‚ÑŒ ÑлоÑ', + 'LayerRectangles' => 'ПрÑмоугольники ÑлоÑ', + 'LayerSelectionIDs' => 'Идентификаторы выборанного ÑлоÑ', + 'LayerUnicodeNames' => 'Юникодные Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñлоёв', + 'LayersGroupInfo' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ группе Ñлоёв', + 'Layout' => { + Description => 'Макет', + PrintConv => { + 'Scan Lines' => 'Линии ÑканированиÑ', + 'Tiles' => 'Тайлы', + }, + }, + 'LeftMargin' => 'ОтÑтуп Ñлева', + 'LegacyIPTCDigest' => 'Хеш-Ñумма прежней верÑии IPTC', + 'Length' => 'Общий размер в байтах', + 'Lens' => 'Объектив', + 'Lens35efl' => 'Объектив', + 'LensDistortInfo' => 'ДиÑторÑÐ¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¸Ð²Ð°', + 'LensID' => 'ID объектива', + 'LensInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± объективе', + 'LensMake' => 'Производитель объектива', + 'LensManufacturer' => 'Производитель объектива', + 'LensModel' => 'Модель объектива', + 'LensNumber' => 'Серийный номер объектива', + 'LensSerialNumber' => 'Серийный номер объектива', + 'LensShading' => 'Виньетирование объектива', + 'LensSpec' => 'Параметры объектива', + 'LensTemperature' => 'Температура объектива', + 'LibraryID' => 'ID библиотеки', + 'License' => 'ЛицензиÑ', + 'LicenseEndDate' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ð¸', + 'LicenseID' => 'PLUS-ID лицензии', + 'LicenseInfoURL' => 'URL лицензии', + 'LicenseStartDate' => 'Дата вÑÑ‚ÑƒÐ¿Ð»ÐµÐ½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ð¸ в Ñилу', + 'LicenseTransactionDate' => 'Дата лицензионной Ñделки', + 'Licensee' => 'Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¾Ñтавлена длÑ', + 'LicenseeID' => 'PLUS-ID лицензиата', + 'LicenseeImageID' => 'ID Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ñвоенный лицензиатом', + 'LicenseeImageNotes' => 'ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ð°Ñ‚Ð°', + 'LicenseeName' => 'Ð˜Ð¼Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ð°Ñ‚Ð°', + 'LicenseeProjectReference' => 'Ðазвание проека приÑвоенное лицензиатом', + 'LicenseeTransactionID' => 'ID транзакции приÑвоенное лицензиатом', + 'Licensor' => 'Лицензор', + 'LicensorCity' => 'Город Ð¿Ñ€Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¾Ñ€Ð°', + 'LicensorCountry' => 'Страна Ð¿Ñ€Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¾Ñ€Ð°', + 'LicensorEmail' => 'ÐÐ´Ñ€ÐµÑ Ñлектронной почты лицензора', + 'LicensorExtendedAddress' => 'Дополнительные адреÑа Ñлектронной почты лицензора', + 'LicensorID' => 'PLUS-ID лицензора', + 'LicensorImageID' => 'ID Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð°Ð½Ð½Ð¾Ðµ лицензором', + 'LicensorName' => 'Ð˜Ð¼Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¾Ñ€Ð°', + 'LicensorNotes' => 'Коментарии лицензора', + 'LicensorPostalCode' => 'Почтовый Ð¸Ð½Ð´ÐµÐºÑ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¸Ð°Ñ€Ð°', + 'LicensorRegion' => 'ОблаÑÑ‚ÑŒ Ð¿Ñ€Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¾Ñ€Ð°', + 'LicensorStreetAddress' => 'Улица Ð¿Ñ€Ð¾Ð¶Ð¸Ð²Ð°Ð½Ð¸Ñ Ð»Ð¸Ñ†ÐµÐ½Ð·Ð¾Ñ€Ð°', + 'LicensorTelephone1' => 'Телефон 1 лицензора', + 'LicensorTelephone2' => 'Телефон 2 лицензора', + 'LicensorTelephoneType1' => { + Description => 'Тип телефона 1', + PrintConv => { + 'Cell' => 'Мобильный', + 'FAX' => 'ФÐКС', + 'Home' => 'Домашний', + 'Pager' => 'Пейджер', + 'Work' => 'Рабочий', + }, + }, + 'LicensorTelephoneType2' => { + Description => 'Тип телефона 2', + PrintConv => { + 'Cell' => 'Мобильный', + 'FAX' => 'ФÐКС', + 'Home' => 'Домашний', + 'Pager' => 'Пейджер', + 'Work' => 'Рабочий', + }, + }, + 'LicensorTransactionID' => 'ID транзакции приÑвоенный лицензором', + 'LicensorURL' => 'URL лицензора', + 'LightSource' => { + Description => 'Тип оÑвещениÑ', + PrintConv => { + 'Cloudy' => 'Облачно (6500 К)', + 'Cool White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Холодный Ñвет (4150 К)', + 'Day White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Дневной белый (5050 К)', + 'Daylight' => 'Дневной Ñвет (5500 К)', + 'Daylight Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° дневного Ñвета (6400 К)', + 'Fine Weather' => 'ЯÑÐ½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð° (5500 К)', + 'Flash' => 'Ð’Ñпышка (5500 К)', + 'Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° (4150 К)', + 'ISO Studio Tungsten' => 'ISO Ð´Ð»Ñ Ñтудийных ламп накаливаниÑ', + 'Other' => 'Другой иÑточник Ñвета', + 'Shade' => 'Тень (7500 К)', + 'Standard Light A' => 'Стандартный Ñвет A', + 'Standard Light B' => 'Стандартный Ñвет B', + 'Standard Light C' => 'Стандартный Ñвет C', + 'Tungsten (Incandescent)' => 'Лампа Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (2850 К)', + 'Unknown' => 'ÐеизвеÑтный', + 'Warm White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Тёплый Ñвет (2925 К)', + 'White Fluorescent' => 'ФлуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð° – Белый Ñвет (3525 К)', + }, + }, + 'LightSourceSpecial' => { + Description => 'Специальный иÑточник Ñвета', + PrintConv => { + 'Off' => 'Ðе иÑпользовалÑÑ', + 'On' => 'ИÑпользовалÑÑ', + }, + }, + 'LightValue' => 'Световое чиÑло', + 'Lightness' => 'ОÑвещенноÑÑ‚ÑŒ', + 'LightroomWorkflow' => 'Рабочий процеÑÑ Lightroom', + 'LineOrder' => { + Description => 'ПорÑдок Ñтрок', + PrintConv => { + 'Decreasing Y' => 'По убыванию Y', + 'Increasing Y' => 'По возраÑтанию Y', + 'Random Y' => 'Случайный Y', + }, + }, + 'LinearResponseLimit' => 'Предел линейного отклика', + 'LinearityLimitBlue' => 'Предел линейноÑти – Синий', + 'LinearityLimitGreen' => 'Предел линейноÑти – Зелёный', + 'LinearityLimitRed' => 'Предел линейноÑти – КраÑный', + 'LinearizationCoefficients1' => 'КоÑффициенты линеаризации 1', + 'LinearizationCoefficients2' => 'КоÑффициенты линеаризации 2', + 'LinearizationTable' => 'Таблица линеаризации', + 'Linearized' => { + Description => 'ЛинеаризациÑ', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'Lines' => 'Строк', + 'LinkedProfileName' => 'Ðазвание ÑвÑзанного профилÑ', + 'LithostratigraphicTerms' => 'ЛитоÑтратиграфичеÑкие Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¾Ñ€Ð¾Ð´', + 'LivingSpecimen' => 'Живой образец', + 'LivingSpecimenMaterialSampleID' => 'Живой образец – ID образца материала', + 'LocalBasePath' => 'Локальный базовый путь', + 'LocalCaption' => 'ОпиÑание меÑта', + 'LocalDefaultAlarm' => 'Локальный Ñигнал по-умолчанию', + 'LocalPositionNED' => 'Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ NED', + 'LocalizedCameraModel' => 'Локализованное название модели камеры', + 'Location' => 'МеÑтоположение', + 'Logo' => 'Логотип', + 'LongExposureNoiseReduction' => { + Description => 'Шумоподавление при длительной выдержке', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкое', + 'Off' => 'Ðе включено', + 'On' => 'Включено', + }, + }, + 'Longitude' => 'Долгота', + 'LookModTransform' => 'Преобразование вида ACES-ACES', + 'LookupTable' => 'Таблица подÑтановки', + 'LowestBiostratigraphicZone' => 'ÐÐ¸Ð·ÑˆÐ°Ñ Ð±Ð¸Ð¾ÑтратиграфичеÑÐºÐ°Ñ Ð·Ð¾Ð½Ð°', + 'MD5Signature' => 'MD5', + 'MD5Sum' => 'Сумма MD5', + 'MDColorTable' => 'MD – Таблица цветов', + 'MDFileTag' => 'MD – Формат иÑходных данных', + 'MDFileUnits' => 'MD – Единицы данных файла', + 'MDItemAccountHandles' => 'MD Item – ДеÑкрипторы аккаунта', + 'MDItemAccountIdentifier' => 'MD Item – Идентификатор аккаунта', + 'MDItemAcquisitionMake' => 'MD Item – Производитель уÑтройÑтва', + 'MDItemAcquisitionModel' => 'MD Item – Модель уÑтройÑтва', + 'MDItemAltitude' => 'MD Item – Ð’Ñ‹Ñота', + 'MDItemAperture' => 'MD Item – Диафрагма', + 'MDItemAudioBitRate' => 'MD Item – Битрейт аудио', + 'MDItemAudioChannelCount' => 'MD Item – КоличеÑтво аудиоканалов', + 'MDItemAuthorEmailAddresses' => 'MD Item – ÐÐ´Ñ€ÐµÑ Ñлектронной почты автора', + 'MDItemAuthors' => 'MD Item – Ðвторы', + 'MDItemBitsPerSample' => 'MD Item – КоличеÑтво бит на образец', + 'MDItemBundleIdentifier' => 'MD Item – Идентификатор комплекта', + 'MDItemCity' => 'MD Item – Город', + 'MDItemCodecs' => 'MD Item – Кодеки', + 'MDItemColorSpace' => 'MD Item – Цветовое проÑтранÑтво', + 'MDItemComment' => 'MD Item – Комментарий', + 'MDItemContentCreationDate' => 'MD Item – Дата ÑозданиÑ', + 'MDItemContentCreationDateRanking' => 'MD Item – Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ â€“ Рейтинг', + 'MDItemContentCreationDate_Ranking' => 'MD Item – Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ â€“ Рейтинг', + 'MDItemContentModificationDate' => 'MD Item – Дата редактированиÑ', + 'MDItemContentType' => 'MD Item – Тип контента', + 'MDItemContentTypeTree' => 'MD Item – Тип контента – Древо', + 'MDItemContributors' => 'MD Item – ВнеÑшие вклад', + 'MDItemCopyright' => 'MD Item – ÐвторÑкое право', + 'MDItemCountry' => 'MD Item – Страна', + 'MDItemCreator' => 'MD Item – Создано в', + 'MDItemDateAdded' => 'MD Item – Дата добавлениÑ', + 'MDItemDateAdded_Ranking' => 'MD Item – Дата Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ â€“ Рейтинг', + 'MDItemDescription' => 'MD Item – ОпиÑание', + 'MDItemDisplayName' => 'MD Item – Локализованное название файла', + 'MDItemDownloadedDate' => 'MD Item – Дата загрузки', + 'MDItemDurationSeconds' => 'MD Item – ПродолжительноÑÑ‚ÑŒ в Ñекундах', + 'MDItemEXIFGPSVersion' => 'MD Item – EXIF – ВерÑÐ¸Ñ GPS', + 'MDItemEXIFVersion' => 'MD Item – ВерÑÐ¸Ñ EXIF', + 'MDItemEmailConversationID' => 'MD Item – ID перепиÑки по Ñлектронной почте', + 'MDItemEncodingApplications' => 'MD Item – Кодировано в приложении', + 'MDItemExposureMode' => 'MD Item – Режим ÑкÑпозиции', + 'MDItemExposureProgram' => 'MD Item – Программа ÑкÑпозиции', + 'MDItemExposureTimeSeconds' => 'MD Item – Выдержка', + 'MDItemFNumber' => 'MD Item – Диафрагменное чиÑло', + 'MDItemFSContentChangeDate' => 'MD Item – FS – Дата редактированиÑ', + 'MDItemFSCreationDate' => 'MD Item – FS – Дата ÑозданиÑ', + 'MDItemFSCreatorCode' => 'MD Item – FS – Код программы, Ñоздавшей файл', + 'MDItemFSFinderFlags' => 'MD Item – FS – Ðтрибуты файла', + 'MDItemFSHasCustomIcon' => 'MD Item – FS – Ðаличие иконки файла', + 'MDItemFSInvisible' => 'MD Item – FS – Скрытый', + 'MDItemFSIsExtensionHidden' => 'MD Item – FS – РаÑширение файла Ñкрыто', + 'MDItemFSIsStationery' => 'MD Item – FS – Шаблон', + 'MDItemFSLabel' => { + Description => 'MD Item – FS – Ð¦Ð²ÐµÑ‚Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° файла', + PrintConv => { + '0 (none)' => '0 (Без метки)', + '1 (Gray)' => '1 (СераÑ)', + '2 (Green)' => '2 (ЗелёнаÑ)', + '3 (Purple)' => '3 (ПурпурнаÑ)', + '4 (Blue)' => '4 (СинÑÑ)', + '5 (Yellow)' => '5 (ЖёлтаÑ)', + '6 (Red)' => '6 (КраÑнаÑ)', + '7 (Orange)' => '7 (ОранжеваÑ)', + }, + }, + 'MDItemFSName' => 'MD Item – FS – Ðазвание файла', + 'MDItemFSNodeCount' => 'MD Item – FS – КоличеÑтво файлов в каталоге', + 'MDItemFSOwnerGroupID' => 'MD Item – FS – ID группы владельца файла', + 'MDItemFSOwnerUserID' => 'MD Item – FS – ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð° файла', + 'MDItemFSSize' => 'MD Item – FS – Размер файла', + 'MDItemFSTypeCode' => 'MD Item – FS – Код типа файла', + 'MDItemFinderComment' => 'MD Item – Комментарий к файлу', + 'MDItemFlashOnOff' => 'MD Item – Срабатывание вÑпышки', + 'MDItemFocalLength' => 'MD Item – ФокуÑное раÑÑтоÑние', + 'MDItemGPSDateStamp' => 'MD Item – GPS – Дата и Ð²Ñ€ÐµÐ¼Ñ Ð¼ÐµÑтоположениÑ', + 'MDItemGPSStatus' => 'MD Item – GPS – СоÑтоÑние приемника во Ð²Ñ€ÐµÐ¼Ñ Ñъёмки', + 'MDItemGPSTrack' => 'MD Item – GPS – Трек маршрута', + 'MDItemHasAlphaChannel' => 'MD Item – Ðаличие Ðльфа-канала', + 'MDItemISOSpeed' => 'MD Item – ISO', + 'MDItemIdentifier' => 'MD Item – Идентификатор', + 'MDItemImageDirection' => 'MD Item – ÐÐ°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÐºÐ°Ð¼ÐµÑ€Ñ‹ при Ñъёмке', + 'MDItemInterestingDateRanking' => 'MD Item – Дата интереÑных меÑÑ‚ – Рейтинг', + 'MDItemInterestingDate_Ranking' => 'MD Item – Дата интереÑных меÑÑ‚ – Рейтинг', + 'MDItemIsApplicationManaged' => 'MD Item – УправлÑетÑÑ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼', + 'MDItemIsExistingThread' => 'MD Item – Цепочка Ñообщений', + 'MDItemIsLikelyJunk' => 'MD Item – Спам', + 'MDItemKeywords' => 'MD Item – Ключевые Ñлова', + 'MDItemKind' => 'MD Item – Тип файла', + 'MDItemLastUsedDate' => 'MD Item – Дата поÑледнего иÑпользованиÑ', + 'MDItemLastUsedDate_Ranking' => 'MD Item – Дата поÑледнего иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ â€“ Рейтинг', + 'MDItemLatitude' => 'MD Item – Широта', + 'MDItemLensModel' => 'MD Item – Модель объектива', + 'MDItemLogicalSize' => 'MD Item – ЛогичеÑкий размер', + 'MDItemLongitude' => 'MD Item – Долгота', + 'MDItemMailDateReceived_Ranking' => 'MD Item – Дата Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð¾Ñ‡Ñ‚Ñ‹ – Рейтинг', + 'MDItemMailboxes' => 'MD Item – Почтовые Ñщики', + 'MDItemMediaTypes' => 'MD Item – Типы медиафайлов', + 'MDItemNumberOfPages' => 'MD Item – КоличеÑтво Ñтраниц', + 'MDItemOrientation' => 'MD Item – ОриентациÑ', + 'MDItemOriginApplicationIdentifier' => 'MD Item – Идентификатор приложениÑ', + 'MDItemOriginMessageID' => 'MD Item – ID ÑообщениÑ', + 'MDItemOriginSenderDisplayName' => 'MD Item – Ð˜Ð¼Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð¸Ñ‚ÐµÐ»Ñ', + 'MDItemOriginSenderHandle' => 'MD Item – ДеÑкриптор отправителÑ', + 'MDItemOriginSubject' => 'MD Item – Тема ÑообщениÑ', + 'MDItemPageHeight' => 'MD Item – Ð’Ñ‹Ñота Ñтраницы', + 'MDItemPageWidth' => 'MD Item – Ширина Ñтраницы', + 'MDItemPhysicalSize' => 'MD Item – ФизичеÑкий размер', + 'MDItemPixelCount' => 'MD Item – КоличеÑтво пикÑелей', + 'MDItemPixelHeight' => 'MD Item – Ð’Ñ‹Ñота в пикÑелÑÑ…', + 'MDItemPixelWidth' => 'MD Item – Ширина в пикÑелÑÑ…', + 'MDItemPrimaryRecipientEmailAddresses' => 'MD Item – ÐÐ´Ñ€ÐµÑ Ñлектронной почты оÑновного получателÑ', + 'MDItemProfileName' => 'MD Item – Ðазвание цветового профилÑ', + 'MDItemRecipients' => 'MD Item – Получатели', + 'MDItemRedEyeOnOff' => 'MD Item – Уменьшение Ñффекта "краÑных глаз"', + 'MDItemResolutionHeightDPI' => 'MD Item – Разрешение по выÑоте в DPI', + 'MDItemResolutionWidthDPI' => 'MD Item – Разрешение по ширине в DPI', + 'MDItemSecurityMethod' => 'MD Item – Метод шифрованиÑ', + 'MDItemSpeed' => 'MD Item – СкороÑÑ‚ÑŒ передвижениÑ', + 'MDItemStateOrProvince' => 'MD Item – ОблаÑÑ‚ÑŒ/Район', + 'MDItemStreamable' => 'MD Item – Потоковый', + 'MDItemSubject' => 'MD Item – Тема', + 'MDItemTimestamp' => 'MD Item – ВременнаÌÑ Ð¼ÐµÑ‚ÐºÐ°', + 'MDItemTitle' => 'MD Item – Ðазвание файла', + 'MDItemTotalBitRate' => 'MD Item – Общий битрейт', + 'MDItemUseCount' => 'MD Item – Счётчик иÑпользованиÑ', + 'MDItemUsedDates' => 'MD Item – ИÑпользуемые даты', + 'MDItemUserDownloadedDate' => 'MD Item – Пользователь – Дата загрузки', + 'MDItemUserDownloadedUserHandle' => 'MD Item – Пользователь – ДеÑкриптор загрузки пользователÑ', + 'MDItemUserSharedReceivedDate' => 'MD Item – User Shared Received Date', + 'MDItemUserSharedReceivedRecipient' => 'MD Item – User Shared Received Recipient', + 'MDItemUserSharedReceivedRecipientHandle' => 'MD Item – User Shared Received Recipient Handle', + 'MDItemUserSharedReceivedSender' => 'MD Item – User Shared Received Sender', + 'MDItemUserSharedReceivedSenderHandle' => 'MD Item – User Shared Received Sender Handle', + 'MDItemUserSharedReceivedTransport' => 'MD Item – ÐžÐ±Ñ‰Ð°Ñ Ð¿Ð°Ð¿ÐºÐ° Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ â€“ Received Transport', + 'MDItemUserTags' => 'MD Item – ПользовательÑкие теги', + 'MDItemVersion' => 'MD Item – ВерÑÐ¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'MDItemVideoBitRate' => 'MD Item – Битрейт видео', + 'MDItemWhereFroms' => 'MD Item – ИÑточник файла', + 'MDItemWhiteBalance' => 'MD Item – Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾', + 'MDLabName' => 'MD – Создатель файла', + 'MDPrepDate' => 'MD – Дата ÑозданиÑ', + 'MDPrepTime' => 'MD – Ð’Ñ€ÐµÐ¼Ñ ÑозданиÑ', + 'MDSampleInfo' => 'MD – ОпиÑание файла', + 'MDScalePixel' => 'MD – Коефициент маÑÑˆÑ‚Ð°Ð±Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ð¸ÐºÑелÑ', + 'MIDIControlVersion' => 'ВерÑÐ¸Ñ MIDI Control', + 'MIDISong' => 'MIDI композициÑ', + 'MIMEType' => 'MIME тип', + 'MOIVersion' => 'ВерÑÐ¸Ñ MOI', + 'MPEG7Binary' => 'Бинарный MPEG7', + 'MPEGAudioVersion' => 'ВерÑÐ¸Ñ MPEG аудио', + 'MPFVersion' => 'ВерÑÐ¸Ñ MPF', + 'MPImage' => 'Изображение MP', + 'MPImageFlags' => { + Description => 'MP изображение – Флаги', + PrintConv => { + 'Dependent child image' => 'ЗавиÑимое вложенное изображение', + 'Dependent parent image' => 'ЗавиÑимое родительÑкое изображение', + 'Representative image' => 'Репрезентативное изображение', + }, + }, + 'MPImageFormat' => 'MP изображение – Формат', + 'MPImageLength' => 'MP изображение – КоличеÑтво Ñтрок', + 'MPImageStart' => 'MP изображение – Ðачало', + 'MPImageType' => { + Description => 'MP изображение – Тип', + PrintConv => { + 'Baseline MP Primary Image' => 'Базовое первичное изображение MP', + 'Large Thumbnail (VGA equivalent)' => 'Большой ÑÑкиз (Ñквивалент VGA)', + 'Large Thumbnail (full HD equivalent)' => 'Большой ÑÑкиз (Ñквивалент Full HD)', + 'Multi-angle' => 'МногоракурÑное', + 'Multi-frame Disparity' => 'Многокадровое Ñмещённое (Disparity)', + 'Multi-frame Panorama' => 'ÐœÐ½Ð¾Ð³Ð¾ÐºÐ°Ð´Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð°Ð½Ð¾Ñ€Ð°Ð¼Ð°', + 'Undefined' => 'Ðеопределённый', + }, + }, + 'MPIndividualNum' => 'Индивидуальный номер MP', + 'MSDocumentText' => 'MS – ТекÑтовый документ', + 'MSDocumentTextPosition' => 'MS – ТекÑтовый документ – ПозициÑ', + 'MSPropertySetStorage' => 'MS – Хранилище ÑвойÑтв', + 'MSStereo' => { + Description => 'MS Ñтерео', + PrintConv => { + 'Off' => 'Ðе включено', + 'On' => 'Включено', + }, + }, + 'MachineID' => 'ID машины', + 'MachineObservation' => 'Машинное наблюдение', + 'MachineObservationDay' => 'День меÑÑца машинного наблюдениÑ', + 'MachineObservationEarliestDate' => 'Дата начала машинного наблюдениÑ', + 'MachineObservationEndDayOfYear' => 'День года Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð½Ð¾Ð³Ð¾ наблюдениÑ', + 'MachineObservationEventDate' => 'Дата машинного наблюдениÑ', + 'MachineObservationEventID' => 'ID машинного наблюдениÑ', + 'MachineObservationEventRemarks' => 'Комментарии к машинному наблюдению', + 'MachineObservationEventTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð½Ð¾Ð³Ð¾ наблюдениÑ', + 'MachineObservationFieldNotes' => 'Полевые заметки о машинном наблюдении', + 'MachineObservationFieldNumber' => 'Ðомер полевых заметок о машинном наблюдении', + 'MachineObservationHabitat' => 'Ðреал машинного наблюдениÑ', + 'MachineObservationLatestDate' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð¼Ð°ÑˆÐ¸Ð½Ð½Ð¾Ð³Ð¾ наблюдениÑ', + 'MachineObservationMonth' => 'МеÑÑц машинного наблюдениÑ', + 'MachineObservationParentEventID' => 'ID оÑновного машинного наблюдениÑ', + 'MachineObservationSampleSizeUnit' => 'Машинное наблюдение – Единицы размера', + 'MachineObservationSampleSizeValue' => 'Машинное наблюдение – Размер образца', + 'MachineObservationSamplingEffort' => 'Машинное наблюдение – Затраченные уÑилиÑ', + 'MachineObservationSamplingProtocol' => 'Машинное наблюдение – Метод иÑÑледованиÑ', + 'MachineObservationStartDayOfYear' => 'День года начала машинного наблюдениÑ', + 'MachineObservationVerbatimEventDate' => 'Дата машинного Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ñловно', + 'MachineObservationYear' => 'Год машинного наблюдениÑ', + 'MacintoshNSPrintInfo' => 'Macintosh NS – Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ печати', + 'MacintoshPrintInfo' => 'Macintosh – Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ печати', + 'Macro' => { + Description => 'Макро', + PrintConv => { + 'Macro' => 'Макро', + 'Manual' => 'Ручной', + 'Normal' => 'Обычный', + 'Off' => 'Выключен', + 'On' => 'Включен', + }, + }, + 'Magnetometer' => 'Магнитометр', + 'MajorBrand' => { + Description => 'ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ñ‚Ð¾Ñ€Ð³Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ€ÐºÐ°', + PrintConv => { + 'JPEG 2000 Compound Image (.JPM)' => 'СоÑтавное изображение JPEG 2000 (.JPM)', + 'JPEG 2000 Image (.JP2)' => 'Изображение JPEG 2000 (.JP2)', + 'JPEG 2000 with extensions (.JPX)' => 'Улучшенный JPEG 2000 (.JPX)', + }, + }, + 'MajorVersion' => 'ÐœÐ°Ð¶Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'Make' => 'Производитель', + 'MakerNote' => 'Приватные данные DNG', + 'MakerNoteApple' => 'Комментарии Apple', + 'MakerNoteCanon' => 'Комментарии Canon', + 'MakerNoteCasio' => 'Комментарии Casio', + 'MakerNoteCasio2' => 'Комментарии Casio 2', + 'MakerNoteDJI' => 'Комментарии DJI', + 'MakerNoteFLIR' => 'Комментарии FLIR', + 'MakerNoteFujiFilm' => 'Комментарии Fuji Film', + 'MakerNoteGE' => 'Комментарии GE', + 'MakerNoteGE2' => 'Комментарии GE2', + 'MakerNoteHP' => 'Комментарии HP', + 'MakerNoteHP2' => 'Комментарии HP2', + 'MakerNoteHP4' => 'Комментарии HP4', + 'MakerNoteHP6' => 'Комментарии HP6', + 'MakerNoteHasselblad' => 'Комментарии Hasselblad', + 'MakerNoteISL' => 'Комментарии ISL', + 'MakerNoteJVC' => 'Комментарии JVC', + 'MakerNoteJVCText' => 'Комментарии JVC – ТекÑÑ‚', + 'MakerNoteKodak10' => 'Комментарии Kodak 10', + 'MakerNoteKodak11' => 'Комментарии Kodak 11', + 'MakerNoteKodak12' => 'Комментарии Kodak 12', + 'MakerNoteKodak1a' => 'Комментарии Kodak 1a', + 'MakerNoteKodak1b' => 'Комментарии Kodak 1b', + 'MakerNoteKodak2' => 'Комментарии Kodak 2', + 'MakerNoteKodak3' => 'Комментарии Kodak 3', + 'MakerNoteKodak4' => 'Комментарии Kodak 4', + 'MakerNoteKodak5' => 'Комментарии Kodak 5', + 'MakerNoteKodak6a' => 'Комментарии Kodak 6a', + 'MakerNoteKodak6b' => 'Комментарии Kodak 6b', + 'MakerNoteKodak7' => 'Комментарии Kodak 7', + 'MakerNoteKodak8a' => 'Комментарии Kodak 8a', + 'MakerNoteKodak8b' => 'Комментарии Kodak 8b', + 'MakerNoteKodak8c' => 'Комментарии Kodak 8c', + 'MakerNoteKodak9' => 'Комментарии Kodak 9', + 'MakerNoteKodakUnknown' => 'Комментарии Kodak – ÐеизвеÑтно', + 'MakerNoteKyocera' => 'Комментарии Kyocera', + 'MakerNoteLeica' => 'Комментарии Leica', + 'MakerNoteLeica10' => 'Комментарии Leica 10', + 'MakerNoteLeica2' => 'Комментарии Leica 2', + 'MakerNoteLeica3' => 'Комментарии Leica 3', + 'MakerNoteLeica4' => 'Комментарии Leica 4', + 'MakerNoteLeica5' => 'Комментарии Leica 5', + 'MakerNoteLeica6' => 'Комментарии Leica 6', + 'MakerNoteLeica7' => 'Комментарии Leica 7', + 'MakerNoteLeica8' => 'Комментарии Leica 8', + 'MakerNoteLeica9' => 'Комментарии Leica 9', + 'MakerNoteMinolta' => 'Комментарии Minolta', + 'MakerNoteMinolta2' => 'Комментарии Minolta 2', + 'MakerNoteMinolta3' => 'Комментарии Minolta 3', + 'MakerNoteMotorola' => 'Комментарии Motorola', + 'MakerNoteNikon' => 'Комментарии Nikon', + 'MakerNoteNikon2' => 'Комментарии Nikon 2', + 'MakerNoteNikon3' => 'Комментарии Nikon 3', + 'MakerNoteNintendo' => 'Комментарии Nintendo', + 'MakerNoteOffset' => 'Смещение заметки производителÑ', + 'MakerNoteOlympus' => 'Комментарии Olympus', + 'MakerNoteOlympus2' => 'Комментарии Olympus 2', + 'MakerNotePanasonic' => 'Комментарии Panasonic', + 'MakerNotePanasonic2' => 'Комментарии Panasonic 2', + 'MakerNotePanasonic3' => 'Комментарии Panasonic 3', + 'MakerNotePentax' => 'Комментарии Pentax', + 'MakerNotePentax2' => 'Комментарии Pentax 2', + 'MakerNotePentax3' => 'Комментарии Pentax 3', + 'MakerNotePentax4' => 'Комментарии Pentax 4', + 'MakerNotePentax5' => 'Комментарии Pentax 5', + 'MakerNotePentax6' => 'Комментарии Pentax 6', + 'MakerNotePhaseOne' => 'Комментарии Phase One', + 'MakerNoteReconyx' => 'Комментарии Reconyx', + 'MakerNoteReconyx2' => 'Комментарии Reconyx 2', + 'MakerNoteReconyx3' => 'Комментарии Reconyx 3', + 'MakerNoteRicoh' => 'Комментарии Ricoh', + 'MakerNoteRicoh2' => 'Комментарии Ricoh 2', + 'MakerNoteRicohPentax' => 'Комментарии Ricoh Pentax', + 'MakerNoteRicohText' => 'Комментарии Ricoh – ТекÑÑ‚', + 'MakerNoteSafety' => { + Description => 'ÐŸÑ€Ð¸Ð¼ÐµÑ‡Ð°Ð½Ð¸Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑти', + PrintConv => { + 'Safe' => 'БезопаÑно', + 'Unsafe' => 'ÐебезопаÑно', + }, + }, + 'MakerNoteSamsung1a' => 'Комментарии Samsung 1a', + 'MakerNoteSamsung1b' => 'Комментарии Samsung 1b', + 'MakerNoteSamsung2' => 'Комментарии Samsung 2', + 'MakerNoteSanyo' => 'Комментарии Sanyo', + 'MakerNoteSanyoC4' => 'Комментарии Sanyo C4', + 'MakerNoteSanyoPatch' => 'Комментарии Sanyo Patch', + 'MakerNoteSigma' => 'Комментарии Sigma', + 'MakerNoteSigma3' => 'Комментарии Sigma 3', + 'MakerNoteSony' => 'Комментарии Sony', + 'MakerNoteSony2' => 'Комментарии Sony 2', + 'MakerNoteSony3' => 'Комментарии Sony 3', + 'MakerNoteSony4' => 'Комментарии Sony 4', + 'MakerNoteSony5' => 'Комментарии Sony 5', + 'MakerNoteSonyEricsson' => 'Комментарии Sony Ericsson', + 'MakerNoteSonySRF' => 'Комментарии Sony SRF', + 'MakerNoteUnknown' => 'Комментарии неизвеÑтного производителÑ', + 'MakerNoteUnknownBinary' => 'Комментарии неизвеÑтного Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ â€“ Бинарный', + 'MakerNoteUnknownText' => 'Комментарии неизвеÑтного Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ â€“ ТекÑтовый', + 'MakerNoteVersion' => 'Заметка Ð¿Ñ€Ð¾Ð¸Ð·Ð²Ð¾Ð´Ð¸Ñ‚ÐµÐ»Ñ â€“ ВерÑиÑ', + 'MakerNotes' => 'Данные производителей', + 'Manager' => 'Руководитель', + 'ManualFocusDistance' => 'РаÑÑтоÑние ручной фокуÑировки', + 'Manufacturer' => 'Разработчик', + 'MappingScheme' => 'Схема подÑтановки отÑутÑтвующего шрифта', + 'MarkerID' => 'ID маркера', + 'MaskedAreas' => 'МаÑкированные облаÑти', + 'MasterDocumentID' => 'ОÑновной ID документа', + 'MaterialSample' => 'Материал образца', + 'MaterialSampleID' => 'ID материала образца', + 'MatrixWorldToCamera' => 'Матрица мира на камеру', + 'MatrixWorldToScreen' => 'Матрица мира на Ñкран', + 'MattColor' => 'Matt цвет', + 'Matte' => 'Matte (МаÑка?)', + 'Matteing' => 'Матирование', + 'MaxAperture' => 'МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð´Ð¸Ð°Ñ„Ñ€Ð°Ð³Ð¼Ð° объектива', + 'MaxApertureValue' => 'МакÑимальное значение диафрагмы', + 'MaxBand' => 'МакÑимальный диапазон', + 'MaxBitrate' => 'МакÑимальный битрейт', + 'MaxPacketSize' => 'Размер макÑимального пакета', + 'MaxSampleValue' => 'МакÑимальное значение компонента', + 'MaxSubfileSize' => 'МакÑимальный размер подфайла', + 'MaxVal' => 'МакÑимальное значение пикÑелÑ', + 'MaxWidth' => 'МакÑÐ¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° глифа', + 'MaximumBitrate' => 'МакÑимальный битрейт', + 'MaximumDensityRange' => 'МакÑимальный диапазон плотноÑти', + 'MaximumObjectSize' => 'МакÑимальный размер объекта', + 'MeasureType' => { + Description => 'Тип Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð³Ð»ÑƒÐ±Ð¸Ð½Ñ‹', + PrintConv => { + 'OpticalAxis' => 'ОптичеÑÐºÐ°Ñ Ð¾ÑÑŒ', + 'OpticalRay' => 'ОптичеÑкий луч', + }, + }, + 'MeasurementAccuracy' => 'ÐŸÐ¾Ñ‚ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ Ð¿Ð¾Ð³Ñ€ÐµÑˆÐ½Ð¾ÑÑ‚ÑŒ измерениÑ', + 'MeasurementDeterminedBy' => 'Люди определившие значение измерениÑ', + 'MeasurementDeterminedDate' => 'Дата Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ', + 'MeasurementID' => 'ID измерениÑ', + 'MeasurementMethod' => 'Метод измерениÑ', + 'MeasurementOrFact' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± измерении', + 'MeasurementRemarks' => 'Заметки измерениÑ', + 'MeasurementScale' => 'Шкала измерений', + 'MeasurementType' => 'Тип измерениÑ', + 'MeasurementUnit' => 'Единицы измерениÑ', + 'MeasurementValue' => 'Значение измерениÑ', + 'MediaConstraints' => 'ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° медиареÑурÑÑ‹', + 'MediaData' => 'Медиа-данные', + 'MediaEventIdDate' => 'Дата ÑобытиÑ', + 'MediaIsDelay' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsFinale' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsLive' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsMovie' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsPremiere' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsRepeat' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsSAP' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsSport' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsStereo' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsSubtitled' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaIsTape' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'MediaSummaryCode' => 'Сводный код медиареÑурÑов', + 'MeetingLocations' => 'МеÑто вÑтречи', + 'Megapixels' => 'МегапикÑелей', + 'MelodicPolyphony' => 'ПолифоничеÑÐºÐ°Ñ Ð¼ÐµÐ»Ð¾Ð´Ð¸Ñ', + 'Message' => 'Сообщение', + 'MetadataCreator' => 'Метаданные – Создатель', + 'MetadataDate' => 'Метаданные – Дата', + 'MeteringMode' => { + Description => 'ЭкÑпозамер', + PrintConv => { + 'Average' => 'УÑреднённый', + 'Center-weighted average' => 'Центрально-взвешенный', + 'Multi-segment' => 'Оценочный/Многозонный', + 'Multi-spot' => 'Многоточечный', + 'Other' => 'Другой', + 'Partial' => 'ЧаÑтичный', + 'Spot' => 'Точечный', + 'Unknown' => 'ÐеизвеÑтный', + }, + }, + 'Method' => 'Метод', + 'Micro1Version' => 'Micro 1 – ВерÑиÑ', + 'Micro2Version' => 'Micro 2 – ВерÑиÑ', + 'Mime' => 'MIME-тип', + 'MinApertureValue' => 'Минимальное чиÑло диафрагмы объектива', + 'MinSampleValue' => 'Минимальное значение компонента', + 'MinimumBitrate' => 'Минимальный битрейт', + 'MinimumVersion' => 'ÐœÐ¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'MinorModelAgeDisclosure' => { + Description => 'ВозраÑÑ‚ Ñамой молодой модели на Ñнимке', + PrintConv => { + 'Age 14 or Under' => '14 лет и меньше', + 'Age 15' => '15 лет', + 'Age 16' => '16 лет', + 'Age 17' => '17 лет', + 'Age 18' => '18 лет', + 'Age 19' => '19 лет', + 'Age 20' => '20 лет', + 'Age 21' => '21 год', + 'Age 22' => '22 года', + 'Age 23' => '23 года', + 'Age 24' => '24 года', + 'Age 25 or Over' => '25 лет и выше', + 'Age Unknown' => 'ВозраÑÑ‚ неизвеÑтен', + }, + }, + 'MinorVersion' => 'ÐœÐ¸Ð½Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'MobiType' => { + Description => 'Тип Mobi', + PrintConv => { + 'Audio' => 'Ðудио', + 'KF8: generated by kindlegen2' => 'KF8: Ñгенерированный kindlegen 2', + 'Mobipocket Book' => 'Книга Mobipocket', + 'News' => 'ÐовоÑти', + 'News_Feed' => 'ÐовоÑÑ‚Ð½Ð°Ñ Ð»ÐµÐ½Ñ‚Ð°', + 'News_Magazine' => 'Журнал новоÑтей', + 'PalmDoc Book' => 'Книга PalmDoc', + 'mobipocket? generated by kindlegen1.2' => 'Mobipocket? Сгенерированный kindlegen 1.2', + }, + }, + 'MobiVersion' => 'ВерÑÐ¸Ñ Mobi', + 'ModDate' => 'Дата редактированиÑ', + 'ModeExtension' => { + Description => 'РаÑширение режима канала', + PrintConv => { + 'Bands 12-31' => 'ПолоÑÑ‹ 12-32', + 'Bands 16-31' => 'ПолоÑÑ‹ 16-31', + 'Bands 4-31' => 'ПолоÑÑ‹ 4-31', + 'Bands 8-31' => 'ПолоÑÑ‹ 8-31', + }, + }, + 'ModeNumber' => 'Режим Ñтандарта факÑ-профилÑ', + 'Model' => 'Модель камеры', + 'Model2' => 'Модель 2', + 'ModelReleaseID' => 'ID релиза модели', + 'ModelReleaseStatus' => { + Description => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ€ÐµÐ»Ð¸Ð·Ð° модели', + PrintConv => { + 'Limited or Incomplete Model Releases' => 'Ограниченные или неполные верÑии моделей', + 'None' => 'Ðе обозначено', + 'Not Applicable' => 'Ðе дейÑтвующий', + 'Unlimited Model Releases' => 'Ðеограниченное количеÑтво релизов модели', + }, + }, + 'ModelTiePoint' => 'ПроÑтранÑÑ‚Ð²ÐµÐ½Ð½Ð°Ñ Ð¿Ñ€Ð¸Ð²Ñзка', + 'ModelTransform' => 'Модель преобразованиÑ', + 'ModificationNumber' => 'Ðомер модификации', + 'ModificationPermissions' => { + Description => 'Ð Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð½Ð° Редактирование', + PrintConv => { + 'Do not restrict applications to reader permissions' => 'Ðе ограничивать вÑем приложениÑм права на чтение', + 'Fill forms, Create page templates, Sign' => 'РазрешаетÑÑ: Заполнение форм, Создание шаблонов Ñтраниц, Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ', + 'Fill forms, Create page templates, Sign, Create/Delete/Edit annotations' => 'РазрешаетÑÑ: Заполнение форм, Создание шаблонов Ñтраниц, Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ, Создание/Удаление/Редактирование аннотаций', + 'No changes permitted' => 'Редактирование запрещено', + 'Restrict all applications to reader permissions' => 'Ограничивать вÑем приложениÑм права на чтение', + }, + }, + 'ModifyDate' => 'Дата редактированиÑ', + 'MoireFilter' => 'Фильтр муара', + 'Montage' => 'Монтаж', + 'Month' => 'МеÑÑц', + 'MoonPhase' => { + Description => 'Фаза луны', + PrintConv => { + 'First Quarter' => 'ÐŸÐµÑ€Ð²Ð°Ñ Ñ‡ÐµÑ‚Ð²ÐµÑ€Ñ‚ÑŒ', + 'Full' => 'Полнолуние', + 'Last Quarter' => 'ПоÑледнÑÑ Ñ‡ÐµÑ‚Ð²ÐµÑ€Ñ‚ÑŒ', + 'New' => 'Ðоволуние', + 'New Crescent' => 'ÐœÐ¾Ð»Ð¾Ð´Ð°Ñ Ð»ÑƒÐ½Ð°', + 'Old Crescent' => 'Ð¡Ñ‚Ð°Ñ€Ð°Ñ Ð»ÑƒÐ½Ð°', + 'Waning Gibbous' => 'Ð£Ð±Ñ‹Ð²Ð°ÑŽÑ‰Ð°Ñ Ð»ÑƒÐ½Ð°', + 'Waxing Gibbous' => 'РаÑÑ‚ÑƒÑ‰Ð°Ñ Ð»ÑƒÐ½Ð°', + }, + }, + 'MotionSensitivity' => 'Обнаружение движениÑ', + 'MultiFrameNoiseReduction' => { + Description => 'Многокадровое шумоподавление', + PrintConv => { + 'Off' => 'Ðе включено', + 'On' => 'Включено', + }, + }, + 'MultiProfiles' => { + Description => 'Мультипрофили', + PrintConv => { + 'JBIG2 Profile M' => 'JBIG2 профиль M', + 'N Layer Profile M' => 'N Ñлой Профиль M', + 'Profile C' => 'Профиль C', + 'Profile F' => 'Профиль F', + 'Profile J' => 'Профиль J', + 'Profile L' => 'Профиль L', + 'Profile M' => 'Профиль M', + 'Profile S' => 'Профиль S', + 'Profile T' => 'Профиль T', + 'Resolution/Image Width' => 'Разрешение/Ширина изображениÑ', + 'Shared Data' => 'Общие данные', + }, + }, + 'MultimediaType' => 'Тип мультимедиа', + 'Multishot' => { + Description => 'МультиÑъёмка', + PrintConv => { + 'Off' => 'Ðе включена', + 'Pixel Shift' => 'Сдвиг пикÑелей', + }, + }, + 'Name' => 'Ðазвание файла', + 'NameTableVersion' => 'Таблица имён – ВерÑиÑ', + 'NameUTF-8' => 'Ðазвание в кодировке UTF-8', + 'Narrator' => 'Ð˜Ð¼Ñ Ð´Ð¸ÐºÑ‚Ð¾Ñ€Ð°', + 'Near' => 'Ближайшее значение карты глубины', + 'NetName' => 'Сетевое имÑ', + 'NetProviderType' => 'Тип Ñетевого провайдера', + 'NewGUID' => 'Ðовый GUID', + 'NewRawImageDigest' => 'Хеш-Ñумма RAW-Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð² новом формате', + 'NewsPhotoVersion' => 'ВерÑÐ¸Ñ News Photo', + 'Nickname' => 'Прозвище', + 'NoMSSmartTags' => 'Смарт-теги MS отÑутÑтвуют', + 'Noise' => 'Уровень шума', + 'NoiseProfile' => 'Профиль – Уровень шума', + 'NoiseReduction' => 'Шумоподавление', + 'NoiseReductionApplied' => 'Применённое шумоподавление', + 'NoiseReductionMode' => { + Description => 'Режим шумоподавлениÑ', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включён', + }, + }, + 'NoiseReductionParams' => 'Параметры шумоподавлениÑ', + 'NoiseReductionValue' => 'Значение шумоподавлениÑ', + 'NominalBitrate' => 'Ðоминальный битрейт', + 'NominalVideoBitrate' => { + Description => 'Ðоминальный битрейт видео', + PrintConv => { + 'Unspecified' => 'Ðеопределённый', + }, + }, + 'Note' => 'Заметка', + 'Notes' => 'Комментарии', + 'Notice' => 'Заметка', + 'Now' => 'Текущие Дата и ВремÑ', + 'NumChannels' => 'КоличеÑтво каналов', + 'NumColors' => 'КоличеÑтво цветов', + 'NumFonts' => 'КоличеÑтво шрифтов в коллекции', + 'NumImportantColors' => 'КоличеÑтво важных цветов', + 'NumIndexEntries' => 'КоличеÑтво индекÑов', + 'NumPackets' => 'КоличеÑтво пакетов', + 'NumProperties' => 'КоличеÑтво ÑвойÑтв', + 'NumRules' => 'КоличеÑтво правил', + 'NumSampleFrames' => 'КоличеÑтво кадров', + 'NumSlices' => 'КоличеÑтво фрагментов', + 'NumStreams' => 'КоличеÑтво потоков', + 'Number' => 'Ðомер', + 'NumberList' => 'Ðумерованный ÑпиÑок', + 'NumberOfComponents' => 'КоличеÑтво компонентов', + 'NumberOfImages' => 'КоличеÑтво изображений', + 'NumberofInks' => 'КоличеÑтво чернил', + 'OPIProxy' => { + Description => 'ПодÑтановка изображениÑ', + PrintConv => { + 'Higher resolution image does not exist' => 'Изображение большего Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¾Ñ‚ÑутÑтвует', + 'Higher resolution image exists' => 'ПриÑутÑтвует изображение Ñ Ð±Ð¾Ð»ÑŒÑˆÐ¸Ð¼ разрешением', + }, + }, + 'Object' => 'Объект', + 'ObjectAttributeReference' => 'СÑылка на атрибут объекта', + 'ObjectCycle' => { + Description => 'Суточный цикл', + PrintConv => { + 'Both Morning and Evening' => 'Утро и вечер', + 'Evening' => 'Вечер', + 'Morning' => 'Утро', + }, + }, + 'ObjectName' => 'Ðазвание объекта', + 'ObjectPreviewData' => 'ПредпроÑмотр объекта – Данные', + 'ObjectPreviewFileFormat' => { + Description => 'ПредпроÑмотр объекта – Формат файла', + PrintConv => { + 'AppleSingle (Apple Computer Inc)' => 'AppleSingle (Apple)', + 'Audio Interchange File Format AIFF (Apple Computer Inc)' => 'Ðудиофайл формата AIFF (Apple)', + 'Bit Mapped Graphics File [.BMP] (Microsoft)' => 'Битовый графичеÑкий файл [.BMP] (Microsoft)', + 'Compressed Binary File [.ZIP] (PKWare Inc)' => 'Сжатый двоичный файл [.ZIP] (ÐšÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ñ PKWare)', + 'Digital Audio File [.WAV] (Microsoft & Creative Labs)' => 'Ðудиофайл формата [.WAV] (Microsoft и Creative Labs)', + 'Hypertext Markup Language [.HTML] (The Internet Society)' => 'Язык гипертекÑтовой разметки [.HTML] (The Internet Society)', + 'IPTC Unstructured Character Oriented File Format (UCOFF)' => 'ÐеÑтруктурированный Ñимвольно-ориентированный формат файла IPTC (UCOFF)', + 'IPTC7901 Recommended Message Format' => 'IPTC7901 Рекомендуемый формат ÑообщениÑ', + 'Illustrator (Adobe Graphics data)' => 'Illustrator (ГрафичеÑкие данные Adobe)', + 'JPEG File Interchange (JFIF)' => 'Формат обмена файлами Ñтандарта JPEG (JFIF)', + 'MPEG 2 Audio Layer 2 (Musicom), ISO/IEC' => 'Ðудио второго ÑƒÑ€Ð¾Ð²Ð½Ñ MPEG 2 (Musicom), ISO/IEC', + 'MPEG 2 Audio Layer 3, ISO/IEC' => 'Ðудио третьего ÑƒÑ€Ð¾Ð²Ð½Ñ MPEG 2 , ISO/IEC', + 'News Industry Text Format (NITF)' => 'ТекÑтовый формат новоÑтной индуÑтрии (NITF)', + 'No ObjectData' => 'Данные объекта отÑутÑтвуют', + 'PC DOS/Windows Executable Files [.COM][.EXE]' => 'ИÑполнÑемый файл PC DOS/Windows [.COM][.EXE]', + 'RIFF Wave (Microsoft Corporation)' => 'RIFF Wave (Microsoft)', + 'Ritzaus Bureau NITF version (RBNITF DTD)' => 'Ritzaus Bureau вариант NITF (RBNITF DTD)', + 'Tagged Image File Format (Adobe/Aldus Image data)' => 'Формат файла Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ñ‚ÐµÐ³Ð°Ð¼Ð¸ (Adobe/Aldus данные изображениÑ)', + 'Tape Archive [.TAR]' => 'Формат файла архива [.TAR]', + 'Tidningarnas Telegrambyra NITF version (TTNITF DTD)' => 'Tidningarnas Telegrambyra вариант NITF (TTNITF DTD)', + 'United Press International ANPA 1312 variant' => 'United Press International – Вариант ANPA 1312', + 'United Press International Down-Load Message' => 'United Press International – Down-Load Message', + }, + }, + 'ObjectPreviewFileVersion' => 'ПредпроÑмотр объекта – ВерÑиÑ', + 'ObjectSizeAnnounced' => 'ЗаÑвленный размер объекта', + 'ObjectType' => 'Тип объекта', + 'ObjectTypeReference' => 'СÑылка на тип объекта', + 'ObservationDate' => 'Дата наблюдениÑ', + 'ObservationDateEnd' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ', + 'ObservationTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ', + 'ObservationTimeEnd' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð½Ð°Ð±Ð»ÑŽÐ´ÐµÐ½Ð¸Ñ', + 'Observer' => 'Ðаблюдатель', + 'ObsoletePhotoshopTag1' => 'Photoshop – УÑтаревший тег 1', + 'ObsoletePhotoshopTag2' => 'Photoshop – УÑтаревший тег 2', + 'ObsoletePhotoshopTag3' => 'Photoshop – УÑтаревший тег 3', + 'Occurrence' => 'Ðаходка', + 'OccurrenceAssociatedMedia' => 'МедиареÑурÑÑ‹ ÑвÑзанные Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¾Ð¹', + 'OccurrenceAssociatedOccurrences' => 'СвÑзанные находки', + 'OccurrenceAssociatedReferences' => 'СÑылки ÑвÑзанные Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¾Ð¹', + 'OccurrenceAssociatedSequences' => 'ГенетичеÑкие поÑледовательноÑти ÑвÑзанные Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¾Ð¹', + 'OccurrenceAssociatedTaxa' => 'ТакÑоны ÑвÑзанные Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¾Ð¹', + 'OccurrenceBehavior' => 'ÐŸÐ¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ñоби во Ð²Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¸', + 'OccurrenceCatalogNumber' => 'Ðомер набора данных', + 'OccurrenceDetails' => 'ПодробноÑти о находке', + 'OccurrenceDisposition' => 'СоÑтоÑние образца по отношению к коллекции', + 'OccurrenceEstablishmentMeans' => 'СпоÑоб оÑÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ Ð½Ð° меÑтноÑти', + 'OccurrenceID' => 'ID находки', + 'OccurrenceIndividualCount' => 'КоличеÑтво найденных оÑобей', + 'OccurrenceIndividualID' => 'ID найденных оÑобей', + 'OccurrenceLifeStage' => 'Жизненные циклы найденных оÑобей', + 'OccurrenceOrganismQuantity' => 'ЧиÑло учётных единиц или обилие вида', + 'OccurrenceOrganismQuantityType' => 'Тип ÑиÑтемы количеÑтвенного определениÑ', + 'OccurrenceOtherCatalogNumbers' => 'Другие номера каталога Ð´Ð»Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¸', + 'OccurrencePreparations' => 'Методы Ð¿Ñ€ÐµÐ¿Ð°Ñ€Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸ конÑÐµÑ€Ð²Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ñ†Ð°', + 'OccurrencePreviousIdentifications' => 'Предыдущие Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¸', + 'OccurrenceRecordNumber' => 'Ðомер приÑвоенный объекту в момент находки', + 'OccurrenceRecordedBy' => 'Люди ответÑтвенные за запиÑÑŒ о находке', + 'OccurrenceRemarks' => 'Комментарии к находке', + 'OccurrenceReproductiveCondition' => 'Репродуктивное ÑоÑтоÑние оÑобей во Ð²Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ…Ð¾Ð´ÐºÐ¸', + 'OccurrenceSex' => 'Пол найденных оÑобей', + 'OccurrenceStatus' => 'ПриÑутÑтвие вида в данной меÑтноÑти', + 'OceApplicationSelector' => 'Задатчик Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Oce', + 'OceIDNumber' => 'ID-номер Oce', + 'OceImageLogic' => 'Логика Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Oce', + 'OceScanjobDesc' => 'ОпиÑание Ð·Ð°Ð´Ð°Ð½Ð¸Ñ ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Oce', + 'OffsetSchema' => 'Схема ÑмещениÑ', + 'OffsetTime' => 'Смещение времени', + 'OffsetTimeDigitized' => 'Ð¡Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ Ð²Ñ€ÐµÐ¼ÐµÐ½Ð¸ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'OffsetTimeOriginal' => 'Смещение времени Ñъёмки', + 'OldSubfileType' => { + Description => 'Тип подфайла (Ñтарый)', + PrintConv => { + 'Full-resolution image' => 'Изображение Ñ Ð¿Ð¾Ð»Ð½Ñ‹Ð¼ разрешением', + 'Reduced-resolution image' => 'Изображение Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + 'Single page of multi-page image' => 'Одна Ñтраница из многоÑтраничного изображениÑ', + }, + }, + 'OnionSkins' => 'Обрамление Ñцены', + 'Opacity' => 'ÐепрозрачноÑÑ‚ÑŒ', + 'OpcodeList1' => 'СпиÑок кодов операций обработки изображений 1', + 'OpcodeList2' => 'СпиÑок кодов операций обработки изображений 2', + 'OpcodeList3' => 'СпиÑок кодов операций обработки изображений 3', + 'OperatingSystem' => { + Description => 'ÐžÐ¿ÐµÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð°Ñ ÑиÑтема', + PrintConv => { + 'FAT filesystem (MS-DOS, OS/2, NT/Win32)' => 'Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема FAT (MS-DOS, OS/2, NT/Win32)', + 'HPFS filesystem (OS/2, NT)' => 'Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема HPFS (OS/2, NT)', + 'NTFS filesystem (NT)' => 'Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема NTFS (NT)', + 'VMS (or OpenVMS)' => 'VMS (или OpenVMS)', + 'Z-System' => 'Z/OS', + 'unknown' => 'ÐеизвеÑтнаÑ', + }, + }, + 'OpticalZoomOn' => { + Description => 'ОптичеÑкий зум', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'Opto-ElectricConvFactor' => 'Фактор оптико-ÑлектричеÑкого преобразованиÑ', + 'Organism' => 'Организм', + 'OrganismAssociatedOccurrences' => 'СвÑзанные находки Ñ Ñтим организмом', + 'OrganismAssociatedOrganisms' => 'Другие организмы ÑвÑзанные Ñ Ñтим организмом', + 'OrganismID' => 'ID организма', + 'OrganismName' => 'Ðазвание приÑвоенное организму', + 'OrganismPreviousIdentifications' => 'Предыдущие Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾Ñ€Ð³Ð°Ð½Ð¸Ð·Ð¼Ð°', + 'OrganismRemarks' => 'Комментарии к ÑкземплÑру организма', + 'OrganismScope' => 'Вид ÑкземплÑра организма', + 'Organization' => 'ОрганизациÑ', + 'Organizer' => 'Организатор', + 'Orientation' => { + Description => 'ОриентациÑ', + PrintConv => { + 'Horizontal (normal)' => 'ГоризонтальнаÑ', + 'Mirror horizontal' => 'Отражение по горизонтали', + 'Mirror horizontal and rotate 270 CW' => 'Отражение по горизонтали и поворот на 270° по чаÑовой Ñтрелке', + 'Mirror horizontal and rotate 90 CW' => 'Отражение по горизонтали и поворот на 90° по чаÑовой Ñтрелке', + 'Mirror vertical' => 'Отражение по вертикали', + 'Rotate 180' => 'Поворот на 180°', + 'Rotate 270 CW' => 'Поворот на 270° по чаÑовой Ñтрелке', + 'Rotate 90 CW' => 'Поворот на 90° по чаÑовой Ñтрелке', + }, + }, + 'OriginPathInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± иÑходном обтравочном контуре', + 'OriginalBestQualitySize' => 'Размер более качеÑтвенного изображениÑ', + 'OriginalCreateDateTime' => 'ИÑходные дата и Ð²Ñ€ÐµÐ¼Ñ ÑозданиÑ', + 'OriginalDecisionData' => 'Ð¦Ð¸Ñ„Ñ€Ð¾Ð²Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ оригинальноÑти Ñнимка (ODD)', + 'OriginalDefaultCropSize' => 'ИÑходный размер кадрированного изображениÑ', + 'OriginalDefaultFinalSize' => 'Полный размер иÑходного изображениÑ', + 'OriginalFileName' => 'ИÑходное название файла', + 'OriginalFileSize' => 'Размер иÑходного файла', + 'OriginalFileType' => 'Тип иÑходного файла', + 'OriginalFrameRate' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ñ‡Ð°Ñтота кадров', + 'OriginalImageHeight' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð²Ñ‹Ñотаи зображениÑ', + 'OriginalImageWidth' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¸Ð½Ð° изображениÑ', + 'OriginalMedia' => { + Description => 'Оригинальный ноÑитель', + PrintConv => { + 'False' => 'Ðет', + 'True' => 'Да', + }, + }, + 'OriginalRawFileData' => 'Данные иÑходного RAW-файла', + 'OriginalRawFileDigest' => 'Хеш-Ñумма иÑходного RAW-файла', + 'OriginalRawFileName' => 'Ðазвание иÑходного RAW-файла', + 'OriginalReleaseTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð° оригинала', + 'OriginalTransmissionReference' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ ÑÑылка на передачу', + 'OriginatingProgram' => 'Создано в риложении', + 'Originator' => 'Контент Ñоздан в', + 'OtherConditions' => 'Другие уÑловиÑ', + 'OtherConstraints' => 'Другие ограничениÑ', + 'OtherDate1' => 'Другое – Дата 1', + 'OtherDate2' => 'Другое – Дата 2', + 'OtherDate3' => 'Другое – Дата 3', + 'OtherFirmware' => 'Ð”Ñ€ÑƒÐ³Ð°Ñ Ð¿Ñ€Ð¾ÑˆÐ¸Ð²ÐºÐ°', + 'OtherImage' => 'Другое изображение', + 'OtherImageInfo' => 'Другие ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± изображении', + 'OtherImageLength' => 'Строк в файле предпроÑмотра', + 'OtherImageStart' => 'Смещение другого изображениÑ', + 'OtherLicenseDocuments' => 'Другие документы лицензии', + 'OtherLicenseInfo' => 'Дополнительные ÑÐ²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ лицензии', + 'OtherLicenseRequirements' => 'Другие лицензионные требованиÑ', + 'OtherSerialNumber' => 'Другой Серийный номер', + 'Owner' => 'Владелец', + 'OwnerAppointmentID' => 'ID владельца ÑобытиÑ', + 'OwnerID' => 'ID владельца', + 'OwnerName' => 'Ð˜Ð¼Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†Ð° камеры', + 'PDFVersion' => 'ВерÑÐ¸Ñ PDF', + 'PFMVersion' => 'ВерÑÐ¸Ñ PFM', + 'PGFVersion' => 'ВерÑÐ¸Ñ PGF', + 'PLUSVersion' => 'ВерÑÐ¸Ñ PLUS', + 'PMVersion' => 'ВерÑÐ¸Ñ PhotoMechanic', + 'PNGWarning' => 'Предупреждение PNG', + 'PStringCaption' => 'P – Строка заголовка', + 'PXC Viewer Info' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ñ‚ PDF-XChange Viewer', + 'Packets' => 'Пакетов', + 'PackingMethod' => { + Description => 'Метод ÑжатиÑ', + PrintConv => { + 'Best Compression' => 'МакÑимальный', + 'Fast' => 'БыÑтрый', + 'Fastest' => 'СкороÑтной', + 'Good Compression' => 'Хороший', + 'Normal' => 'Обычный', + 'Stored' => 'Без ÑжатиÑ', + }, + }, + 'Padding' => 'Внутренние отÑтупы', + 'Page' => 'Размер и раÑположение холÑта', + 'PageCount' => 'КоличеÑтво Ñтраниц', + 'PageEnter' => 'Эффект при заходе на Ñтраницу', + 'PageExit' => 'Эффект при уходе Ñо Ñтраницы', + 'PageFront' => 'КоличеÑтво фронтальных Ñтраниц', + 'PageLayout' => 'Макет Ñтраницы', + 'PageMode' => 'Режим Ñтраницы', + 'PageName' => 'Ðазвание Ñтраницы', + 'PageNormal' => 'КоличеÑтво обычных Ñтраниц', + 'PageNumber' => 'Ðомер Ñтраницы', + 'PageSpecial' => 'КоличеÑтво Ñпециальных Ñтраниц', + 'Pages' => 'Страниц', + 'Palette' => 'Палитра', + 'PaletteHistogram' => 'ГиÑтограмма палитры', + 'PalmFileType' => 'Тип файла Palm', + 'PanOrientation' => { + Description => 'ÐžÑ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð¿Ð°Ð½Ð¾Ñ€Ð°Ð¼Ñ‹', + PrintConv => { + 'Bottom to top' => 'Снизу вверх', + 'Clockwise' => 'По чаÑовой Ñтрелке', + 'Counter clockwise' => 'Против чаÑовой Ñтрелки', + 'Left to right' => 'Слева направо', + 'Right to left' => 'Справа налево', + 'Start at bottom left' => 'Ðачало внизу Ñлева', + 'Start at bottom right' => 'Ðачало внизу Ñправа', + 'Start at top left' => 'Ðачало Ñверху Ñлева', + 'Start at top right' => 'Ðачало Ñверху Ñправа', + 'Top to bottom' => 'Сверху вниз', + 'Zigzag (column start)' => 'Зигзаг (начало колонки)', + 'Zigzag (row start)' => 'Зигзаг (начало Ñтроки)', + '[unused]' => 'ÐеиÑпользуетÑÑ', + }, + }, + 'PanOverlapH' => 'Горизонтальное перекрытие панорамы', + 'PanOverlapV' => 'Вертикальное перекрытие панорамы', + 'PanasonicRawVersion' => 'Panasonic – ВерÑÐ¸Ñ RAW', + 'PanasonicTitle' => 'Panasonic – Ðазвание', + 'PanasonicTitle2' => 'Panasonic – Ðазвание 2', + 'PanoramicStitchCameraMotion' => { + Description => 'Метод ÑÑˆÐ¸Ð²Ð°Ð½Ð¸Ñ Ð¿Ð°Ð½Ð¾Ñ€Ð°Ð¼Ñ‹', + PrintConv => { + '3D Rotation' => '3D-вращение', + 'Affine' => 'Ðффинное преобразование', + 'Homography' => 'ГомографиÑ', + 'Rigid Scale' => 'ЖёÑÑ‚ÐºÐ°Ñ ÑˆÐºÐ°Ð»Ð°', + }, + }, + 'PanoramicStitchMapType' => { + Description => 'Тип карты', + PrintConv => { + 'Horizontal Cylindrical' => 'Ð“Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ†Ð¸Ð»Ð¸Ð½Ð´Ñ€Ð¸Ñ‡ÐµÑкаÑ', + 'Horizontal Spherical' => 'Ð“Ð¾Ñ€Ð¸Ð·Ð¾Ð½Ñ‚Ð°Ð»ÑŒÐ½Ð°Ñ ÑферичеÑкаÑ', + 'Perspective' => 'ПерÑпектива', + 'Vertical Cylindrical' => 'Ð’ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ñ†Ð¸Ð»Ð¸Ð½Ð´Ñ€Ð¸Ñ‡ÐµÑкаÑ', + 'Vertical Spherical' => 'Ð’ÐµÑ€Ñ‚Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ ÑферичеÑкаÑ', + }, + }, + 'PanoramicStitchPhi0' => 'Угол Phi 0', + 'PanoramicStitchPhi1' => 'Угол Phi 1', + 'PanoramicStitchTheta0' => 'Угол Theta 0', + 'PanoramicStitchTheta1' => 'Угол Theta 1', + 'Paragraphs' => 'Ðбзацев', + 'ParentMEID' => 'РодительÑкий MEID', + 'ParentMediaEventID' => 'ID ÑобытиÑ', + 'PathSelectionState' => 'СоÑтоÑние выбранного обтравочного контура', + 'PathTableLocation' => 'РаÑположение таблицы путей', + 'PathTableSize' => 'Размер таблицы путей', + 'PatientBirthDate' => 'Дата Ñ€Ð¾Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ†Ð¸ÐµÐ½Ñ‚Ð°', + 'PatientID' => 'ID пациента', + 'PatientName' => 'Ð˜Ð¼Ñ Ð¿Ð°Ñ†Ð¸ÐµÐ½Ñ‚Ð°', + 'PatientSex' => 'Пол пациента', + 'PeakSpectralSensitivity' => 'ÐŸÐ¸ÐºÐ¾Ð²Ð°Ñ ÑÐ¿ÐµÐºÑ‚Ñ€Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ', + 'People' => 'Люди', + 'PercentComplete' => 'Процент завершениÑ', + 'PercussivePolyphony' => 'ПолифоничеÑÐºÐ°Ñ Ð¿ÐµÑ€ÐºÑƒÑÑиÑ', + 'Performer' => 'ИÑполнитель', + 'PeripheralIllumCentralRadius' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð·Ð¸Ñ‚Ð½Ð¾Ð³Ð¾ Ñигнала – Центральный радиуÑ', + 'PeripheralIllumCentralValue' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð·Ð¸Ñ‚Ð½Ð¾Ð³Ð¾ Ñигнала – Ð¦ÐµÐ½Ñ‚Ñ€Ð°Ð»ÑŒÐ½Ð°Ñ Ð½Ð°ÑыщенноÑÑ‚ÑŒ', + 'PeripheralIllumPeriphValue' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð·Ð¸Ñ‚Ð½Ð¾Ð³Ð¾ Ñигнала – ÐŸÐµÑ€Ð¸Ñ„ÐµÑ€Ð¸Ð¹Ð½Ð°Ñ Ð½Ð°ÑыщенноÑÑ‚ÑŒ', + 'Personality' => 'ЛичноÑти', + 'Photo' => 'ФотографиÑ', + 'PhotoResolution' => 'Разрешение Ñнимка', + 'PhotometricInterpretation' => { + Description => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ', + PrintConv => { + 'BlackIsZero' => 'Чёрный равен нулю', + 'Color Filter Array' => 'МаÑÑив цветных фильтров (CFA)', + 'RGB Palette' => 'Палитра RGB', + 'Transparency Mask' => 'МаÑка прозрачноÑти', + 'WhiteIsZero' => 'Белый равен нулю', + }, + }, + 'Photoshop2ColorTable' => 'Photoshop 2 – Таблица цветов', + 'Photoshop2Info' => 'Photoshop 2 – СведениÑ', + 'PhotoshopBGRThumbnail' => 'Photoshop – BGR миниатюра', + 'PhotoshopFormat' => { + Description => 'Photoshop – Формат', + PrintConv => { + 'Optimized' => 'Оптимизированный', + 'Progressive' => 'ПрогреÑÑивный', + 'Standard' => 'Стандартный', + }, + }, + 'PhotoshopQuality' => 'Photoshop – КачеÑтво', + 'PhotoshopThumbnail' => 'Photoshop – Миниатюра', + 'PhysicalStreamNumberMap' => 'ФизичеÑкий поток – Number Map', + 'PhysicalStreamNumbers' => 'Ðомера физичеÑких потоков', + 'PhysicalStreams' => 'ФизичеÑких потоков', + 'PicsLabel' => 'Метка взроÑлоÑти контента', + 'PictInfo' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± изображении', + 'Picture' => 'Картина', + 'PictureBitsPerPixel' => 'КоличеÑтво бит на пикÑель картинки', + 'PictureDescription' => 'ОпиÑание изображениÑ', + 'PictureHeight' => 'Ð’Ñ‹Ñота картинки', + 'PictureIndexedColors' => 'ИндекÑированные цвета изображениÑ', + 'PictureLength' => 'Строк в картинке', + 'PictureMIMEType' => 'MIME тип изображениÑ', + 'PictureType' => { + Description => 'Тип изображениÑ', + PrintConv => { + '32x32 PNG Icon' => '32x32 иконка PNG', + 'Artist' => 'ИÑполнитель', + 'Back Cover' => 'ЗаднÑÑ Ð¾Ð±Ð»Ð¾Ð¶ÐºÐ°', + 'Band' => 'Группа', + 'Band Logo' => 'Логотип группы/иÑполнителÑ', + 'Bright(ly) Colored Fish' => 'Ярко Ð¾ÐºÑ€Ð°ÑˆÐµÐ½Ð½Ð°Ñ Ñ€Ñ‹Ð±Ð°', + 'Capture from Movie or Video' => 'Захват из фильма или видео', + 'Composer' => 'Композитор', + 'Conductor' => 'Дирижер', + 'Front Cover' => 'ПереднÑÑ Ð¾Ð±Ð»Ð¾Ð¶ÐºÐ°', + 'Illustration' => 'ИллюÑтрациÑ', + 'Lead Artist' => 'Ведущий ÐртиÑÑ‚/ИÑполнитель/СолиÑÑ‚', + 'Leaflet' => 'ЛиÑтовка', + 'Lyricist' => 'Ðвтор текÑта', + 'Media' => 'ÐоÑитель', + 'Other' => 'Другое', + 'Other Icon' => 'Ð”Ñ€ÑƒÐ³Ð°Ñ Ð¸ÐºÐ¾Ð½ÐºÐ°', + 'Performance' => 'ПредÑтавление', + 'Publisher Logo' => 'Логотип издателÑ/Ñтудии', + 'Recording Session' => 'ЗапиÑÑŒ ÑеÑÑии', + 'Recording Studio or Location' => 'Ð¡Ñ‚ÑƒÐ´Ð¸Ñ Ð·Ð²ÑƒÐºÐ¾Ð·Ð°Ð¿Ð¸Ñи или меÑтоположение', + }, + }, + 'PictureWidth' => 'Ширина картинки', + 'PieceLength' => 'Размер блока в байтах', + 'Pieces' => 'Блоков', + 'PipelineVersion' => 'ВерÑÐ¸Ñ Pipeline', + 'Pitch' => 'Тангаж (Ðаклон)', + 'PitchAndFamily' => 'Шаг и ÑемейÑтво шрифта', + 'PitchAngle' => 'Угол наклона (Тангаж)', + 'PixHeight' => 'Ð’Ñ‹Ñота в пикÑелÑÑ…', + 'PixWidth' => 'Ширина в пикÑелÑÑ…', + 'PixelAspectRatio' => 'Соотношение Ñторон пикÑелей', + 'PixelCalibration' => 'Калибровка по пикÑелÑм', + 'PixelFormat' => { + Description => 'Формат пикÑелÑ', + PrintConv => { + '112-bit 6 Channels Alpha' => '112-битный, 6 каналов, альфа-канал', + '112-bit 7 Channels' => '112-битный, 7 каналов', + '128-bit 7 Channels Alpha' => '128-битный, 7 каналов, альфа-канал', + '128-bit 8 Channels' => '128-битный, 8 каналов', + '128-bit PRGBA Float' => '128-битный, PRGBA Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой', + '128-bit RGB Float' => '128-битный, RGB Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой', + '128-bit RGBA Fixed Point' => '128-битный, RGBA Ñ Ñ„Ð¸ÐºÑированной точкой', + '128-bit RGBA Float' => '128-битный, RGBA Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой', + '144-bit 8 Channels Alpha' => '144-битный, 8 каналов, альфа-канал', + '16-bit BGR555' => '16-битный, BGR555', + '16-bit BGR565' => '16-битный, BGR565', + '16-bit Gray' => '16-битный, Серый', + '16-bit Gray Half' => '16-битный, половина Ñерого', + '24-bit 3 Channels' => '24-битный, 3 канала', + '24-bit BGR' => '24-битный, BGR', + '24-bit RGB' => '24-битный, RGB', + '32-bit 3 Channels Alpha' => '32-битный, 3 канала, альфа-канал', + '32-bit 4 Channels' => '32-битный, 4 канала', + '32-bit BGR' => '32-битный, BGR', + '32-bit BGR101010' => '32-битный, BGR101010', + '32-bit BGRA' => '32-битный, BGRA', + '32-bit CMYK' => '32-битный, CMYK', + '32-bit Gray Fixed Point' => '32-битный, Ñерый Ñ Ñ„Ð¸ÐºÑированной точкой', + '32-bit Gray Float' => '32-битный, Серый Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой', + '32-bit PBGRA' => '32-битный, PBGRA', + '32-bit RGBE' => '32-битный, RGBE', + '40-bit 4 Channels Alpha' => '40-битный, 4 канала, альфа-канал', + '40-bit 5 Channels' => '40-битный, 5 каналов', + '40-bit CMYK Alpha' => '40-битный, CMYK, альфа-канал', + '48-bit 3 Channels' => '48-битный, 3 канала', + '48-bit 5 Channels Alpha' => '48-битный, 5 каналов, альфа-канал', + '48-bit 6 Channels' => '48-битный, 6 каналов', + '48-bit RGB' => '48-битный, RGB', + '48-bit RGB Fixed Point' => '48-битный, RGB Ñ Ñ„Ð¸ÐºÑированной точкой', + '48-bit RGB Half' => '48-битный, RGB Half', + '4:2:0 (chroma at 0, 0.5)' => '4:2:0 (цветноÑÑ‚ÑŒ в 0, 0.5)', + '4:2:0 (chroma at 0.5, 0.5)' => '4:2:0 (цветноÑÑ‚ÑŒ в 0.5, 0.5)', + '4:2:2 (chroma at 0, 0)' => '4:2:2 (цветноÑÑ‚ÑŒ в 0, 0)', + '4:2:2 (chroma at 0.5, 0)' => '4:2:2 (цветноÑÑ‚ÑŒ в 0.5, 0)', + '56-bit 6 Channels Alpha' => '56-битный, 6 каналов, альфа-канал', + '56-bit 7 Channels' => '56-битный, 7 каналов', + '64-bit 3 Channels Alpha' => '64-битный, 3 канала, альфа-канал', + '64-bit 4 Channels' => '64-битный, 4 канала', + '64-bit 7 Channels Alpha' => '64-битный, 7 каналов, альфа-канал', + '64-bit 8 Channels' => '64-битный, 8 каналов', + '64-bit CMYK' => '64-битный, CMYK', + '64-bit PRGBA' => '64-битный, PRGBA', + '64-bit RGBA' => '64-битный, RGBA', + '64-bit RGBA Fixed Point' => '64-битный, RGBA Ñ Ñ„Ð¸ÐºÑированной точкой', + '64-bit RGBA Half' => '64-битный, RGBA Half', + '72-bit 8 Channels Alpha' => '72-битный, 8 каналов, альфа-канал', + '8-bit Gray' => '8-битный, Серый', + '80-bit 4 Channels Alpha' => '80-битный, 4 канала, альфа-канал', + '80-bit 5 Channels' => '80-битный, 5 канаов', + '80-bit CMYK Alpha' => '80-битный, CMYK, альфа-канал', + '96-bit 5 Channels Alpha' => '96-битный, 5 каналов, альфа-канал', + '96-bit 6 Channels' => '96-битный, 6 канаов', + '96-bit RGB Fixed Point' => '96-битный, RGB Ñ Ñ„Ð¸ÐºÑированной точкой', + 'Black & White' => 'Чёрно-белый', + 'Grayscale' => 'Оттенки Ñерого', + }, + }, + 'PixelIntensityRange' => 'Диапазон интенÑивноÑти пикÑелей (%)', + 'PixelMagicJBIGOptions' => 'Pixel Magic – Параметры JBIG', + 'PixelScale' => 'МаÑштаб пикÑелÑ', + 'PixelUnits' => { + Description => 'ПикÑельные единицы', + PrintConv => { + 'Unknown' => 'ÐеизвеÑтно', + 'meters' => 'Метры', + }, + }, + 'PixelsPerMeterX' => 'ПикÑелей на метр по X', + 'PixelsPerMeterY' => 'ПикÑелей на метр по Y', + 'PixelsPerUnitX' => 'ПикÑелей на единицу по X', + 'PixelsPerUnitY' => 'ПикÑелей на единицу по Y', + 'PlanarConfiguration' => { + Description => 'Принцип организации данных', + PrintConv => { + 'Chunky' => 'Ðепрерывный (RGBRGB)', + 'Planar' => 'По каналам (RRGGBB)', + }, + }, + 'Planes' => 'ПлоÑкоÑти', + 'PointSize' => 'Размер точки', + 'PopupFillAttributes' => 'Ðттрибуты Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²Ñплывающего окна', + 'PortraitVersion' => 'ÐŸÐ¾Ñ€Ñ‚Ñ€ÐµÑ‚Ð½Ð°Ñ Ð¾Ñ€Ð¸ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ', + 'PoseHeadingDegrees' => 'Ðаправление по компаÑу Ð´Ð»Ñ Ñ†ÐµÐ½Ñ‚Ñ€Ð° Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (°)', + 'PosePitchDegrees' => 'Продольный наклон Ð´Ð»Ñ Ñ†ÐµÐ½Ñ‚Ñ€Ð° Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (°)', + 'PoseRollDegrees' => 'Поперечный наклон Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ (°)', + 'PostScriptFontName' => 'PostScript название шрифта', + 'Pragma' => 'Контроль кÑшированиÑ', + 'Predictor' => { + Description => 'Предиктор', + PrintConv => { + 'Horizontal differencing' => 'Горизонтальное дифференцирование', + 'None' => 'Ðе иÑпользовалÑÑ', + }, + }, + 'PreferredFamily' => 'Предпочитаемое ÑемейÑтво шрифта', + 'PreferredSubfamily' => 'Предпочитаемый Ñтиль шрифта', + 'Prefs' => 'ÐаÑтройки', + 'PreservedSpecimen' => 'Сохраненный образец', + 'PreservedSpecimenMaterialSampleID' => 'ID материала Ñохранённого образца', + 'PresetWhiteBalance' => { + Description => 'ПредуÑтановка баланÑа белого', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкий', + 'Camera Setting' => 'ÐаÑтройка камеры', + 'Cloudy' => 'Облачно', + 'Color Temperature' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð°', + 'Cool White Fluorescent' => 'Холодный белый (флуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð°)', + 'Day Light Fluorescent' => 'Дневной Ñвет (флуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð°)', + 'Day White Fluorescent' => 'Дневной белый (флуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð°)', + 'Daylight' => 'Дневной Ñвет', + 'Flash' => 'Ð’Ñпышка', + 'Shade' => 'Тень', + 'Specify Gray Point' => 'Ð£ÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° Ñерого', + 'Tungsten' => 'Лампа накаливаниÑ', + 'Warm White Fluorescent' => 'Тёплый белый (флуореÑÑ†ÐµÐ½Ñ‚Ð½Ð°Ñ Ð»Ð°Ð¼Ð¿Ð°)', + }, + }, + 'PresetWhiteBalanceAdj' => 'ПредуÑтановка баланÑа белого', + 'Pressure' => 'Давление', + 'Preview' => 'ПредпроÑмотр', + 'PreviewApplicationName' => 'Файл предпроÑмотра – Ðазвание приложениÑ', + 'PreviewApplicationVersion' => 'Файл предпроÑмотра – ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'PreviewColorSpace' => { + Description => 'Файл предпроÑмотра – Цветовое проÑтранÑтво', + PrintConv => { + 'Unknown' => 'ÐеизвеÑтно', + }, + }, + 'PreviewCropBottom' => 'ПредпроÑмотр – Обрезка Ñнизу', + 'PreviewCropLeft' => 'ПредпроÑмотр – Обрезка Ñлева', + 'PreviewCropRight' => 'ПредпроÑмотр – Обрезка Ñправа', + 'PreviewCropTop' => 'ПредпроÑмотр – Обрезка Ñверху', + 'PreviewDateTime' => 'Файл предпроÑмотра – Дата и ВремÑ', + 'PreviewImage' => 'Файл предпроÑмотра', + 'PreviewImageLength' => 'Строк в файле предпроÑмотра', + 'PreviewImageSize' => 'Размер файла предпроÑмотра', + 'PreviewImageStart' => 'Смещение файла предпроÑмотра', + 'PreviewPDF' => 'Файл предпроÑмотра PDF', + 'PreviewPNG' => 'Файл предпроÑмотра PNG', + 'PreviewSettingsDigest' => 'Файл предпроÑмотра – Идентификатор параметров преобразованиÑ', + 'PreviewSettingsName' => 'Файл предпроÑмотра – Ðазвание параметров преобразованиÑ', + 'PreviewTIFF' => 'Файл предпроÑмотра TIFF', + 'PreviewWMF' => 'Файл предпроÑмотра WMF', + 'PrimaryChromaticities' => 'ЦветноÑÑ‚ÑŒ оÑновных цветов', + 'PrimaryFTP' => 'ОÑновной FTP', + 'PrintFlags' => 'Флаги печати', + 'PrintFlagsInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ флагах печати', + 'PrintIMVersion' => 'ВерÑÐ¸Ñ PrintIM', + 'PrintInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ печати', + 'PrintInfo2' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ печати 2', + 'PrintPosition' => 'Положение при печати', + 'PrintScale' => 'МаÑштаб при печати', + 'PrintStyle' => { + Description => 'Стиль печати', + PrintConv => { + 'Centered' => 'По центру', + 'Size to Fit' => 'Подогнать под формат лиÑта', + 'User Defined' => 'Определённый пользователем', + }, + }, + 'Priority' => 'Приоритет', + 'Private' => 'ЧаÑтный', + 'PrivateRTKInfo' => 'ЧаÑÑ‚Ð½Ð°Ñ Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾ RTK', + 'ProTune' => { + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'ProcessingSoftware' => 'Редактировано в приложении', + 'ProcessingTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ¸', + 'ProdNotes' => 'КоличеÑтво заметок производителÑ', + 'ProducedDate' => 'Дата производÑтва', + 'Producer' => 'Производитель', + 'ProductID' => 'ID продукта', + 'ProductOrServiceConstraints' => 'ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð½Ð° продукты или уÑлуги', + 'Profile' => 'Профиль', + 'Profile1AudioCodec' => 'Профиль 1 – Кодек аудио', + 'Profile1Height' => 'Профиль 1 – Ð’Ñ‹Ñота', + 'Profile1VideoCodec' => 'Профиль 1 – Кодек видео', + 'Profile1Width' => 'Профиль 1 – Ширина', + 'ProfileCalibrationSig' => 'Сигнатура калибровки профилÑ', + 'ProfileCopyright' => 'ÐвторÑкое право профилÑ', + 'ProfileDataOffset' => 'Смещение данных профилÑ', + 'ProfileEmbedPolicy' => { + Description => 'Политика Ð²Ð½ÐµÐ´Ñ€ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ', PrintConv => { - 'Horizontal (normal)' => 'Положительное направление', - 'Rotate 180' => 'Поворот на 180°', - 'Rotate 270 CW' => 'Поворот на 270° по чаÑовой Ñтрелке', - 'Rotate 90 CW' => 'Поворот на 90° по чаÑовой Ñтрелке', + 'Allow Copying' => 'Разрешено копирование', + 'Embed if Used' => 'Внедрить еÑли иÑпользуетÑÑ', + 'Never Embed' => 'Ðикогда не внедрÑÑ‚ÑŒ', + 'No Restrictions' => 'Без ограничений', }, }, - 'FileFormat' => 'Формат', - 'FileModifyDate' => 'Дата обновлениÑ', - 'FileName' => 'Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°', - 'FileSize' => 'Размер файла', - 'FileSource' => { - Description => 'ИÑточник файла', + 'ProfileHueSatMapData1' => 'Профиль – Карта оттенков/наÑыщенноÑти – Данные 1', + 'ProfileHueSatMapData2' => 'Профиль – Карта оттенков/наÑыщенноÑти – Данные 2', + 'ProfileHueSatMapDims' => 'Профиль – Карта оттенков/наÑыщенноÑти – Затемнение', + 'ProfileHueSatMapEncoding' => { + Description => 'Профиль – Карта оттенков/наÑыщенноÑти – Кодирование', PrintConv => { - 'Digital Camera' => 'DSC', - 'Film Scanner' => 'Сканнер проÑвечивающего типа', - 'Reflection Print Scanner' => 'Сканнер отражающего типа', + 'Linear' => 'Линейное', }, }, - 'FileType' => 'Тип файла', - 'Filename' => 'Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°', - 'Flash' => { - Description => 'Ð’Ñпышка', + 'ProfileLookTableData' => 'Профиль – Таблица подÑтановки – Данные', + 'ProfileLookTableDims' => 'Профиль – Таблица подÑтановки – Затемнение', + 'ProfileLookTableEncoding' => { + Description => 'Профиль – Таблица подÑтановки – Кодирование', PrintConv => { - 'Auto, Fired' => 'Вкл. (автоматичеÑÐºÐ°Ñ Ð²Ñпышка)', - 'Auto, Fired, Red-eye reduction' => '"Вкл. (автоматичеÑÐºÐ°Ñ Ð²Ñпышка, Ñнижение Ñффекта «краÑных глаз»)"', - 'Auto, Fired, Red-eye reduction, Return detected' => '"Вкл. (автоматичеÑÐºÐ°Ñ Ð²Ñпышка, Ñнижение Ñффекта «краÑных глаз», региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ луча)"', - 'Auto, Fired, Return detected' => '"Вкл. (автоматичеÑÐºÐ°Ñ Ð²Ñпышка, региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ луча)"', - 'Did not fire' => 'Ð’Ñпышка не Ñработала', - 'Fired' => 'Ð’Ñпышка Ñработала', - 'Fired, Red-eye reduction' => 'Вкл. (Ñнижение Ñффекта «краÑных глаз»)', - 'Fired, Red-eye reduction, Return detected' => '"Вкл. (Ñнижение Ñффекта «краÑных глаз», региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ луча)"', - 'Fired, Return detected' => 'Вкл. (региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ луча)', - 'No Flash' => 'Ðет функции вÑпышки', - 'On, Fired' => 'Вкл. (принудительнаÑ)', - 'On, Red-eye reduction' => '"Вкл. (принудительнаÑ, Ñнижение Ñффекта «краÑных глаз»)"', - 'On, Red-eye reduction, Return detected' => '"Вкл. (принудительнаÑ, Ñнижение Ñффекта «краÑных глаз», региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ луча)"', - 'On, Return detected' => '"Вкл. (принудительнаÑ, региÑÑ‚Ñ€Ð°Ñ†Ð¸Ñ Ð¾Ñ‚Ñ€Ð°Ð¶ÐµÐ½Ð½Ð¾Ð³Ð¾ луча)"', + 'Linear' => 'Линейное', }, }, - 'FlashEnergy' => 'МощноÑÑ‚ÑŒ вÑпышки', - 'FlashExposureComp' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð²Ñпышки', - 'FlashpixVersion' => 'ÐŸÐ¾Ð´Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°ÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑÐ¸Ñ Flashpix', - 'FocalLength' => 'ФокуÑное раÑÑтоÑние', - 'FocalLength35efl' => 'ФокуÑное раÑÑтоÑние (приведено к 35 мм)', - 'FocalLengthIn35mmFormat' => 'ФокуÑное раÑÑтоÑние Ð´Ð»Ñ 35-мм фотопленки', - 'FocalPlaneResolutionUnit' => { - Description => 'Элемент Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð² фокальной плоÑкоÑти', + 'ProfileName' => 'Ðазвание профилÑ', + 'ProfileSize' => 'Размер профилÑ', + 'ProfileToneCurve' => 'Профиль – Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ', + 'ProfileType' => { + Description => 'Тип профилÑ', PrintConv => { - 'inches' => 'дюйм', + 'Unspecified' => 'Ðе указан', }, }, - 'FocalPlaneXResolution' => 'Разрешение в фокальной плоÑкоÑти по X', - 'FocalPlaneYResolution' => 'Разрешение в фокальной плоÑкоÑти по Y', - 'FocusMode' => 'ФокуÑировка', - 'ForwardMatrix1' => 'ПрÑÐ¼Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° â„–1', - 'ForwardMatrix2' => 'ПрÑÐ¼Ð°Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ð° â„–2', - 'FrameRate' => 'ПлотноÑÑ‚ÑŒ кадров', - 'FrameSize' => '"Кадр, размер"', - 'GPSAltitude' => 'Ð’Ñ‹Ñота', - 'GPSAltitudeRef' => { - Description => 'Определение по выÑоте', - PrintConv => { - 'Above Sea Level' => 'Уровень морÑ', - 'Below Sea Level' => 'Опорное значение ÑƒÑ€Ð¾Ð²Ð½Ñ Ð¼Ð¾Ñ€Ñ (негативное значение)', - }, - }, - 'GPSAreaInformation' => 'Ðазвание облаÑти GPS', - 'GPSDOP' => 'ТочноÑÑ‚ÑŒ измерениÑ', - 'GPSDateStamp' => 'Дата GPS', - 'GPSDestBearing' => 'Ðзимут пункта назначениÑ', - 'GPSDestBearingRef' => 'ÐžÐ¿Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð´Ð»Ñ Ð°Ð·Ð¸Ð¼ÑƒÑ‚Ð° пункта назначениÑ', - 'GPSDestDistance' => 'РаÑÑтоÑние до пункта назначениÑ', - 'GPSDestDistanceRef' => 'ÐžÐ¿Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° раÑÑтоÑÐ½Ð¸Ñ Ð´Ð¾ пункта назначениÑ', - 'GPSDestLatitude' => 'Широта пункта назначениÑ', - 'GPSDestLatitudeRef' => 'ÐžÐ¿Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð´Ð»Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ñ‹ пункта назначениÑ', - 'GPSDestLongitude' => 'Долгота пункта назначениÑ', - 'GPSDestLongitudeRef' => 'ÐžÐ¿Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð´Ð»Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ñ‹ пункта назначениÑ', - 'GPSDifferential' => { - Description => 'Ð”Ð¸Ñ„Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ GPS', + 'ProgID' => 'ID приложениÑ', + 'ProgramID' => 'ID программы', + 'ProgramMode' => { + Description => 'Режим программы', PrintConv => { - 'Differential Corrected' => 'Ð”Ð¸Ñ„Ñ„ÐµÑ€ÐµÐ½Ñ†Ð¸Ð°Ð»ÑŒÐ½Ð°Ñ ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¿Ñ€Ð¸Ð¼ÐµÐ½ÐµÐ½Ð°', - 'No Correction' => 'Измерение без дифференциальной коррекции', + 'Night Portrait' => 'Ðочной портрет', + 'None' => 'ОтÑутÑтвует', + 'Portrait' => 'Портрет', + 'Sports' => 'Спорт', + 'Sunset' => 'Закат', + 'Text' => 'ТекÑÑ‚', }, }, - 'GPSImgDirection' => 'Ðаправление изображениÑ', - 'GPSImgDirectionRef' => 'ÐžÐ¿Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð´Ð»Ñ Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ', - 'GPSInfo' => 'IFD указатель информации GPS', - 'GPSLatitude' => 'Широта', - 'GPSLatitudeRef' => { - Description => 'Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð¸Ð»Ð¸ ÑŽÐ¶Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', + 'ProgramVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'ProgressiveScans' => { + Description => 'ПрогреÑÑивное Ñканирование', PrintConv => { - 'North' => 'Ð¡ÐµÐ²ÐµÑ€Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', - 'South' => 'Ð®Ð¶Ð½Ð°Ñ ÑˆÐ¸Ñ€Ð¾Ñ‚Ð°', + '3 Scans' => '3 прохода', + '4 Scans' => '4 прохода', + '5 Scans' => '5 проходов', }, }, - 'GPSLongitude' => 'Долгота', - 'GPSLongitudeRef' => { - Description => 'ВоÑÑ‚Ð¾Ñ‡Ð½Ð°Ñ Ð¸Ð»Ð¸ Ð·Ð°Ð¿Ð°Ð´Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', + 'Project' => 'Проект', + 'ProjectionType' => 'Тип проекции', + 'PropertyReleaseID' => 'ID ÑвойÑтв релиза', + 'PropertyReleaseStatus' => { + Description => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ ÑвойÑтв релиза', PrintConv => { - 'East' => 'ВоÑÑ‚Ð¾Ñ‡Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', - 'West' => 'Ð—Ð°Ð¿Ð°Ð´Ð½Ð°Ñ Ð´Ð¾Ð»Ð³Ð¾Ñ‚Ð°', + 'Limited or Incomplete Property Releases' => 'Ограниченные или неполные релизы', + 'None' => 'Ðе обозначено', + 'Not Applicable' => 'Ðе иÑпользуетÑÑ', + 'Unlimited Property Releases' => 'Ðеограниченные релизы ÑвойÑтв', }, }, - 'GPSMapDatum' => 'ИÑпользованы данные геодезичеÑких иÑÑледований', - 'GPSMeasureMode' => { - Description => 'Режим Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ GPS', + 'Protect' => 'Защита', + 'Provider' => 'ПоÑтавщик', + 'ProviderCopyright' => 'ПоÑтавщик – ÐвторÑкое право', + 'ProviderRating' => 'Провайдер – Рейтинг', + 'Province-State' => 'ОблаÑÑ‚ÑŒ/район', + 'PublishDate' => 'Дата публикации', + 'PublishDateStart' => 'Дата начала публикации', + 'Publisher' => 'Издатель', + 'PublisherLimit' => 'ÐžÐ³Ñ€Ð°Ð½Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¸Ð·Ð´Ð°Ñ‚ÐµÐ»Ñ', + 'PxShiftPeriphEdgeNR' => { PrintConv => { - '3-Dimensional Measurement' => '3-мерное измерение', + 'Off' => 'Ðе включён', + 'On' => 'Включен', }, }, - 'GPSProcessingMethod' => 'Ðазвание метода обработки GPS', - 'GPSSatellites' => '"Спутники GPS, иÑпользуемые Ð´Ð»Ñ Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ"', - 'GPSSpeed' => 'СкороÑÑ‚ÑŒ GPS-уÑтройÑтва', - 'GPSSpeedRef' => { - Description => 'СкороÑтной Ñлемент', + 'PyramidLevels' => 'Уровни пирамиды', + 'Quality' => { + Description => 'КачеÑтво', PrintConv => { - 'km/h' => 'Километры в чаÑ', - 'knots' => 'Узлы', - 'mph' => 'Мили в чаÑ', + '2 (Telephone)' => '2 (Телефон)', + '3 (Thumb)' => '3 (ЭÑкиз)', + '4 (Radio)' => '4 (Радио)', + '5 (Standard)' => '5 (Стандартное)', + '6 (Xtreme)' => '6 (ЭкÑтремальное)', + '7 (Insane)' => '7 (СумаÑшедшее)', + '8 (BrainDead)' => '8 (Полный улёт)', + 'Compressed RAW' => 'cRAW', + 'Compressed RAW + JPEG' => 'cRAW+JPEG', + 'Extra Fine' => 'СверхвыÑокое', + 'Fine' => 'Ð’Ñ‹Ñокое', + 'Low' => 'Ðизкое качеÑтво', + 'Normal' => 'Стандартное качеÑтво', + 'RAW + JPEG' => 'RAW+JPEG', + 'Standard' => 'Стандартное', + 'Unstable/Experimental' => 'ÐеÑтабильное/ЭкÑпериментальное', }, }, - 'GPSStatus' => { - Description => 'СоÑтоÑние GPS-уÑтройÑтва', + 'QuantizationMethod' => { + Description => 'Метод квантованиÑ', PrintConv => { - 'Measurement Active' => 'ПроизводитÑÑ Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ðµ', - 'Measurement Void' => 'Ð’Ð·Ð°Ð¸Ð¼Ð½Ð°Ñ ÑовмеÑтимоÑÑ‚ÑŒ измерений', + 'Color Space Specific' => 'Специфичное цветовое проÑтранÑтво', + 'Compression Method Specific' => 'Специфичный метод ÑжатиÑ', + 'Gamma Compensated' => 'КомпенÑÐ°Ñ†Ð¸Ñ Ð³Ð°Ð¼Ð¼Ñ‹', + 'Linear Density' => 'Ð›Ð¸Ð½ÐµÐ¹Ð½Ð°Ñ Ð¿Ð»Ð¾Ñ‚Ð½Ð¾ÑÑ‚ÑŒ', + 'Linear Reflectance/Transmittance' => 'Линейное Отражение/ПропуÑкание', }, }, - 'GPSTimeStamp' => 'GPS-Ð²Ñ€ÐµÐ¼Ñ (атомные чаÑÑ‹)', - 'GPSTrack' => 'Ðаправление движениÑ', - 'GPSTrackRef' => { - Description => 'ÐžÐ¿Ð¾Ñ€Ð½Ð°Ñ Ð²ÐµÐ»Ð¸Ñ‡Ð¸Ð½Ð° Ð½Ð°Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ', + 'QuickEdit' => 'БыÑтрое редактирование', + 'QuickMaskInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ быÑтрой маÑке', + 'QuickShot' => { + Description => 'БыÑтрый Ñнимок', PrintConv => { - 'Magnetic North' => 'Ðаправление магнитной Ñтрелки', - 'True North' => 'ИÑтинное направление', + 'Off' => 'Ðе включён', + 'On' => 'Включен', }, }, - 'GPSVersionID' => 'ВерÑÐ¸Ñ GPS-Ñ‚Ñга', - 'GainControl' => { - Description => 'Управление шагом', + 'RAFVersion' => 'ВерÑÐ¸Ñ RAF', + 'RGBCurves' => 'Кривые RGB', + 'ROIDescription' => 'ОпиÑание ROI', + 'RPP' => 'Raw Photo Processor (RPP)', + 'RasterPadding' => { + Description => 'РаÑтровое заполнение', PrintConv => { - 'High gain down' => 'С большим шагом вниз', - 'High gain up' => 'С большим шагом вверх', - 'Low gain down' => 'С малым шагом вниз', - 'Low gain up' => 'С малым шагом вверх', - 'None' => 'Ðет', + 'Byte' => 'Байт', + 'Long Sector' => 'Длинный Ñектор', + 'Long Word' => 'Длинное Ñлово', + 'Sector' => 'Сектор', + 'Word' => 'Слово', }, }, - 'Gamma' => 'Гамма', - 'Gradation' => 'ВпечатлÑющ.режим', - 'HDR' => { - Description => 'Ðвто HDR', + 'RasterizedCaption' => 'РаÑтрированное опиÑание', + 'Rate' => 'Темп', + 'Rating' => 'Рейтинг', + 'RatingPercent' => 'Рейтинг (%)', + 'RawCropBottom' => 'Raw – Обрезка Ñнизу', + 'RawCropLeft' => 'Raw – Обрезка Ñлева', + 'RawCropRight' => 'Raw – Обрезка Ñправа', + 'RawCropTop' => 'Raw – Обрезка Ñверху', + 'RawData' => 'Raw-данные', + 'RawDataLength' => 'Строк в Raw-данных', + 'RawDataOffset' => 'Смещение RAW-данных', + 'RawDataUniqueID' => 'Уникальный ID RAW-данных', + 'RawDepth' => 'Глубина Raw-изображениÑ', + 'RawFile' => 'RAW-файл', + 'RawFormat' => 'RAW-формат', + 'RawImageDigest' => 'Хеш-Ñумма RAW-изображениÑ', + 'RawImageMode' => 'Режим Raw-изображениÑ', + 'RawImageSegmentation' => 'Ð¡ÐµÐ³Ð¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ RAW-изображениÑ', + 'RawToPreviewGain' => 'КоÑффициент ÑƒÐ²ÐµÐ»Ð¸Ñ‡ÐµÐ½Ð¸Ñ Ð¼ÐµÐ¶Ð´Ñƒ Raw и файлом предпроÑмотра', + 'Rawrppused' => 'ИÑпользовалÑÑ RPP', + 'RawzorCreatorVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'RawzorRequiredVersion' => 'Ð¢Ñ€ÐµÐ±ÑƒÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'ReaderName' => 'Ðазвание проÑмотрщика', + 'ReaderRequirements' => 'Ð¢Ñ€ÐµÐ±Ð¾Ð²Ð°Ð½Ð¸Ñ Ðº ридеру', + 'RecEngineer' => 'Инженер', + 'RecLocation' => 'ЛокациÑ', + 'RecommendedExposureIndex' => 'Рекомендуемый Ð¸Ð½Ð´ÐµÐºÑ ÑкÑпозиции', + 'Record' => 'ЗапиÑÑŒ', + 'RecordBasisOfRecord' => 'ОÑнование запиÑи', + 'RecordCollectionCode' => 'Код/Ðазвание коллекции запиÑи', + 'RecordCollectionID' => 'ID коллекции запиÑи', + 'RecordDataGeneralizations' => 'Обобщение данных запиÑи', + 'RecordDatasetID' => 'ID базы данных запиÑи', + 'RecordDatasetName' => 'Ðазвание базы данных запиÑи', + 'RecordDynamicProperties' => 'ДинамичеÑкие ÑвойÑтва запиÑи', + 'RecordInformationWithheld' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ñ‚ÑутÑÑ‚Ð²ÑƒÑŽÑ‰Ð°Ñ Ð² запиÑи', + 'RecordInstitutionCode' => 'ÐžÑ€Ð³Ð°Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ñ†Ð° или информации', + 'RecordInstitutionID' => 'ID организации Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ñ†Ð° или информации', + 'RecordMode' => 'Режим запиÑи', + 'RecordOwnerInstitutionCode' => 'ОрганизациÑ-владелец образца или информации', + 'RecordShutterRelease' => { + Description => 'СпуÑк затвора при запиÑи', PrintConv => { - 'Off' => 'Отключено', + 'Press start, press stop' => 'Ðажать «Старт», нажать «Стоп»', + 'Record while down' => 'ЗапиÑÑŒ пока нажата кнопка', }, }, - 'Headline' => 'Заголовок', - 'HighISONoiseReduction' => { - Description => 'NR выÑокого ISO', + 'RecurrenceDateTimes' => 'Дата/Ð’Ñ€ÐµÐ¼Ñ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð¸Ñ ÑобытиÑ', + 'RecurrenceID' => 'ID повторÑющегоÑÑ ÑобытиÑ', + 'RecurrenceRule' => 'Правило повторениÑ', + 'RedBalance' => 'Ð‘Ð°Ð»Ð°Ð½Ñ ÐºÑ€Ð°Ñного', + 'RedBlueFlatField' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð¿Ð»Ð¾Ñкого Ð¿Ð¾Ð»Ñ â€“ КраÑный и Синий', + 'RedEndpoint' => 'ÐšÐ¾Ð½ÐµÑ‡Ð½Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° КраÑного', + 'RedEyeReduction' => { + Description => 'Уменьшение Ñффекта краÑных глаз', PrintConv => { - 'Auto' => 'Ðвто', - 'High' => 'Hi', - 'Low' => 'Lo', - 'Normal' => 'ÐормальнаÑ', - 'Off' => 'Отключено', + 'Off' => 'Ðе включено', + 'On' => 'Включено', }, }, - 'Hue' => 'Оттенок', - 'ISO' => 'Значение ISO', - 'ImageHeight' => 'Ð’Ñ‹Ñота Ñнимка', - 'ImageSize' => '"Снимок, размер"', - 'ImageStabilization' => { + 'RedMask' => 'МаÑка КраÑного', + 'RedPrimary' => 'ОÑновной краÑный', + 'RedX' => 'КраÑный по X', + 'RedY' => 'КраÑный по Y', + 'RedcodeVersion' => 'ВерÑÐ¸Ñ Redcode', + 'ReductionMatrix1' => 'Матрица редукции 1', + 'ReductionMatrix2' => 'Матрица редукции 2', + 'ReelName' => 'Ðазвание ноÑÐ¸Ñ‚ÐµÐ»Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ð¸', + 'ReelNumber' => 'Ðомер запиÑи', + 'ReelTimecode' => 'Таймкод запиÑи', + 'Reference' => 'СÑылка', + 'ReferenceBlackWhite' => 'ИÑходные Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ñ‡Ñ‘Ñ€Ð½Ð¾Ð³Ð¾ и белого', + 'ReferenceDate' => 'Дата предыдущего конверта', + 'ReferenceNumber' => 'Ðомер предыдущего конверта', + 'ReferenceService' => 'СÑылка на предыдущий конверт', + 'Refresh' => 'Задержка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ñтраницы', + 'RegionAppliedToDimensions' => 'Размеры Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ которых применÑлÑÑ Ñ€ÐµÐ³Ð¸Ð¾Ð½', + 'RegionAppliedToDimensionsH' => 'Ð’Ñ‹Ñота Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ которой применÑÐ»Ñ Ñ€ÐµÐ³Ð¸Ð¾Ð½', + 'RegionAppliedToDimensionsUnit' => 'Единицы размеров изображениÑ', + 'RegionAppliedToDimensionsW' => 'Ширина Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ которой применÑÐ»Ñ Ñ€ÐµÐ³Ð¸Ð¾Ð½', + 'RegionArea' => 'ОблаÑÑ‚ÑŒ региона', + 'RegionAreaD' => 'Диаметр круглой облаÑти', + 'RegionAreaH' => 'Ð’Ñ‹Ñота прÑмоугольной облаÑи', + 'RegionAreaUnit' => 'Единицы Ð¸Ð·Ð¼ÐµÑ€ÐµÐ½Ð¸Ñ Ð¾Ð±Ð»Ð°Ñти', + 'RegionAreaW' => 'Ширина прÑмоугольной облаÑти', + 'RegionAreaX' => 'Координаты центра облаÑти по X', + 'RegionAreaY' => 'Координаты центра облаÑти по Y', + 'RegionBarCodeValue' => 'Значение штрихкода региона', + 'RegionConstraints' => 'Региональные ограничениÑ', + 'RegionDescription' => 'ОпиÑание региона', + 'RegionExtensions' => 'Дополнительное ÑвойÑтво региона', + 'RegionFocusUsage' => { + Description => 'ИÑпользование фокуÑа', PrintConv => { - 'CCD Shift' => 'ОптичеÑкий Ñтабилизатор', - 'High Sensitivity' => 'Движение объекта Ñъёмки', - 'Off' => 'Выкл', - 'Off (1)' => 'Выкл (1)', + 'Evaluated, Not Used' => 'УчитывалÑÑ, но не иÑпользовалÑÑ', + 'Evaluated, Used' => 'УчитывалÑÑ Ð¸ иÑпользовалÑÑ', + 'Not Evaluated, Not Used' => 'Ðе учитывалÑÑ Ð¸ не иÑпользовалÑÑ', }, }, - 'ImageUniqueID' => 'Уникальный ID-код Ñнимка', - 'ImageWidth' => 'Ширина Ñнимка', - 'Index' => 'ИндекÑ', - 'Instructions' => 'ИнÑтрукции', - 'InteropIndex' => 'Ð˜Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð²Ð·Ð°Ð¸Ð¼Ð½Ð¾Ð¹ ÑовмеÑтимоÑти', - 'InteropOffset' => 'ТÑг взаимной ÑовмеÑтимоÑти', - 'InteropVersion' => 'ВерÑÐ¸Ñ Ð²Ð·Ð°Ð¸Ð¼Ð½Ð¾Ð¹ ÑовмеÑтимоÑти', - 'JPEGQuality' => { - Description => 'КачеÑтво изображениÑ', + 'RegionInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð± регионе', + 'RegionInfoDateRegionsValid' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ð¾Ñледнего региона', + 'RegionInfoMP' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ регионе в Microsoft Photo', + 'RegionInfoRegions' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ регионах', + 'RegionList' => 'СпиÑок Ñтруктуры регионов', + 'RegionName' => 'Ðазвание региона', + 'RegionPersonDisplayName' => 'Ð˜Ð¼Ñ Ñ‡ÐµÐ»Ð¾Ð²ÐµÐºÐ° отмеченное регионом', + 'RegionPersonEmailDigest' => 'Хеш-Ñумма Ñлектронной почты Windows Live пользователÑ', + 'RegionPersonLiveIdCID' => 'ID Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Windows Live CID', + 'RegionPersonSourceID' => 'ИÑходный ID пользователÑ', + 'RegionRectangle' => 'ПрÑмоугольник региона', + 'RegionRotation' => 'Вращение региона', + 'RegionSeeAlso' => 'Смотрите также', + 'RegionType' => { + Description => 'Тип региона', PrintConv => { - 'Extra Fine' => 'СверхвыÑокое', - 'Fine' => 'Ð’Ñ‹Ñокое', - 'Standard' => 'Стандартное качеÑтво', + 'BarCode' => 'Штрихкод', + 'Face' => 'Лицо', + 'Focus' => 'ФокуÑ', + 'Pet' => 'Животное', }, }, - 'Keywords' => 'Ключевые Ñлова', - 'Lens' => 'Объектив', - 'LensInfo' => 'Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¾Ð± объективе', - 'LightSource' => { - Description => 'ИÑточник Ñвета', + 'RegionXformTackPoint' => 'Точки-модификаторы облаÑти Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Xform', + 'RelatedImageFileFormat' => 'Формат файла ÑвÑзанного изображениÑ', + 'RelatedImageHeight' => 'Ð’Ñ‹Ñота ÑвÑзанного изображениÑ', + 'RelatedImageWidth' => 'Ширина ÑвÑзанного изображениÑ', + 'RelatedResourceID' => 'ID ÑвÑзанного реÑурÑа', + 'RelatedSoundFile' => 'СвÑзанный аудиофайл', + 'RelatedTo' => 'ОтноÑитÑÑ Ðº', + 'Relation' => 'СÑылка на ÑвÑзанный реÑурÑ', + 'RelationshipAccordingTo' => 'СвÑзь между реÑурÑами Ñоздал', + 'RelationshipEstablishedDate' => 'Дата ÑвÑзи между реÑурÑами', + 'RelationshipOfResource' => 'СвÑзь реÑурÑов', + 'RelationshipRemarks' => 'Комментарии к ÑвÑзи реÑурÑов', + 'RelativeAltitude' => 'ОтноÑÐ¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð²Ñ‹Ñота', + 'RelativePath' => 'ОтноÑительный путь', + 'ReleaseDate' => 'Дата публикации', + 'ReleaseTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¿ÑƒÐ±Ð»Ð¸ÐºÐ°Ñ†Ð¸Ð¸', + 'RemoveHistoryDuplicates' => 'Удалить иÑторию дубликатов', + 'RenderingIntent' => { + Description => 'Методы цветового преобразованиÑ', PrintConv => { - 'Cloudy' => 'ОблачноÑÑ‚ÑŒ', - 'Cool White Fluorescent' => 'ФлуореÑцентный белый холодный (W 3800 - 4500K)', - 'Day White Fluorescent' => 'ФлуореÑцентный белый дневной', - 'Daylight' => 'Дневной Ñвет', - 'Daylight Fluorescent' => 'ФлуореÑцентный белый дневного Ñвета (D 5700 - 7100K)', - 'Fine Weather' => 'ЯÑÐ½Ð°Ñ Ð¿Ð¾Ð³Ð¾Ð´Ð°', - 'Flash' => 'Ð’Ñпышка', - 'Fluorescent' => 'ФлуореÑцентный', - 'ISO Studio Tungsten' => 'ISO Ð´Ð»Ñ Ñтудийных ламп накаливаниÑ', - 'Other' => 'другой иÑточник Ñвета', - 'Shade' => 'Тень', - 'Standard Light A' => 'Стандартный Ñвет A', - 'Standard Light B' => 'Стандартный Ñвет B', - 'Standard Light C' => 'Стандартный Ñвет C', - 'Tungsten (Incandescent)' => 'Лампа Ð½Ð°ÐºÐ°Ð»Ð¸Ð²Ð°Ð½Ð¸Ñ (Ñркий Ñвет)', - 'Unknown' => 'неизвеÑтно', - 'Warm White Fluorescent' => 'ФлуореÑцентный теплый белый (L 2600 - 3250K)', - 'White Fluorescent' => 'ФлуореÑцентный белый (WW 3250 - 3800K)', + 'Absolute Colorimetric (LCS_GM_ABS_COLORIMETRIC)' => 'ÐбÑолютный колориметричеÑкий (LCS_GM_ABS_COLORIMETRIC)', + 'Graphic (LCS_GM_BUSINESS)' => 'По наÑыщенноÑти (LCS_GM_BUSINESS)', + 'Picture (LCS_GM_IMAGES)' => 'Перцепционный (LCS_GM_IMAGES)', + 'Proof (LCS_GM_GRAPHICS)' => 'ОтноÑительный колориметричеÑкий (LCS_GM_GRAPHICS)', }, }, - 'Lightness' => 'ОÑвещенноÑÑ‚ÑŒ', - 'LinearResponseLimit' => 'Предел линейного отклика', - 'LinearizationTable' => 'Таблица линеаризации', - 'LocalizedCameraModel' => 'Локализованное название фотоаппарата', - 'Location' => 'МеÑто Ñъемки', - 'LongExposureNoiseReduction' => { - Description => 'NR долгой ÑкÑп.', + 'RenderingTransform' => 'Преобразование цвета', + 'RentalExpirationDate' => 'Дата Ð¾ÐºÐ¾Ð½Ñ‡Ð°Ð½Ð¸Ñ Ð°Ñ€ÐµÐ½Ð´Ñ‹', + 'RentalFlag' => 'Флаг аренды', + 'Repeat' => 'КоличеÑтво повторов', + 'ReplayGainAlbumGain' => 'Replay Gain – ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾Ñти альбома', + 'ReplayGainAlbumPeak' => 'Replay Gain – Пиковый уровень альбома', + 'ReplayGainTrackGain' => 'Replay Gain – ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð³Ñ€Ð¾Ð¼ÐºÐ¾Ñти трека', + 'ReplayGainTrackPeak' => 'Replay Gain – Пиковый уровень трека', + 'ReplyTo' => 'E-Mail вебмаÑтера', + 'RepresentativeDisparityFar' => 'Ð ÐµÐ¿Ñ€ÐµÐ·ÐµÐ½Ñ‚Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ Ð½ÐµÑоглаÑованноÑÑ‚ÑŒ – Вдали', + 'RepresentativeDisparityNear' => 'Ð ÐµÐ¿Ñ€ÐµÐ·ÐµÐ½Ñ‚Ð°Ñ‚Ð¸Ð²Ð½Ð°Ñ Ð½ÐµÑоглаÑованноÑÑ‚ÑŒ – РÑдом', + 'RepresentativeImage' => { + Description => 'Репрезентативное изображение', PrintConv => { - 'Off' => 'Отключено', - 'On' => 'Включено', + 'Left Viewpoint' => 'Ð›ÐµÐ²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° проÑмотра', + 'Right Viewpoint' => 'ÐŸÑ€Ð°Ð²Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° проÑмотра', }, }, - 'Make' => 'Изготовитель', - 'MakerNote' => 'Приватные данные DNG', - 'MakerNoteSafety' => { - Description => 'БезопаÑноÑÑ‚ÑŒ «примечаний производителÑ»', + 'RequestID' => 'ID запрÑа', + 'RequestStatus' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð·Ð°Ð¿Ñ€Ð¾Ñа', + 'Resaved' => { + Description => 'Повторное Ñохранение', PrintConv => { - 'Safe' => 'БезопаÑно', - 'Unsafe' => 'ÐебезопаÑно', + 'No' => 'Ðет', + 'Yes' => 'Да', }, }, - 'MakerNotes' => 'Данные производителей', - 'MaskedAreas' => 'Ðеактивные облаÑти', - 'MaxAperture' => 'МакÑ. диафрагма объектива', - 'MeteringMode' => { - Description => 'ЭкÑпозамер', + 'Reserved5' => 'Зарезервировано 5', + 'Resolution' => 'Разрешение изображениÑ', + 'ResolutionUnit' => { + Description => 'Единицы Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾ X и Y', PrintConv => { - 'Average' => 'Средний', - 'Center-weighted average' => 'Центрально-взвешенный Ñредний', - 'Multi-segment' => 'Узор', - 'Multi-spot' => 'Многозональный', - 'Other' => 'Другое', - 'Partial' => 'ЧаÑтичный', - 'Spot' => 'Точечный', - 'Unknown' => 'неизвеÑтно', + 'None' => 'Ðе указаны', + 'cm' => 'Ñм', + 'inches' => 'дюймы', }, }, - 'Model' => 'Камера', - 'ModifyDate' => '"Файл, изменить дату и времÑ"', - 'MultiFrameNoiseReduction' => { - Description => 'Многокадр. шумоподавл.', + 'ResourceCount' => 'КоличеÑтво реÑурÑов', + 'ResourceForkSize' => 'Размер Ñ€Ð°Ð·Ð²ÐµÑ‚Ð²Ð»ÐµÐ½Ð¸Ñ Ñ€ÐµÑурÑа', + 'ResourceID' => 'ID реÑурÑа', + 'ResourceRelationship' => 'СвÑзи реÑурÑов', + 'ResourceRelationshipID' => 'ID ÑвÑзи между реÑурÑами', + 'ResourceType' => 'Тип реÑурÑа', + 'Resources' => 'РеÑурÑÑ‹', + 'RetailPrice' => 'Ð Ð¾Ð·Ð½Ð¸Ñ‡Ð½Ð°Ñ Ñ†ÐµÐ½Ð°', + 'RetailPriceCurrency' => 'Валюта розничной цены', + 'Reuse' => { + Description => 'Повторное иÑпользование', PrintConv => { - 'Off' => 'Отключено', - 'On' => 'Включено', + 'Not Applicable' => 'Запрещено', + 'Repeat Use' => 'Разрешено', }, }, - 'NoiseReduction' => 'Шумоподавление', - 'NoiseReductionApplied' => 'Применённое шумоподавление', - 'Opto-ElectricConvFactor' => 'Фактор оптико-ÑлектричеÑкого преобразованиÑ', - 'Orientation' => { - Description => 'ОриентациÑ', + 'Review' => 'Обзор', + 'Revision' => 'Дата Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ vCard', + 'RevisionDate' => 'Дата ревизии', + 'RevisionNumber' => 'КоличеÑтво редакций файла', + 'RevisitAfter' => 'Повторно поÑетить через', + 'RicohPitch' => 'Ricoh – Тангаж (Ðаклон)', + 'RicohRoll' => 'Ricoh – Крен (Вращение)', + 'RightAlbedo' => 'Правильное ÑтереоÑкопичеÑкое изображение', + 'Rights' => 'Права', + 'Robots' => 'Политика обработки Ñтраницы роботами', + 'Roll' => 'Крен (Вращение)', + 'RollAngle' => 'Угол Ð²Ñ€Ð°Ñ‰ÐµÐ½Ð¸Ñ (Крен)', + 'RootDirectoryCreateDate' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÐºÐ¾Ñ€Ð½ÐµÐ²Ð¾Ð³Ð¾ каталога', + 'Rotation' => 'Вращение', + 'RoundTripVersion' => 'ВерÑÐ¸Ñ Round Trip', + 'Routing' => 'Роутинг', + 'RoutingDestinations' => 'Ðазначение маршрутизации', + 'RoutingExclusions' => 'ИÑÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¼Ð°Ñ€ÑˆÑ€ÑƒÑ‚Ð¸Ð·Ð°Ñ†Ð¸Ð¸', + 'RowInterleaveFactor' => 'КоÑффициент Ñ‡ÐµÑ€ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтрок', + 'RowsPerStrip' => 'КоличеÑтво Ñтрок на полоÑу', + 'RtkFlag' => 'Rtk – Флаг', + 'RtkStdHgt' => 'Rtk – Стандартное отклонение выÑоты', + 'RtkStdLat' => 'Rtk – Стандартное отклонение широты', + 'RtkStdLon' => 'Rtk – Стандартное отклонение долготы', + 'RunTimeEpoch' => 'Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ â€“ Ðомер Ñпохи', + 'RunTimeFlags' => { + Description => 'Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ â€“ Флаги', PrintConv => { - 'Horizontal (normal)' => 'Положительное направление', - 'Rotate 180' => 'Поворот на 180°', - 'Rotate 270 CW' => 'Поворот на 270° по чаÑовой Ñтрелке', - 'Rotate 90 CW' => 'Поворот на 90° по чаÑовой Ñтрелке', + 'Has been rounded' => 'Округленное времÑ', + 'Indefinite' => 'Ðеопределённое времÑ', + 'Negative infinity' => 'ÐœÐ¸Ð½ÑƒÑ Ð±ÐµÑконечноÑÑ‚ÑŒ', + 'Positive infinity' => 'ÐŸÐ»ÑŽÑ Ð±ÐµÑконечноÑÑ‚ÑŒ', + 'Valid' => 'ДейÑтвительное времÑ', }, }, - 'OriginalRawFileData' => 'ИÑходные данные raw-файла', - 'OriginalRawFileDigest' => 'Сигнатура иÑходного Raw-файла', - 'OriginalRawFileName' => 'ИÑходное Ð¸Ð¼Ñ Raw-файла', - 'PhotometricInterpretation' => 'СоÑтав пикÑела', - 'PlanarConfiguration' => { - Description => 'ÐžÑ€Ð³Ð°Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð´Ð°Ð½Ð½Ñ‹Ñ… изображениÑ', + 'RunTimeScale' => 'Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ â€“ Шкала времени', + 'RunTimeSincePowerUp' => 'Ð’Ñ€ÐµÐ¼Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¼Ð¾Ð¼ÐµÐ½Ñ‚Ð° включениÑ', + 'RunTimeValue' => 'Ð’Ñ€ÐµÐ¼Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ â€“ Значение', + 'RunWindow' => { + Description => 'ЗапуÑтить окно', PrintConv => { - 'Chunky' => 'крупный формат', - 'Planar' => 'планарный формат', + 'Hide' => 'Скрытый', + 'Minimized' => 'Минимизировать', + 'Normal' => 'Обычный', + 'Restore' => 'ВоÑÑтановить', + 'Show' => 'Показывать', + 'Show Default' => 'Отображать по-умолчанию', + 'Show Maximized' => 'Отображать развёрнутым', + 'Show Minimized' => 'Отображать Ñвернутым', + 'Show Minimized No Activate' => 'Отображать Ñвернутым и не активвным', + 'Show No Activate' => 'Отображать', }, }, - 'PreviewApplicationName' => 'Ð˜Ð¼Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра', - 'PreviewApplicationVersion' => 'ВерÑÐ¸Ñ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра', - 'PreviewColorSpace' => { - Description => 'Цветовое проÑтранÑтво предпроÑмотра', + 'SEMInfo' => 'SEM – ОпиÑание', + 'SIUnits' => 'Единицы SI', + 'SMaxSampleValue' => 'МакÑимальное значение компонента', + 'SMinSampleValue' => 'Минимальное значение компонента', + 'SRGBRendering' => { + Description => 'SRGB-рендеринг', PrintConv => { - 'Unknown' => 'ÐеизвеÑтно', + 'Absolute Colorimetric' => 'ÐбÑолютно колориметричеÑкий', + 'Perceptual' => 'Перцепционный', + 'Relative Colorimetric' => 'ОтноÑительно колориметричеÑкий', + 'Saturation' => 'ÐаÑыщенный', }, }, - 'PreviewDateTime' => 'Дата и Ð²Ñ€ÐµÐ¼Ñ Ð¿Ñ€ÐµÐ´Ð¿Ñ€Ð¾Ñмотра', - 'PreviewSettingsDigest' => 'Сигнатура наÑтроек предпроÑмотра', - 'PreviewSettingsName' => 'Ðазвание наÑтроек предпроÑмотра', - 'PrimaryChromaticities' => 'ТональноÑÑ‚ÑŒ оÑновных цветов', - 'ProfileCalibrationSig' => 'Сигнатура калибровки профилÑ', - 'ProfileCopyright' => 'ÐвторÑкие права профилÑ', - 'ProfileEmbedPolicy' => { - Description => 'Политика Ð²Ð½ÐµÐ´Ñ€ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ', + 'SRawType' => 'Тип SRaw', + 'SampleFlag' => 'Флаг образца', + 'SampleFormat' => { + Description => 'Формат компонента', PrintConv => { - 'Allow Copying' => 'Разрешено копирование', - 'Embed if Used' => 'Внедрить еÑли иÑпользован', - 'Never Embed' => 'Ðикогда не внедрÑÑ‚ÑŒ', - 'No Restrictions' => 'Ðет ограничений', + 'Complex float' => 'КомплекÑные данные Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой IEEE', + 'Complex int' => 'КомплекÑные целые данные', + 'Float' => 'Данные Ñ Ð¿Ð»Ð°Ð²Ð°ÑŽÑ‰ÐµÐ¹ точкой IEEE', + 'Signed' => 'ЦелочиÑленные данные Ñо знаком', + 'Undefined' => 'Ðеопределенный формат данных', + 'Unsigned' => 'Беззнаковые целочиÑленные данные', }, }, - 'ProfileHueSatMapData1' => 'Даные Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ñ‚ÐµÐ½ÐºÐ°/наÑыщенноÑти â„–1', - 'ProfileHueSatMapData2' => 'Даные Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¾Ñ‚Ñ‚ÐµÐ½ÐºÐ°/наÑыщенноÑти â„–2', - 'ProfileHueSatMapDims' => 'КоличеÑтво образцов оттенков', - 'ProfileLookTableData' => 'Данные таблицы проÑмотра', - 'ProfileLookTableDims' => 'КоличеÑтво образцов оттенков', - 'ProfileName' => 'Ð˜Ð¼Ñ Ð¿Ñ€Ð¾Ñ„Ð¸Ð»Ñ', - 'ProfileToneCurve' => 'ÐšÑ€Ð¸Ð²Ð°Ñ ÑрокÑти профилÑ', - 'Province-State' => 'ОблаÑÑ‚ÑŒ/район', - 'Quality' => { - Description => 'КачеÑтво изображениÑ', + 'SampleRate' => 'ЧаÑтота диÑкретизации', + 'SampleRate2' => 'ЧаÑтота диÑкретизации 2', + 'SampleSize' => 'Размер', + 'SampleStructure' => { + Description => 'Структура компонента', PrintConv => { - 'Compressed RAW' => 'cRAW', - 'Compressed RAW + JPEG' => 'cRAW+JPEG', - 'Extra Fine' => 'СверхвыÑокое', - 'Fine' => 'Ð’Ñ‹Ñокое', - 'Low' => 'Ðизкое качеÑтво', - 'Normal' => 'Стандартное качеÑтво', - 'RAW + JPEG' => 'RAW+JPEG', - 'Standard' => 'Стандартное', + 'CompressionDependent' => 'ЗавиÑÐ¸Ð¼Ð°Ñ Ð¾Ñ‚ ÑжатиÑ', + 'Orthogonal4-2-2Sampling' => 'ÐžÑ€Ñ‚Ð¾Ð³Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ñ Ñ‡Ð°Ñтотами диÑкретизации в Ñоотношении 4: 2: 2: (4)', + 'OrthogonalConstangSampling' => 'ÐžÑ€Ñ‚Ð¾Ð³Ð¾Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ñ Ñ‚ÐµÐ¼Ð¸ же отноÑительными чаÑтотами диÑкретизации в каждом компоненте', }, }, - 'RawDataUniqueID' => 'Уникальный идентификатор файла', - 'RawImageDigest' => 'Сигнатура RAW-файла', - 'RecordMode' => 'Режим запиÑи', - 'ReductionMatrix1' => 'Матрица редукции â„–1', - 'ReductionMatrix2' => 'Матрица редукции 2', - 'ReferenceBlackWhite' => 'Пара опорных значений черного и белого', - 'RelatedImageFileFormat' => 'Формат файла ÑвÑзанного Ñнимка', - 'RelatedImageHeight' => 'Длина ÑвÑзанного Ñнимка', - 'RelatedImageWidth' => 'Ширина ÑвÑзанного Ñнимка', - 'RelatedSoundFile' => 'СвÑзанный аудио-файл', - 'ResolutionUnit' => { - Description => 'Элемент Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ñ Ð¿Ð¾ X и Y', + 'SampleText' => 'Пример текÑта', + 'SamplesPerPixel' => 'КоличеÑтво компонентов на пикÑель', + 'SamsungRawByteOrder' => 'Samsung RAW – ПорÑдок байтов', + 'SamsungRawPointersLength' => 'Samsung RAW – Длина указателей', + 'SamsungRawPointersOffset' => 'Samsung RAW – Смещение указателей', + 'SamsungRawUnknown' => 'Samsung RAW – ÐеизвеÑтно', + 'SanyoQuality' => { + Description => 'Sanyo – КачеÑтво', PrintConv => { - 'cm' => 'Ñантиметры', - 'inches' => 'дюймы', + 'Fine/High' => 'Хорошее/Ð’Ñ‹Ñокое', + 'Fine/Low' => 'Хорошее/Ðизкое', + 'Fine/Medium' => 'Хорошее/Среднее', + 'Fine/Medium High' => 'Хорошее/Выше Ñреднего', + 'Fine/Medium Low' => 'Хорошее/Ðиже Ñреднего', + 'Fine/Super High' => 'Хорошее/Лучшее', + 'Fine/Very High' => 'Хорошее/Очень выÑокое', + 'Fine/Very Low' => 'Хорошее/Очень низкое', + 'Normal/High' => 'Ðормальное/Ð’Ñ‹Ñокое', + 'Normal/Low' => 'Ðормальное/Ðизкое', + 'Normal/Medium' => 'Ðормальное/Среднее', + 'Normal/Medium High' => 'Ðормальное/Выше Ñреднего', + 'Normal/Medium Low' => 'Ðормальное/Ðиже Ñреднего', + 'Normal/Super High' => 'Ðормальное/Лучшее', + 'Normal/Very High' => 'Ðормальное/Очень выÑокое', + 'Normal/Very Low' => 'Ðормальное/Очень низкое', + 'Super Fine/High' => 'Лучшее/Ð’Ñ‹Ñокое', + 'Super Fine/Low' => 'Лучшее/Ðизкое', + 'Super Fine/Medium' => 'Лучшее/Среднее', + 'Super Fine/Medium High' => 'Лучшее/Выше Ñреднего', + 'Super Fine/Medium Low' => 'Лучшее/Ðиже Ñреднего', + 'Super Fine/Super High' => 'Лучшее/Лучшее', + 'Super Fine/Very High' => 'Лучшее/Очень выÑокое', + 'Super Fine/Very Low' => 'Лучшее/Очень низкое', }, }, - 'RowInterleaveFactor' => 'Ширина Ñ‡ÐµÑ€ÐµÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ Ñтрок', - 'RowsPerStrip' => 'ЧиÑло Ñ€Ñдов в полоÑе', - 'SamplesPerPixel' => 'КоличеÑтво компонентов', + 'SanyoThumbnail' => 'Sanyo – Миниатюра', 'Saturation' => { Description => 'ÐаÑыщенноÑÑ‚ÑŒ', PrintConv => { - 'High' => 'Ð’Ñ‹ÑÐ¾ÐºÐ°Ñ Ð½Ð°ÑыщенноÑÑ‚ÑŒ', - 'Low' => 'ÐÐ¸Ð·ÐºÐ°Ñ Ð½Ð°ÑыщенноÑÑ‚ÑŒ', - 'Normal' => 'Стандартный', + 'High' => 'Ð’Ñ‹ÑокаÑ', + 'Low' => 'ÐизкаÑ', + 'Normal' => 'СтандартнаÑ', }, }, + 'SaturationAdj' => 'Регулировка наÑыщенноÑти', + 'ScaleFactor' => 'КоÑффициент маÑштабированиÑ', + 'ScaleFactor35efl' => 'КоÑффициент маÑÑˆÑ‚Ð°Ð±Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ðº 35-мм формату', + 'ScaledIMU' => 'МаÑштабируемый IMU', + 'ScaledPressure' => 'ВычиÑленное давление', + 'ScalingFactor' => 'КоÑффициент маÑштабированиÑ', + 'ScanningDirection' => { + Description => 'Ðаправление ÑканированиÑ', + PrintConv => { + 'Bottom-Top, L-R' => 'Снизу вверх, Ñлева направо', + 'Bottom-Top, R-L' => 'Снизу вверх, Ñправа налево', + 'L-R, Bottom-Top' => 'Слева направо, Ñнизу вверх', + 'L-R, Top-Bottom' => 'Слева направо, Ñверху вниз', + 'R-L, Bottom-Top' => 'Справа налево, Ñнизу вверх', + 'R-L, Top-Bottom' => 'Справа налево, Ñверху вниз', + 'Top-Bottom, L-R' => 'Сверху вниз, Ñлева направо', + 'Top-Bottom, R-L' => 'Сверху вниз, Ñправа налево', + }, + }, + 'Scene' => 'Ðомер изображениÑ', 'SceneCaptureType' => { - Description => 'Ð¡ÑŽÐ¶ÐµÑ‚Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¼Ð°', + Description => 'Тип Ñнимаемой Ñцены', PrintConv => { 'Landscape' => 'Пейзаж', - 'Night' => 'ÐÐ¾Ñ‡Ð½Ð°Ñ Ñъемка', + 'Night' => 'ÐÐ¾Ñ‡Ð½Ð°Ñ Ñъёмка', + 'Other' => 'Другой', 'Portrait' => 'Портрет', - 'Standard' => 'Стандартный', + 'Standard' => 'Стандартный режим', }, }, 'SceneMode' => { Description => 'Выбор Ñцены', PrintConv => { '3D Sweep Panorama' => '3D', - 'Anti Motion Blur' => 'УÑÑ‚Ñ€. размыт. движ.', + 'Anti Motion Blur' => 'УÑтранение ÑмазываниÑ', 'Auto' => 'Ðвто', - 'Cont. Priority AE' => 'Ðепрер. приор. ÐЭ', - 'Handheld Night Shot' => 'ÐÐ¾Ñ‡Ð½Ð°Ñ Ñъемка Ñ Ñ€ÑƒÐº', + 'Cont. Priority AE' => 'ÐвтоÑкÑÐ¿Ð¾Ð·Ð¸Ñ†Ð¸Ñ Ñ Ð¿Ñ€Ð¸Ð¾Ñ€Ð¸Ñ‚ÐµÑ‚Ð¾Ð¼ Ñерийной Ñъёмки', + 'Handheld Night Shot' => 'ÐÐ¾Ñ‡Ð½Ð°Ñ Ñъёмка Ñ Ñ€ÑƒÐº', 'Landscape' => 'Пейзаж', 'Macro' => 'МакроÑъёмка', 'Night Portrait' => 'Ðочной портрет', @@ -624,75 +4836,742 @@ $VERSION = '1.04'; 'Sweep Panorama' => 'Панорамный обзор', }, }, + 'SceneSelect' => { + Description => 'Выбор Ñцены', + PrintConv => { + 'Lamp' => 'Лампа', + 'Night' => 'Ðочь', + 'Off' => 'Ðе задейÑтвован', + 'Sport' => 'Спорт', + 'User 1' => 'ПользовательÑÐºÐ°Ñ 1', + 'User 2' => 'ПользовательÑÐºÐ°Ñ 2', + }, + }, 'SceneType' => { - Description => 'Тип Ñюжета', + Description => 'Тип Ñцены', + PrintConv => { + 'Directly photographed' => 'Сфотографировано цифровой камерой', + }, + }, + 'School' => 'Школа', + 'ScreenBufferSize' => 'Размер буфера Ñкрана', + 'ScreenHeight' => 'Ð’Ñ‹Ñота Ñкрана', + 'ScreenWidth' => 'Ширина Ñкрана', + 'ScreenWindowCenter' => 'Окно по центру Ñкрана', + 'ScreenWindowWidth' => 'Окно по ширине Ñкрана', + 'SecondaryFTP' => 'Дополнительный FTP', + 'SecurityClassification' => { + Description => 'КлаÑÑÐ¸Ñ„Ð¸ÐºÐ°Ñ†Ð¸Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°ÑноÑти', + PrintConv => { + 'Confidential' => 'Личное', + 'Restricted' => 'Ð”Ð»Ñ ÑƒÐ·ÐºÐ¾Ð³Ð¾ круга', + 'Secret' => 'Секретно', + 'Top Secret' => 'Совершенно Ñекретно', + 'Unclassified' => 'Без клаÑÑификации', + }, + }, + 'SeekTable' => 'Таблица поиÑка', + 'SelfData' => 'СобÑтвенные данные', + 'SelfTimer' => { + Description => 'Режим автоÑпуÑка затвора', PrintConv => { - 'Directly photographed' => 'ÐепоÑредÑтвенно полученный Ñнимок', + 'Off' => 'Ðе задейÑтвован', + 'On' => 'Включен', }, }, + 'SelfTimerMode' => 'Режим таймера ÑпуÑка затвора', 'SensingMethod' => { - Description => 'Метод региÑтрации', + Description => 'Тип датчика', + PrintConv => { + 'Color sequential area' => 'Цветной поÑледовательный ÑенÑор', + 'Color sequential linear' => 'Цветной поÑледовательный линейный ÑенÑор', + 'Monochrome area' => 'Монохромный ÑенÑор', + 'Monochrome linear' => 'Монохромный линейный ÑенÑор', + 'Not defined' => 'Ðе опредеен', + 'One-chip color area' => 'Одночиповый цветной ÑенÑор', + 'Three-chip color area' => 'Трехчиповый цветной ÑенÑор', + 'Trilinear' => 'Трехлинейный цветной ÑенÑор', + 'Two-chip color area' => 'Двухчиповый цветной ÑенÑор', + }, + }, + 'SensitivityType' => { + Description => 'Тип чувÑтвительноÑти', + PrintConv => { + 'ISO Speed' => 'ЧувÑтвительноÑÑ‚ÑŒ ISO', + 'Recommended Exposure Index' => 'Рекомендуемый Ð¸Ð½Ð´ÐµÐºÑ ÑкÑпозиции', + 'Recommended Exposure Index and ISO Speed' => 'Рекомендуемый Ð¸Ð½Ð´ÐµÐºÑ ÑкÑпозиции и ISO', + 'Standard Output Sensitivity' => 'Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð°Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ', + 'Standard Output Sensitivity and ISO Speed' => 'Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð°Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ и ISO', + 'Standard Output Sensitivity and Recommended Exposure Index' => 'Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð°Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ и рекомендуемый Ð¸Ð½Ð´ÐµÐºÑ ÑкÑпозиции', + 'Standard Output Sensitivity, Recommended Exposure Index and ISO Speed' => 'Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð°Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ и рекомендуемый Ð¸Ð½Ð´ÐµÐºÑ ÑкÑпозиции и ISO', + 'Unknown' => 'ÐеизвеÑтно', + }, + }, + 'Sensor' => 'СенÑор', + 'SensorBottomBorder' => 'ÐижнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° ÑенÑора', + 'SensorCalibration_0x0404' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0404', + 'SensorCalibration_0x0405' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0405', + 'SensorCalibration_0x0406' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0406', + 'SensorCalibration_0x0408' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0408', + 'SensorCalibration_0x040f' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x040f', + 'SensorCalibration_0x0413' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0413', + 'SensorCalibration_0x0414' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0414', + 'SensorCalibration_0x0418' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x0418', + 'SensorCalibration_0x041c' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x041c', + 'SensorCalibration_0x041e' => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ ÑенÑора 0x041e', + 'SensorDefects' => 'Дефекты ÑенÑора', + 'SensorHeight' => 'Ð’Ñ‹Ñота ÑенÑора', + 'SensorLeftBorder' => 'Ð›ÐµÐ²Ð°Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° ÑенÑора', + 'SensorLeftMargin' => 'Матрица – ОтÑтуп Ñлева', + 'SensorRightBorder' => 'ÐŸÑ€Ð°Ð²Ð°Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° ÑенÑора', + 'SensorSerialNumber' => 'Серийный номер ÑенÑора', + 'SensorTemperature' => 'Датчик температуры', + 'SensorTemperature2' => 'Датчик температуры 2', + 'SensorTopBorder' => 'ВерхнÑÑ Ð³Ñ€Ð°Ð½Ð¸Ñ†Ð° ÑенÑора', + 'SensorTopMargin' => 'Матрица – ОтÑтуп Ñправа', + 'SensorWidth' => 'Ширина ÑенÑора', + 'Sequence' => 'ПоÑледовательноÑÑ‚ÑŒ', + 'SequenceNumber' => 'ПорÑдковый номер', + 'SequenceShotInterval' => { + Description => 'Интервал поÑледовательных Ñнимков', + PrintConv => { + '10 frames/s' => '10 кадров/Ñ', + '15 frames/s' => '15 кадров/Ñ', + '20 frames/s' => '20 кадров/Ñ', + '5 frames/s' => '5 кадров/Ñ', + }, + }, + 'SequentialShot' => { + Description => 'ПоÑледовательноÑÑ‚ÑŒ Ñнимков', PrintConv => { - 'Color sequential area' => 'ПоÑледовательный ÑенÑор цветовой облаÑти', - 'Color sequential linear' => 'ПоÑледовательный линейный цветовой ÑенÑор', - 'One-chip color area' => 'ОднопроцеÑÑорный ÑенÑор цветовой облаÑти', - 'Three-chip color area' => 'ТрехпроцеÑÑорный ÑенÑор цветовой облаÑти', - 'Trilinear' => 'Трехлинейный цветовой ÑенÑор', - 'Two-chip color area' => 'ДвухпроцеÑÑорный ÑенÑор цветовой облаÑти', + 'Adjust Exposure' => 'По Ñдвигу ÑкÑпозиции', + 'Best' => 'Лучший Ñнимок', + 'None' => 'Ðет', + 'Standard' => 'СтандартнаÑ', }, }, - 'SerialNumber' => 'ID-код фотокамеры', + 'SerialNumber' => 'Серийный номер камеры', + 'Series' => 'СериÑ', + 'SeriesDateTime' => 'Дата Ñерии', + 'SeriesDescription' => 'ОпиÑание Ñрии', + 'SeriesModality' => 'МодальноÑÑ‚ÑŒ Ñерии', + 'SeriesNumber' => 'Ðомер Ñерии', + 'ServiceID' => 'ID ÑервиÑа', + 'ServiceIdentifier' => 'Идентификатор поÑтавщика и продукта', + 'SetCookie' => 'ÐаÑтройки cookie', 'ShadingCompensation' => 'УÑтранение теней', 'ShadowScale' => 'Диапазон теней', + 'Shadows' => 'Тени', + 'ShadowsAdj' => 'Регулировка теней', + 'SharedData' => 'Общие данные', 'Sharpness' => { Description => 'РезкоÑÑ‚ÑŒ', PrintConv => { - 'Hard' => 'Резкий', - 'Normal' => 'Стандартный', - 'Soft' => 'ÐœÑгкий', + 'Hard' => 'СильнаÑ', + 'Normal' => 'СтандартнаÑ', + 'Soft' => 'СлабаÑ', + }, + }, + 'SharpnessAdj' => 'Регулировка резкоÑтти', + 'SharpnessOvershoot' => 'РезкоÑÑ‚ÑŒ – Положительное отклонение', + 'SharpnessThreshold' => 'РезкоÑÑ‚ÑŒ – Порог', + 'SharpnessUndershoot' => 'РезкоÑÑ‚ÑŒ – Отрицательное отклонение', + 'ShootingCount' => 'КоличеÑтво Ñнимков Ñ Ð¾Ð±ÐµÐ¸Ñ… точек проÑмотра', + 'ShootingMode' => 'Режим Ñъёмки', + 'ShortDocumentID' => 'Краткий ID документа', + 'ShutterCurtainHack' => { + Description => 'Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ ÑˆÑ‚Ð¾Ñ€ÐºÐ¸ затвора', + PrintConv => { + '1st-curtain sync' => 'Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾ 1-й шторке', + '2nd-curtain sync' => 'Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð¿Ð¾ 2-й шторке', + }, + }, + 'ShutterSpeed' => 'СкороÑÑ‚ÑŒ ÑÑ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ñ‚Ð²Ð¾Ñ€Ð°', + 'ShutterSpeedValue' => 'СкороÑÑ‚ÑŒ ÑÑ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ð·Ð°Ñ‚Ð²Ð¾Ñ€Ð°', + 'Sidebars' => 'КоличеÑтво боковых панелей', + 'SidecarForExtension' => 'РаÑширение файла', + 'Signature' => 'ПодпиÑÑŒ', + 'SignatureUsageRights' => 'Права на иÑпользование ПодпиÑи', + 'SignerContactInfo' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – ÐšÐ¾Ð½Ñ‚Ð°ÐºÑ‚Ð½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ', + 'SignificantBits' => 'Старшие биты', + 'SigningAuthority' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – Орган', + 'SigningDate' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – Дата подпиÑи', + 'SigningLocation' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – МеÑтоположение', + 'SigningReason' => 'Ð­Ð»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð°Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÑŒ – Причина подпиÑаниÑ', + 'SimilarityIndex' => 'Ð˜Ð½Ð´ÐµÐºÑ ÑходÑтва', + 'Site' => 'Сайт', + 'SiteEnter' => 'Эффект при заходе на Ñайт', + 'SiteExit' => 'Эффект при уходе Ñ Ñайта', + 'SizeMode' => { + Description => 'Режим размера', + PrintConv => { + 'Size Known' => 'Размер извеÑтный', + 'Size Not Known' => 'Размер не извеÑтен', + }, + }, + 'SlateInformation' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ Slate', + 'SlicesGroupName' => 'Ðазвание группы фрагментов', + 'Smoothness' => 'Сглаживание', + 'Snapshots' => 'Скриншоты', + 'SocTemperature' => 'Температура на чипе (Soc)', + 'SocialProfile' => 'Социальный профиль', + 'Software' => { + Description => 'Приложение', + PrintConv => { + 'PC Paintbrush 2.8 (with palette)' => 'PC Paintbrush 2.8 (Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð¾Ð¹)', + 'PC Paintbrush 2.8 (without palette)' => 'PC Paintbrush 2.8 (без палитры)', + 'PC Paintbrush for Windows' => 'PC Paintbrush Ð´Ð»Ñ Windows', + }, + }, + 'SoftwareVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'SonyCropSize' => 'Sony – Размер рамки кадрированиÑ', + 'SonyCropTopLeft' => 'Sony – Верхний левый угол рамки кадрированиÑ', + 'SonyRawFileType' => { + Description => 'Sony – Тип RAW-файла', + PrintConv => { + 'Sony Compressed RAW' => 'Sony – Ñжатый RAW', + 'Sony Lossless Compressed RAW' => 'Sony – Ñжатый без потерь RAW', + 'Sony Uncompressed 12-bit RAW' => 'Sony – 12-битный неÑжатый RAW', + 'Sony Uncompressed 14-bit RAW' => 'Sony – 14-битный неÑжатый RAW', }, }, - 'ShootingMode' => 'Режим Ñъемки', - 'ShutterSpeed' => 'Выдержка', - 'ShutterSpeedValue' => 'Выдержка', - 'Software' => 'Ð˜Ð¼Ñ Ð¸ верÑÐ¸Ñ ÐŸÐž', + 'SonyToneCurve' => 'Sony – Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ', + 'Sound' => 'ЗвукозапиÑÑŒ', 'Source' => 'ИÑточник', - 'SpatialFrequencyResponse' => 'ПроÑтранÑÑ‚Ð²ÐµÐ½Ð½Ð°Ñ Ñ‡Ð°ÑÑ‚Ð¾Ñ‚Ð½Ð°Ñ Ñ…Ð°Ñ€Ð°ÐºÑ‚ÐµÑ€Ð¸Ñтика', + 'SourceCount' => 'КоличеÑтво иÑпользованых камер', + 'SourceCreateDate' => 'ИÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð´Ð°Ñ‚Ð° ÑозданиÑ', + 'SourceData' => 'ИÑходные данные', + 'SourceDate' => 'Дата публикации', + 'SourceEdition' => 'Печатное издание', + 'SourceFileName' => 'Ðазвание иÑходного файла', + 'SourcePhotosCount' => 'КоличеÑтво иÑходных изображений', + 'SourcePublisher' => 'ИздательÑтво', + 'SourceRights' => 'Права печатного изданиÑ', + 'SourceTitle' => 'Ðазвание издательÑтва', + 'SpatialFrequencyResponse' => 'Отклик проÑтранÑтвенной чаÑтоты', + 'SpatialResolution' => 'ПроÑтранÑтвенное разрешение', + 'SpecialInstructions' => 'Специальные указаниÑ', + 'SpecialMode' => 'Специальный режим', + 'SpecialTypeID' => 'ID Ñпециального типа', 'SpectralSensitivity' => 'Ð¡Ð¿ÐµÐºÑ‚Ñ€Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ', + 'SpeedX' => 'СкороÑÑ‚ÑŒ по оÑи X', + 'SpeedY' => 'СкороÑÑ‚ÑŒ по оÑи Y', + 'SpeedZ' => 'СкороÑÑ‚ÑŒ по оÑи Z', + 'Spherical' => 'СферичеÑкое видео', + 'SplitColumn' => 'Ð Ð°Ð·Ð´ÐµÐ»ÐµÐ½Ð½Ð°Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ°', + 'SpotHalftone' => 'Точка полутона', + 'StandardOutputSensitivity' => 'Ð¡Ñ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð°Ñ Ð²Ñ‹Ñ…Ð¾Ð´Ð½Ð°Ñ Ñ‡ÑƒÐ²ÑтвительноÑÑ‚ÑŒ', + 'StartEdgeCode' => 'Edge код Ñтарта', + 'StartReading' => 'Ðачало чтениÑ', + 'StartTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð°', + 'StartTimecode' => 'Таймкод Ñтарта', 'State' => 'ОблаÑÑ‚ÑŒ', - 'StripByteCounts' => 'Байт на Ñжатую полоÑу', - 'StripOffsets' => 'РаÑположение данных изображениÑ', - 'SubSecTime' => '"Дата и времÑ, Ñуб-Ñекунды"', - 'SubSecTimeDigitized' => '"Дата и Ð²Ñ€ÐµÐ¼Ñ Ñ†Ð¸Ñ„Ñ€Ð¾Ð²Ð¾Ðµ, Ñуб-Ñекунды"', - 'SubSecTimeOriginal' => '"Дата и Ð²Ñ€ÐµÐ¼Ñ Ð¸Ñходное, Ñуб-Ñекунды"', - 'SubTileBlockSize' => 'Размер блока в тайле', + 'Status' => 'СтатуÑ', + 'Stereo' => 'Стерео', + 'StereoMode' => 'Режим Ñтерео', + 'StimVersion' => 'ВерÑÐ¸Ñ Stim', + 'Stitched' => 'Ð¡ÑˆÐ¸Ñ‚Ð°Ñ Ð²Ð¸Ð´ÐµÐ¾Ð¿Ð°Ð½Ð¾Ñ€Ð°Ð¼Ð°', + 'StitchingSoftware' => 'Сшито в программе', + 'StoNits' => 'ОÑвещенноÑÑ‚ÑŒ (коÑффициент переÑчета кд/м2)', + 'StorageFormatDate' => 'ПамÑÑ‚ÑŒ – Дата форматированиÑ', + 'StorageFormatTime' => 'ПамÑÑ‚ÑŒ – Ð’Ñ€ÐµÐ¼Ñ Ñ„Ð¾Ñ€Ð¼Ð°Ñ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'StorageMethod' => 'СпоÑоб хранениÑ', + 'StorageModel' => 'ПамÑÑ‚ÑŒ – Модель', + 'StorageSerialNumber' => 'ПамÑÑ‚ÑŒ – Серийный номер', + 'StorageType' => 'ПамÑÑ‚ÑŒ – Тип', + 'StreamAvgBitrate' => 'Средний битрейт потока', + 'StreamAvgPacketSize' => 'Размер Ñреднего битрейта потока', + 'StreamDuration' => 'ПродолжительноÑÑ‚ÑŒ потока', + 'StreamMaxBitrate' => 'МакÑимальный битрейт потока', + 'StreamMaxPacketSize' => 'Размер макÑимального битрейта потока', + 'StreamMimeLen' => 'Mime потока Len', + 'StreamMimeType' => 'Mime-тип потока', + 'StreamName' => 'Ðазвание потока', + 'StreamNameLen' => 'Ðазвание потока Len', + 'StreamNumber' => 'Ðомер потока', + 'StreamPreroll' => 'Предварительный проÑмотр потока', + 'StreamStartTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° потока', + 'StreamType' => 'Тип потока', + 'Strikeout' => 'Перечёркнутый', + 'StripByteCounts' => 'КоличеÑтво байт на полоÑу', + 'StripOffsets' => 'Смещение Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ полоÑÑ‹ изображениÑ', + 'StripRowCounts' => 'КоличеÑтво полоÑ', + 'StrobeTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ñтроба', + 'StructureType' => 'Тип конÑтрукции', + 'StudyDateTime' => 'Дата обÑледованиÑ', + 'StudyDescription' => 'ОпиÑание обÑледованиÑ', + 'StudyID' => 'ID иÑÑледованиÑ', + 'StudyPhysician' => 'Врач проводивший обÑледование', + 'Sub-location' => 'МеÑтоположение в городе', + 'SubFile' => 'Подфайл', + 'SubPacketH' => 'Субпакет H', + 'SubPacketSize' => 'Размер Ñубпакета', + 'SubSecCreateDate' => 'Дата, Ð²Ñ€ÐµÐ¼Ñ Ð¸ милиÑекунды ÑозданиÑ', + 'SubSecDateTimeOriginal' => 'ИÑходные дата, Ð²Ñ€ÐµÐ¼Ñ Ð¸ милиÑекунды ÑозданиÑ', + 'SubSecModifyDate' => 'Дата, Ð²Ñ€ÐµÐ¼Ñ Ð¸ милиÑекунды редактированиÑ', + 'SubSecTime' => 'Ð’Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² милиÑекундах', + 'SubSecTimeDigitized' => 'Ð’Ñ€ÐµÐ¼Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° в милиÑекундах', + 'SubSecTimeOriginal' => 'Ð’Ñ€ÐµÐ¼Ñ Ñъёмки в милиÑекундах', + 'SubTileBlockSize' => 'Размер блока подзаголовка', + 'SubfileType' => { + Description => 'Тип подфайла', + PrintConv => { + 'Alternate reduced-resolution image' => 'Ðльтернативное изображение Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + 'Color IW44' => 'Цветной IW44', + 'Full-resolution image' => 'Изображение Ñ Ð¿Ð¾Ð»Ð½Ñ‹Ð¼ разрешением', + 'Grayscale IW44' => 'Ð“Ñ€Ð°Ð´Ð°Ñ†Ð¸Ñ Ñерого IW44', + 'Multi-page document' => 'МногоÑтраничный документ', + 'Reduced-resolution image' => 'Изображение Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + 'Shared component' => 'Общий компонент', + 'Single page of multi-page image' => 'Одна Ñтраница из многоÑтраничного изображениÑ', + 'Single page of multi-page reduced-resolution image' => 'Одна Ñтраница из многоÑтраничного Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + 'Single-page image' => 'ОдноÑтраничное изображение', + 'TIFF-FX mixed raster content' => 'Смешанное раÑтровое Ñодержимое TIFF-FX', + 'TIFF/IT final page' => 'ПоÑледнÑÑ Ñтраница TIFF/IT', + 'Thumbnail image' => 'Миниатюра', + 'Transparency mask' => 'МаÑка прозрачноÑти изображениÑ', + 'Transparency mask of multi-page image' => 'МаÑка прозрачноÑти многоÑтраничного изображениÑ', + 'Transparency mask of reduced-resolution image' => 'МаÑка прозрачноÑти Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + 'Transparency mask of reduced-resolution multi-page image' => 'МаÑка прозрачноÑти многоÑтраничного Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + 'invalid' => 'Ðекорректный', + }, + }, + 'Subject' => 'Тема', 'SubjectArea' => 'ОблаÑÑ‚ÑŒ объекта', - 'SubjectDistance' => 'РаÑÑтоÑние до объекта', + 'SubjectCode' => 'Предметный код', + 'SubjectDistance' => 'ДиÑÑ‚Ð°Ð½Ñ†Ð¸Ñ Ðº фокуÑируемому объекту', 'SubjectDistanceRange' => { - Description => 'Диапазон раÑÑтоÑний до объекта', + Description => 'РаÑÑтоÑние до Ñнимаемого объекта', PrintConv => { - 'Close' => 'Крупный план', - 'Distant' => 'Удаленный план', - 'Macro' => 'Макро', + 'Close' => 'Съёмка Ñ Ð±Ð»Ð¸Ð·ÐºÐ¾Ð³Ð¾ раÑÑтоÑниÑ', + 'Distant' => 'Съёмка Ñ Ð´Ð°Ð»ÑŒÐ½ÐµÐ³Ð¾ раÑÑтоÑниÑ', + 'Macro' => 'Макро Ñъёмка', + 'Unknown' => 'ÐеизвеÑтно', }, }, 'SubjectLocation' => 'РаÑположение объекта', + 'SubjectPixelHeight' => 'Ð’Ñ‹Ñота объекта в пикÑелÑÑ…', + 'SubjectPixelWidth' => 'Ширина объекта в пикÑелÑÑ…', + 'SubjectReference' => 'СÑылка на предмет', + 'SubjectUnits' => { + Description => 'Единицы объекта', + PrintConv => { + 'meters' => 'Метры', + 'radians' => 'Радианы', + }, + }, + 'Subtitle' => 'Субтитры', + 'SubtitleDescription' => 'Субтитры – ОпиÑание', + 'SuggestedPalette' => 'Ð ÐµÐºÐ¾Ð¼ÐµÐ½Ð´Ð¾Ð²Ð°Ð½Ð½Ð°Ñ Ð¿Ð°Ð»Ð¸Ñ‚Ñ€Ð°', + 'Summary' => 'Резюме', 'SupplementalCategories' => 'Дополнительные категории', - 'ThumbnailImage' => 'Пиктограмма', - 'ThumbnailImageSize' => 'Размер пиктограмм', - 'Title' => 'Заголовок', + 'SupplementalType' => { + Description => 'Тип дополнениÑ', + PrintConv => { + 'Logo' => 'Логотип', + 'Main Image' => 'ОÑновное изображение', + 'Rasterized Caption' => 'РаÑтрированный заголовок', + 'Reduced Resolution Image' => 'Изображение Ñ Ð¿Ð¾Ð½Ð¸Ð¶ÐµÐ½Ð½Ñ‹Ð¼ разрешением', + }, + }, + 'SymLink' => 'СимволичеÑÐºÐ°Ñ ÑÑылка', + 'System' => 'СиÑтема', + 'SystemTime' => 'СиÑтемное времÑ', + 'T4Options' => { + Description => 'Параметры ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ T4', + PrintConv => { + '2-Dimensional encoding' => 'Двумерное кодирование', + 'Fill bits added' => 'Добавление заполнÑющих битов', + 'Uncompressed' => 'Без ÑжатиÑ', + }, + }, + 'T6Options' => { + Description => 'Параметры ÐºÐ¾Ð´Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ T6', + PrintConv => { + 'Uncompressed' => 'Без ÑжатиÑ', + }, + }, + 'T82Options' => 'Параметры T82', + 'T88Options' => 'Параметры T88', + 'TIFF-EPStandardID' => 'ID Ñтандарта TIFF-EP', + 'TIFFPreview' => 'ПредпроÑмотр TIFF', + 'TIFF_FXExtensions' => { + Description => 'Ð Ð°Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¸Ñ TIFF_FX', + PrintConv => { + 'JBIG2 Profile M' => 'JBIG2 профиль M', + 'N Layer Profile M' => 'N Ñлой Профиль M', + 'Resolution/Image Width' => 'Разрешение/Ширина изображениÑ', + 'Shared Data' => 'Общие данные', + }, + }, + 'TOCItems' => 'КоличеÑтво точек навигации', + 'TStop' => 'Ð˜Ð½Ð´ÐµÐºÑ ÑветопропуÑÐºÐ°Ð½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð¸Ð²Ð° (T-Stop)', + 'Tagged' => { + Description => 'Тегированный', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'TaggedPDF' => { + Description => 'Тегированный PDF', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'Take' => 'Дубль', + 'Tamper-proofKeys' => 'Ключи от взлома', + 'TargetAudiences' => 'Ð¦ÐµÐ»ÐµÐ²Ð°Ñ Ð°ÑƒÐ´Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ', + 'TargetFileDOSName' => 'DOS название целевого файла', + 'TargetFileSize' => 'Размер целевого файла', + 'TargetLayerID' => 'ID целевого ÑлоÑ', + 'TargetPrinter' => 'Среда печати', + 'Tattoo' => 'Татуировка', + 'Taxon' => 'ТакÑон', + 'TaxonAcceptedNameUsage' => 'ОбщепринÑтое название такÑона', + 'TaxonAcceptedNameUsageID' => 'ID общепринÑтого Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonClass' => 'КлаÑÑ Ñ‚Ð°ÐºÑона', + 'TaxonConceptID' => 'ID такÑономичеÑкой концепции', + 'TaxonFamily' => 'СемейÑтво такÑона', + 'TaxonGenus' => 'Род такÑона', + 'TaxonHigherClassification' => 'ТакÑоны рангом выше', + 'TaxonID' => 'ID такÑона', + 'TaxonInfraspecificEpithet' => 'Ðизший внутривидовой Ñпитет', + 'TaxonKingdom' => 'ЦарÑтво такÑона', + 'TaxonNameAccordingTo' => 'ИÑточник опиÑÐ°Ð½Ð¸Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ† такÑона', + 'TaxonNameAccordingToID' => 'ID иÑточника опиÑÐ°Ð½Ð¸Ñ Ð³Ñ€Ð°Ð½Ð¸Ñ† такÑона', + 'TaxonNamePublishedIn' => 'Ðазвание такÑона впервые опубликовано в', + 'TaxonNamePublishedInID' => 'ID первой публикации Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonNamePublishedInYear' => 'Год первой публикации Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonNomenclaturalCode' => 'Код номенклатуры такÑона', + 'TaxonNomenclaturalStatus' => 'Ðоменклатурный ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ‚Ð°ÐºÑона', + 'TaxonOrder' => 'ПорÑдок такÑона', + 'TaxonOriginalNameUsage' => 'ПервоиÑточник Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonOriginalNameUsageID' => 'ID первоиÑточника Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonParentNameUsage' => 'РодительÑкий такÑон', + 'TaxonParentNameUsageID' => 'ID родительÑкого такÑона', + 'TaxonPhylum' => 'Тип такÑона', + 'TaxonRank' => 'Ранг такÑона', + 'TaxonRemarks' => 'Комментарии к такÑону', + 'TaxonScientificName' => 'Ðаучное название такÑона', + 'TaxonScientificNameAuthorship' => 'Ðвтор научного Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonScientificNameID' => 'ID научного Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð°ÐºÑона', + 'TaxonSpecificEpithet' => 'Видовой Ñпитет такÑона', + 'TaxonSubgenus' => 'Подрод такÑона', + 'TaxonTaxonomicStatus' => 'Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ñ‚Ð°ÐºÑона', + 'TaxonVerbatimTaxonRank' => 'Ранг такÑона по первоиÑточнику', + 'TaxonVernacularName' => 'Ðародное название такÑона', + 'Telephone' => 'Ðомер телефона', + 'Telescope' => 'ТелеÑкоп', + 'Template' => 'Шаблон', + 'TermsAndConditionsText' => 'ТекÑÑ‚ лицензионного ÑоглашениÑ', + 'TermsAndConditionsURL' => 'СÑылка на лицензионное Ñоглашение', + 'TestName' => 'ТеÑтовое название файла', + 'Text' => 'ТекÑÑ‚', + 'TextLayerName' => 'ÐÐ°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ‚ÐµÐºÑтовых Ñлоёв', + 'TextLayerText' => 'ТекÑÑ‚ текÑтового ÑлоÑ', + 'TextLayers' => 'ТекÑтовые Ñлои', + 'TextToSpeech' => { + Description => 'ТекÑÑ‚ в речь', + PrintConv => { + 'Disabled' => 'Ðе включеён', + 'Enabled' => 'Включен', + }, + }, + 'TextureFormat' => 'Формат текÑтуры', + 'TheoraVersion' => 'ВерÑÐ¸Ñ Theora', + 'Thresholding' => { + Description => 'ÐŸÐ¾Ñ€Ð¾Ð³Ð¾Ð²Ð°Ñ Ð¾Ð±Ñ€Ð°Ð±Ð¾Ñ‚ÐºÐ°', + PrintConv => { + 'No dithering or halftoning' => 'Дизеринг или полутонирование не применÑлоÑÑŒ', + 'Ordered dither or halftone' => 'Заказной дизеринг или полутонирование', + 'Randomized dither' => 'Случайный дизеринг', + }, + }, + 'ThumbnailBPG' => 'Миниатюра BPG', + 'ThumbnailHeight' => 'Ð’Ñ‹Ñота миниатюры', + 'ThumbnailImage' => 'Миниатюра изображениÑ', + 'ThumbnailImageSize' => 'Размер миниатюри', + 'ThumbnailLength' => 'Строк в миниатюре', + 'ThumbnailOffset' => 'Смещение миниатюры', + 'ThumbnailTIFF' => 'TIFF миниатюра', + 'ThumbnailWidth' => 'Ширина миниатюры', + 'TileByteCounts' => 'КоличеÑтво байт в тайле', + 'TileDepth' => 'Глубина тайла', + 'TileLength' => 'Строк в тайле', + 'TileOffsets' => 'Смещение тайла', + 'TileWidth' => 'Колонок в тайле', + 'Tiles' => 'Тайлы', + 'Time' => 'ВремÑ', + 'TimeCode' => 'Код времени', + 'TimeCodes' => 'Таймкоды', + 'TimeCreated' => 'Ð’Ñ€ÐµÐ¼Ñ ÑозданиÑ', + 'TimeSent' => 'Ð’Ñ€ÐµÐ¼Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ', + 'TimeShot' => 'Ð’Ñ€ÐµÐ¼Ñ Ñъёмки', + 'TimeStamp' => 'ВременнаÌÑ Ð¼ÐµÑ‚ÐºÐ°', + 'TimeTransparency' => 'ПрозрачноÑÑ‚ÑŒ времени', + 'TimeZone' => 'ЧаÑовой поÑÑ', + 'TimeZone2' => 'ЧаÑовой поÑÑ 2', + 'TimeZoneOffset' => 'Смещение чаÑового поÑÑа', + 'TimeZoneURL' => 'URL ЧаÑового поÑÑа', + 'TimelineInfo' => 'Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾ шкале времени', + 'TimezoneID' => 'ID чаÑового поÑÑа', + 'TimezoneName' => 'Ðазвание чаÑового поÑÑа', + 'TimezoneOffsetFrom' => 'Смещение чаÑового поÑÑа Ñ', + 'TimezoneOffsetTo' => 'Смещение чаÑового поÑÑа к', + 'Title' => 'Ðазвание', + 'TitleLen' => 'Ðазвание Len', + 'ToneCurveBlueX' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ Синий X', + 'ToneCurveBlueY' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ Синий Y', + 'ToneCurveBrightnessX' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ ЯркоÑÑ‚ÑŒ X', + 'ToneCurveBrightnessY' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ ЯркоÑÑ‚ÑŒ Y', + 'ToneCurveGreenX' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ Зелёный X', + 'ToneCurveGreenY' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ Зелёный Y', + 'ToneCurveRedX' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ КраÑный X', + 'ToneCurveRedY' => 'Ð¢Ð¾Ð½Ð¾Ð²Ð°Ñ ÐºÑ€Ð¸Ð²Ð°Ñ â€“ КраÑный Y', + 'ToolName' => 'Приложение', + 'ToolVersion' => 'ВерÑÐ¸Ñ Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ', + 'TopMargin' => 'ОтÑтуп Ñверху', + 'TotalBitrate' => 'Общий битрейт', + 'TotalDataRate' => 'ÐžÐ±Ñ‰Ð°Ñ ÑкороÑÑ‚ÑŒ передачи данных', + 'TotalDuration' => 'ÐžÐ±Ñ‰Ð°Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð»Ð¶Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾ÑÑ‚ÑŒ', + 'TotalEditTime' => 'Общее Ð²Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'TotalFrames' => 'Ð’Ñего кадров', + 'TotalSamples' => 'Ð’Ñего образцов', + 'Track' => 'Трек', + 'TrackCategory' => 'ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ñ‚Ñ€ÐµÐºÐ°', + 'TrackComments' => 'Комментарии к треку', + 'TrackID' => 'ID трека', + 'TrackLyrics' => 'ТекÑÑ‚ пеÑни', + 'TrackNumber' => 'Ðомер трека', + 'Trademark' => 'Ð¢Ð¾Ñ€Ð³Ð¾Ð²Ð°Ñ Ð¼Ð°Ñ€ÐºÐ°', 'TransferFunction' => 'Ð¤ÑƒÐ½ÐºÑ†Ð¸Ñ Ð¿ÐµÑ€ÐµÐ½Ð¾Ñа', + 'TransferRange' => 'Диапазон функции переноÑа', + 'Transformation' => { + Description => 'ТранÑформациÑ', + PrintConv => { + 'Horizontal (normal)' => 'Горизонтально', + 'Mirror horizontal' => 'Отразить по горизонтали', + 'Mirror horizontal and rotate 270 CW' => 'Отражение по горизонтали и поворот на 270° по чаÑовой Ñтрелке', + 'Mirror horizontal and rotate 90 CW' => 'Отражение по горизонтали и поворот на 90° по чаÑовой Ñтрелке', + 'Mirror vertical' => 'Отразить по вертикали', + 'Rotate 180' => 'Повернуть на 180°', + 'Rotate 270 CW' => 'Поворот на 270° по чаÑовой Ñтрелке', + 'Rotate 90 CW' => 'Поворот на 90° по чаÑовой Ñтрелке', + }, + }, 'TransmissionReference' => 'СÑылка на иÑточник', - 'UniqueCameraModel' => 'Ð£Ð½Ð¸ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð¼Ð¾Ð´ÐµÐ»ÑŒ фотоаппарата', - 'Urgency' => 'ПриоритетноÑÑ‚ÑŒ', + 'Transparency' => 'ПрозрачноÑÑ‚ÑŒ', + 'TransparencyIndicator' => 'Ðаличие прозрачноÑти', + 'TransparentIndex' => 'Ð˜Ð½Ð´ÐµÐºÑ Ð¿Ñ€Ð¾Ð·Ñ€Ð°Ñ‡Ð½Ð¾Ñти', + 'TrapIndicator' => 'Применен ли треппинг к файлу', + 'Trapped' => 'Треппинг', + 'Trigger' => 'Ð’Ñ€ÐµÐ¼Ñ ÑÑ€Ð°Ð±Ð°Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ Ñигнала', + 'TriggerMode' => { + Description => 'Режим триггера', + PrintConv => { + 'CodeLoc Not Entered' => 'Код блокировки не задан', + 'External Sensor' => 'Внешний датчик', + 'Motion Detection' => 'Обнаружение движениÑ', + 'Point and Shoot' => 'Ðаведи и Ñнимай', + 'Time Lapse' => 'ТаймлапÑ', + }, + }, + 'Type' => 'Тип', + 'TypeStatus' => 'СпиÑок номенклатурных типов', + 'UIC1Tag' => 'UIC – Тег 1', + 'UIC2Tag' => 'UIC – Тег 2', + 'UIC3Tag' => 'UIC – Тег 3', + 'UIC4Tag' => 'UIC – Тег 4', + 'UID' => 'Уникальный ID', + 'URLList1' => 'СпиÑок URL 1', + 'URL_List' => 'СпиÑок URL', + 'USPTOOriginalContentType' => { + Description => 'USPTO – ИÑходный тип контента', + PrintConv => { + 'Color' => 'Цвет', + 'Grayscale' => 'Оттенки Ñерого', + 'Text or Drawing' => 'ТекÑÑ‚ или риÑунок', + }, + }, + 'UUID-Unknown' => 'ÐеизвеÑтный UUID', + 'UUIDList' => 'СпиÑок UUID', + 'Uncompressed' => { + Description => 'Ðе Ñжато', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'UncompressedSize' => 'ÐеÑжатый размер', + 'UncompressedTextLength' => 'Длина неÑжатого текÑта', + 'Underline' => 'Подчёркнутый', + 'UnderlinePosition' => 'ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð¿Ð¾Ð´Ñ‡Ñ‘Ñ€ÐºÐ¸Ð²Ð°Ð½Ð¸Ñ', + 'UnderlineThickness' => 'Толщина подчёркиваниÑ', + 'UnicodeAlphaNames' => 'Юникодное название альфа-канала', + 'UniqueCameraModel' => 'Уникальное название модели камеры', + 'UniqueDocumentID' => 'Уникальный ID документа', + 'UniqueObjectName' => 'Уникальное название объекта', + 'Units' => { + Description => 'Единицы измерениÑ', + PrintConv => { + 'Inches' => 'Дюймы', + 'Picas' => 'Пики', + 'Points' => 'Точки', + 'mm' => 'Милиметры', + }, + }, + 'Unknown' => 'ÐеизвеÑтный', + 'UnknownDate' => 'ÐеизвеÑÑ‚Ð½Ð°Ñ Ð´Ð°Ñ‚Ð°', + 'UpdatedTitle' => 'Обновленное название', + 'Urgency' => { + Description => 'Приоритет обработки', + PrintConv => { + '0 (reserved)' => '0 (Зарезервированно)', + '1 (most urgent)' => '1 (Срочно)', + '5 (normal urgency)' => '5 (Обычный)', + '8 (least urgent)' => '8 (Ðе Ñрочно)', + '9 (user-defined priority)' => '9 (ПользовательÑкий приоритет)', + }, + }, + 'UsageRightsMessage' => 'Сообщение о правах иÑпользованиÑ', + 'UsePanoramaViewer' => 'ИÑпользовать проÑмотрщик панорам', + 'UserAccess' => { + Description => 'РазрешаетÑÑ', + PrintConv => { + 'Annotate' => 'Ðннотирование', + 'Assemble' => 'Сборка', + 'Copy' => 'Копирование', + 'Extract' => 'Извлечение', + 'Fill forms' => 'Заполнение форм', + 'Modify' => 'Редактирование', + 'Print' => 'Печать', + 'Print high-res' => 'Печать в выÑоком разрешении', + }, + }, 'UserComment' => 'Комментарии пользователÑ', + 'UserFields' => 'Дополнительное поле', + 'UserID' => 'ID пользователÑ', + 'UserLabel' => 'Ярлык пользователÑ', + 'VBRBytes' => 'Переменный битрейт – Бит', + 'VBRFrames' => 'Переменный битрейт – КоличеÑтво фреймов', + 'VBRScale' => 'Переменный битрейт – Шкала', + 'VCalendarVersion' => 'ВерÑÐ¸Ñ VCalendar', + 'VCardVersion' => 'ВерÑÐ¸Ñ VCard', + 'Vary' => 'Ðльтернативный HTTP-заголовок', + 'Vendor' => 'ПоÑтавщик', + 'VendorURL' => 'URL поÑтавщика', + 'Version' => 'ВерÑиÑ', + 'Version2' => 'ВерÑÐ¸Ñ 2', + 'VersionCreateDate' => 'ВерÑÐ¸Ñ â€“ Дата ÑозданиÑ', + 'VersionModifyDate' => 'ВерÑÐ¸Ñ â€“ Дата редактированиÑ', + 'VersionYear' => 'Год Ñтандарта факÑ-профилÑ', + 'VerticalDivergence' => 'Угол вертикального раÑхождениÑ', + 'Vibrance' => 'КраÑочноÑÑ‚ÑŒ', + 'VideoBitrate' => 'Битрейт видео', + 'VideoClosedCaptioning' => { + Description => 'Видео Ñ Ñубтитрами', + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'VideoCodecID' => 'ID видеокодека', + 'VideoEncoding' => 'Видеокодирование', + 'VideoFormat' => 'Формат видео', + 'VideoMode' => 'Режим видео', + 'VideoQuality' => 'КачеÑтво видео', + 'VideoScanType' => 'Тип ÑÐºÐ°Ð½Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ð¸Ð´ÐµÐ¾', + 'VideoSize' => 'Размер видео', + 'View' => 'ПроÑмотр', + 'ViewType' => { + Description => 'Тип проÑмотра', + PrintConv => { + 'No Pop-up Effect' => 'Без вÑплывающего Ñффекта', + 'Pop-up Effect' => 'С вÑплывающим Ñффектом', + }, + }, + 'Viewfinder' => 'ВидоиÑкатель', + 'VignetteCorrectionAlreadyApplied' => 'Применена ÐºÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð²Ð¸Ð½ÑŒÐµÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + 'VignettingCorrParams' => 'Параметры коррекции виньетированиÑ', + 'VignettingCorrection' => { + Description => 'ÐšÐ¾Ñ€Ñ€ÐµÐºÑ†Ð¸Ñ Ð²Ð¸Ð½ÑŒÐµÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ', + PrintConv => { + 'Auto' => 'ÐвтоматичеÑкаÑ', + 'No correction params available' => 'ÐедоÑтупна', + 'Off' => 'Ðе включена', + }, + }, + 'VirtualImageHeight' => 'Ð’Ñ‹Ñота виртуального изображениÑ', + 'VirtualImageWidth' => 'Ширина виртуального изображениÑ', + 'VirtualPageUnits' => 'Единицы виртуальной Ñтраницы', + 'VisualFlightRulesHUD' => 'Визуальные правила полетов HUD', + 'VoiceMemo' => { + Description => 'ГолоÑовые заметки', + PrintConv => { + 'Off' => 'Ðе включено', + 'On' => 'Включено', + }, + }, + 'Volume' => 'Том', + 'VolumeBlockCount' => 'КоличеÑтво блоков в томе', + 'VolumeBlockSize' => 'Размер блока в томе', + 'VolumeCreateDate' => 'Дата ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð¼Ð°', + 'VolumeEffectiveDate' => 'Дата начала иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð¼Ð°', + 'VolumeExpirationDate' => 'Дата уÑÑ‚Ð°Ñ€ÐµÐ²Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð¼Ð°', + 'VolumeID' => 'ID тома', + 'VolumeLabel' => 'Метка тома', + 'VolumeModifyDate' => 'Дата Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ‚Ð¾Ð¼Ð°', + 'VolumeName' => 'Ðазвание тома', + 'VolumeSetDiskCount' => 'КоличеÑтво диÑков в наборе томов', + 'VolumeSetDiskNumber' => 'Ðомер диÑка в наборе томов', + 'VolumeSetName' => 'Ðазвание набора томов', + 'VolumeSize' => 'Размер тома', + 'VorbisVersion' => 'ВерÑÐ¸Ñ Vorbis', + 'WBBlueLevel' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð‘ÐµÐ»Ð¾Ð³Ð¾ – Уровень Ñинего', + 'WBGreenLevel' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð‘ÐµÐ»Ð¾Ð³Ð¾ – Уровень зелёного', + 'WBMode' => 'Режим баланÑа белого', + 'WBRedLevel' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð‘ÐµÐ»Ð¾Ð³Ð¾ – Уровень краÑного', + 'WBScale' => 'Чёрно-Белое – Шкала', + 'WB_GBRGLevels' => 'Чёрно-Белое – Уровни GBRG', + 'WB_GRGBLevels' => 'Уровни WB_GRGB', + 'WB_RBLevelsCloudy' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Облачно', + 'WB_RBLevelsCoolWhiteF' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Холодный белый F', + 'WB_RBLevelsDayWhiteF' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Дневной белый F', + 'WB_RBLevelsDaylight' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Дневной Ñвет', + 'WB_RBLevelsDaylightF' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Дневной Ñвет F', + 'WB_RBLevelsFlash' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Ð’Ñпышка', + 'WB_RBLevelsShade' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Тень', + 'WB_RBLevelsTungsten' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Лампа накаливаниÑ', + 'WB_RBLevelsUnknown' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – ÐеизвеÑтный иÑточник Ñвета', + 'WB_RBLevelsWhiteF' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ – Уровни RB – Белый', + 'WB_RGBLevels' => 'Уровни WB RGB', + 'WB_RGGBLevels' => 'Чёрно-Белое – Уровни RGGB', + 'WWSFamilyName' => 'Ðазвание ÑемейÑтва WWS', + 'WWSSubfamilyName' => 'Ðазвание ÑÑ‚Ð¸Ð»Ñ WWS', + 'WangAnnotation' => 'Wang Imaging – ÐннотациÑ', + 'WangTag1' => 'Wang Imaging – Тег 1', + 'WangTag3' => 'Wang Imaging – Тег 3', + 'WangTag4' => 'Wang Imaging – Тег 4', + 'Warning' => 'Уведомление', + 'WarpQuadrilateral' => 'Ð”ÐµÑ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ñ‡ÐµÑ‚Ñ‹Ñ€Ñ‘Ñ…ÑƒÐ³Ð¾Ð»ÑŒÐ½Ð¸ÐºÐ°', + 'Watched' => { + PrintConv => { + 'No' => 'Ðет', + 'Yes' => 'Да', + }, + }, + 'WaterDepth' => 'Глубина воды', + 'Watermark' => 'ВодÑной знак', + 'Weight' => 'Толщина шрифта', 'WhiteBalance' => { Description => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾', PrintConv => { - 'Auto' => 'ÐвтоматичеÑкий Ð±Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾', + 'Auto' => 'ÐвтоматичеÑкий', 'Black & White' => 'Монохром', 'Cloudy' => 'ОблачноÑÑ‚ÑŒ', - 'Color Temperature/Color Filter' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð° / Цветовой фильтр', + 'Color Temperature/Color Filter' => 'Ð¦Ð²ÐµÑ‚Ð¾Ð²Ð°Ñ Ñ‚ÐµÐ¼Ð¿ÐµÑ€Ð°Ñ‚ÑƒÑ€Ð°/Цветовой фильтр', 'Cool White Fluorescent' => 'ФлуореÑцентный белый холодный', 'Custom' => 'Пользователь', 'Custom 1' => 'ПЕРСОÐÐЛЬÐЫЙ 1', @@ -704,7 +5583,7 @@ $VERSION = '1.04'; 'Daylight Fluorescent' => 'ФлуореÑцентный дневной', 'Flash' => 'Ð’Ñпышка', 'Fluorescent' => 'ФлуореÑцентный', - 'Manual' => 'Ð ÑƒÑ‡Ð½Ð°Ñ Ð½Ð°Ñтройка баланÑа белого', + 'Manual' => 'Ручной', 'Shade' => 'Тень', 'Tungsten' => 'Лампа накаливаниÑ', 'Unknown' => 'неизвеÑтно', @@ -712,31 +5591,120 @@ $VERSION = '1.04'; 'White Fluorescent' => 'ФлуореÑцентный белый', }, }, + 'WhiteBalance0' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ 0', + 'WhiteBalance1' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ 1', + 'WhiteBalance2' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ 2', + 'WhiteBalanceRGB' => 'Ð‘Ð°Ð»Ð°Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾ RGB', 'WhiteLevel' => 'Уровень белого', + 'WhiteLuminance' => 'ЯркоÑÑ‚ÑŒ белого', 'WhitePoint' => 'ЦветноÑÑ‚ÑŒ белой точки', - 'Writer-Editor' => 'Ðвтор подпиÑи', - 'YCbCrCoefficients' => 'Матричные коÑффициенты Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñ†Ð²ÐµÑ‚Ð¾Ð²Ð¾Ð¹ Ñреды', + 'WhitePointX' => 'Ð‘ÐµÐ»Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° по X', + 'WhitePointY' => 'Ð‘ÐµÐ»Ð°Ñ Ñ‚Ð¾Ñ‡ÐºÐ° по Y', + 'WhitesAdj' => 'Регулировка ÑƒÑ€Ð¾Ð²Ð½Ñ Ð±ÐµÐ»Ð¾Ð³Ð¾', + 'WideRange' => { + Description => 'Широкий диапазон', + PrintConv => { + 'Off' => 'Ðе включён', + 'On' => 'Включен', + }, + }, + 'WidthBytes' => 'Ширина в байтах', + 'WidthResolution' => 'Разрешение по ширине (PPI)', + 'WindowOrigin' => 'Ðачало координат окна', + 'WindowOriginAuto' => 'Ðачало координат окна – ÐвтоматичеÑки', + 'WindowSize' => 'Размер окна', + 'WindowTarget' => 'Целевое окно', + 'Words' => 'Слов', + 'WorkflowURL' => 'URL рабочего процеÑÑа', + 'WorkingDirectory' => 'Рабочий каталог', + 'WorkingPath' => 'Рабочий контур', + 'WorldToCamera' => 'Мир на камеру', + 'WorldToNDC' => 'Мир на NDC', + 'WrapModes' => 'Режим обёртываниÑ', + 'Writer-Editor' => 'ПиÑатель/Редактор', + 'WriterName' => 'Ðазвание редактора', + 'XAttrAppleMailDateReceived' => 'X Attr – Почта Apple – Дата получениÑ', + 'XAttrAppleMailDateSent' => 'X Attr – Почта Apple – Дата отправки', + 'XAttrAppleMailIsRemoteAttachment' => 'X Attr – Почта Apple – Ðаличие удалённого вложениÑ', + 'XAttrFinderInfo' => 'X Attr – СвойÑтва файла', + 'XAttrLastUsedDate' => 'X Attr – Дата поÑледнего иÑпользованиÑ', + 'XAttrMDItemDownloadedDate' => 'X Attr – MD Item – Дата загрузки', + 'XAttrMDItemFinderComment' => 'X Attr – MD Item – Комментарий к файлу', + 'XAttrMDItemWhereFroms' => 'X Attr – MD Item – ИÑточник файла', + 'XAttrMDLabel' => 'X Attr – MD – Ð¦Ð²ÐµÑ‚Ð½Ð°Ñ Ð¼ÐµÑ‚ÐºÐ° файла', + 'XAttrQuarantine' => 'X Attr – Карантинный', + 'XAttrResourceFork' => 'X Attr – Вилка реÑурÑов', + 'XCFVersion' => 'ВерÑÐ¸Ñ XCF', + 'XClipPathUnits' => 'Единицы обтравочного контура по X', + 'XHeight' => 'Ð’Ñ‹Ñота Ñтрочных букв', + 'XMLData' => 'Данные XML', + 'XOffset' => 'Смещение по X', + 'XPAuthor' => 'XP – Ðвтор', + 'XPComment' => 'XP – Комментарии', + 'XPKeywords' => 'XP – Ключевые Ñлова', + 'XPSubject' => 'XP – Тема', + 'XPTitle' => 'XP – Ðазвание', + 'XPosition' => 'Положение Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ X', + 'XResolution' => 'Разрешение по X', + 'XYResolution' => 'Разрешение по X и Y', + 'YCbCrCoefficients' => 'КоÑффициенты Ð¿Ñ€ÐµÐ¾Ð±Ñ€Ð°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð· RGB в Y Cb Cr', 'YCbCrPositioning' => { - Description => 'ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð¿Ð¾ Y и C', + Description => 'Положение точки, определÑющей цвет в Y Cb Cr', PrintConv => { - 'Centered' => 'центрованный', - 'Co-sited' => 'Ñовпадающий по меÑту', + 'Centered' => 'Центрованный', + 'Co-sited' => 'СовмеÑтимый', }, }, - 'YCbCrSubSampling' => 'КоÑффициент ÑубдиÑкретизации Y и C', + 'YCbCrSubSampling' => 'КоÑффициент ÑубдиÑкретизации Y Cb Cr', + 'YClipPathUnits' => 'Единицы обтравочного контура по Y', + 'YLevel' => 'Уровень – Y', + 'YOffset' => 'Смещение по Y', + 'YPosition' => 'Положение Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð¿Ð¾ Y', + 'YResolution' => 'Разрешение по Y', + 'YTarget' => 'Цель – Y', + 'Yaw' => 'РыÑкание (Поворот)', + 'YawAngle' => 'Угол поворота (РыÑкание)', + 'Year' => 'Год', + 'ZipBitFlag' => 'Zip – Битовый флаг', + 'ZipCRC' => 'Zip – CRC', + 'ZipCompressedSize' => 'Zip – Сжатый размер', + 'ZipCompression' => { + Description => 'Zip – Сжатие', + PrintConv => { + 'Enhanced Deflate using Deflate64(tm)' => 'Улучшенный Deflate Ñ Ð¸Ñпользованием Deflate64(tm)', + 'IBM LZ77 z Architecture (PFS)' => 'IBM LZ77 z/Architecture (PFS)', + 'IBM TERSE (new)' => 'IBM TERSE (новый)', + 'Imploded (old IBM TERSE)' => 'Imploded (Ñтарый IBM TERSE)', + 'None' => 'Без ÑжатиÑ', + 'PPMd version I, Rev 1' => 'PPMd верÑÐ¸Ñ I, Ð ÐµÐ²Ð¸Ð·Ð¸Ñ 1', + 'Reduced with compression factor 1' => 'Сжатый Ñ ÐºÐ¾Ñффициентом ÑÐ¶Ð°Ñ‚Ð¸Ñ 1', + 'Reduced with compression factor 2' => 'Сжатый Ñ ÐºÐ¾Ñффициентом ÑÐ¶Ð°Ñ‚Ð¸Ñ 2', + 'Reduced with compression factor 3' => 'Сжатый Ñ ÐºÐ¾Ñффициентом ÑÐ¶Ð°Ñ‚Ð¸Ñ 3', + 'Reduced with compression factor 4' => 'Сжатый Ñ ÐºÐ¾Ñффициентом ÑÐ¶Ð°Ñ‚Ð¸Ñ 4', + 'WavPack compressed' => 'WavPack', + }, + }, + 'ZipFileName' => 'Zip – Ðазвание файла', + 'ZipFileNameLength' => 'Zip – Длина Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð°', + 'ZipModifyDate' => 'Zip – Дата редактированиÑ', + 'ZipRequiredVersion' => 'Zip – Ð¢Ñ€ÐµÐ±ÑƒÐµÐ¼Ð°Ñ Ð²ÐµÑ€ÑиÑ', + 'ZipUncompressedSize' => 'Zip – ÐеÑжатый размер', 'ZoneMatching' => { - Description => 'СоответÑтвие облаÑтей', + Description => 'СоглаÑование зон', PrintConv => { - 'High Key' => 'Hi', - 'ISO Setting Used' => 'Отключено', - 'Low Key' => 'Lo', + 'High Key' => 'Ð’ выÑоком ключе', + 'ISO Setting Used' => 'ИÑпользуютÑÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ‹ ISO', + 'Low Key' => 'Ð’ низком ключе', }, }, + 'Zoom' => 'Зум', + 'ZoomPos' => 'ÐŸÐ¾Ð·Ð¸Ñ†Ð¸Ñ Ð·ÑƒÐ¼Ð°', + 'ZoomedPreviewImage' => 'Увеличенный предпроÑмотр изображениÑ', + 'iTunesMediaType' => 'Тип iTunes медиа', ); 1; # end - __END__ =head1 NAME @@ -750,15 +5718,15 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 ACKNOWLEDGEMENTS -Thanks to Jens Duttke, Sergey Shemetov, Dmitry Yerokhin and Anton Sukhinov -for providing this translation. +Thanks to Jens Duttke, Sergey Shemetov, Dmitry Yerokhin, Anton Sukhinov and +Alexander for providing this translation. =head1 SEE ALSO diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/sv.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/sv.pm index 9c1250fb..66251e42 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/sv.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/sv.pm @@ -620,7 +620,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/tr.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/tr.pm index c6665f2c..2d689d14 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/tr.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/tr.pm @@ -11,7 +11,7 @@ package Image::ExifTool::Lang::tr; use strict; use vars qw($VERSION); -$VERSION = '1.04'; +$VERSION = '1.05'; %Image::ExifTool::Lang::tr::Translate = ( 'Album' => 'Albüm', @@ -499,6 +499,7 @@ $VERSION = '1.04'; }, 'WhitePoint' => 'Beya nokta kromatik', 'Writer-Editor' => 'Açıklama Yazarı', + 'XResolution' => 'X çözünürlüğü', 'YCbCrCoefficients' => 'Renk alanı transformasyon matriks katsayısı', 'YCbCrPositioning' => { Description => 'Y ve C konumlama', @@ -508,6 +509,7 @@ $VERSION = '1.04'; }, }, 'YCbCrSubSampling' => 'Y den C\'ye alt örnekleme oranı', + 'YResolution' => 'Y çözünürlüğü', ); 1; # end @@ -526,7 +528,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_cn.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_cn.pm index 9cc9c27a..6efd69ad 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_cn.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_cn.pm @@ -1313,7 +1313,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_tw.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_tw.pm index 1df5e0f8..8f1f2297 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_tw.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lang/zh_tw.pm @@ -784,7 +784,7 @@ and values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Leaf.pm b/src/Image-ExifTool/lib/Image/ExifTool/Leaf.pm index 81a5c5fe..d7e588c6 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Leaf.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Leaf.pm @@ -504,7 +504,7 @@ Capture. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Lytro.pm b/src/Image-ExifTool/lib/Image/ExifTool/Lytro.pm index bd8d8fd7..69f33894 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Lytro.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Lytro.pm @@ -50,6 +50,7 @@ sub ExtractTags($$$); DevicesAccelerometerSampleArrayZ => { Name => 'AccelerometerZ'}, DevicesClockZuluTime => { Name => 'DateTimeOriginal', + Description => 'Date/Time Original', Groups => { 2 => 'Time' }, ValueConv => 'require Image::ExifTool::XMP; Image::ExifTool::XMP::ConvertXMPDate($val)', PrintConv => '$self->ConvertDateTime($val)', @@ -191,7 +192,7 @@ from Lytro Light Field Picture (LFP) files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/M2TS.pm b/src/Image-ExifTool/lib/Image/ExifTool/M2TS.pm index fba525bf..8d131c41 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/M2TS.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/M2TS.pm @@ -31,7 +31,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.15'; +$VERSION = '1.16'; # program map table "stream_type" lookup (ref 6/1) my %streamType = ( @@ -391,7 +391,7 @@ sub ProcessM2TS($$) my $prefix = unpack("x${pos}N", $buff); # (use unpack instead of Get32u for speed) # validate sync byte unless (($prefix & 0xff000000) == 0x47000000) { - $et->Warn('Synchronization error') unless defined $backScan; + $et->Warn('M2TS synchronization error') unless defined $backScan; last; } # my $transport_error_indicator = $prefix & 0x00800000; @@ -694,7 +694,7 @@ video. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MIE.pm b/src/Image-ExifTool/lib/Image/ExifTool/MIE.pm index c6e72042..45750878 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MIE.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MIE.pm @@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::GPS; -$VERSION = '1.47'; +$VERSION = '1.48'; sub ProcessMIE($$); sub ProcessMIEGroup($$$); @@ -152,11 +152,11 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); (eg. C<55(mi/h)>). If no units are specified, the default units are written. - 4) ExifTool writes compressed metadata to MIE files if the Compress (-z) + 4) ExifTool writes compressed metadata to MIE files if the L<Compress|../ExifTool.html#Compress> (-z) option is used and Compress::Zlib is available. - See L<http://owl.phy.queensu.ca/~phil/exiftool/MIE1.1-20070121.pdf> for the - official MIE specification. + See L<https://exiftool.org/MIE1.1-20070121.pdf> for the official MIE + specification. }, '0Type' => { Name => 'SubfileType', @@ -1001,10 +1001,10 @@ sub WriteMIEGroup($$$) } } # don't rewrite free bytes or information in deleted groups - if ($format eq 0x80 or ($delGroup and $tagLen and ($format & 0xf0) != 0x10)) { + if ($format == 0x80 or ($delGroup and $tagLen and ($format & 0xf0) != 0x10)) { $raf->Seek($valLen, 1) or $msg = 'Seek error', last; if ($verbose > 1) { - my $free = ($format eq 0x80) ? ' free' : ''; + my $free = ($format == 0x80) ? ' free' : ''; print $out " - $grp1:$tag ($valLen$free bytes)\n"; } ++$$et{CHANGED} if $delGroup; @@ -1242,8 +1242,7 @@ sub WriteMIEGroup($$$) # write new value if creating, or if List and list existed, or # if tag was previously deleted next unless $$nvHash{IsCreating} or - (($newTag eq $lastTag and ($$newInfo{List} or $deletedTag eq $lastTag) - and not $$nvHash{EditOnly})); + ($newTag eq $lastTag and ($$newInfo{List} or $deletedTag eq $lastTag)); } # get the new value to write (undef to delete) push @newVals, $et->GetNewValue($nvHash); @@ -1340,7 +1339,7 @@ sub WriteMIEGroup($$$) $extLen = Set32u($len); $len = 254; } else { - $et->Warn("Can't write $newTag (DataLength > 2GB not yet suppported)"); + $et->Warn("Can't write $newTag (DataLength > 2GB not yet supported)"); last; # don't write this tag } # write this element (with leading MIE group element if not done already) @@ -2545,7 +2544,7 @@ tag name. For example: =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The MIE format itself is also @@ -2555,7 +2554,7 @@ copyright Phil Harvey, and is covered by the same free-use license. =over 4 -=item L<http://owl.phy.queensu.ca/~phil/exiftool/MIE1.1-20070121.pdf> +=item L<https://exiftool.org/MIE1.1-20070121.pdf> =back diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MIEUnits.pod b/src/Image-ExifTool/lib/Image/ExifTool/MIEUnits.pod index 7cdfbfca..4c98233f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MIEUnits.pod +++ b/src/Image-ExifTool/lib/Image/ExifTool/MIEUnits.pod @@ -356,7 +356,7 @@ A few examples of combined units strings: =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MIFF.pm b/src/Image-ExifTool/lib/Image/ExifTool/MIFF.pm index a6cfe2c1..ec010db5 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MIFF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MIFF.pm @@ -255,7 +255,7 @@ This module contains routines required by Image::ExifTool to read MIFF =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MNG.pm b/src/Image-ExifTool/lib/Image/ExifTool/MNG.pm index 2f1d819a..ca2e6cb5 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MNG.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MNG.pm @@ -661,7 +661,7 @@ This module contains definitions required by Image::ExifTool to read MNG =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MOI.pm b/src/Image-ExifTool/lib/Image/ExifTool/MOI.pm new file mode 100644 index 00000000..c82cac70 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/MOI.pm @@ -0,0 +1,159 @@ +#------------------------------------------------------------------------------ +# File: MOI.pm +# +# Description: Read MOI meta information +# +# Revisions: 2014/12/15 - P. Harvey Created +# +# References: 1) https://en.wikipedia.org/wiki/MOI_(file_format) +#------------------------------------------------------------------------------ + +package Image::ExifTool::MOI; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.02'; + +# MOI tags (ref 1) +%Image::ExifTool::MOI::Main = ( + GROUPS => { 2 => 'Video' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + NOTES => q{ + MOI files store information about associated MOD or TOD files, and are + written by some JVC, Canon and Panasonic camcorders. + }, + 0x00 => { Name => 'MOIVersion', Format => 'string[2]' }, + # 0x02 => { Name => 'MOIFileSize', Format => 'int32u' }, + 0x06 => { + Name => 'DateTimeOriginal', + Description => 'Date/Time Original', + Format => 'undef[8]', + Groups => { 2 => 'Time' }, + ValueConv => sub { + my $val = shift; + return undef unless length($val) >= 8; + my @v = unpack('nCCCCn', $val); + $v[5] /= 1000; + return sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%06.3f', @v); + }, + PrintConv => '$self->ConvertDateTime($val)', + }, + 0x0e => { + Name => 'Duration', + Format => 'int32u', + ValueConv => '$val / 1000', + PrintConv => 'ConvertDuration($val)', + }, + 0x80 => { + Name => 'AspectRatio', + Format => 'int8u', + PrintConv => q{ + my $lo = ($val & 0x0f); + my $hi = ($val >> 4); + my $aspect; + if ($lo < 2) { + $aspect = '4:3'; + } elsif ($lo == 4 or $lo == 5) { + $aspect = '16:9'; + } else { + $aspect = 'Unknown'; + } + if ($hi == 4) { + $aspect .= ' NTSC'; + } elsif ($hi == 5) { + $aspect .= ' PAL'; + } + return $aspect; + }, + }, + 0x84 => { + Name => 'AudioCodec', + Format => 'int16u', + Groups => { 2 => 'Audio' }, + PrintHex => 1, + PrintConv => { + 0x00c1 => 'AC3', + 0x4001 => 'MPEG', + }, + }, + 0x86 => { + Name => 'AudioBitrate', + Format => 'int8u', + Groups => { 2 => 'Audio' }, + ValueConv => '$val * 16000 + 48000', + PrintConv => 'ConvertBitrate($val)', + }, + 0xda => { + Name => 'VideoBitrate', + Format => 'int16u', + PrintHex => 1, + ValueConv => { + 0x5896 => '8500000', + 0x813d => '5500000', + }, + PrintConv => 'ConvertBitrate($val)', + }, +); + +#------------------------------------------------------------------------------ +# Validate and extract metadata from MOI file +# Inputs: 0) ExifTool ref, 1) dirInfo ref +# Returns: 1 on success, 0 if this wasn't a valid MOI file +sub ProcessMOI($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my $buff; + # read enough to allow skipping over run-in if it exists + $raf->Read($buff, 256) == 256 and $buff =~ /^V6/ or return 0; + if (defined $$et{VALUE}{FileSize}) { + my $size = unpack('x2N', $buff); + $size == $$et{VALUE}{FileSize} or return 0; + } + $et->SetFileType(); + SetByteOrder('MM'); + my $tagTablePtr = GetTagTable('Image::ExifTool::MOI::Main'); + return $et->ProcessBinaryData({ DataPt => \$buff }, $tagTablePtr); +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::MOI - Read MOI meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read meta +information from MOI files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://en.wikipedia.org/wiki/MOI_(file_format)> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/MOI Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MPC.pm b/src/Image-ExifTool/lib/Image/ExifTool/MPC.pm index 1576fc9c..3b86d17e 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MPC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MPC.pm @@ -134,7 +134,7 @@ information from Musepack (MPC) audio files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MPEG.pm b/src/Image-ExifTool/lib/Image/ExifTool/MPEG.pm index c9acb2bc..00b44fad 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MPEG.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MPEG.pm @@ -704,7 +704,7 @@ based on unofficial sources which may be incomplete, inaccurate or outdated. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MPF.pm b/src/Image-ExifTool/lib/Image/ExifTool/MPF.pm index a6b5bd06..b5176a90 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MPF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MPF.pm @@ -97,7 +97,7 @@ sub ProcessMPImageList($$$); NOTES => q{ The first MPF "Large Thumbnail" image is extracted as PreviewImage, and the rest of the embedded MPF images are extracted as MPImage#. The - ExtractEmbedded (-ee) option may be used to extract information from these + L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option may be used to extract information from these embedded images. }, 0.1 => { @@ -163,7 +163,7 @@ sub ProcessMPImageList($$$); }, Notes => q{ the first MPF "Large Thumbnail" is extracted as PreviewImage, and the rest - of the embedded MPF images are extracted as MPImage#. The ExtractEmbedded + of the embedded MPF images are extracted as MPImage#. The L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option may be used to extract information from these embedded images. }, # extract all MPF images (not just one) @@ -266,7 +266,7 @@ Format (MPF) information from JPEG images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MWG.pm b/src/Image-ExifTool/lib/Image/ExifTool/MWG.pm index d63fe225..28b5321b 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MWG.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MWG.pm @@ -16,7 +16,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::XMP; -$VERSION = '1.22'; +$VERSION = '1.23'; sub RecoverTruncatedIPTC($$$); sub ListToString($); @@ -29,6 +29,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags %Image::ExifTool::MWG::Composite = ( GROUPS => { 0 => 'Composite', 1 => 'MWG', 2 => 'Image' }, VARS => { NO_ID => 1 }, + WRITE_PROC => \&Image::ExifTool::DummyWriteProc, NOTES => q{ The table below lists special Composite tags which are used to access other tags based on the MWG 2.0 recommendations. These tags are only accessible @@ -59,7 +60,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags string values be stored as UTF-8. To honour this, the exiftool application sets the default internal EXIF string encoding to "UTF8" when the MWG module is loaded, but via the API this must be done manually by setting the - CharsetEXIF option. + L<CharsetEXIF|../ExifTool.html#CharsetEXIF> option. A complication of the MWG specification is that although the MWG:Creator property may consist of multiple values, the associated EXIF tag @@ -116,7 +117,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags DateTimeOriginal => { Description => 'Date/Time Original', Groups => { 2 => 'Time' }, - Notes => '"creation date of the intellectual content being shown" - MWG', + Notes => '"specifies when a photo was taken" - MWG', Writable => 1, Shift => 0, # don't shift this tag Desire => { @@ -158,7 +159,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags }, CreateDate => { Groups => { 2 => 'Time' }, - Notes => '"creation date of the digital representation" - MWG', + Notes => '"specifies when an image was digitized" - MWG', Writable => 1, Shift => 0, # don't shift this tag Desire => { @@ -196,7 +197,7 @@ my $mwgLoaded; # flag set if we alreaded Load()ed the MWG tags }, ModifyDate => { Groups => { 2 => 'Time' }, - Notes => '"modification date of the digital image file" - MWG', + Notes => '"specifies when a file was modified by the user" - MWG', Writable => 1, Shift => 0, # don't shift this tag Desire => { @@ -459,7 +460,8 @@ my %sKeywordStruct; NOTES => q{ Image region metadata defined by the MWG 2.0 specification. These tags may be accessed without the need to load the MWG Composite tags above. See - L<http://www.metadataworkinggroup.org/> for the official specification. + L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> + for the official specification. }, Regions => { Name => 'RegionInfo', @@ -487,8 +489,9 @@ my %sKeywordStruct; Hierarchical keywords metadata defined by the MWG 2.0 specification. ExifTool unrolls keyword structures to an arbitrary depth of 6 to allow individual levels to be accessed with different tag names, and to avoid - infinite recursion. See L<http://www.metadataworkinggroup.org/> for the - official specification. + infinite recursion. See + L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> + for the official specification. }, # arbitrarily define only the first 6 levels of the keyword hierarchy Keywords => { @@ -526,7 +529,8 @@ my %sKeywordStruct; NAMESPACE => 'mwg-coll', NOTES => q{ Collections metadata defined by the MWG 2.0 specification. See - L<http://www.metadataworkinggroup.org/> for the official specification. + L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> + for the official specification. }, Collections => { FlatName => '', @@ -744,7 +748,7 @@ must be loaded explicitly as described above. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MXF.pm b/src/Image-ExifTool/lib/Image/ExifTool/MXF.pm index 45d30b3b..e52568c3 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MXF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MXF.pm @@ -2987,7 +2987,7 @@ information from MXF (Material Exchange Format) files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MacOS.pm b/src/Image-ExifTool/lib/Image/ExifTool/MacOS.pm new file mode 100644 index 00000000..c35469b9 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/MacOS.pm @@ -0,0 +1,619 @@ +#------------------------------------------------------------------------------ +# File: MacOS.pm +# +# Description: Read/write MacOS system tags +# +# Revisions: 2017/03/01 - P. Harvey Created +#------------------------------------------------------------------------------ + +package Image::ExifTool::MacOS; +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.09'; + +sub MDItemLocalTime($); + +my %mdDateInfo = ( + ValueConv => \&MDItemLocalTime, + PrintConv => '$self->ConvertDateTime($val)', +); + +# "mdls" tags (ref PH) +%Image::ExifTool::MacOS::MDItem = ( + WRITE_PROC => \&Image::ExifTool::DummyWriteProc, + VARS => { NO_ID => 1 }, + GROUPS => { 0 => 'File', 1 => 'MacOS', 2 => 'Other' }, + NOTES => q{ + MDItem tags are extracted using the "mdls" utility. They are extracted if + any "MDItem*" tag or the MacOS group is specifically requested, or by + setting the L<MDItemTags|../ExifTool.html#MDItemTags> API option to 1 or the L<RequestAll|../ExifTool.html#RequestAll> API option to 2 or + higher. Note that these tags do not necessarily reflect the current + metadata of a file -- it may take some time for the MacOS mdworker daemon to + index the file after a metadata change. + }, + MDItemFinderComment => { + Writable => 1, + WritePseudo => 1, + Protected => 1, # (all writable pseudo tags must be protected) + }, + MDItemFSLabel => { + Writable => 1, + WritePseudo => 1, + Protected => 1, # (all writable pseudo tags must be protected) + WriteCheck => '$val =~ /^[0-7]$/ ? undef : "Not an integer in the range 0-7"', + PrintConv => { + 0 => '0 (none)', + 1 => '1 (Gray)', + 2 => '2 (Green)', + 3 => '3 (Purple)', + 4 => '4 (Blue)', + 5 => '5 (Yellow)', + 6 => '6 (Red)', + 7 => '7 (Orange)', + }, + }, + MDItemFSCreationDate => { + Writable => 1, + WritePseudo => 1, + DelCheck => q{"Can't delete"}, + Protected => 1, # (all writable pseudo tags must be protected) + Shift => 'Time', # (but not supported yet) + Notes => q{ + file creation date. Requires "setfile" for writing. Note that when + reading, it may take a few seconds after writing a file before this value + reflects the change. However, L<FileCreateDate|Extra.html> is updated immediately + }, + Groups => { 2 => 'Time' }, + ValueConv => \&MDItemLocalTime, + ValueConvInv => '$val', + PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', + }, + MDItemAcquisitionMake => { Groups => { 2 => 'Camera' } }, + MDItemAcquisitionModel => { Groups => { 2 => 'Camera' } }, + MDItemAltitude => { Groups => { 2 => 'Location' } }, + MDItemAperture => { Groups => { 2 => 'Camera' } }, + MDItemAudioBitRate => { Groups => { 2 => 'Audio' } }, + MDItemAudioChannelCount => { Groups => { 2 => 'Audio' } }, + MDItemAuthors => { Groups => { 2 => 'Author' } }, + MDItemBitsPerSample => { Groups => { 2 => 'Image' } }, + MDItemCity => { Groups => { 2 => 'Location' } }, + MDItemCodecs => { }, + MDItemColorSpace => { Groups => { 2 => 'Image' } }, + MDItemComment => { }, + MDItemContentCreationDate => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemContentCreationDateRanking => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemContentModificationDate => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemContentType => { }, + MDItemContentTypeTree => { }, + MDItemContributors => { }, + MDItemCopyright => { Groups => { 2 => 'Author' } }, + MDItemCountry => { Groups => { 2 => 'Location' } }, + MDItemCreator => { Groups => { 2 => 'Document' } }, + MDItemDateAdded => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemDescription => { }, + MDItemDisplayName => { }, + MDItemDownloadedDate => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemDurationSeconds => { PrintConv => 'ConvertDuration($val)' }, + MDItemEncodingApplications => { }, + MDItemEXIFGPSVersion => { Groups => { 2 => 'Location' }, Description => 'MD Item EXIF GPS Version' }, + MDItemEXIFVersion => { }, + MDItemExposureMode => { Groups => { 2 => 'Camera' } }, + MDItemExposureProgram => { Groups => { 2 => 'Camera' } }, + MDItemExposureTimeSeconds => { Groups => { 2 => 'Camera' } }, + MDItemFlashOnOff => { Groups => { 2 => 'Camera' } }, + MDItemFNumber => { Groups => { 2 => 'Camera' } }, + MDItemFocalLength => { Groups => { 2 => 'Camera' } }, + MDItemFSContentChangeDate => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemFSCreatorCode => { Groups => { 2 => 'Author' } }, + MDItemFSFinderFlags => { }, + MDItemFSHasCustomIcon => { }, + MDItemFSInvisible => { }, + MDItemFSIsExtensionHidden => { }, + MDItemFSIsStationery => { }, + MDItemFSName => { }, + MDItemFSNodeCount => { }, + MDItemFSOwnerGroupID => { }, + MDItemFSOwnerUserID => { }, + MDItemFSSize => { }, + MDItemFSTypeCode => { }, + MDItemGPSDateStamp => { Groups => { 2 => 'Time' } }, + MDItemGPSStatus => { Groups => { 2 => 'Location' } }, + MDItemGPSTrack => { Groups => { 2 => 'Location' } }, + MDItemHasAlphaChannel => { Groups => { 2 => 'Image' } }, + MDItemImageDirection => { Groups => { 2 => 'Location' } }, + MDItemInterestingDateRanking => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemISOSpeed => { Groups => { 2 => 'Camera' } }, + MDItemKeywords => { }, + MDItemKind => { }, + MDItemLastUsedDate => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemLastUsedDate_Ranking => { }, + MDItemLatitude => { Groups => { 2 => 'Location' } }, + MDItemLensModel => { }, + MDItemLogicalSize => { }, + MDItemLongitude => { Groups => { 2 => 'Location' } }, + MDItemMediaTypes => { }, + MDItemNumberOfPages => { }, + MDItemOrientation => { Groups => { 2 => 'Image' } }, + MDItemOriginApplicationIdentifier => { }, + MDItemOriginMessageID => { }, + MDItemOriginSenderDisplayName => { }, + MDItemOriginSenderHandle => { }, + MDItemOriginSubject => { }, + MDItemPageHeight => { Groups => { 2 => 'Image' } }, + MDItemPageWidth => { Groups => { 2 => 'Image' } }, + MDItemPhysicalSize => { Groups => { 2 => 'Image' } }, + MDItemPixelCount => { Groups => { 2 => 'Image' } }, + MDItemPixelHeight => { Groups => { 2 => 'Image' } }, + MDItemPixelWidth => { Groups => { 2 => 'Image' } }, + MDItemProfileName => { Groups => { 2 => 'Image' } }, + MDItemRedEyeOnOff => { Groups => { 2 => 'Camera' } }, + MDItemResolutionHeightDPI => { Groups => { 2 => 'Image' } }, + MDItemResolutionWidthDPI => { Groups => { 2 => 'Image' } }, + MDItemSecurityMethod => { }, + MDItemSpeed => { Groups => { 2 => 'Location' } }, + MDItemStateOrProvince => { Groups => { 2 => 'Location' } }, + MDItemStreamable => { }, + MDItemTimestamp => { Groups => { 2 => 'Time' } }, # (time only) + MDItemTitle => { }, + MDItemTotalBitRate => { }, + MDItemUseCount => { }, + MDItemUsedDates => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemUserDownloadedDate => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemUserDownloadedUserHandle=> { }, + MDItemUserSharedReceivedDate => { }, + MDItemUserSharedReceivedRecipient => { }, + MDItemUserSharedReceivedRecipientHandle => { }, + MDItemUserSharedReceivedSender=> { }, + MDItemUserSharedReceivedSenderHandle => { }, + MDItemUserSharedReceivedTransport => { }, + MDItemUserTags => { + List => 1, + Writable => 1, + WritePseudo => 1, + Protected => 1, # (all writable pseudo tags must be protected) + Notes => q{ + requires "tag" utility for writing -- install with "brew install tag". Note + that user tags may not contain a comma, and that duplicate user tags will + not be written + }, + }, + MDItemVersion => { }, + MDItemVideoBitRate => { Groups => { 2 => 'Video' } }, + MDItemWhereFroms => { }, + MDItemWhiteBalance => { Groups => { 2 => 'Image' } }, + # tags used by Apple Mail on .emlx files + com_apple_mail_dateReceived => { Name => 'AppleMailDateReceived', Groups => { 2 => 'Time' }, %mdDateInfo }, + com_apple_mail_dateSent => { Name => 'AppleMailDateSent', Groups => { 2 => 'Time' }, %mdDateInfo }, + com_apple_mail_flagged => { Name => 'AppleMailFlagged' }, + com_apple_mail_messageID => { Name => 'AppleMailMessageID' }, + com_apple_mail_priority => { Name => 'AppleMailPriority' }, + com_apple_mail_read => { Name => 'AppleMailRead' }, + com_apple_mail_repliedTo => { Name => 'AppleMailRepliedTo' }, + com_apple_mail_isRemoteAttachment => { Name => 'AppleMailIsRemoteAttachment' }, + MDItemAccountHandles => { }, + MDItemAccountIdentifier => { }, + MDItemAuthorEmailAddresses => { }, + MDItemBundleIdentifier => { }, + MDItemContentCreationDate_Ranking=>{Groups=> { 2 => 'Time' }, %mdDateInfo }, + MDItemDateAdded_Ranking => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemEmailConversationID => { }, + MDItemIdentifier => { }, + MDItemInterestingDate_Ranking => { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemIsApplicationManaged => { }, + MDItemIsExistingThread => { }, + MDItemIsLikelyJunk => { }, + MDItemMailboxes => { }, + MDItemMailDateReceived_Ranking=> { Groups => { 2 => 'Time' }, %mdDateInfo }, + MDItemPrimaryRecipientEmailAddresses => { }, + MDItemRecipients => { }, + MDItemSubject => { }, +); + +# "xattr" tags +%Image::ExifTool::MacOS::XAttr = ( + WRITE_PROC => \&Image::ExifTool::DummyWriteProc, + GROUPS => { 0 => 'File', 1 => 'MacOS', 2 => 'Other' }, + VARS => { NO_ID => 1 }, # (id's are too long) + NOTES => q{ + XAttr tags are extracted using the "xattr" utility. They are extracted if + any "XAttr*" tag or the MacOS group is specifically requested, or by setting + the L<XAttrTags|../ExifTool.html#XAttrTags> API option to 1 or the L<RequestAll|../ExifTool.html#RequestAll> API option to 2 or higher. + }, + 'com.apple.FinderInfo' => { + Name => 'XAttrFinderInfo', + ConvertBinary => 1, + # ref https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-9A581/Finder.h + ValueConv => q{ + my @a = unpack('a4a4n3x10nx2N', $$val); + tr/\0//d, $_="'${_}'" foreach @a[0,1]; + return "@a"; + }, + PrintConv => q{ + $val =~ s/^('.*?') ('.*?') //s or return $val; + my ($type, $creator) = ($1, $2); + my ($flags, $y, $x, $exFlags, $putAway) = split ' ', $val; + my $label = ($flags >> 1) & 0x07; + my $flags = DecodeBits((($exFlags<<16) | $flags) & 0xfff1, { + 0 => 'OnDesk', + 6 => 'Shared', + 7 => 'HasNoInits', + 8 => 'Inited', + 10 => 'CustomIcon', + 11 => 'Stationery', + 12 => 'NameLocked', + 13 => 'HasBundle', + 14 => 'Invisible', + 15 => 'Alias', + # extended flags + 22 => 'HasRoutingInfo', + 23 => 'ObjectBusy', + 24 => 'CustomBadge', + 31 => 'ExtendedFlagsValid', + }); + my $str = "Type=$type Creator=$creator Flags=$flags Label=$label Pos=($x,$y)"; + $str .= " Putaway=$putAway" if $putAway; + return $str; + }, + }, + 'com.apple.quarantine' => { + Name => 'XAttrQuarantine', + Writable => 1, + WritePseudo => 1, + WriteCheck => '"May only delete this tag"', + Protected => 1, + Notes => q{ + quarantine information for files downloaded from the internet. May only be + deleted when writing + }, + # ($a[1] is the time when the quarantine tag was set) + PrintConv => q{ + my @a = split /;/, $val; + $a[0] = 'Flags=' . $a[0]; + $a[1] = 'set at ' . ConvertUnixTime(hex $a[1]); + $a[2] = 'by ' . $a[2]; + return join ' ', @a; + }, + PrintConvInv => '$val', + }, + 'com.apple.metadata:com_apple_mail_dateReceived' => { + Name => 'XAttrAppleMailDateReceived', + Groups => { 2 => 'Time' }, + }, + 'com.apple.metadata:com_apple_mail_dateSent' => { + Name => 'XAttrAppleMailDateSent', + Groups => { 2 => 'Time' }, + }, + 'com.apple.metadata:com_apple_mail_isRemoteAttachment' => { + Name => 'XAttrAppleMailIsRemoteAttachment', + }, + 'com.apple.metadata:kMDItemDownloadedDate' => { + Name => 'XAttrMDItemDownloadedDate', + Groups => { 2 => 'Time' }, + }, + 'com.apple.metadata:kMDItemFinderComment' => { Name => 'XAttrMDItemFinderComment' }, + 'com.apple.metadata:kMDItemWhereFroms' => { Name => 'XAttrMDItemWhereFroms' }, + 'com.apple.metadata:kMDLabel' => { Name => 'XAttrMDLabel', Binary => 1 }, + 'com.apple.ResourceFork' => { Name => 'XAttrResourceFork', Binary => 1 }, + 'com.apple.lastuseddate#PS' => { + Name => 'XAttrLastUsedDate', + Groups => { 2 => 'Time' }, + # (first 4 bytes are date/time. Not sure what remaining 12 bytes are for) + RawConv => 'ConvertUnixTime(unpack("V",$$val))', + PrintConv => '$self->ConvertDateTime($val)', + }, +); + +#------------------------------------------------------------------------------ +# Convert OS MDItem time string to standard EXIF-formatted local time +# Inputs: 0) time string (eg. "2017-02-21 17:21:43 +0000") +# Returns: EXIF-formatted local time string with timezone +sub MDItemLocalTime($) +{ + my $val = shift; + $val =~ tr/-/:/; + $val =~ s/ ?([-+]\d{2}):?(\d{2})/$1:$2/; + # convert from UTC to local time + if ($val =~ /\+00:00$/) { + my $time = Image::ExifTool::GetUnixTime($val); + $val = Image::ExifTool::ConvertUnixTime($time, 1) if $time; + } + return $val; +} + +#------------------------------------------------------------------------------ +# Set MacOS MDItem and XAttr tags from new tag values +# Inputs: 0) Exiftool ref, 1) file name, 2) list of tags to set +# Returns: 1=something was set OK, 0=didn't try, -1=error (and warning set) +# Notes: There may be errors even if 1 is returned +sub SetMacOSTags($$$) +{ + my ($et, $file, $setTags) = @_; + my $result = 0; + my $tag; + + foreach $tag (@$setTags) { + my ($nvHash, $f, $v, $attr, $cmd, $err, $silentErr); + my $val = $et->GetNewValue($tag, \$nvHash); + next unless $nvHash; + my $overwrite = $et->IsOverwriting($nvHash); + unless ($$nvHash{TagInfo}{List}) { + next unless $overwrite; + if ($overwrite < 0) { + my $operation = $$nvHash{Shift} ? 'Shifting' : 'Conditional replacement'; + $et->Warn("$operation of MacOS $tag not yet supported"); + next; + } + } + if ($tag eq 'MDItemFSCreationDate' or $tag eq 'FileCreateDate') { + ($f = $file) =~ s/'/'\\''/g; + # convert to local time if value has a time zone + if ($val =~ /[-+Z]/) { + my $time = Image::ExifTool::GetUnixTime($val, 1); + $val = Image::ExifTool::ConvertUnixTime($time, 1) if $time; + } + $val =~ s{(\d{4}):(\d{2}):(\d{2})}{$2/$3/$1}; # reformat for setfile + $cmd = "setfile -d '${val}' '${f}'"; + } elsif ($tag eq 'MDItemUserTags') { + # (tested with "tag" version 0.9.0) + ($f = $file) =~ s/'/'\\''/g; + my @vals = $et->GetNewValue($nvHash); + if ($overwrite < 0 and @{$$nvHash{DelValue}}) { + # delete specified tags + my @dels = @{$$nvHash{DelValue}}; + s/'/'\\''/g foreach @dels; + my $del = join ',', @dels; + $err = system "tag -r '${del}' '${f}'>/dev/null 2>&1"; + unless ($err) { + $et->VerboseValue("- $tag", $del); + $result = 1; + undef $err if @vals; # more to do if there are tags to add + } + } + unless (defined $err) { + # add new tags, or overwrite or delete existing tags + s/'/'\\''/g foreach @vals; + my $opt = $overwrite > 0 ? '-s' : '-a'; + $val = @vals ? join(',', @vals) : ''; + $cmd = "tag $opt '${val}' '${f}'"; + $et->VPrint(1," - $tag = (all)\n") if $overwrite > 0; + undef $val if $val eq ''; + } + } elsif ($tag eq 'XAttrQuarantine') { + ($f = $file) =~ s/'/'\\''/g; + $cmd = "xattr -d com.apple.quarantine '${f}'"; + $silentErr = 256; # (will get this error if attribute doesn't exist) + } else { + ($f = $file) =~ s/(["\\])/\\$1/g; # escape necessary characters for script + $f =~ s/'/'"'"'/g; + if ($tag eq 'MDItemFinderComment') { + # (write finder comment using osascript instead of xattr + # because it is more work to construct the necessary bplist) + $val = '' unless defined $val; # set to empty string instead of deleting + $v = $et->Encode($val, 'UTF8'); + $v =~ s/(["\\])/\\$1/g; + $v =~ s/'/'"'"'/g; + $attr = 'comment'; + } else { # $tag eq 'MDItemFSLabel' + $v = $val ? 8 - $val : 0; # convert from label to label index (0 for no label) + $attr = 'label index'; + } + $cmd = qq(osascript -e 'set fp to POSIX file "$f" as alias' -e \\ + 'tell application "Finder" to set $attr of file fp to "$v"'); + } + if (defined $cmd) { + $err = system $cmd . '>/dev/null 2>&1'; # (pipe all output to /dev/null) + } + if (not $err) { + $et->VerboseValue("+ $tag", $val) if defined $val; + $result = 1; + } elsif (not $silentErr or $err != $silentErr) { + $cmd =~ s/ .*//s; + $et->Warn(qq{Error $err running "$cmd" to set $tag}); + $result = -1 unless $result; + } + } + return $result; +} + +#------------------------------------------------------------------------------ +# Extract MacOS metadata item tags +# Inputs: 0) ExifTool object ref, 1) file name +sub ExtractMDItemTags($$) +{ + local $_; + my ($et, $file) = @_; + my ($fn, $tag, $val, $tmp); + + ($fn = $file) =~ s/([`"\$\\])/\\$1/g; # escape necessary characters + $et->VPrint(0, '(running mdls)'); + my @mdls = `mdls "$fn" 2> /dev/null`; # get MacOS metadata + if ($? or not @mdls) { + $et->Warn('Error running "mdls" to extract MDItem tags'); + return; + } + my $tagTablePtr = GetTagTable('Image::ExifTool::MacOS::MDItem'); + $$et{INDENT} .= '| '; + $et->VerboseDir('MDItem'); + foreach (@mdls) { + chomp; + if (ref $val ne 'ARRAY') { + s/^k?(\w+)\s*= // or next; + $tag = $1; + $_ eq '(' and $val = [ ], next; # (start of a list) + $_ = '' if $_ eq '(null)'; + s/^"// and s/"$//; # remove quotes if they exist + $val = $_; + } elsif ($_ eq ')') { # (end of a list) + $_ = $$val[0]; + next unless defined $_; + } else { + # add item to list + s/^ //; # remove leading spaces + s/,$//; # remove trailing comma + $_ = '' if $_ eq '(null)'; + s/^"// and s/"$//; # remove quotes if they exist + s/\\"/"/g; # un-escape quotes + $_ = $et->Decode($_, 'UTF8'); + push @$val, $_; + next; + } + # add to Extra tags if not done already + unless ($$tagTablePtr{$tag}) { + # check for a date/time format + my %tagInfo; + %tagInfo = ( + Groups => { 2 => 'Time' }, + ValueConv => \&MDItemLocalTime, + PrintConv => '$self->ConvertDateTime($val)', + ) if /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/; + # change tags like "com_apple_mail_xxx" to "AppleMailXxx" + ($tmp = $tag) =~ s/^com_//; # remove leading "com_" + $tmp =~ s/_([a-z])/\u$1/g; # use CamelCase + $tagInfo{Name} = Image::ExifTool::MakeTagName($tmp); + $tagInfo{List} = 1 if ref $val eq 'ARRAY'; + $tagInfo{Groups}{2} = 'Audio' if $tag =~ /Audio/; + $tagInfo{Groups}{2} = 'Author' if $tag =~ /(Copyright|Author)/; + $et->VPrint(0, " [adding $tag]\n"); + AddTagToTable($tagTablePtr, $tag, \%tagInfo); + } + $val = $et->Decode($val, 'UTF8') unless ref $val; + $et->HandleTag($tagTablePtr, $tag, $val); + undef $val; + } + $$et{INDENT} =~ s/\| $//; +} + +#------------------------------------------------------------------------------ +# Extract MacOS extended attribute tags +# Inputs: 0) ExifTool object ref, 1) file name +sub ExtractXAttrTags($$) +{ + local $_; + my ($et, $file) = @_; + my ($fn, $tag, $val, $warn); + + ($fn = $file) =~ s/([`"\$\\])/\\$1/g; # escape necessary characters + $et->VPrint(0, '(running xattr)'); + my @xattr = `xattr -lx "$fn" 2> /dev/null`; # get MacOS extended attributes + if ($? or not @xattr) { + $? and $et->Warn('Error running "xattr" to extract XAttr tags'); + return; + } + my $tagTablePtr = GetTagTable('Image::ExifTool::MacOS::XAttr'); + $$et{INDENT} .= '| '; + $et->VerboseDir('XAttr'); + push @xattr, ''; # (for a list terminator) + foreach (@xattr) { + chomp; + if (s/^[\dA-Fa-f]{8}//) { + $tag or $warn = 1, next; + s/\|.*//; + tr/ //d; + (/[^\dA-Fa-f]/ or length($_) & 1) and $warn = 2, next; + $val = '' unless defined $val; + $val .= pack('H*', $_); + next; + } elsif ($tag and defined $val) { + # add to our table if necessary + unless ($$tagTablePtr{$tag}) { + my $name; + # generate tag name from attribute name + if ($tag =~ /^com\.apple\.(.*)$/) { + ($name = $1) =~ s/^metadata:_?k//; + $name =~ s/^metadata:(com_)?//; + } else { + $name = $tag; + } + $name =~ s/[.:_]([a-z])/\U$1/g; + $name = 'XAttr' . ucfirst $name; + my %tagInfo = ( Name => $name ); + $tagInfo{Groups} = { 2 => 'Time' } if $tag=~/Date$/; + $et->VPrint(0, " [adding $tag]\n"); + AddTagToTable($tagTablePtr, $tag, \%tagInfo); + } + if ($val =~ /^bplist0/) { + my %dirInfo = ( DataPt => \$val ); + require Image::ExifTool::PLIST; + if (Image::ExifTool::PLIST::ProcessBinaryPLIST($et, \%dirInfo, $tagTablePtr)) { + next if ref $dirInfo{Value} eq 'HASH'; + $val = $dirInfo{Value} + } else { + $et->Warn("Error decoding $$tagTablePtr{$tag}{Name}"); + next; + } + } + if (not ref $val and ($val =~ /\0/ or length($val) > 200) or $tag eq 'XAttrMDLabel') { + my $buff = $val; + $val = \$buff; + } + $et->HandleTag($tagTablePtr, $tag, $val); + undef $tag; + undef $val; + } + next unless length; + s/:$// or $warn = 3, next; # attribute name must have trailing ":" + defined $val and $warn = 4, undef $val; + # remove random ID after kMDLabel in tag ID + ($tag = $_) =~ s/^com.apple.metadata:kMDLabel_.*/com.apple.metadata:kMDLabel/s; + } + $warn and $et->Warn(qq{Error $warn parsing "xattr" output}); + $$et{INDENT} =~ s/\| $//; +} + +#------------------------------------------------------------------------------ +# Extract MacOS file creation date/time +# Inputs: 0) ExifTool object ref, 1) file name +sub GetFileCreateDate($$) +{ + local $_; + my ($et, $file) = @_; + my ($fn, $tag, $val, $tmp); + + ($fn = $file) =~ s/([`"\$\\])/\\$1/g; # escape necessary characters + $et->VPrint(0, '(running stat)'); + my $time = `stat -f '%SB' -t '%Y:%m:%d %H:%M:%S%z' "$fn" 2> /dev/null`; + if ($? or not $time or $time !~ s/([-+]\d{2})(\d{2})\s*$/$1:$2/) { + $et->Warn('Error running "stat" to extract FileCreateDate'); + return; + } + $$et{SET_GROUP1} = 'MacOS'; + $et->FoundTag(FileCreateDate => $time); + delete $$et{SET_GROUP1}; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::MacOS - Read/write MacOS system tags + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to extract +MDItem* and XAttr* tags on MacOS systems using the "mdls" and "xattr" +utilities respectively. Writable tags use "xattr", "setfile" or "osascript" +for writing. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/MacOS Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MakerNotes.pm b/src/Image-ExifTool/lib/Image/ExifTool/MakerNotes.pm index 96d02bf6..f1940884 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MakerNotes.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MakerNotes.pm @@ -21,7 +21,7 @@ sub ProcessKodakPatch($$$); sub WriteUnknownOrPreview($$$); sub FixLeicaBase($$;$); -$VERSION = '2.06'; +$VERSION = '2.10'; my $debug; # set to 1 to enable debugging code @@ -32,7 +32,7 @@ my $debug; # set to 1 to enable debugging code # write maker notes into a file with different byte ordering! # - Put these in alphabetical order to make TagNames documentation nicer. @Image::ExifTool::MakerNotes::Main = ( - # decide which MakerNotes to use (based on camera make/model) + # decide which MakerNotes to use (based on makernote header and camera make/model) { Name => 'MakerNoteApple', Condition => '$$valPt =~ /^Apple iOS\0/', @@ -160,6 +160,10 @@ my $debug; # set to 1 to enable debugging code Start => '$valuePtr', Base => 0, # (avoids warnings since maker notes are not self-contained) }, + # 0x0011 - sensor code (ref IB) + # 0x0012 - camera model id? + # 0x0015 - camera model name + # 0x0016 - coating code (ref IB) }, # (the GE X5 has really messed up EXIF-like maker notes starting with # "GENIC\x0c\0" --> currently not decoded) @@ -687,7 +691,15 @@ my $debug; # set to 1 to enable debugging code SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::Leica9', Start => '$valuePtr + 8', - Base => '$start - 8', + ByteOrder => 'Unknown', + }, + }, + { + Name => 'MakerNoteLeica10', # used by the D-Lux7 + Condition => '$$valPt =~ /^LEICA CAMERA AG\0/', + SubDirectory => { + TagTable => 'Image::ExifTool::Panasonic::Main', + Start => '$valuePtr + 18', ByteOrder => 'Unknown', }, }, @@ -832,6 +844,25 @@ my $debug; # set to 1 to enable debugging code ByteOrder => 'Little-endian', }, }, + { + Name => 'MakerNoteReconyx3', + Condition => '$$valPt =~ /^RECONYXH2\0/', + SubDirectory => { + TagTable => 'Image::ExifTool::Reconyx::Type3', + ByteOrder => 'Little-endian', + }, + }, + { + Name => 'MakerNoteRicohPentax', + # used by cameras such as the Ricoh GR III + Condition => '$$valPt=~/^RICOH\0(II|MM)/', + SubDirectory => { + TagTable => 'Image::ExifTool::Pentax::Main', + Start => '$valuePtr + 8', + Base => '$start - 8', + ByteOrder => 'Unknown', + }, + }, { Name => 'MakerNoteRicoh', # (my test R50 image starts with " \x02\x01" - PH) @@ -891,9 +922,9 @@ my $debug; # set to 1 to enable debugging code }, { Name => 'MakerNoteSamsung2', - # Samsung EXIF-format maker notes + # Samsung EXIF-format maker notes ( Condition => q{ - $$self{Make} eq 'SAMSUNG' and ($$self{TIFF_TYPE} eq 'SRW' or + uc $$self{Make} eq 'SAMSUNG' and ($$self{TIFF_TYPE} eq 'SRW' or $$valPt=~/^(\0.\0\x01\0\x07\0{3}\x04|.\0\x01\0\x07\0\x04\0{3})0100/s) }, SubDirectory => { @@ -942,8 +973,12 @@ my $debug; # set to 1 to enable debugging code }, { Name => 'MakerNoteSigma', - # (starts with "SIGMA\0") - Condition => '$$self{Make}=~/^(SIGMA|FOVEON)/', + Condition => q{ + return undef unless $$self{Make}=~/^(SIGMA|FOVEON)/; + # save version number in "MakerNoteSigmaVer" member variable + $$self{MakerNoteSigmaVer} = $$valPt=~/^SIGMA\0\0\0\0(.)/ ? ord($1) : -1; + return 1; + }, SubDirectory => { TagTable => 'Image::ExifTool::Sigma::Main', Validate => '$val =~ /^(SIGMA|FOVEON)/', @@ -1777,7 +1812,7 @@ maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Matroska.pm b/src/Image-ExifTool/lib/Image/ExifTool/Matroska.pm index 8f8cd76d..5aeb07ad 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Matroska.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Matroska.pm @@ -28,7 +28,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); The following tags are extracted from Matroska multimedia container files. This container format is used by file types such as MKA, MKV, MKS and WEBM. For speed, ExifTool extracts tags only up to the first Cluster unless the - Verbose (-v) or Unknown = 2 (-U) option is used. See + L<Verbose|../ExifTool.html#Verbose> (-v) or L<Unknown|../ExifTool.html#Unknown> = 2 (-U) option is used. See L<http://www.matroska.org/technical/specs/index.html> for the official Matroska specification. }, @@ -798,7 +798,7 @@ sub ProcessMKV($$) # just skip unknown and large data blocks if (not $tagInfo or $more > 10000000) { # don't try to skip very large blocks unless LargeFileSupport is enabled - last if $more > 0x80000000 and not $et->Options('LargeFileSupport'); + last if $more >= 0x80000000 and not $et->Options('LargeFileSupport'); $raf->Seek($more, 1) or last; $buff = ''; $dataPos += $dataLen + $more; @@ -912,7 +912,7 @@ information from Matroska multimedia files (MKA, MKV, MKS and WEBM). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Microsoft.pm b/src/Image-ExifTool/lib/Image/ExifTool/Microsoft.pm index 7ae6167f..9b93c976 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Microsoft.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Microsoft.pm @@ -152,7 +152,7 @@ my %sRegions = ( Rectangle => { }, PersonDisplayName => { }, PersonEmailDigest => { }, - PersonLiveIdCID => { }, # (see http://130.15.24.88/exiftool/forum/index.php?topic=4274.msg20368#msg20368) + PersonLiveIdCID => { }, # (see https://exiftool.org/forum/index.php?topic=4274.msg20368#msg20368) PersonSourceID => { }, ); %Image::ExifTool::Microsoft::MP = ( @@ -884,7 +884,7 @@ Microsoft-specific EXIF and XMP tags. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Minolta.pm b/src/Image-ExifTool/lib/Image/ExifTool/Minolta.pm index 4115c21e..22d15364 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Minolta.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Minolta.pm @@ -31,10 +31,10 @@ # 22) http://www.mi-fo.de/forum/index.php?act=attach&type=post&id=6024 # 23) Marcin Krol private communication # 24) http://cpanforum.com/threads/12291 -# 26) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3521.0.html -# 27) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3833.0.html +# 26) https://exiftool.org/forum/index.php/topic,3521.0.html +# 27) https://exiftool.org/forum/index.php/topic,3833.0.html # 28) Michael Reitinger private communication (RX100) -# 29) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4086.0.html +# 29) https://exiftool.org/forum/index.php/topic,4086.0.html # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication # JR) Jos Roost private communication @@ -49,7 +49,7 @@ use vars qw($VERSION %minoltaLensTypes %minoltaTeleconverters %minoltaColorMode use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '2.66'; +$VERSION = '2.83'; # Full list of product codes for Sony-compatible Minolta lenses # (ref http://www.kb.sony.com/selfservice/documentLink.do?externalId=C1000570) @@ -236,12 +236,13 @@ $VERSION = '2.66'; 24 => 'Minolta/Sony AF 24-105mm F3.5-4.5 (D) or Sigma or Tamron Lens', # 24 => 'Sony 24-105mm F3.5-4.5 (SAL24105)', (ref JR) 24.1 => 'Sigma 18-50mm F2.8', - 24.2 => 'Sigma 17-70mm F2.8-4.5 (D)', + 24.2 => 'Sigma 17-70mm F2.8-4.5 DC Macro', # (changed "(D)" to "DC Macro", ref JR) 24.3 => 'Sigma 20-40mm F2.8 EX DG Aspherical IF', #JD/22 24.4 => 'Sigma 18-200mm F3.5-6.3 DC', #22 24.5 => 'Sigma DC 18-125mm F4-5,6 D', #exiv2 0.23 # 24.6 => 'Tamron SP AF 28-75mm F2.8 XR Di (IF) Macro', #JD 24.6 => 'Tamron SP AF 28-75mm F2.8 XR Di LD Aspherical [IF] Macro', #NJ (Model A09) + 24.7 => 'Sigma 15-30mm F3.5-4.5 EX DG Aspherical', #JR 25 => 'Minolta AF 100-300mm F4.5-5.6 APO (D) or Sigma Lens', 25.1 => 'Sigma 100-300mm F4 EX (APO (D) or D IF)', #JD 25.2 => 'Sigma 70mm F2.8 EX DG Macro', #JD @@ -250,6 +251,7 @@ $VERSION = '2.66'; 25.5 => 'Sigma 24mm F1.8 EX DG ASP Macro', #Florian Knorn # 25 - also seen for an "old Sigma 50mm Macro" (forum2833) 27 => 'Minolta AF 85mm F1.4 G (D)', # added (D) (ref 13) + # 27 => 'Venus Optics Laowa 105mm F2 STF', #IB (NC) 28 => 'Minolta/Sony AF 100mm F2.8 Macro (D) or Tamron Lens', # 28 => 'Sony 100mm F2.8 Macro (SAL100M28)', (ref 18/JR) 28.1 => 'Tamron SP AF 90mm F2.8 Di Macro', #JD (Model 272E) @@ -287,12 +289,14 @@ $VERSION = '2.66'; 45 => 'Carl Zeiss Planar T* 85mm F1.4 ZA (SAL85F14Z)', #JR 46 => 'Carl Zeiss Vario-Sonnar T* DT 16-80mm F3.5-4.5 ZA (SAL1680Z)', #JR 47 => 'Carl Zeiss Sonnar T* 135mm F1.8 ZA (SAL135F18Z)', #JR - 48 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM (SAL2470Z) or ZA SSM II', #11/JR + 48 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM (SAL2470Z) or Other Lens', #11/JR 48.1 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM II (SAL2470Z2)', #JR + 48.2 => 'Tamron SP 24-70mm F2.8 Di USD', #IB (A007) (also with id 204) 49 => 'Sony DT 55-200mm F4-5.6 (SAL55200)', #JD/JR 50 => 'Sony DT 18-250mm F3.5-6.3 (SAL18250)', #11/JR 51 => 'Sony DT 16-105mm F3.5-5.6 (SAL16105)', #11/JR #51.1 => 'Sony AF DT 55-200mm F4-5.5', #11 (anomaly? - PH) + # LensType 52 also seen for Fringer Contax_N to E-mount adapter Ver.31 and Ver.21 (ref JR) 52 => 'Sony 70-300mm F4.5-5.6 G SSM (SAL70300G) or G SSM II or Tamron Lens', #JD 52.1 => 'Sony 70-300mm F4.5-5.6 G SSM II (SAL70300G2)', #JR 52.2 => 'Tamron SP 70-300mm F4-5.6 Di USD', #JR,NJ (Model A005) @@ -303,7 +307,7 @@ $VERSION = '2.66'; 55.1 => 'Sony DT 18-55mm F3.5-5.6 SAM II (SAL18552)', #JR 56 => 'Sony DT 55-200mm F4-5.6 SAM (SAL55200-2)', #22/JR 57 => 'Sony DT 50mm F1.8 SAM (SAL50F18) or Tamron Lens or Commlite CM-EF-NEX adapter', #22/JR - 57.1 => 'Tamron SP AF 60mm F2 Di II LD [IF] Macro 1:1', # (Model G005) (ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3858.0.html) + 57.1 => 'Tamron SP AF 60mm F2 Di II LD [IF] Macro 1:1', # (Model G005) (ref https://exiftool.org/forum/index.php/topic,3858.0.html) 57.2 => 'Tamron 18-270mm F3.5-6.3 Di II PZD', #27 (Model B008) # (note: the Commlite CM-EF-NEX adapter also appears to give LensType 57, ref JR) 58 => 'Sony DT 30mm F2.8 Macro SAM (SAL30M28)', #22/JR @@ -324,35 +328,35 @@ $VERSION = '2.66'; # was 128.1 => 'Tamron 18-200mm F3.5-6.3', 128.2 => 'Tamron AF 28-300mm F3.5-6.3 XR Di LD Aspherical [IF] Macro', #JR (Model A061) # was 128.2 => 'Tamron 28-300mm F3.5-6.3', - 128.3 => 'Tamron 80-300mm F3.5-6.3', - 128.4 => 'Tamron AF 28-200mm F3.8-5.6 XR Di Aspherical [IF] Macro', #JD (Model A031) + # (removed -- probably never existed, ref IB) 'Tamron 80-300mm F3.5-6.3', + 128.3 => 'Tamron AF 28-200mm F3.8-5.6 XR Di Aspherical [IF] Macro', #JD (Model A031) # also Tamron AF 28-200mm F3.8-5.6 Aspherical', #IB (Model 71D) # and 'Tamron AF 28-200mm F3.8-5.6 LD Aspherical [IF] Super', #IB (Model 171D) - 128.5 => 'Tamron SP AF 17-35mm F2.8-4 Di LD Aspherical IF', #JD (Model A05) - 128.6 => 'Sigma AF 50-150mm F2.8 EX DC APO HSM II', #JD - 128.7 => 'Sigma 10-20mm F3.5 EX DC HSM', #11 (Model 202-205) - 128.8 => 'Sigma 70-200mm F2.8 II EX DG APO MACRO HSM', #24 - 128.9 => 'Sigma 10mm F2.8 EX DC HSM Fisheye', #Florian Knorn + 128.4 => 'Tamron SP AF 17-35mm F2.8-4 Di LD Aspherical IF', #JD (Model A05) + 128.5 => 'Sigma AF 50-150mm F2.8 EX DC APO HSM II', #JD + 128.6 => 'Sigma 10-20mm F3.5 EX DC HSM', #11 (Model 202-205) + 128.7 => 'Sigma 70-200mm F2.8 II EX DG APO MACRO HSM', #24 + 128.8 => 'Sigma 10mm F2.8 EX DC HSM Fisheye', #Florian Knorn # (yes, '128.10'. My condolences to typed languages that use this database - PH) - '128.10' => 'Sigma 50mm F1.4 EX DG HSM', #Florian Knorn (Model A014, ref IB) - '128.11' => 'Sigma 85mm F1.4 EX DG HSM', #27 - '128.12' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #27 - '128.13' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM', #27 - '128.14' => 'Sigma 17-50mm F2.8 EX DC HSM', #Exiv2 - '128.15' => 'Sigma 17-70mm F2.8-4 DC Macro HSM', #JR (OS Model C013, ref IB) - '128.16' => 'Sigma 150mm F2.8 EX DG OS HSM APO Macro', #Marcus Holland-Moritz - '128.17' => 'Sigma 150-500mm F5-6.3 APO DG OS HSM', #IB - '128.18' => 'Tamron AF 28-105mm F4-5.6 [IF]', #IB (Model 179D) - '128.19' => 'Sigma 35mm F1.4 DG HSM', #JR - '128.20' => 'Sigma 18-35mm F1.8 DC HSM', #JR (Model A013, ref IB) - '128.21' => 'Sigma 50-500mm F4.5-6.3 APO DG OS HSM', #JR - '128.22' => 'Sigma 24-105mm F4 DG HSM | A', #JR (013) - '128.23' => 'Sigma 30mm F1.4', #IB - '128.24' => 'Sigma 35mm F1.4 DG HSM | A', #IB/JR (012) - '128.25' => 'Sigma 105mm F2.8 EX DG OS HSM Macro', #IB - '128.26' => 'Sigma 180mm F2.8 EX DG OS HSM APO Macro', #IB - '128.27' => 'Sigma 18-300mm F3.5-6.3 DC Macro HSM | C', #IB/JR (014) - '128.28' => 'Sigma 18-50mm F2.8-4.5 DC HSM', #IB + 128.9 => 'Sigma 50mm F1.4 EX DG HSM', #Florian Knorn (Model A014, ref IB) + '128.10' => 'Sigma 85mm F1.4 EX DG HSM', #27 + '128.11' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #27 + '128.12' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM', #27 + '128.13' => 'Sigma 17-50mm F2.8 EX DC HSM', #Exiv2 + '128.14' => 'Sigma 17-70mm F2.8-4 DC Macro HSM', # (no OS for Sony mount, ref JR) (also C013 Model, ref IB) + '128.15' => 'Sigma 150mm F2.8 EX DG OS HSM APO Macro', #Marcus Holland-Moritz + '128.16' => 'Sigma 150-500mm F5-6.3 APO DG OS HSM', #IB + '128.17' => 'Tamron AF 28-105mm F4-5.6 [IF]', #IB (Model 179D) + '128.18' => 'Sigma 35mm F1.4 DG HSM', #JR + '128.19' => 'Sigma 18-35mm F1.8 DC HSM', #JR (Model A013, ref IB) + '128.20' => 'Sigma 50-500mm F4.5-6.3 APO DG OS HSM', #JR + '128.21' => 'Sigma 24-105mm F4 DG HSM | A', #JR (013) + '128.22' => 'Sigma 30mm F1.4', #IB + '128.23' => 'Sigma 35mm F1.4 DG HSM | A', #IB/JR (012) + '128.24' => 'Sigma 105mm F2.8 EX DG OS HSM Macro', #IB + '128.25' => 'Sigma 180mm F2.8 EX DG OS HSM APO Macro', #IB + '128.26' => 'Sigma 18-300mm F3.5-6.3 DC Macro HSM | C', #IB/JR (014) + '128.27' => 'Sigma 18-50mm F2.8-4.5 DC HSM', #IB 129 => 'Tamron Lens (129)', 129.1 => 'Tamron 200-400mm F5.6 LD', #12 (LD ref 23) 129.2 => 'Tamron 70-300mm F4-5.6 LD', #12 @@ -362,12 +366,14 @@ $VERSION = '2.66'; 137 => 'Cosina 70-210mm F2.8-4 AF', #11 138 => 'Soligor 19-35mm F3.5-4.5', #11 139 => 'Tokina AF 28-300mm F4-6.3', #IB - 142 => 'Voigtlander 70-300mm F4.5-5.6', #JD + # (the following Cosina 70-300mm lens was also marketed as a Phoenix, Vivitar Series 1, and + # some sort of 3rd-party marketing as a Voightlander 70-300mm F4.5-5.6 SKOPAR AF, ref IB) + 142 => 'Cosina AF 70-300mm F4.5-5.6 MC', #IB (was 'Voigtlander 70-300mm F4.5-5.6', #JD) 146 => 'Voigtlander Macro APO-Lanthar 125mm F2.5 SL', #JD 194 => 'Tamron SP AF 17-50mm F2.8 XR Di II LD Aspherical [IF]', #23 (Model A16) 202 => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro', #JR (Model A001) (see also 255.7) 203 => 'Tamron SP 70-200mm F2.8 Di USD', #JR (Model A009) - 204 => 'Tamron SP 24-70mm F2.8 Di USD', #JR (Model A007) + 204 => 'Tamron SP 24-70mm F2.8 Di USD', #JR (Model A007) (also with id 48) 212 => 'Tamron 28-300mm F3.5-6.3 Di PZD', #JR (Model A010) 213 => 'Tamron 16-300mm F3.5-6.3 Di II PZD Macro', #JR (Model B016) 214 => 'Tamron SP 150-600mm F5-6.3 Di USD', #JR (Model A011) @@ -409,10 +415,11 @@ $VERSION = '2.66'; 25521.7 => 'Angenieux AF 28-70mm F2.6', #JD 25521.8 => 'Tokina AT-X 17 AF 17mm F3.5', #27 25521.9 => 'Tokina 20-35mm F3.5-4.5 II AF', #IB - 25531 => 'Minolta AF 28-135mm F4-4.5 or Sigma Lens', + 25531 => 'Minolta AF 28-135mm F4-4.5 or Other Lens', 25531.1 => 'Sigma ZOOM-alpha 35-135mm F3.5-4.5', #16 25531.2 => 'Sigma 28-105mm F2.8-4 Aspherical', #JD 25531.3 => 'Sigma 28-105mm F4-5.6 UC', #JR + 25531.4 => 'Tokina AT-X 242 AF 24-200mm F3.5-5.6', #IB 25541 => 'Minolta AF 35-105mm F3.5-4.5', #13 25551 => 'Minolta AF 70-210mm F4 Macro or Sigma Lens', 25551.1 => 'Sigma 70-210mm F4-5.6 APO', #7 @@ -431,7 +438,7 @@ $VERSION = '2.66'; 25611.5 => 'Tokina AT-X AF 300mm F4', #JD 25611.6 => 'Tokina AT-X AF 400mm F5.6 SD', #22 25611.7 => 'Tokina AF 730 II 75-300mm F4.5-5.6', #JD - 25611.8 => 'Sigma 800mm F5.6 APO', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3472.0.html + 25611.8 => 'Sigma 800mm F5.6 APO', #https://exiftool.org/forum/index.php/topic,3472.0.html 25611.9 => 'Sigma AF 400mm F5.6 APO Macro', #27 '25611.10' => 'Sigma 1000mm F8 APO', #JR 25621 => 'Minolta AF 50mm F1.4 [New]', # original and New, not Sony (ref 13/18) @@ -444,7 +451,7 @@ $VERSION = '2.66'; 25641.1 => 'Sigma 50mm F2.8 EX Macro', #11 25651 => 'Minolta AF 600mm F4 APO', # ("APO" added - ref JR) 25661 => 'Minolta AF 24mm F2.8 or Sigma Lens', - 25661.1 => 'Sigma 17-35mm F2.8-4 EX Aspherical', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3789.msg17679.html#msg17679 + 25661.1 => 'Sigma 17-35mm F2.8-4 EX Aspherical', #https://exiftool.org/forum/index.php/topic,3789.msg17679.html#msg17679 25721 => 'Minolta/Sony AF 500mm F8 Reflex', # 25721 => 'Sony 500mm F8 Reflex (SAL500F80)', (ref JR) 25781 => 'Minolta/Sony AF 16mm F2.8 Fisheye or Sigma Lens', # Sony added (ref 13/18) @@ -454,12 +461,12 @@ $VERSION = '2.66'; 25781.3 => 'Sigma 15mm F2.8 Fisheye', #JD (writes 16mm to EXIF) 25791 => 'Minolta/Sony AF 20mm F2.8 or Tokina Lens', # Sony added (ref 11) # 25791 => 'Sony 20mm F2.8 (SAL20F28)', (ref JR) - 25791.1 => 'Tokina AT-X Pro DX 11-16mm F2.8', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3593.0.html + 25791.1 => 'Tokina AT-X Pro DX 11-16mm F2.8', #https://exiftool.org/forum/index.php/topic,3593.0.html 25811 => 'Minolta AF 100mm F2.8 Macro [New] or Sigma or Tamron Lens', # not Sony (ref 13/18) 25811.1 => 'Sigma AF 90mm F2.8 Macro', #JD 25811.2 => 'Sigma AF 105mm F2.8 EX [DG] Macro', #JD 25811.3 => 'Sigma 180mm F5.6 Macro', - 25811.4 => 'Sigma 180mm F3.5 EX DG Macro', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3789.msg17679.html#msg17679 + 25811.4 => 'Sigma 180mm F3.5 EX DG Macro', #https://exiftool.org/forum/index.php/topic,3789.msg17679.html#msg17679 25811.5 => 'Tamron 90mm F2.8 Macro', 25851 => 'Beroflex 35-135mm F3.5-4.5', #16 25858 => 'Minolta AF 35-105mm F3.5-4.5 New or Tamron Lens', @@ -499,7 +506,7 @@ $VERSION = '2.66'; 26241 => 'Minolta AF 35-80mm F4-5.6 Power Zoom', 26281 => 'Minolta AF 80-200mm F2.8 HS-APO G', #11 ("HS-APO" added, white, probably same as 1, non-HS is 25891 - ref JR) 26291 => 'Minolta AF 85mm F1.4 New', - 26311 => 'Minolta/Sony AF 100-300mm F4.5-5.6 APO', #11 + 26311 => 'Minolta AF 100-300mm F4.5-5.6 APO', #11 (does not exist? https://www.dyxum.com/dforum/lens-data-requested_topic23435_page2.html) 26321 => 'Minolta AF 24-50mm F4 New', 26381 => 'Minolta AF 50mm F2.8 Macro New', 26391 => 'Minolta AF 100mm F2.8 Macro', @@ -514,6 +521,7 @@ $VERSION = '2.66'; # - this is the base to which the Canon LensType is added 30464 => 'Metabones Canon EF Speed Booster', #Metabones (to this, add Canon LensType) 45671 => 'Tokina 70-210mm F4-5.6', #22 + 45681 => 'Tokina AF 35-200mm F4-5.6 Zoom SD', #IB (model 352) 45701 => 'Tamron AF 35-135mm F3.5-4.5', #IB (model 40d) 45711 => 'Vivitar 70-210mm F4.5-5.6', #IB 45741 => '2x Teleconverter or Tamron or Tokina Lens', #18 @@ -538,108 +546,13 @@ $VERSION = '2.66'; 65280 => 'Sigma 16mm F2.8 Filtermatic Fisheye', #IB # all M42-type lenses give a value of 65535 (and FocalLength=0, FNumber=1) 65535 => 'E-Mount, T-Mount, Other Lens or no lens', #JD/JR -# -# Sony E-type lenses (NOTE: these should be kept in sync with %sonyLensTypes2 of Sony.pm) -# - 65535.1 => 'Sony E 16mm F2.8', #PH (32784 - SEL16F28) - 65535.2 => 'Sony E 18-55mm F3.5-5.6 OSS', #PH (32785 - SEL1855) - 65535.3 => 'Sony E 55-210mm F4.5-6.3 OSS', #PH (32786 - SEL55210) - 65535.4 => 'Sony E 18-200mm F3.5-6.3 OSS', #PH (32787 - SEL18200) - 65535.5 => 'Sony E 30mm F3.5 Macro', #JR (32788 - SEL30M35) - 65535.6 => 'Sony E 24mm F1.8 ZA', #PH (32789 - SEL24F18Z) - 65535.7 => 'Sony E 50mm F1.8 OSS', #PH (32790 - SEL50F18) - 65535.8 => 'Sony E 16-70mm F4 ZA OSS', #JR (32791 - SEL1670Z) - 65535.9 => 'Sony E 10-18mm F4 OSS', #PH (32792 - SEL1018) - '65535.10' => 'Sony E PZ 16-50mm F3.5-5.6 OSS', #PH (32793 - SELP1650) - '65535.11' => 'Sony FE 35mm F2.8 ZA', #JR (32794 - SEL35F28Z) - '65535.12' => 'Sony FE 24-70mm F4 ZA OSS', #JR (32795 - SEL2470Z) - '65535.13' => 'Sony FE 85mm F1.8', #JR (32796 - SEL85F18) - '65535.14' => 'Sony E 18-200mm F3.5-6.3 OSS LE', #JR (32797 or 0 - SEL18200LE) - '65535.15' => 'Sony E 20mm F2.8', #PH (32798 - SEL20F28) - '65535.16' => 'Sony E 35mm F1.8 OSS', #JR (32799 - SEL35F18) - '65535.17' => 'Sony E PZ 18-105mm F4 G OSS', #JR (32800 - SELP18105G) - '65535.18' => 'Sony FE 12-24mm F4 G', #JR (32801 - SEL1224G) - '65535.19' => 'Sony FE 90mm F2.8 Macro G OSS', #JR (32802 - SEL90M28G) - '65535.20' => 'Sony E 18-50mm F4-5.6', #JR (32803 - SEL1850) - '65535.21' => 'Sony FE 24mm F1.4 GM', #IB (32804 - SEL24F14GM) - '65535.22' => 'Sony FE 24-105mm F4 G OSS', #IB (32805 - SEL24105G) - '65535.23' => 'Sony E PZ 18-200mm F3.5-6.3 OSS', #JR (32807 - SELP18200) - '65535.24' => 'Sony FE 55mm F1.8 ZA', #JR (32808 - SEL55F18Z) - '65535.25' => 'Sony FE 70-200mm F4 G OSS', #JR (32810 - SEL70200G) - '65535.26' => 'Sony FE 16-35mm F4 ZA OSS', #JR (32811 - SEL1635Z) - '65535.27' => 'Sony FE 50mm F2.8 Macro', #JR (32812 - SEL50M28) - '65535.28' => 'Sony FE 28-70mm F3.5-5.6 OSS', #JR (32813 - SEL2870) - '65535.29' => 'Sony FE 35mm F1.4 ZA', #JR (32814 - SEL35F14Z) - '65535.30' => 'Sony FE 24-240mm F3.5-6.3 OSS', #JR (32815 - SEL24240) - '65535.31' => 'Sony FE 28mm F2', #JR (32816 - SEL28F20) - '65535.32' => 'Sony FE PZ 28-135mm F4 G OSS', #JR (32817 - SELP28135G) - '65535.33' => 'Sony FE 100mm F2.8 STF GM OSS', #JR (32819 - SEL100F28GM, uses 33076 when set to 0.57m - 1.0m range) - '65535.34' => 'Sony E PZ 18-110mm F4 G OSS', #JR (32820 - SELP18110G) - '65535.35' => 'Sony FE 24-70mm F2.8 GM', #JR (32821 - SEL2470GM) - '65535.36' => 'Sony FE 50mm F1.4 ZA', #JR (32822 - SEL50F14Z) - '65535.37' => 'Sony FE 85mm F1.4 GM', #JR (32823 - SEL85F14GM) - '65535.38' => 'Sony FE 50mm F1.8', #JR (32824 - SEL50F18F with trailing "F" as compared to 32790) - '65535.39' => 'Sony FE 21mm F2.8 (SEL28F20 + SEL075UWC)', #JR (32826 - SEL28F20 + SEL075UWC Ultra-wide converter) - '65535.40' => 'Sony FE 16mm F3.5 Fisheye (SEL28F20 + SEL057FEC)', #JR (32827 - SEL28F20 + SEL057FEC Fisheye converter) - '65535.41' => 'Sony FE 70-300mm F4.5-5.6 G OSS', #JR (32828 - SEL70300G) - '65535.42' => 'Sony FE 100-400mm F4.5-5.6 GM OSS', #JR (32829 - SEL100400GM) - '65535.43' => 'Sony FE 70-200mm F2.8 GM OSS', #JR (32830 - SEL70200GM) - '65535.44' => 'Sony FE 16-35mm F2.8 GM', #JR (32831 - SEL1635GM) - '65535.45' => 'Sony FE 400mm F2.8 GM OSS', #IB (32848 - SEL400F28GM) - '65535.46' => 'Sony E 18-135mm F3.5-5.6 OSS', #JR (32849 - SEL18135) - '65535.47' => 'Sony FE 70-200mm F2.8 GM OSS + 1.4X Teleconverter', #JR (33072 - SEL70200GM + SEL14TC) - '65535.48' => 'Sony FE 70-200mm F2.8 GM OSS + 2X Teleconverter', #JR (33073 - SEL70200GM + SEL20TC) - '65535.49' => 'Sony FE 100-400mm F4.5-5.6 GM OSS + 1.4X Teleconverter', #JR (33077 - SEL100400GM + SEL14TC) - '65535.50' => 'Sony FE 100-400mm F4.5-5.6 GM OSS + 2X Teleconverter', #JR (33078 - SEL100400GM + SEL20TC) - '65535.51' => 'Sony FE 400mm F2.8 GM OSS + 1.4X Teleconverter', #IB (33079 - SEL400F28GM + SEL14TC) - '65535.52' => 'Sony FE 400mm F2.8 GM OSS + 2X Teleconverter', #JR (33080 - SEL400F28GM + SEL20TC) -# -# 3rd party E lenses -# - '65535.53' => 'Samyang AF 50mm F1.4 FE', #JR (32789) - '65535.54' => 'Samyang AF 14mm F2.8 FE', #JR (32790 and 51505) - '65535.55' => 'Samyang AF 24mm F2.8', #JR (32794) - '65535.56' => 'Samyang AF 35mm F2.8 FE', #PH (51505) - '65535.57' => 'Samyang AF 35mm F1.4', #IB (51507) - '65535.58' => 'Sigma 19mm F2.8 [EX] DN', #JR (0) - '65535.59' => 'Sigma 30mm F2.8 [EX] DN', #JR (0) - '65535.60' => 'Sigma 60mm F2.8 DN', #JR (0) - '65535.61' => 'Sigma 30mm F1.4 DC DN | C', #IB (50480) (016) - '65535.62' => 'Sigma 85mm F1.4 DG HSM | A', #JR (50499) (018) - '65535.63' => 'Sigma 16mm F1.4 DC DN | C', #JR (50503) (017) - '65535.64' => 'Sigma 70mm F2.8 DG MACRO | A', #JR (50513) (018) - '65535.65' => 'Tamron 18-200mm F3.5-6.3 Di III VC', #JR (0 - Model B011) - '65535.66' => 'Tamron 28-75mm F2.8 Di III RXD', #JR (49457 - Model A036) - '65535.67' => 'Tokina Firin 20mm F2 FE MF', #JR (0) - '65535.68' => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR (50992) - '65535.69' => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB (50993) - '65535.70' => 'Voigtlander ULTRA WIDE-HELIAR 12mm F5.6 III', #IB (50994) - '65535.71' => 'Voigtlander MACRO APO-LANTHAR 65mm F2 Aspherical', #JR (50995) - '65535.72' => 'Voigtlander NOKTON 40mm F1.2 Aspherical', #JR (50996) - '65535.73' => 'Voigtlander NOKTON classic 35mm F1.4', #JR (50997) - '65535.74' => 'Zeiss Touit 12mm F2.8', #JR (49201 or 0) - '65535.75' => 'Zeiss Touit 32mm F1.8', #JR (49202 or 0) - '65535.76' => 'Zeiss Touit 50mm F2.8 Macro', #JR (49203 or 0) - '65535.77' => 'Zeiss Batis 25mm F2', #JR (49216) - '65535.78' => 'Zeiss Batis 85mm F1.8', #JR (49217) - '65535.79' => 'Zeiss Batis 18mm F2.8', #IB (49218) - '65535.80' => 'Zeiss Batis 135mm F2.8', #IB (49219) - '65535.81' => 'Zeiss Batis 40mm F2 CF', #JR (49220) - '65535.82' => 'Zeiss Loxia 50mm F2', #JR (49232 or 0) - '65535.83' => 'Zeiss Loxia 35mm F2', #JR (49233 or 0) - '65535.84' => 'Zeiss Loxia 21mm F2.8', #JR (49234) - '65535.85' => 'Zeiss Loxia 85mm F2.4', #JR (49235) - '65535.86' => 'Zeiss Loxia 25mm F2.4', #JR (49236) -# -# other lenses -# - '65535.87' => 'Arax MC 35mm F2.8 Tilt+Shift', #JD - '65535.88' => 'Arax MC 80mm F2.8 Tilt+Shift', #JD - '65535.89' => 'Zenitar MF 16mm F2.8 Fisheye M42', #JD - '65535.90' => 'Samyang 500mm Mirror F8.0', #19 - '65535.91' => 'Pentacon Auto 135mm F2.8', #19 - '65535.92' => 'Pentacon Auto 29mm F2.8', #19 - '65535.93' => 'Helios 44-2 58mm F2.0', #19 + '65535.1' => 'Arax MC 35mm F2.8 Tilt+Shift', #JD + '65535.2' => 'Arax MC 80mm F2.8 Tilt+Shift', #JD + '65535.3' => 'Zenitar MF 16mm F2.8 Fisheye M42', #JD + '65535.4' => 'Samyang 500mm Mirror F8.0', #19 + '65535.5' => 'Pentacon Auto 135mm F2.8', #19 + '65535.6' => 'Pentacon Auto 29mm F2.8', #19 + '65535.7' => 'Helios 44-2 58mm F2.0', #19 ); %minoltaTeleconverters = ( @@ -1925,7 +1838,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); }, ); -# Image stabilization inforamtion used by the Sony DSLR-A100 (ref 20) +# Image stabilization information used by the Sony DSLR-A100 (ref 20) %Image::ExifTool::Minolta::ISInfoA100 = ( PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, WRITE_PROC => \&Image::ExifTool::WriteBinaryData, @@ -2774,7 +2687,7 @@ my %offOn = ( 0 => 'Off', 1 => 'On' ); PrintConv => 'int($val + 0.5)', PrintConvInv => '$val', }, - 0x49bb => { # (http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3688.0.html) + 0x49bb => { # (https://exiftool.org/forum/index.php/topic,3688.0.html) # if this value is the 35mm equivalent magnification, then the formula could # be (1.5 * 2**($val/16-5)+1) * FocalLength, but this tends to underestimate # distance by about 18% (ref 20) (255=inf) @@ -2974,7 +2887,7 @@ sub ConvertWhiteBalance($) my $printConv = $minoltaWhiteBalance{$val}; unless (defined $printConv) { if ($val & 0xffff0000) { - # the A2 values can be shifted by += 3 settings, where + # the A2 values can be shifted by +- 3 settings, where # each setting adds or subtracts 0x0010000 (ref 2) my $type = ($val & 0xff000000) + 0x800000; if ($minoltaWhiteBalance{$type}) { @@ -3010,7 +2923,7 @@ and write Minolta RAW (MRW) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/MinoltaRaw.pm b/src/Image-ExifTool/lib/Image/ExifTool/MinoltaRaw.pm index 32d4b0c8..206d4c12 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/MinoltaRaw.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/MinoltaRaw.pm @@ -511,7 +511,7 @@ write Konica-Minolta RAW (MRW) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Motorola.pm b/src/Image-ExifTool/lib/Image/ExifTool/Motorola.pm new file mode 100644 index 00000000..04bd371a --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Motorola.pm @@ -0,0 +1,172 @@ +#------------------------------------------------------------------------------ +# File: Motorola.pm +# +# Description: Read Motorola meta information +# +# Revisions: 2015/10/29 - P. Harvey Created +# +# References: 1) Neal Krawetz private communication +#------------------------------------------------------------------------------ + +package Image::ExifTool::Motorola; + +use strict; +use vars qw($VERSION); +use Image::ExifTool::Exif; + +$VERSION = '1.01'; + +# Motorola makernotes tags (ref PH) +%Image::ExifTool::Motorola::Main = ( + WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, + CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + WRITABLE => 1, + # 0x54e0 - int8u: 1 + # 0x54f0 - float + 0x5500 => { Name => 'BuildNumber', Writable => 'string' }, #1 (eg. 'MPJ24.139-23.4') + 0x5501 => { Name => 'SerialNumber', Writable => 'string' }, #1 (eg. 'ZY2238TJ4V') + # 0x5502 - int8u + # 0x5503 - int8u + # 0x5510 - int8u: 0,1 + # 0x5511 - int32u (3 of these tags for some cameras) + # 0x5512 - int32u + # 0x5520 - int16s + # 0x5530 - string: 'continuous-picture','auto','continuous-video' + # 0x5540 - int8u: 95 + # 0x5550 - int8u: 85,90 + # 0x5560 - string: 'auto' + # 0x5570 - string: 'auto','auto-hdr' + # 0x5580 - int32s: 9000,14949,15000,24000 + # 0x5590 - int32s: 30000 + # 0x55a0 - int32s: 960,1280,1440 + # 0x55b0 - int32s: 720,960,1080 + # 0x55c0 - int32s: 30 + # 0x55d0 - string: 'yuv420sp' + # 0x55e0-0x55e9 - int16u + # 0x55f0 - int8u: 10 + # 0x55f1 - int8u: 13 + # 0x55f2-0x55f5 - int16u[130] + # 0x5600 - int8u: 0,16 + # 0x5601 - int16u[16] + # 0x5602 - int32u[3,50] + # 0x5603 - int32u: 0 + # 0x6400 - string: 'AUTO','ON','OFF' + # 0x6401 - string: 'HDR' + # 0x6410 - string: 'NO','YES' + # 0x6420 - int32s: 0 (only exists in HDR images?) + # 0x6430 - float + # 0x6431 - int8u: 0,1 + # 0x6432 - int8u: 0,79,100 + # 0x6433 - int8u: 0,1 + # 0x6434 - int8u: 0,65,100 + # 0x6435 - int8u: 1,6,24 + # 0x6436 - int8u: 55,60 + # 0x6437 - int8u: 30,35,40 + # 0x6438 - int8u: 24,40 + # 0x6439 - int8u: 15,50 + # 0x643a - int8u: 0,20 + # 0x643b - string: '2,8,-4','2,10,-4','' + # 0x643c - int32s + # 0x643d - float + # 0x6440 - int8u[N]: 0's and 1's + # 0x6441 - int8u[N] + # 0x6442,0x6443 - int8u[N]: 0's and 1's + # 0x644d - string: 'YES' + # 0x644f - float + # 0x6450 - float + # 0x6451 - float: 0.699999988079071 + # 0x6452 - int8u: 1 + # 0x6470 - string: 'AUTO' + # 0x6471 - int8u: 1 + # 0x6473 - int8u: 24 + # 0x6474 - int8u: 10 + # 0x6475 - int32u[24] + # 0x6476 - int32u: 2 + # 0x6490 - int8u: 0 + # 0x64c0 - int32s: 0,2 + # 0x64c1 - int32u: 1,4,64 + # 0x64c2,0x64c3 - int32s + # 0x64c4 - int32s + # 0x64c5 - int32u + # 0x6500 - int8u: 1 + # 0x6501 - string: 'Luma-Chroma Plane','Chroma only' or int8u: 0 + # 0x6502 - string: 'Luma-Chroma Plane','Chroma only','' or int8u: 1,255 + # 0x6504 - int32s + # 0x6530-0x6535 - int32s + # 0x6600-0x6605 - int8u + # 0x6606 - string: 'D50','TL84','5000' - illuminant? color temperature? + # 0x6607 - string: 'D50g','D65','3000' - illuminant? color temperature? + # 0x6608 - string: 'A' + # 0x6609-0x660e - float + # 0x660f - int12u + # 0x6612-0x661b - int16u + # 0x661d - int16u + # 0x661e-0x6635 - float + # 0x6637 - int8u[212] + # 0x6640,0x6641 - int8u + # 0x6642-0x6649 - int16u + # 0x664e - in8u + # 0x664f-0x6652 - int16u + # 0x6653 - string: 'QC','AL' + # 0x6654-0x6656 - int16u + # 0x665d - int8u: 0 + 0x665e => { Name => 'Sensor', Writable => 'string' }, # (eg. 'BACK,IMX230') + # 0x6700 - string: eg. 'eac040d0','333e1721','001b7b3a','000000000005040f' + # 0x6701 - string: eg. '14048001',940140230','940140190' + # 0x6702 - string: '0L','1L','0S','3S','32','33,'42' + # 0x6703 - string: 'PR','SEG','LIG','LI','SHV','SH','SO' + # 0x6704 - string: 'DO','GX1','GZ0','GZ1','GX2','VI','VI1','VI2','GU','' + 0x6705 => { Name => 'ManufactureDate', Writable => 'string' }, # (NC, eg. '03Jun2015') + # 0x6706 - string: eg. '30454e4e','42%','01%','01','1','904c2ca2' + # 0x6707 - string: eg. '1','25a2ca16','002371e1','69' + # 0x6708-0x670c - string or int16u (string may be firmware revision) + # 0x6800 - int32u: 1,2 + # 0x6801,0x6802 - float + # 0x6803 - int16u + # 0x6804,0x6805 - float + # 0x6806 - int16u,int32s + # 0x6807 - int32s,int32u[3] + # 0x6808 - int32u,int32u[3] + # 0x6809,0x680a - float[3] + # 0x680d - int8u: 0 + # 0x680e - float: 0 + # 0x7000 - int8u: 0,2 + # 0x7001,0x7002 - int16s + # 0x7003-0x7005 - int16u + # 0x7100 - string: '0-7' + # 0x7101 - string: '4-7','0-7' + # 0x7102 - string: '0-3','' + # 0x7103,0x7104 - string: comma-separated lists of numbers +); + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Motorola - Read Motorola meta information + +=head1 SYNOPSIS + +This module is loaded automatically by Image::ExifTool when required. + +=head1 DESCRIPTION + +This module contains the definitions to read meta information from Motorola +cell phone images. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/Motorola Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Nikon.pm b/src/Image-ExifTool/lib/Image/ExifTool/Nikon.pm index 2dc334e0..c61859db 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Nikon.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Nikon.pm @@ -41,11 +41,14 @@ # 27) Jens Kriese private communication # 28) Warren Hatch private communication (D3v2.00 with SB-800 and SB-900) # 29) Anonymous contribution 2011/05/25 (D700, D7000) -# 30) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3833.30.html +# 30) https://exiftool.org/forum/index.php/topic,3833.30.html # 31) Michael Relt private communication -# 32) Stefan http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4494.0.html +# 32) Stefan https://exiftool.org/forum/index.php/topic,4494.0.html # 34) Stewart Bennett private communication (D4S, D810) # 35) David Puschel private communication +# 36) Hayo Baann (forum10207) +# 37) Tom Lachecki, private communication +# 38) https://github.com/exiftool/exiftool/pull/40 (and forum10893) # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication # NJ) Niels Kristian Bech Jensen private communication @@ -59,7 +62,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::GPS; -$VERSION = '3.54'; +$VERSION = '3.80'; sub LensIDConv($$$); sub ProcessNikonAVI($$$); @@ -78,11 +81,9 @@ sub GetAFPointGrid($$;$); The Nikon LensID is constructed as a Composite tag from the raw hex values of 8 other tags: LensIDNumber, LensFStops, MinFocalLength, MaxFocalLength, MaxApertureAtMinFocal, MaxApertureAtMaxFocal, MCUVersion and LensType, in - that order. (source: - L<http://www.rottmerhusen.com/objektives/lensid/thirdparty.html>.) Multiple - lenses with the same LensID are differentiated by decimal values in the list - below. The user-defined "Lenses" list may be used to specify the lens for - ExifTool to choose in these cases (see the + that order. Multiple lenses with the same LensID are differentiated by + decimal values in the list below. The user-defined "Lenses" list may be + used to specify the lens for ExifTool to choose in these cases (see the L<sample config file|../config.html> for details). }, OTHER => \&LensIDConv, @@ -277,7 +278,7 @@ sub GetAFPointGrid($$;$); 'A5 40 3C 8E 2C 3C A7 0E' => 'AF-S Nikkor 28-300mm f/3.5-5.6G ED VR', 'A6 48 8E 8E 24 24 A8 0E' => 'AF-S Nikkor 300mm f/2.8G IF-ED VR II', 'A7 4B 62 62 2C 2C A9 0E' => 'AF-S DX Micro Nikkor 85mm f/3.5G ED VR', - 'A8 48 80 98 30 30 AA 0E' => 'AF-S Zoom-Nikkor 200-400mm f/4G IF-ED VR II', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3218.msg15495.html#msg15495 + 'A8 48 80 98 30 30 AA 0E' => 'AF-S Zoom-Nikkor 200-400mm f/4G IF-ED VR II', #https://exiftool.org/forum/index.php/topic,3218.msg15495.html#msg15495 'A9 54 80 80 18 18 AB 0E' => 'AF-S Nikkor 200mm f/2G ED VR II', 'AA 3C 37 6E 30 30 AC 0E' => 'AF-S Nikkor 24-120mm f/4G ED VR', 'AC 38 53 8E 34 3C AE 0E' => 'AF-S DX Nikkor 55-300mm f/4.5-5.6G ED VR', @@ -315,6 +316,7 @@ sub GetAFPointGrid($$;$); 'A0 40 2D 53 2C 3C CA 8E' => 'AF-P DX Nikkor 18-55mm f/3.5-5.6G', #Yang You pvt communication 'A0 40 2D 53 2C 3C CA 0E' => 'AF-P DX Nikkor 18-55mm f/3.5-5.6G VR', #PH 'AF 4C 37 37 14 14 CC 06' => 'AF-S Nikkor 24mm f/1.8G ED', #IB + 'A2 38 5C 8E 34 40 CD 86' => 'AF-P DX Nikkor 70-300mm f/4.5-6.3G VR', #PH 'A3 38 5C 8E 34 40 CE 8E' => 'AF-P DX Nikkor 70-300mm f/4.5-6.3G ED VR', 'A3 38 5C 8E 34 40 CE 0E' => 'AF-P DX Nikkor 70-300mm f/4.5-6.3G ED', 'A4 48 5C 80 24 24 CF 4E' => 'AF-S Nikkor 70-200mm f/2.8E FL ED VR', @@ -333,6 +335,7 @@ sub GetAFPointGrid($$;$); 'AA 48 88 A4 3C 3C D5 0E' => 'AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR + 1.4x TC', 'AB 44 5C 8E 34 3C D6 CE' => 'AF-P Nikkor 70-300mm f/4.5-5.6E ED VR', 'AB 44 5C 8E 34 3C D6 0E' => 'AF-P Nikkor 70-300mm f/4.5-5.6E ED VR', + 'AB 44 5C 8E 34 3C D6 4E' => 'AF-P Nikkor 70-300mm f/4.5-5.6E ED VR', #IB 'AC 54 3C 3C 0C 0C D7 46' => 'AF-S Nikkor 28mm f/1.4E ED', 'AC 54 3C 3C 0C 0C D7 06' => 'AF-S Nikkor 28mm f/1.4E ED', 'AD 3C A0 A0 3C 3C D8 0E' => 'AF-S Nikkor 500mm f/5.6E PF ED VR', @@ -362,12 +365,13 @@ sub GetAFPointGrid($$;$); '91 54 44 44 0C 0C 4B 06' => 'Sigma 35mm F1.4 DG HSM', #30 'DE 54 50 50 0C 0C 4B 06' => 'Sigma 50mm F1.4 EX DG HSM', '88 54 50 50 0C 0C 4B 06' => 'Sigma 50mm F1.4 DG HSM | A', - '02 48 50 50 24 24 02 00' => 'Sigma Macro 50mm F2.8', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4027.0.html + '02 48 50 50 24 24 02 00' => 'Sigma Macro 50mm F2.8', #https://exiftool.org/forum/index.php/topic,4027.0.html '32 54 50 50 24 24 35 02' => 'Sigma Macro 50mm F2.8 EX DG', - 'E3 54 50 50 24 24 35 02' => 'Sigma Macro 50mm F2.8 EX DG', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3215.0.html + 'E3 54 50 50 24 24 35 02' => 'Sigma Macro 50mm F2.8 EX DG', #https://exiftool.org/forum/index.php/topic,3215.0.html '79 48 5C 5C 24 24 1C 06' => 'Sigma Macro 70mm F2.8 EX DG', #JD '9B 54 62 62 0C 0C 4B 06' => 'Sigma 85mm F1.4 EX DG HSM', 'C8 54 62 62 0C 0C 4B 46' => 'Sigma 85mm F1.4 DG HSM | A', #JamiBradley + 'C8 54 62 62 0C 0C 4B 06' => 'Sigma 85mm F1.4 DG HSM | A', #KennethCochran '02 48 65 65 24 24 02 00' => 'Sigma Macro 90mm F2.8', '32 54 6A 6A 24 24 35 02.2' => 'Sigma Macro 105mm F2.8 EX DG', #JD 'E5 54 6A 6A 24 24 35 02' => 'Sigma Macro 105mm F2.8 EX DG', @@ -377,6 +381,7 @@ sub GetAFPointGrid($$;$); '99 48 76 76 24 24 4B 0E' => 'Sigma APO Macro 150mm F2.8 EX DG OS HSM', #(Christian Hesse) '48 4C 7C 7C 2C 2C 4B 02' => 'Sigma APO Macro 180mm F3.5 EX DG HSM', '48 4C 7D 7D 2C 2C 4B 02' => 'Sigma APO Macro 180mm F3.5 EX DG HSM', + 'F4 4C 7C 7C 2C 2C 4B 02' => 'Sigma APO Macro 180mm F3.5 EX DG HSM', #Bruno '94 48 7C 7C 24 24 4B 0E' => 'Sigma APO Macro 180mm F2.8 EX DG OS HSM', #MichaelTapes (HSM from ref 8) '48 54 8E 8E 24 24 4B 02' => 'Sigma APO 300mm F2.8 EX DG HSM', 'FB 54 8E 8E 24 24 4B 02' => 'Sigma APO 300mm F2.8 EX DG HSM', #26 @@ -406,7 +411,7 @@ sub GetAFPointGrid($$;$); '7A 48 2B 5C 24 34 4B 06' => 'Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF HSM', '7F 48 2B 5C 24 34 1C 06' => 'Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF', '8E 3C 2B 5C 24 30 4B 0E' => 'Sigma 17-70mm F2.8-4 DC Macro OS HSM | C', - 'A0 48 2A 5C 24 30 4B 0E' => 'Sigma 17-70mm F2.8-4 DC Macro OS HSM', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5170.0.html + 'A0 48 2A 5C 24 30 4B 0E' => 'Sigma 17-70mm F2.8-4 DC Macro OS HSM', #https://exiftool.org/forum/index.php/topic,5170.0.html '8B 4C 2D 44 14 14 4B 06' => 'Sigma 18-35mm F1.8 DC HSM', #30/NJ '26 40 2D 44 2B 34 1C 02' => 'Sigma 18-35mm F3.5-4.5 Aspherical', '26 48 2D 50 24 24 1C 06' => 'Sigma 18-50mm F2.8 EX DC', @@ -423,6 +428,7 @@ sub GetAFPointGrid($$;$); '7A 40 2D 80 2C 40 4B 0E' => 'Sigma 18-200mm F3.5-6.3 DC OS HSM', 'ED 40 2D 80 2C 40 4B 0E' => 'Sigma 18-200mm F3.5-6.3 DC OS HSM', #JD '90 40 2D 80 2C 40 4B 0E' => 'Sigma 18-200mm F3.5-6.3 II DC OS HSM', #JohnHelour + '89 30 2D 80 2C 40 4B 0E' => 'Sigma 18-200mm F3.5-6.3 DC Macro OS HS | C', #JoeSchonberg 'A5 40 2D 88 2C 40 4B 0E' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM', # LensFStops varies with FocalLength for this lens (ref 2): '92 2C 2D 88 2C 40 4B 0E' => 'Sigma 18-250mm F3.5-6.3 DC Macro OS HSM', #2 @@ -467,7 +473,7 @@ sub GetAFPointGrid($$;$); '26 40 3C 80 2B 3C 1C 02' => 'Sigma 28-200mm F3.5-5.6 Compact Aspherical Hyperzoom Macro', '26 3D 3C 80 2F 3D 1C 02' => 'Sigma 28-300mm F3.8-5.6 Aspherical', '26 41 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 DG Macro', - 'E6 41 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 DG Macro', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3301.0.html + 'E6 41 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 DG Macro', #https://exiftool.org/forum/index.php/topic,3301.0.html '26 40 3C 8E 2C 40 1C 02' => 'Sigma 28-300mm F3.5-6.3 Macro', '02 3B 44 61 30 3D 02 00' => 'Sigma 35-80mm F4-5.6', '02 40 44 73 2B 36 02 00' => 'Sigma 35-135mm F3.5-4.5 a', @@ -498,7 +504,7 @@ sub GetAFPointGrid($$;$); 'F3 48 68 8E 30 30 4B 02' => 'Sigma APO 100-300mm F4 EX IF HSM', '48 54 6F 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM', '7A 54 6E 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM', - 'FA 54 6E 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2787.0.html + 'FA 54 6E 8E 24 24 4B 02' => 'Sigma APO 120-300mm F2.8 EX DG HSM', #https://exiftool.org/forum/index.php/topic,2787.0.html 'CF 38 6E 98 34 3C 4B 0E' => 'Sigma APO 120-400mm F4.5-5.6 DG OS HSM', 'C3 34 68 98 38 40 4B 4E' => 'Sigma 100-400mm F5-6.3 DG OS HSM | C', #JR (017) '8D 48 6E 8E 24 24 4B 0E' => 'Sigma 120-300mm F2.8 DG OS HSM Sports', @@ -509,11 +515,14 @@ sub GetAFPointGrid($$;$); '26 40 7B A0 34 40 1C 02' => 'Sigma APO 170-500mm F5-6.3 Aspherical RF', 'A7 49 80 A0 24 24 4B 06' => 'Sigma APO 200-500mm F2.8 EX DG', '48 3C 8E B0 3C 3C 4B 02' => 'Sigma APO 300-800mm F5.6 EX DG HSM', + 'D2 3C 8E B0 3C 3C 4B 02' => 'Sigma APO 300-800mm F5.6 EX DG HSM', #forum10942 # '00 47 25 25 24 24 00 02' => 'Tamron SP AF 14mm f/2.8 Aspherical (IF) (69E)', + 'C8 54 44 44 0D 0D DF 46' => 'Tamron SP 35mm f/1.4 Di USD (F045)', #IB 'E8 4C 44 44 14 14 DF 0E' => 'Tamron SP 35mm f/1.8 Di VC USD (F012)', #35 'E7 4C 4C 4C 14 14 DF 0E' => 'Tamron SP 45mm f/1.8 Di VC USD (F013)', 'F4 54 56 56 18 18 84 06' => 'Tamron SP AF 60mm f/2.0 Di II Macro 1:1 (G005)', #24 + 'E5 4C 62 62 14 14 C9 4E' => 'Tamron SP 85mm f/1.8 Di VC USD (F016)', #30 '1E 5D 64 64 20 20 13 00' => 'Tamron SP AF 90mm f/2.5 (52E)', '20 5A 64 64 20 20 14 00' => 'Tamron SP AF 90mm f/2.5 Macro (152E)', '22 53 64 64 24 24 E0 02' => 'Tamron SP AF 90mm f/2.8 Macro 1:1 (72E)', @@ -525,27 +534,29 @@ sub GetAFPointGrid($$;$); '00 4C 7C 7C 2C 2C 00 02' => 'Tamron SP AF 180mm f/3.5 Di Model (B01)', '21 56 8E 8E 24 24 14 00' => 'Tamron SP AF 300mm f/2.8 LD-IF (60E)', '27 54 8E 8E 24 24 1D 02' => 'Tamron SP AF 300mm f/2.8 LD-IF (360E)', - 'E1 40 19 36 2C 35 DF 4E' => 'Tamron 10-24mm F/3.5-4.5 Di II VC HLD (B023)', + 'E1 40 19 36 2C 35 DF 4E' => 'Tamron 10-24mm f/3.5-4.5 Di II VC HLD (B023)', 'F6 3F 18 37 2C 34 84 06' => 'Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)', 'F6 3F 18 37 2C 34 DF 06' => 'Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)', #30 '00 36 1C 2D 34 3C 00 06' => 'Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical (IF) (A13)', 'E9 48 27 3E 24 24 DF 0E' => 'Tamron SP 15-30mm f/2.8 Di VC USD (A012)', #IB - 'EA 40 29 8E 2C 40 DF 0E' => 'Tamron AF 16-300mm f/3.5-6.3 Di II VC PZD (B016)', + 'CA 48 27 3E 24 24 DF 4E' => 'Tamron SP 15-30mm f/2.8 Di VC USD G2 (A041)', #IB + 'EA 40 29 8E 2C 40 DF 0E' => 'Tamron 16-300mm f/3.5-6.3 Di II VC PZD (B016)', # (removed AF designation, ref 37) '07 46 2B 44 24 30 03 02' => 'Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical (IF) (A05)', + 'CB 3C 2B 44 24 31 DF 46' => 'Tamron 17-35mm f/2.8-4 Di OSD (A037)', #IB '00 53 2B 50 24 24 00 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16)', #PH '00 54 2B 50 24 24 00 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)', - 'FB 54 2B 50 24 24 84 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3787.0.html + 'FB 54 2B 50 24 24 84 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)', #https://exiftool.org/forum/index.php/topic,3787.0.html 'F3 54 2B 50 24 24 84 0E' => 'Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical (IF) (B005)', '00 3F 2D 80 2B 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) (A14)', '00 3F 2D 80 2C 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14)', '00 40 2D 80 2C 40 00 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)', #NJ 'FC 40 2D 80 2C 40 DF 06' => 'Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)', #PH (NC) - 'E6 40 2D 80 2C 40 DF 0E' => 'Tamron AF 18-200mm f/3.5-6.3 Di II VC (B018)', #Tanel + 'E6 40 2D 80 2C 40 DF 0E' => 'Tamron 18-200mm f/3.5-6.3 Di II VC (B018)', #Tanel (removed AF designation, ref 37) '00 40 2D 88 2C 40 62 06' => 'Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18)', '00 40 2D 88 2C 40 00 06' => 'Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18NII)', #JD 'F5 40 2C 8A 2C 40 40 0E' => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical (IF) Macro (B003)', 'F0 3F 2D 8A 2C 40 DF 0E' => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)', - 'E0 40 2D 98 2C 41 DF 4E' => 'Tamron AF 18-400mm f/3.5-6.3 Di II VC HLD (B028)', + 'E0 40 2D 98 2C 41 DF 4E' => 'Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)', # (removed AF designation, ref 37) '07 40 2F 44 2C 34 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)', '07 40 30 45 2D 35 03 02' => 'Tamron AF 19-35mm f/3.5-4.5 (A10)', '00 49 30 48 22 2B 00 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)', @@ -577,6 +588,7 @@ sub GetAFPointGrid($$;$); '69 47 5C 8E 30 3C 00 02' => 'Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17N)', '00 48 5C 8E 30 3C 00 06' => 'Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17NII)', #JD 'F1 47 5C 8E 30 3C DF 0E' => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)', + 'CF 47 5C 8E 31 3D DF 0E' => 'Tamron SP 70-300mm f/4-5.6 Di VC USD (A030)', #forum9773 'EB 40 76 A6 38 40 DF 0E' => 'Tamron SP AF 150-600mm f/5-6.3 VC USD (A011)', 'E3 40 76 A6 38 40 DF 4E' => 'Tamron SP 150-600mm f/5-6.3 Di VC USD G2', #30 '20 3C 80 98 3D 3D 1E 02' => 'Tamron AF 200-400mm f/5.6 LD IF (75D)', @@ -592,6 +604,7 @@ sub GetAFPointGrid($$;$); '00 40 18 2B 2C 34 00 06' => 'Tokina AT-X 107 AF DX Fisheye (AF 10-17mm f/3.5-4.5)', '00 48 1C 29 24 24 00 06' => 'Tokina AT-X 116 PRO DX (AF 11-16mm f/2.8)', '7A 48 1C 29 24 24 7E 06' => 'Tokina AT-X 116 PRO DX II (AF 11-16mm f/2.8)', + '80 48 1C 29 24 24 7A 06' => 'Tokina atx-i 11-16mm F2.8 CF', #exiv2 issue 1078 '7A 48 1C 30 24 24 7E 06' => 'Tokina AT-X 11-20 F2.8 PRO DX (AF 11-20mm f/2.8)', '00 3C 1F 37 30 30 00 06' => 'Tokina AT-X 124 AF PRO DX (AF 12-24mm f/4)', '7A 3C 1F 37 30 30 7E 06.2' => 'Tokina AT-X 124 AF PRO DX II (AF 12-24mm f/4)', @@ -650,6 +663,7 @@ sub GetAFPointGrid($$;$); '00 54 72 72 18 18 00 00' => 'Carl Zeiss Apo Sonnar T* 2/135 ZF.2', '00 54 53 53 0C 0C 00 00' => 'Zeiss Otus 1.4/55', #IB '01 54 62 62 0C 0C 00 00' => 'Zeiss Otus 1.4/85', + '03 54 68 68 0C 0C 00 00' => 'Zeiss Otus 1.4/100', #IB '52 54 44 44 18 18 00 00' => 'Zeiss Milvus 35mm f/2', '53 54 50 50 0C 0C 00 00' => 'Zeiss Milvus 50mm f/1.4', #IB '54 54 50 50 18 18 00 00' => 'Zeiss Milvus 50mm f/2 Macro', @@ -664,14 +678,15 @@ sub GetAFPointGrid($$;$); '4A 40 11 11 2C 0C 4D 02' => 'Samyang 8mm f/3.5 Fish-Eye CS', '4A 48 24 24 24 0C 4D 02.1' => 'Samyang 10mm f/2.8 ED AS NCS CS', '4A 48 1E 1E 24 0C 4D 02' => 'Samyang 12mm f/2.8 ED AS NCS Fish-Eye', #Jurgen Sahlberg - '4A 48 24 24 24 0C 4D 02.2' => 'Samyang AE 14mm f/2.8 ED AS IF UMC', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3150.0.html + '4A 48 24 24 24 0C 4D 02.2' => 'Samyang AE 14mm f/2.8 ED AS IF UMC', #https://exiftool.org/forum/index.php/topic,3150.0.html '4A 4C 24 24 1E 6C 4D 06' => 'Samyang 14mm f/2.4 Premium', '4A 54 29 29 18 0C 4D 02' => 'Samyang 16mm f/2.0 ED AS UMC CS', #Jon Bloom (by email) '4A 60 36 36 0C 0C 4D 02' => 'Samyang 24mm f/1.4 ED AS UMC', '4A 60 44 44 0C 0C 4D 02' => 'Samyang 35mm f/1.4 AS UMC', - '4A 60 62 62 0C 0C 4D 02' => 'Samyang AE 85mm f/1.4 AS IF UMC', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2888.0.html + '4A 60 62 62 0C 0C 4D 02' => 'Samyang AE 85mm f/1.4 AS IF UMC', #https://exiftool.org/forum/index.php/topic,2888.0.html # '9A 4C 50 50 14 14 9C 06' => 'Yongnuo YN50mm F1.8N', + '9F 48 48 48 24 24 A1 06' => 'Yongnuo YN40mm F2.8N', #30 # '02 40 44 5C 2C 34 02 00' => 'Exakta AF 35-70mm 1:3.5-4.5 MC', # @@ -718,7 +733,7 @@ my %flashFirmware = ( '4 4' => '4.04 (SB-400)', '5 1' => '5.01 (SB-900)', '5 2' => '5.02 (SB-900)', - '6 1' => '6.01 (SB-700)', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5034.0.html + '6 1' => '6.01 (SB-700)', #https://exiftool.org/forum/index.php/topic,5034.0.html '7 1' => '7.01 (SB-910)', #PH OTHER => sub { my ($val, $inv) = @_; @@ -931,16 +946,56 @@ my %afPoints153 = ( 31 => 'B8', 62 => 'H13', 93 => 'C17', 124 => 'G4', ); +# AF point indices for models with 81 focus points, eg. Z6/Z7/Z50 (ref 38) +# - 9 rows (A-I) with 9 columns (1-9), center is E5 +# NOTE: the AF points start 2 bytes into the data, so the map starts +# at 17 instead of 1 +# +# 7 6 5 4 3 2 1 0 +# 00 : [H5][G5][F5][A5][B5][C5][D5][E5] +# 01 : [G6][F6][A6][B6][C6][D6][E6][I5] +# 02 : [F4][A4][B4][C4][D4][E4][I6][H6] +# 03 : [A7][B7][C7][D7][E7][I4][H4][G4] +# 04 : [B3][C3][D3][E3][I7][H7][G7][F7] +# 05 : [C8][D8][E8][I3][H3][G3][F3][A3] +# 06 : [D2][E2][I8][H8][G8][F8][A8][B8] +# 07 : [E9][I2][H2][G2][F2][A2][B2][C2] +# 08 : [I9][H9][G9][F9][A9][B9][C9][D9] +# 09 : [H1][G1][F1][A1][B1][C1][D1][E1] +# 0a : [ ][ ][ ][ ][ ][ ][ ][I1] +my %afPoints81 = ( + 17 => 'E5', 34 => 'I6', 51 => 'H7', 68 => 'G8', 85 => 'F9', + 18 => 'D5', 35 => 'E4', 52 => 'I7', 69 => 'H8', 86 => 'G9', + 19 => 'C5', 36 => 'D4', 53 => 'E3', 70 => 'I8', 87 => 'H9', + 20 => 'B5', 37 => 'C4', 54 => 'D3', 71 => 'E2', 88 => 'I9', + 21 => 'A5', 38 => 'B4', 55 => 'C3', 72 => 'D2', 89 => 'E1', + 22 => 'F5', 39 => 'A4', 56 => 'B3', 73 => 'C2', 90 => 'D1', + 23 => 'G5', 40 => 'F4', 57 => 'A3', 74 => 'B2', 91 => 'C1', + 24 => 'H5', 41 => 'G4', 58 => 'F3', 75 => 'A2', 92 => 'B1', + 25 => 'I5', 42 => 'H4', 59 => 'G3', 76 => 'F2', 93 => 'A1', + 26 => 'E6', 43 => 'I4', 60 => 'H3', 77 => 'G2', 94 => 'F1', + 27 => 'D6', 44 => 'E7', 61 => 'I3', 78 => 'H2', 95 => 'G1', + 28 => 'C6', 45 => 'D7', 62 => 'E8', 79 => 'I2', 96 => 'H1', + 29 => 'B6', 46 => 'C7', 63 => 'D8', 80 => 'E9', 97 => 'I1', + 30 => 'A6', 47 => 'B7', 64 => 'C8', 81 => 'D9', + 31 => 'F6', 48 => 'A7', 65 => 'B8', 82 => 'C9', + 32 => 'G6', 49 => 'F7', 66 => 'A8', 83 => 'B9', + 33 => 'H6', 50 => 'G7', 67 => 'F8', 84 => 'A9', +); + my %cropHiSpeed = ( #IB 0 => 'Off', 1 => '1.3x Crop', # (1.3x Crop, Large) - 2 => 'DX Crop', + 2 => 'DX Crop', # (1.5x) 3 => '5:4 Crop', - 4 => '3:2 Crop', + 4 => '3:2 Crop', # (1.2x, ref 36) 6 => '16:9 Crop', + 8 => '2.7x Crop', #36 (D4/D500) 9 => 'DX Movie Crop', # (DX during movie recording, Large) + 10 => '1.3x Movie Crop', #36 (D4/D500) 11 => 'FX Uncropped', 12 => 'DX Uncropped', + 15 => '1.5x Movie Crop', #36 (D4/D500) 17 => '1:1 Crop', OTHER => sub { my ($val, $inv, $conv) = @_; @@ -1225,18 +1280,32 @@ my %binaryDataAttrs = ( }, 0x0023 => [ { #PH (D300, but also found in D3,D3S,D3X,D90,D300S,D700,D3000,D5000) - Condition => '$$valPt =~ /^01/', Name => 'PictureControlData', + Condition => '$$valPt =~ /^01/', Writable => 'undef', Permanent => 0, Flags => [ 'Binary', 'Protected' ], SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' }, },{ #28 Name => 'PictureControlData', + Condition => '$$valPt =~ /^02/', Writable => 'undef', Permanent => 0, Flags => [ 'Binary', 'Protected' ], SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl2' }, + },{ + Name => 'PictureControlData', + Condition => '$$valPt =~ /^03/', + Writable => 'undef', + Permanent => 0, + Flags => [ 'Binary', 'Protected' ], + SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl3' }, + },{ + Name => 'PictureControlData', + Writable => 'undef', + Permanent => 0, + Flags => [ 'Binary', 'Protected' ], + SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControlUnknown' }, }, ], 0x0024 => { #JD @@ -1284,7 +1353,17 @@ my %binaryDataAttrs = ( ByteOrder => 'BigEndian', #(NC) }, }, - # 0x0034 - Nikon 1 models only, values: 0,16,33 + 0x0034 => { #forum9646 + Name => 'ShutterMode', + Writable => 'int16u', + PrintConv => { + 0 => 'Mechanical', + 16 => 'Electronic', + # 33 => ? seen for 1J2 + 48 => 'Electronic Front Curtain', + # 81 => ? seen for Z50 + }, + }, 0x0035 => { #32 Name => 'HDRInfo', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::HDRInfo' }, @@ -1303,6 +1382,12 @@ my %binaryDataAttrs = ( Count => 4, # (may need to divide by 4 for some images, eg. D3300/D5300, 12 bit - ref IB) }, + 0x0045 => { #IB + Name => 'CropArea', + Notes => 'left, top, width, height', + Writable => 'int16u', + Count => 4, + }, 0x004f => { #IB (D850) Name => 'ColorTemperatureAuto', Writable => 'int16u', @@ -1314,25 +1399,36 @@ my %binaryDataAttrs = ( Name => 'LensType', Writable => 'int8u', # credit to Tom Christiansen (ref 7) for figuring this out... + # (note that older models don't seem to set bits 4-7 (0xf0), so the + # LensType may be different with different models, ref Kenneth Cochran) PrintConv => q[$_ = $val ? Image::ExifTool::DecodeBits($val, { 0 => 'MF', 1 => 'D', 2 => 'G', 3 => 'VR', - # bit 4 set for Nikon 1 lenses - PH - # bit 5 set for FT-1 adapter? - PH - # bit 6 set for FL lenses? - PH + 4 => '1', #PH + 5 => 'FT-1', #PH/IB + 6 => 'E', #PH (electromagnetic aperture mechanism) + 7 => 'AF-P', #PH/IB }) : 'AF'; # remove commas and change "D G" to just "G" - s/,//g; s/\bD G\b/G/; $_ + s/,//g; s/\bD G\b/G/; + s/ E\b// and s/^(G )?/E /; # put "E" at the start instead of "G" + s/ 1// and $_ = "1 $_"; # put "1" at start + s/FT-1 // and $_ .= ' FT-1'; # put "FT-1" at end + return $_; ], PrintConvInv => q[ my $bits = 0; - $bits |= 0x01 if $val =~ /\bMF\b/i; - $bits |= 0x02 if $val =~ /\bD\b/i; - $bits |= 0x06 if $val =~ /\bG\b/i; - $bits |= 0x08 if $val =~ /\bVR\b/i; + $bits |= 0x01 if $val =~ /\bMF\b/i; # bit 0 + $bits |= 0x02 if $val =~ /\bD\b/i; # bit 1 + $bits |= 0x06 if $val =~ /\bG\b/i; # bits 1 and 2 + $bits |= 0x08 if $val =~ /\bVR\b/i; # bit 3 + $bits |= 0x10 if $val =~ /\b1\b/; # bit 4 + $bits |= 0x20 if $val =~ /\bFT-1/i; # bit 5 + $bits |= 0x80 if $val =~ /\bAF-P/i; # bit 7 (not used by all models) + $bits |= 0x46 if $val =~ /\bE\b/i; # bits 1, 2 and 6 return $bits; ], }, @@ -1673,7 +1769,7 @@ my %binaryDataAttrs = ( TagTable => 'Image::ExifTool::Nikon::ShotInfoD500', DecryptStart => 4, DecryptLen => 0x2c24 + 12, - DecryptMore => 'Get32u(\$data, 0xa0) + 12', + DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90', ByteOrder => 'LittleEndian', }, }, @@ -1684,7 +1780,7 @@ my %binaryDataAttrs = ( TagTable => 'Image::ExifTool::Nikon::ShotInfoD500', DecryptStart => 4, DecryptLen => 0x2cb2 + 4, - DecryptMore => 'Get32u(\$data, 0xa0) + 12', + DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90', ByteOrder => 'LittleEndian', }, }, @@ -1698,9 +1794,8 @@ my %binaryDataAttrs = ( ByteOrder => 'BigEndian', }, }, - # 0227 - D7100 - { - Condition => '$$valPt =~ /^02/', + { # D7100=0227, Z6/Z7=0800 + Condition => '$$valPt =~ /^0[28]/', Name => 'ShotInfo02xx', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ShotInfo', @@ -1740,7 +1835,7 @@ my %binaryDataAttrs = ( 9 => 'Packed 12 bits', #IB (2 pixels in 3 bytes) }, }, - 0x0094 => { Name => 'Saturation', Writable => 'int16s' }, + 0x0094 => { Name => 'SaturationAdj', Writable => 'int16s' }, 0x0095 => { Name => 'NoiseReduction', Writable => 'string' }, # ("Off" or "FPNR"=long exposure NR) 0x0096 => { Name => 'NEFLinearizationTable', # same table as DNG LinearizationTable (ref JD) @@ -1835,7 +1930,7 @@ my %binaryDataAttrs = ( DirOffset => 10, }, }, - { # (D3100=0215,D7000/D5100=0216,D4/D800/D3200=0217) + { # (D3100=0215,D7000/D5100=0216,D4/D600/D800/D800E/D3200=0217) Condition => '$$valPt =~ /^021[567]/', Name => 'ColorBalance0215', SubDirectory => { @@ -1857,9 +1952,9 @@ my %binaryDataAttrs = ( DecryptLen => 10, # (arbitrary) }, }, - { # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403) + { # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800) Name => 'ColorBalanceUnknown04', - Condition => '$$valPt =~ /^04/', + Condition => '$$valPt =~ /^0[48]/', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown', ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, @@ -1909,7 +2004,7 @@ my %binaryDataAttrs = ( }, }, { - Condition => '$$valPt =~ /^0400/', # 1J1, 1V1 + Condition => '$$valPt =~ /^040[01]/', # 0=1J1/1V1, 1=1J2 Name => 'LensData0400', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData0400', @@ -1918,10 +2013,44 @@ my %binaryDataAttrs = ( DecryptStart => 4, }, }, - { # (1J1/1V1=0400) + { + Condition => '$$valPt =~ /^0402/', # 1J3/1S1/1V2 + Name => 'LensData0402', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::LensData0402', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, + }, + }, + { + Condition => '$$valPt =~ /^0403/', # 1J4,1J5 + Name => 'LensData0403', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::LensData0403', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, + }, + }, + { + Condition => '$$valPt =~ /^0800/', # Z6/Z7 + Name => 'LensData0800', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::LensData0800', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, + ByteOrder => 'LittleEndian', + }, + }, + { Name => 'LensDataUnknown', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensDataUnknown', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, }, }, ], @@ -1949,6 +2078,17 @@ my %binaryDataAttrs = ( Name => 'SceneAssist', Writable => 'string', }, + 0x009d => { #NealKrawetz + Name => 'DateStampMode', + Writable => 'int16u', + Notes => 'feature to imprint date/time on image', + PrintConv => { #PH + 0 => 'Off', + 1 => 'Date & Time', + 2 => 'Date', + 3 => 'Date Counter', # (NC) (D3500) + }, + }, 0x009e => { #JD Name => 'RetouchHistory', Writable => 'int16u', @@ -2189,11 +2329,14 @@ my %binaryDataAttrs = ( 0x0e09 => { #12 Name => 'NikonCaptureVersion', Writable => 'string', - PrintConv => undef, + Permanent => 0, + PrintConv => undef, # (avoid applying default print conversion to string) }, # 0x0e0e is in D70 Nikon Capture files (not out-of-the-camera D70 files) - PH 0x0e0e => { #PH Name => 'NikonCaptureOffsets', + Writable => 'undef', + Permanent => 0, SubDirectory => { TagTable => 'Image::ExifTool::Nikon::CaptureOffsets', Validate => '$val =~ /^0100/', @@ -2209,11 +2352,11 @@ my %binaryDataAttrs = ( Start => '$val', }, }, - 0x0e13 => [{ # PH/http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2737.0.html + 0x0e13 => [{ # PH/https://exiftool.org/forum/index.php/topic,2737.0.html Name => 'NikonCaptureEditVersions', Condition => '$self->Options("ExtractEmbedded")', Notes => q{ - the ExtractEmbedded option may be used to decode settings from the stored + the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option may be used to decode settings from the stored edit versions, otherwise this is extracted as a binary data block }, Writable => 'undef', @@ -2359,9 +2502,10 @@ my %binaryDataAttrs = ( 6 => { Name => 'VRMode', PrintConv => { - 0 => 'Normal', - # 1 - seen this for 1V1 - PH + 0 => 'Normal', # (Z7 gives this value for "off" - PH) + 1 => 'On (1)', #PH (NC) 2 => 'Active', # (1J1) + 3 => 'Sport', #PH (Z7) }, }, # 7 - values: 0, 1 @@ -2640,7 +2784,125 @@ my %binaryDataAttrs = ( PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)', }, - 48 => { #21 + 51 => { + Name => 'Sharpness', + DelValue => 0xff, + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', + }, + 53 => { + Name => 'Clarity', + DelValue => 0xff, + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv2($val,4)', + }, + 55 => { + Name => 'Contrast', + DelValue => 0xff, + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', + }, + 57 => { #21 + Name => 'Brightness', + # settings: -1 to +1 + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,undef,"%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', + }, + 59 => { + Name => 'Saturation', + DelValue => 0xff, + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', + }, + 61 => { + Name => 'Hue', + DelValue => 0xff, + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)', + }, + 63 => { + Name => 'FilterEffect', + # settings: Off,Yellow,Orange,Red,Green (n/a for color modes) + DelValue => 0xff, + PrintHex => 1, + PrintConv => { + 0x80 => 'Off', + 0x81 => 'Yellow', + 0x82 => 'Orange', + 0x83 => 'Red', + 0x84 => 'Green', + 0xff => 'n/a', + }, + }, + 64 => { + Name => 'ToningEffect', + # settings: B&W,Sepia,Cyanotype,Red,Yellow,Green,Blue-Green,Blue, + # Purple-Blue,Red-Purple (n/a for color modes) + DelValue => 0xff, + PrintHex => 1, + PrintConvColumns => 2, + PrintConv => { + 0x80 => 'B&W', + 0x81 => 'Sepia', + 0x82 => 'Cyanotype', + 0x83 => 'Red', + 0x84 => 'Yellow', + 0x85 => 'Green', + 0x86 => 'Blue-green', + 0x87 => 'Blue', + 0x88 => 'Purple-blue', + 0x89 => 'Red-purple', + 0xff => 'n/a', + }, + }, + 65 => { + Name => 'ToningSaturation', + DelValue => 0xff, + ValueConv => '$val - 0x80', #$val == 0x7f (n/a) for "B&W" + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', + + }, +); + +# Picture Control information V3 (ref PH, Z7) +%Image::ExifTool::Nikon::PictureControl3 = ( + %binaryDataAttrs, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added + 0 => { + Name => 'PictureControlVersion', + Format => 'undef[4]', + Writable => 0, + }, + 8 => { + Name => 'PictureControlName', + Format => 'string[20]', + # make lower case with a leading capital for each word + PrintConv => \&FormatString, + PrintConvInv => 'uc($val)', + }, + # 48 - looks like PictureControl2 byte 45 + 28 => { + Name => 'PictureControlBase', + Format => 'string[20]', + PrintConv => \&FormatString, + PrintConvInv => 'uc($val)', + }, + 54 => { # (NC) Name => 'PictureControlAdjust', PrintConv => { 0 => 'Default Settings', @@ -2648,16 +2910,15 @@ my %binaryDataAttrs = ( 2 => 'Full Control', }, }, - 49 => { + 55 => { # (NC) Name => 'PictureControlQuickAdjust', - # settings: -2 to +2 (n/a for Neutral and Monochrome modes) DelValue => 0xff, ValueConv => '$val - 0x80', ValueConvInv => '$val + 0x80', PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)', }, - 51 => { + 57 => { Name => 'Sharpness', DelValue => 0xff, ValueConv => '$val - 0x80', @@ -2665,7 +2926,15 @@ my %binaryDataAttrs = ( PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', }, - 53 => { + 59 => { + Name => 'MidRangeSharpness', + DelValue => 0xff, + ValueConv => '$val - 0x80', + ValueConvInv => '$val + 0x80', + PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', + PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', + }, + 61 => { Name => 'Clarity', DelValue => 0xff, ValueConv => '$val - 0x80', @@ -2673,7 +2942,7 @@ my %binaryDataAttrs = ( PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv2($val,4)', }, - 55 => { + 63 => { Name => 'Contrast', DelValue => 0xff, ValueConv => '$val - 0x80', @@ -2681,15 +2950,14 @@ my %binaryDataAttrs = ( PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', }, - 57 => { #21 + 65 => { #21 Name => 'Brightness', - # settings: -1 to +1 ValueConv => '$val - 0x80', ValueConvInv => '$val + 0x80', PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,undef,"%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', }, - 59 => { + 67 => { Name => 'Saturation', DelValue => 0xff, ValueConv => '$val - 0x80', @@ -2697,7 +2965,7 @@ my %binaryDataAttrs = ( PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', }, - 61 => { + 69 => { Name => 'Hue', DelValue => 0xff, ValueConv => '$val - 0x80', @@ -2705,9 +2973,8 @@ my %binaryDataAttrs = ( PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)', }, - 63 => { + 71 => { # (NC) Name => 'FilterEffect', - # settings: Off,Yellow,Orange,Red,Green (n/a for color modes) DelValue => 0xff, PrintHex => 1, PrintConv => { @@ -2719,10 +2986,8 @@ my %binaryDataAttrs = ( 0xff => 'n/a', }, }, - 64 => { + 72 => { # (NC) Name => 'ToningEffect', - # settings: B&W,Sepia,Cyanotype,Red,Yellow,Green,Blue-Green,Blue, - # Purple-Blue,Red-Purple (n/a for color modes) DelValue => 0xff, PrintHex => 1, PrintConvColumns => 2, @@ -2740,10 +3005,10 @@ my %binaryDataAttrs = ( 0xff => 'n/a', }, }, - 65 => { + 73 => { # (NC) Name => 'ToningSaturation', DelValue => 0xff, - ValueConv => '$val - 0x80', #$val == 0x7f (n/a) for "B&W" + ValueConv => '$val - 0x80', ValueConvInv => '$val + 0x80', PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)', PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)', @@ -2751,6 +3016,18 @@ my %binaryDataAttrs = ( }, ); +# Unknown Picture Control information +%Image::ExifTool::Nikon::PictureControlUnknown = ( + %binaryDataAttrs, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added + 0 => { + Name => 'PictureControlVersion', + Format => 'undef[4]', + Writable => 0, + }, +); + # World Time information - JD (D300) %Image::ExifTool::Nikon::WorldTime = ( %binaryDataAttrs, @@ -2992,7 +3269,10 @@ my %binaryDataAttrs = ( 4 => { #PH Name => 'ContrastDetectAF', RawConv => '$$self{ContrastDetectAF} = $val', - PrintConv => \%offOn, + PrintConv => { + %offOn, + 2 => 'On (2)', #PH (Z7) + }, Notes => 'this is Off for the hybrid AF used in Nikon 1 models', }, 5 => [ @@ -3025,6 +3305,11 @@ my %binaryDataAttrs = ( 131 => 'Face Priority (41 points)', #PH (1J1,1J3,1S1,1V2,AW1) # 134 - seen for 1V1[PhaseDetectAF=0] (PH) # 135 - seen for 1J2[PhaseDetectAF=4] (PH) + 192 => 'Pinpoint', #PH (NC) + 193 => 'Single', #PH (NC) + 195 => 'Wide (S)', #PH (NC) + 196 => 'Wide (L)', #PH (NC) + 197 => 'Auto', #PH (NC) }, }, { #PH (D3/D90/D5000) @@ -3043,6 +3328,14 @@ my %binaryDataAttrs = ( 129 => 'Auto (41 points)', #PH (NC) 130 => 'Subject Tracking (41 points)', #PH (NC) 131 => 'Face Priority (41 points)', #PH (NC) + 192 => 'Pinpoint', #PH (Z7) + 193 => 'Single', #PH (Z7) (AF-S?) + 194 => 'Dynamic', #PH (Z7) + 195 => 'Wide (S)', #PH (Z7) + 196 => 'Wide (L)', #PH (Z7) + 197 => 'Auto', #PH (Z7) + 198 => 'Auto (198)', #PH (Z7) (focus lock with AF-C maybe?) + 199 => 'Auto (focus lock)', #PH (Z7, AF-S) }, }, ], @@ -3060,6 +3353,7 @@ my %binaryDataAttrs = ( 5 => 'On (5)', #PH (1S2[128/129], 1J4/1V3[129]) 6 => 'On (105-point)', #PH (1J4/1V3[128/130]) 7 => 'On (153-point)', #PH (D5/D500/D850) + 8 => 'On (81-point)', #38 }, }, 7 => [ @@ -3171,6 +3465,22 @@ my %binaryDataAttrs = ( 1 => 'E9 (Center)', }, }, + { #PH (Z7) (NC) + Name => 'PrimaryAFPoint', + Condition => '$$self{PhaseDetectAF} == 8 and $$self{AFInfo2Version} =~ /^03/', + Notes => q{ + Nikon models with 493-point AF -- 17 rows (A-Q) and 29 columns (1-29), I15 + at the center + }, + PrintConv => { + 0 => '(none)', + 246 => 'I15 (Center)', + OTHER => sub { + my ($val, $inv) = @_; + return GetAFPointGrid($val, 29, $inv); + }, + }, + }, { Name => 'PrimaryAFPoint', Condition => '$$self{AFInfo2Version} eq "0100"', @@ -3253,7 +3563,7 @@ my %binaryDataAttrs = ( Name => 'AFPointsUsed', Condition => '$$self{PhaseDetectAF} == 5', Notes => q{ - newer models with 135-point AF -- 9 rows (B-J) and 15 colums (1-15). Center + newer models with 135-point AF -- 9 rows (B-J) and 15 columns (1-15). Center point is F8 }, Format => 'undef[21]', @@ -3288,7 +3598,20 @@ my %binaryDataAttrs = ( PrintConv => sub { PrintAFPoints(shift, \%afPoints153); }, PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints153); }, }, - { + { #38 (Z6/Z7/Z50) + Name => 'AFPointsUsed', + Condition => '$$self{PhaseDetectAF} == 8 and $$self{Model} =~ /^NIKON Z/', + Notes => q{ + models with 81-selectable point AF -- 9 rows (A-I) and 9 columns (1-9) for + phase detect AF points. Center point is E5 + }, + Format => 'undef[13]', + ValueConv => 'join(" ", unpack("H2"x13, $val))', + ValueConvInv => '$val=~tr/ //d; pack("H*",$val)', + PrintConv => sub { PrintAFPoints(shift, \%afPoints81); }, + PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints81); }, + }, + { #PH Name => 'AFPointsUsed', Format => 'undef[7]', ValueConv => 'join(" ", unpack("H2"x7, $val))', @@ -3345,6 +3668,40 @@ my %binaryDataAttrs = ( PrintConv => { 0 => 'No', 1 => 'Yes' }, }, # 0x1d - always zero (with or without live view) + 0x2a => { #PH (Z7) + Name => 'AFImageWidth', + Condition => '$$self{AFInfo2Version} =~ /^03/', + Format => 'int16u', + RawConv => '$val ? $val : undef', + }, + 0x2c => { #PH (Z7) + Name => 'AFImageHeight', + Condition => '$$self{AFInfo2Version} =~ /^03/', + Format => 'int16u', + RawConv => '$val ? $val : undef', + }, + 0x2e => { #PH (Z7) + Name => 'AFAreaXPosition', + Condition => '$$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/', + Format => 'int16u', + }, + 0x30 => { #PH (Z7) + Name => 'AFAreaYPosition', + Condition => '$$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/', + Format => 'int16u', + }, + 0x32 => { #PH (Z7) + Name => 'AFAreaWidth', + Condition => '$$self{AFInfo2Version} =~ /^03/', + Format => 'int16u', + RawConv => '$val ? $val : undef', + }, + 0x34 => { #PH (Z7) + Name => 'AFAreaHeight', + Condition => '$$self{AFInfo2Version} =~ /^03/', + Format => 'int16u', + RawConv => '$val ? $val : undef', + }, 0x44 => [ { Name => 'PrimaryAFPoint', @@ -3356,10 +3713,31 @@ my %binaryDataAttrs = ( 1 => 'E9 (Center)', }, }, + { #PH + Name => 'PrimaryAFPoint', + Notes => 'D3500', + Condition => '$$self{PhaseDetectAF} == 2 and $$self{AFInfo2Version} eq "0101"', + PrintConvColumns => 2, + PrintConv => { + 0 => '(none)', + 1 => 'Center', + 2 => 'Top', + 3 => 'Bottom', + 4 => 'Mid-left', + 5 => 'Upper-left', + 6 => 'Lower-left', + 7 => 'Far Left', + 8 => 'Mid-right', + 9 => 'Upper-right', + 10 => 'Lower-right', + 11 => 'Far Right', + }, + }, { Name => 'PrimaryAFPoint', Condition => '$$self{AFInfo2Version} eq "0101"', Notes => 'future models?...', + Priority => 0, PrintConv => { 0 => '(none)', 1 => 'Center', @@ -3509,6 +3887,8 @@ my %binaryDataAttrs = ( %Image::ExifTool::Nikon::CaptureOffsets = ( PROCESS_PROC => \&ProcessNikonCaptureOffsets, GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + # (note that these are duplicates of offsets in the normal TIFF structure, + # and that these offsets are not updated when ExifTool rewrites the file) 1 => 'IFD0_Offset', 2 => 'PreviewIFD_Offset', 3 => 'SubIFD_Offset', @@ -3994,7 +4374,7 @@ my %nikonFocalConversions = ( %Image::ExifTool::Nikon::LensData0400 = ( %binaryDataAttrs, GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, - NOTES => 'Tags extracted from the encrypted lens data of Nikon 1 models.', + NOTES => 'Tags extracted from the encrypted lens data of the Nikon 1J1/1V1/1J2.', 0x00 => { Name => 'LensDataVersion', Format => 'string[4]', @@ -4006,6 +4386,198 @@ my %nikonFocalConversions = ( }, ); +# Nikon lens data version 0402 (note: needs decrypting) (ref PH) +%Image::ExifTool::Nikon::LensData0402 = ( + %binaryDataAttrs, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + NOTES => 'Tags extracted from the encrypted lens data of the Nikon 1J3/1S1/1V2.', + 0x00 => { + Name => 'LensDataVersion', + Format => 'string[4]', + Writable => 0, + }, + 0x18b => { #PH + Name => 'LensModel', + Format => 'string[64]', + }, +); + +# Nikon lens data version 0403 (note: needs decrypting) (ref PH) +%Image::ExifTool::Nikon::LensData0403 = ( + %binaryDataAttrs, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + NOTES => 'Tags extracted from the encrypted lens data of the Nikon 1J4/1J5.', + 0x00 => { + Name => 'LensDataVersion', + Format => 'string[4]', + Writable => 0, + }, + 0x2ac => { #PH + Name => 'LensModel', + Format => 'string[64]', + }, +); + +# Nikon Z lens data (note: needs decrypting) (ref PH, based on LensData0204) +%Image::ExifTool::Nikon::LensData0800 = ( + %binaryDataAttrs, + NOTES => 'Tags found in the encrypted LensData from cameras such as the Z6 and Z7.', + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + DATAMEMBER => [ 0x03, 0x2f ], + 0x00 => { + Name => 'LensDataVersion', + Format => 'string[4]', + Writable => 0, + }, + 0x03 => { # look forward to see if new old data exists... + Name => 'OldLensData', + Format => 'undef[17]', + RawConv => '$$self{OldLensData} = 1 unless $val =~ /^.\0+$/s; undef', + Hidden => 1, + }, + 0x04 => { + Name => 'ExitPupilPosition', + Condition => '$$self{OldLensData}', + ValueConv => '$val ? 2048 / $val : $val', + ValueConvInv => '$val ? 2048 / $val : $val', + PrintConv => 'sprintf("%.1f mm",$val)', + PrintConvInv => '$val=~s/\s*mm$//; $val', + }, + 0x05 => { + Name => 'AFAperture', + Condition => '$$self{OldLensData}', + %nikonApertureConversions, + }, + # --> another extra byte at position 0x08 in this version of LensData (PH) + 0x09 => { + Name => 'FocusPosition', + Condition => '$$self{OldLensData}', + PrintConv => 'sprintf("0x%02x", $val)', + PrintConvInv => '$val', + }, + 0x0b => { + Notes => 'this focus distance is approximate, and not very accurate for some lenses', + Name => 'FocusDistance', + Condition => '$$self{OldLensData}', + ValueConv => '0.01 * 10**($val/40)', # in m + ValueConvInv => '$val>0 ? 40*log($val*100)/log(10) : 0', + PrintConv => '$val ? sprintf("%.2f m",$val) : "inf"', + PrintConvInv => '$val eq "inf" ? 0 : $val =~ s/\s*m$//, $val', + }, + 0x0c => { + Name => 'FocalLength', + Condition => '$$self{OldLensData}', + Priority => 0, + %nikonFocalConversions, + }, + 0x0d => { + Name => 'LensIDNumber', + Condition => '$$self{OldLensData}', + Notes => 'see LensID values below', + }, + 0x0e => { + Name => 'LensFStops', + Condition => '$$self{OldLensData}', + ValueConv => '$val / 12', + ValueConvInv => '$val * 12', + PrintConv => 'sprintf("%.2f", $val)', + PrintConvInv => '$val', + }, + 0x0f => { + Name => 'MinFocalLength', + Condition => '$$self{OldLensData}', + %nikonFocalConversions, + }, + 0x10 => { + Name => 'MaxFocalLength', + Condition => '$$self{OldLensData}', + %nikonFocalConversions, + }, + 0x11 => { + Name => 'MaxApertureAtMinFocal', + Condition => '$$self{OldLensData}', + %nikonApertureConversions, + }, + 0x12 => { + Name => 'MaxApertureAtMaxFocal', + Condition => '$$self{OldLensData}', + %nikonApertureConversions, + }, + 0x13 => { + Name => 'MCUVersion', + Condition => '$$self{OldLensData}', + }, + 0x14 => { + Name => 'EffectiveMaxAperture', + Condition => '$$self{OldLensData}', + %nikonApertureConversions, + }, +# +# ---- new LensData tags used by Nikkor Z lenses ---- (ref PH) +# + 0x2f => { # look forward to see if new lens data exists... + Name => 'NewLensData', + Format => 'undef[17]', + RawConv => '$$self{NewLensData} = 1 unless $val =~ /^.\0+$/s; undef', + Hidden => 1, + }, + 0x30 => { + Name => 'LensID', + Condition => '$$self{NewLensData}', + Notes => 'tags from here onward used for Nikkor Z lenses only', + Format => 'int16u', + PrintConv => { + 1 => 'Nikkor Z 24-70mm f/4 S', + 2 => 'Nikkor Z 14-30mm f/4 S', + 4 => 'Nikkor Z 35mm f/1.8 S', + 8 => 'Nikkor Z 58mm f/0.95 S Noct', #IB + 9 => 'Nikkor Z 50mm f/1.8 S', + 11 => 'Nikkor Z DX 16-50mm f/3.5-6.3 VR', + 12 => 'Nikkor Z DX 50-250mm f/4.5-6.3 VR', + 13 => 'Nikkor Z 24-70mm f/2.8 S', + 14 => 'Nikkor Z 85mm f/1.8 S', + 15 => 'Nikkor Z 24mm f/1.8 S', #IB + }, + }, + 0x36 => { + Name => 'MaxAperture', + Condition => '$$self{NewLensData}', + Format => 'int16u', + Priority => 0, + ValueConv => '2**($val/384-1)', + ValueConvInv => '384*(log($val)/log(2)+1)', + PrintConv => 'sprintf("%.1f",$val)', + PrintConvInv => '$val', + }, + 0x38 => { + Name => 'FNumber', + Condition => '$$self{NewLensData}', + Format => 'int16u', + Priority => 0, + ValueConv => '2**($val/384-1)', + ValueConvInv => '384*(log($val)/log(2)+1)', + PrintConv => 'sprintf("%.1f",$val)', + PrintConvInv => '$val', + }, + 0x3c => { + Name => 'FocalLength', + Condition => '$$self{NewLensData}', + Format => 'int16u', + Priority => 0, + PrintConv => '"$val mm"', + PrintConvInv => '$val=~s/\s*mm$//;$val', + }, + 0x4f => { + Name => 'FocusDistance', + Condition => '$$self{NewLensData}', + # (perhaps int16u Format? -- although upper byte would always be zero) + ValueConv => '0.01 * 10**($val/40)', # in m + ValueConvInv => '$val>0 ? 40*log($val*100)/log(10) : 0', + PrintConv => '$val ? sprintf("%.2f m",$val) : "inf"', + PrintConvInv => '$val eq "inf" ? 0 : $val =~ s/\s*m$//, $val', + }, +); + # Unknown Nikon lens data (note: data may need decrypting after byte 4) %Image::ExifTool::Nikon::LensDataUnknown = ( PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, @@ -4095,6 +4667,7 @@ my %nikonFocalConversions = ( 1 => 'On', }, }, + # 0xac - int16u[600] TiffMeteringImage1: 30x20 image (ShotInfoVersion 0800, ref JR) 0x157 => { #JD Name => 'ShutterCount', Condition => '$$self{ShotInfoVersion} eq "0205"', @@ -4125,6 +4698,14 @@ my %nikonFocalConversions = ( Priority => 0, }, # note: DecryptLen currently set to 0x251 + + # 0x55c - int16u[2400] TiffMeteringImage2: 60x40 image (ShotInfoVersion 0800, ref JR) + # 0x181c - int16u[1200] TiffMeteringImage?: 60x20 image for some NEF's (ShotInfoVersion 0800, ref JR) + # 0x217c - int16u[2400] TiffMeteringImage3: 60x40 image (ShotInfoVersion 0800, ref JR) + # 0x3d9c - int16u[2400] TiffMeteringImage4: 60x40 image (ShotInfoVersion 0800, ref JR) + # 0x59c0 - TiffMeteringImageWidth (ShotInfoVersion 0800, ref JR) + # 0x59c2 - TiffMeteringImageHeight (ShotInfoVersion 0800, ref JR) + # 0x59c4 - int16u[1800] TiffMeteringImage5: 30x20 RGB image (ShotInfoVersion 0800, ref JR) ); # shot information for D40 and D40X (encrypted) - ref PH @@ -5176,8 +5757,8 @@ my %nikonFocalConversions = ( WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, CHECK_PROC => \&Image::ExifTool::CheckBinaryData, VARS => { ID_LABEL => 'Index' }, - DATAMEMBER => [ 0x04, 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xb0, - 0x07b0, 0x086c, 0x0e7c, 0x0eea, 0x2c23 ], + DATAMEMBER => [ 0x04, 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8, 0xb0, + 0x07b0, 0x086c, 0x0e7c, 0x0eea, 0x2c23, 0x2c8f ], IS_SUBDIR => [ 0x0eeb ], WRITABLE => 1, FIRST_ENTRY => 0, @@ -5200,42 +5781,56 @@ my %nikonFocalConversions = ( DataMember => 'RotationInfoOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; $val', # (ignore if 0) + Hidden => 1, + RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; undef', # (ignore if 0) }, 0x14 => { Name => 'JPGInfoOffset', DataMember => 'JPGInfoOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; $val', # (ignore if 0) + Hidden => 1, + RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; undef', # (ignore if 0) }, 0x2c => { Name => 'BracketingInfoOffset', DataMember => 'BracketingInfoOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; $val', # (ignore if 0) + Hidden => 1, + RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; undef', # (ignore if 0) }, 0x50 => { Name => 'ShootingMenuOffset', DataMember => 'ShootingMenuOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; $val', # (ignore if 0) + Hidden => 1, + RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; undef', # (ignore if 0) }, 0x58 => { Name => 'CustomSettingsOffset', DataMember => 'CustomSettingsOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; $val', # (ignore if 0) + Hidden => 1, + RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', # (ignore if 0) }, 0xa0 => { Name => 'OrientationOffset', DataMember => 'OrientationOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{OrientationOffset} = $val || 0x10000000; $val', # (ignore if 0) + Hidden => 1, + RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0) + }, + 0xa8 => { + Name => 'OtherOffset', + DataMember => 'OtherOffset', + Format => 'int32u', + Writable => 0, + Hidden => 1, + RawConv => '$$self{OtherOffset} = $val || 0x10000000; undef', # (ignore if 0) }, # # Tag ID's below are the offsets for a D500 JPEG image, but these offsets change @@ -5626,9 +6221,15 @@ my %nikonFocalConversions = ( PrintConv => 'sprintf("%.1f", $val)', PrintConvInv => '$val', }, - # note: DecryptLen currently set to OrientationOffset + 12 - - # (not sure about how this moves around) +### 0x2c90 - OtherInfo start (D500 firmware 1.20d) + 0x2c8f => { + Name => 'Hook7', + Hidden => 1, + RawConv => 'undef', + # account for variable location of OtherInfo data + Hook => '$varSize = $$self{OtherOffset} - 0x2c90', + }, + # (needs testing) #0x2cb2 => { # Name => 'ExtendedPhotoShootingBanks', # Mask => 0x01, @@ -5637,10 +6238,10 @@ my %nikonFocalConversions = ( # 1 => 'Off', # }, #}, - # don't decode this because it is duplicate information and moves around with firmware versions + # (may not be reliable and is found elsewhere) #0x2ea2 => { # Name => 'Rotation', - # Condition => '$$self{Model} =~ /\bD500\b/ and $$self{FirmwareVersion} =~ /^1.1/', + # Condition => '$$self{Model} =~ /\bD500\b/', # Notes => 'D500 firmware 1.1x', # Mask => 0x30, # PrintConv => { @@ -5650,6 +6251,19 @@ my %nikonFocalConversions = ( # 3 => 'Rotate 180', # }, #}, + 0x2ea4 => { + Name => 'NikonMeteringMode', + Condition => '$$self{Model} =~ /\bD500\b/', # (didn't seem to work for D5, but I need more samples) + Notes => 'D500 only', + Mask => 0x03, + PrintConv => { + 0 => 'Matrix', + 1 => 'Center', + 2 => 'Spot', + 3 => 'Highlight' + }, + }, + # note: DecryptLen currently set to OtherOffset + 0x2ea5 - 0x2c90 ); # shot information for the D610 firmware 1.00 (encrypted) - ref PH %Image::ExifTool::Nikon::ShotInfoD610 = ( @@ -5688,12 +6302,16 @@ my %nikonFocalConversions = ( WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, CHECK_PROC => \&Image::ExifTool::CheckBinaryData, VARS => { ID_LABEL => 'Index' }, - DATAMEMBER => [ 0x04, 0x24, 0x40, 0x84, 0x01d0, 0x175e, 0x185d ], + DATAMEMBER => [ 0x04, 0x24, 0x38, 0x40, 0x84, 0x01d0, 0x175e, 0x185d, 0x18ab ], IS_SUBDIR => [ 0x18ab ], WRITABLE => 1, FIRST_ENTRY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, - NOTES => 'These tags are extracted from encrypted data in images from the D810.', + NOTES => q{ + These tags are extracted from encrypted data in images from the D810. Note + that the indices listed below are for firmware version 1.0, but they may be + different for other firmware versions. + }, 0x00 => { Name => 'ShotInfoVersion', Format => 'string[4]', @@ -5713,21 +6331,32 @@ my %nikonFocalConversions = ( DataMember => 'BracketingOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{BracketingOffset} = $val', + Hidden => 1, + RawConv => '$$self{BracketingOffset} = $val || 0x10000000; undef', + }, + 0x38 => { + Name => 'ISOAutoOffset', + DataMember => 'ISOAutoOffset', + Format => 'int32u', + Writable => 0, + Hidden => 1, + RawConv => '$$self{ISOAutoOffset} = $val || 0x10000000; undef', }, 0x40 => { Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data) DataMember => 'CustomSettingsOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{CustomSettingsOffset} = $val', + Hidden => 1, + RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', }, 0x84 => { Name => 'OrientationOffset', DataMember => 'OrientationOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{OrientationOffset} = $val', + Hidden => 1, + RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', }, 0x01d0 => { Name => 'SecondarySlotFunction', @@ -5840,7 +6469,7 @@ my %nikonFocalConversions = ( }, }, 0x175e => { - Name => 'D810MeteringMode', + Name => 'NikonMeteringMode', Mask => 0x03, PrintConv => { 0 => 'Matrix', @@ -5848,15 +6477,7 @@ my %nikonFocalConversions = ( 2 => 'Spot', 3 => 'Highlight' }, - Hook => '$varSize = $$self{CustomSettingsOffset} - 0x18ab', - }, - 0x18ab => { # (actual offset adjusted by Hook above) - Name => 'CustomSettingsD810', - Notes => 'actual offset determined by CustomSettingsOffset', - Format => 'undef[53]', - SubDirectory => { - TagTable => 'Image::ExifTool::NikonCustom::SettingsD810', - }, + Hook => '$varSize = $$self{ISOAutoOffset} - 0x1858', }, 0x185c => { Name => 'ISOAutoShutterTime', @@ -5905,7 +6526,6 @@ my %nikonFocalConversions = ( Name => 'ISOAutoHiLimit', Mask => 0xff, PrintHex => 1, - Hook => '$varSize = $$self{OrientationOffset} - 0x36f4', PrintConv => { 0x24 => 'ISO 200', 0x26 => 'ISO 250', @@ -5949,6 +6569,15 @@ my %nikonFocalConversions = ( 0x6c => 'ISO Hi 4.0', 0x72 => 'ISO Hi 5.0', }, + Hook => '$varSize = $$self{CustomSettingsOffset} - 0x18ab', + }, + 0x18ab => { # (actual offset adjusted by Hook above) + Name => 'CustomSettingsD810', + Format => 'undef[53]', + SubDirectory => { + TagTable => 'Image::ExifTool::NikonCustom::SettingsD810', + }, + Hook => '$varSize = $$self{OrientationOffset} - 0x36f4', }, 0x36f4 => { Name => 'RollAngle', @@ -6022,7 +6651,8 @@ my %nikonFocalConversions = ( DataMember => 'CustomSettingsOffset', Format => 'int32u', Writable => 0, - RawConv => '$$self{CustomSettingsOffset} = $val', + Hidden => 1, + RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', }, 0x0791 => { Name => 'PhotoShootingMenuBankImageArea', @@ -7426,6 +8056,24 @@ my %nikonFocalConversions = ( }, ); +# extra info found in IFD0 of NEF files (ref PH, Z6/Z7) +%Image::ExifTool::Nikon::NEFInfo = ( + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + NOTES => q{ + As-yet unknown information found in SubIFD1 tag 0xc7d5 of NEF images from + cameras such as the Z6 and Z7, and NRW images from some Coolpix cameras. + }, + # 0x01 - undef[12] + # 0x02 - undef[148] + # 0x03 - undef[284] + # 0x04 - undef[148,212] + # 0x05 - undef[84] + # 0x06 - undef[116] + # 0x07 - undef[104] + # 0x08 - undef[24] + # 0x09 - undef[36] +); + # tags in Nikon QuickTime videos (PH - observations with Coolpix S3) # (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos) %Image::ExifTool::Nikon::MOV = ( @@ -8012,18 +8660,32 @@ my %nikonFocalConversions = ( }, 0x2000023 => [ { #PH (D300, but also found in D3,D3S,D3X,D90,D300S,D700,D3000,D5000) - Condition => '$$valPt =~ /^01/', Name => 'PictureControlData', + Condition => '$$valPt =~ /^01/', Writable => 'undef', Permanent => 0, Flags => [ 'Binary', 'Protected' ], SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' }, },{ #28 Name => 'PictureControlData', + Condition => '$$valPt =~ /^02/', Writable => 'undef', Permanent => 0, Flags => [ 'Binary', 'Protected' ], SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl2' }, + },{ + Name => 'PictureControlData', + Condition => '$$valPt =~ /^03/', + Writable => 'undef', + Permanent => 0, + Flags => [ 'Binary', 'Protected' ], + SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl3' }, + },{ + Name => 'PictureControlData', + Writable => 'undef', + Permanent => 0, + Flags => [ 'Binary', 'Protected' ], + SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControlUnknown' }, }, ], 0x2000024 => { @@ -8072,9 +8734,16 @@ my %nikonFocalConversions = ( 1 => 'D', 2 => 'G', 3 => 'VR', + 4 => '1', #PH + # bit 5 set for FT-1 adapter? - PH + 6 => 'E', #PH (electromagnetic aperture mechanism) + # bit 7 set for AF-P lenses? - PH }) : 'AF'; # remove commas and change "D G" to just "G" - s/,//g; s/\bD G\b/G/; $_ + s/,//g; s/\bD G\b/G/; + s/ E\b// and s/^(G )?/E /; # put "E" at the start instead of "G" + s/ 1// and $_ = "1 $_"; # put "1" at start + return $_; ], }, 0x2000084 => { @@ -8130,7 +8799,7 @@ my %nikonFocalConversions = ( }, }, { - Condition => '$$valPt =~ /^0400/', # 1J1, 1V1 + Condition => '$$valPt =~ /^040[01]/', # 0=1J1/1V1, 1=1J2 Name => 'LensData0400', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData0400', @@ -8139,10 +8808,45 @@ my %nikonFocalConversions = ( DecryptStart => 4, }, }, - { # (1J1/1V1=0400) + { + Condition => '$$valPt =~ /^0402/', # 1J3/1S1/1V2 + Name => 'LensData0402', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::LensData0402', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, + }, + }, + { + Condition => '$$valPt =~ /^0403/', # 1J4,1J5 + Name => 'LensData0403', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::LensData0403', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, + }, + }, + { + Condition => '$$valPt =~ /^0800/', # Z6/Z7 + Name => 'LensData0800', + SubDirectory => { + TagTable => 'Image::ExifTool::Nikon::LensData0800', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, + ByteOrder => 'LittleEndian', + # 0x5a0c - NikonMeteringMode for some Z6 ver1.00 samples (ref PH) + }, + }, + { Name => 'LensDataUnknown', SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensDataUnknown', + ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted, + DecryptStart => 4, }, }, ], @@ -8439,20 +9143,26 @@ sub LensIDConv($$$) return join(' or ', @user) if @user; return join(' or ', @vals); } - # Sigma has been changing the LensID on some new lenses + # Sigma has been changing the LensIDNumber on some new lenses # and with some Sigma lenses the LensFStops changes! (argh!) + # Also, older cameras my not set bits 4-7 of LensType my $pat = $val; - $pat =~ s/^\w+ \w+/.. ../; + $pat =~ s/^\w+ \w+/.. ../; # ignore LensIDNumber and LensFStops + $pat =~ s/\w(\w)$/.$1/; # ignore bits 4-7 of LensType my @ids = sort grep /^$pat$/, keys %$conv; if (@ids) { # first try different LensFStops (2nd value) ($pat = $val) =~ s/ \w+/ ../; my @good = grep /^$pat$/, @ids; return $$conv{$good[0]} if @good; - # then try different LensType (1st value) + # then try different LensIDNumber (1st value) ($pat = $val) =~ s/^\w+/../; @good = grep /^$pat$/, @ids; return "Unknown ($val) $$conv{$good[0]} ?" if @good; + # older cameras may not set bits 4-7 of LensType + ($pat = $val) =~ s/\w(\w)$/.$1/; + @good = grep /^$pat$/, @ids; + return "Unknown ($val) $$conv{$good[0]} ?" if @good; } return undef; } @@ -8580,35 +9290,47 @@ sub ProcessNikonMOV($$$) my ($et, $dirInfo, $tagTablePtr) = @_; my $dataPt = $$dirInfo{DataPt}; my $dataPos = $$dirInfo{DataPos}; - my $pos = $$dirInfo{DirStart}; - my $end = $pos + $$dirInfo{DirLen}; + my %needTags = ( 0x110a431 => 0, 0x20000a7 => undef ); # needed for decryption $et->VerboseDir($$dirInfo{DirName}, 0, $$dirInfo{DirLen}); - while ($pos + 8 < $end) { - my $tag = Get32u($dataPt, $pos); - my $fmt = Get16u($dataPt, $pos + 4); # (same format code as EXIF) - my $count = Get16u($dataPt, $pos + 6); - $pos += 8; - my $fmtStr = $Image::ExifTool::Exif::formatName[$fmt]; - unless ($fmtStr) { - $et->Warn(sprintf("Unknown format ($fmt) for $$dirInfo{DirName} tag 0x%x",$tag)); - last; - } - my $size = $count * $Image::ExifTool::Exif::formatSize[$fmt]; - if ($pos + $size > $end) { - $et->Warn(sprintf("Truncated data for $$dirInfo{DirName} tag 0x%x",$tag)); - last; + my $pass; + # do two passes so we can pre-scan for necessary decryption keys + for ($pass=0; $pass<2; ++$pass) { + my $pos = $$dirInfo{DirStart}; + my $end = $pos + $$dirInfo{DirLen}; + while ($pos + 8 < $end) { + my $tag = Get32u($dataPt, $pos); + my $fmt = Get16u($dataPt, $pos + 4); # (same format code as EXIF) + my $count = Get16u($dataPt, $pos + 6); + $pos += 8; + my $fmtStr = $Image::ExifTool::Exif::formatName[$fmt]; + unless ($fmtStr) { + $et->Warn(sprintf("Unknown format ($fmt) for $$dirInfo{DirName} tag 0x%x",$tag)) if $pass; + last; + } + my $size = $count * $Image::ExifTool::Exif::formatSize[$fmt]; + if ($pos + $size > $end) { + $et->Warn(sprintf("Truncated data for $$dirInfo{DirName} tag 0x%x",$tag)) if $pass; + last; + } + if ($pass) { + my $rational; + my $val = ReadValue($dataPt, $pos, $fmtStr, $count, $size, \$rational); + my $key = $et->HandleTag($tagTablePtr, $tag, $val, + DataPt => $dataPt, + DataPos => $dataPos, + Format => $fmtStr, + Start => $pos, + Size => $size, + Base => $$dirInfo{Base}, + ); + $$et{RATIONAL}{$key} = $rational if $rational and $key; + } elsif (exists $needTags{$tag}) { + $needTags{$tag} = ReadValue($dataPt, $pos, $fmtStr, $count, $size); + $$et{NikonSerialKey} = SerialKey($et, $needTags{0x110a431}); + $$et{NikonCountKey} = $needTags{0x20000a7}; + } + $pos += $size; # is this padded to an even offset???? } - my $rational; - my $val = ReadValue($dataPt, $pos, $fmtStr, $count, $size, \$rational); - my $key = $et->HandleTag($tagTablePtr, $tag, $val, - DataPt => $dataPt, - DataPos => $dataPos, - Format => $fmtStr, - Start => $pos, - Size => $size, - ); - $$et{RATIONAL}{$key} = $rational if $rational and $key; - $pos += $size; # is this padded to an even offset???? } return 1; } @@ -8902,7 +9624,7 @@ Nikon maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/NikonCapture.pm b/src/Image-ExifTool/lib/Image/ExifTool/NikonCapture.pm index 9f20dbfd..a31930dd 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/NikonCapture.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/NikonCapture.pm @@ -918,7 +918,7 @@ the maker notes of NEF images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/NikonCustom.pm b/src/Image-ExifTool/lib/Image/ExifTool/NikonCustom.pm index cfe18f4e..f29bda73 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/NikonCustom.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/NikonCustom.pm @@ -3083,7 +3083,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 3 => 'D', }, }, - 1.1 => { #CSa1 + 1.1 => { # CSa1 Name => 'AF-CPrioritySelection', Mask => 0xc0, PrintConv => { @@ -3093,7 +3093,15 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 3 => 'Focus + Release', }, }, - 1.2 => { # CSa6 + 1.2 => { # CSa2 + Name => 'AF-SPrioritySelection', + Mask => 0x20, + PrintConv => { + 0 => 'Focus', + 1 => 'Release', + }, + }, + 1.3 => { # CSa6 Name => 'NumberOfFocusPoints', Mask => 0x10, PrintConv => { @@ -3101,7 +3109,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 1 => '15 Points', }, }, - 1.3 => { # CSa4 + 1.4 => { # CSa4 Name => 'Three-DTrackingFaceDetection', Mask => 0x08, PrintConv => { @@ -3109,14 +3117,6 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 1 => 'On', }, }, - 1.4 => { # CSa2 - Name => 'AF-SPrioritySelection', - Mask => 0x20, - PrintConv => { - 0 => 'Focus', - 1 => 'Release', - }, - }, 1.5 => { # CSa3-a Name => 'BlockShotAFResponse', Mask => 0x07, @@ -4150,7 +4150,7 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 3 => 'D', }, }, - 1.1 => { #CSa1 + 1.1 => { # CSa1 Name => 'AF-CPrioritySelection', Mask => 0xc0, PrintConv => { @@ -4160,7 +4160,15 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 3 => 'Focus + Release', }, }, - 1.2 => { # CSa6 + 1.2 => { # CSa2 + Name => 'AF-SPrioritySelection', + Mask => 0x20, + PrintConv => { + 0 => 'Focus', + 1 => 'Release', + }, + }, + 1.3 => { # CSa6 Name => 'NumberOfFocusPoints', Mask => 0x10, PrintConv => { @@ -4168,19 +4176,11 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); 1 => '15 Points', }, }, - 1.3 => { # CSa4 + 1.4 => { # CSa4 Name => 'Three-DTrackingFaceDetection', Mask => 0x08, PrintConv => \%offOn, }, - 1.4 => { # CSa2 - Name => 'AF-SPrioritySelection', - Mask => 0x20, - PrintConv => { - 0 => 'Focus', - 1 => 'Release', - }, - }, 1.5 => { # CSa3-a Name => 'BlockShotAFResponse', Mask => 0x07, @@ -6950,8 +6950,8 @@ my %noYes = ( 0 => 'No', 1 => 'Yes' ); }, }, 49.1 => { # CSa9 - Name => 'LimitAFAreaModeSelection', #note that 'Dynamic area (9 points)' can be selected from the camera menu but the setting is not writen to the EXIF data. - Mask => 0x7e, #...This AF Mode was addded to the D5 firmware several months after the camera's initial release which may help explain the inconsistency. + Name => 'LimitAFAreaModeSelection', #note that 'Dynamic area (9 points)' can be selected from the camera menu but the setting is not written to the EXIF data. + Mask => 0x7e, #...This AF Mode was added to the D5 firmware several months after the camera's initial release which may help explain the inconsistency. PrintConv => { 0 => 'No Restrictions', BITMASK => { @@ -9534,7 +9534,7 @@ this information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Nintendo.pm b/src/Image-ExifTool/lib/Image/ExifTool/Nintendo.pm index 636ef6c4..3d1090d4 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Nintendo.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Nintendo.pm @@ -107,7 +107,7 @@ interpret Nintendo maker notes EXIF meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/OOXML.pm b/src/Image-ExifTool/lib/Image/ExifTool/OOXML.pm index 03daed03..e1ec1271 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/OOXML.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/OOXML.pm @@ -14,13 +14,14 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::XMP; use Image::ExifTool::ZIP; -$VERSION = '1.07'; +$VERSION = '1.08'; # test for recognized OOXML document extensions my %isOOXML = ( DOCX => 1, DOCM => 1, DOTX => 1, DOTM => 1, POTX => 1, POTM => 1, + PPAX => 1, PPAM => 1, PPSX => 1, PPSM => 1, PPTX => 1, PPTM => 1, THMX => 1, XLAM => 1, @@ -394,7 +395,7 @@ archives of XML files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Ogg.pm b/src/Image-ExifTool/lib/Image/ExifTool/Ogg.pm index 75d36fd5..e81ef3ac 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Ogg.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Ogg.pm @@ -214,7 +214,7 @@ information from Ogg bitstream container files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Olympus.pm b/src/Image-ExifTool/lib/Image/ExifTool/Olympus.pm index 3c997349..9f60c6fb 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Olympus.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Olympus.pm @@ -9,8 +9,8 @@ # References: 1) http://park2.wakwak.com/~tsuruzoh/Computer/Digicams/exif-e.html # 2) http://www.cybercom.net/~dcoffin/dcraw/ # 3) http://www.ozhiker.com/electronics/pjmt/jpeg_info/olympus_mn.html -# 4) Markku HŠnninen private communication (tests with E-1) -# 5) RŽmi Guyomarch from http://forums.dpreview.com/forums/read.asp?forum=1022&message=12790396 +# 4) Markku Hanninen private communication (tests with E-1) +# 5) Remi Guyomarch from http://forums.dpreview.com/forums/read.asp?forum=1022&message=12790396 # 6) Frank Ledwon private communication (tests with E/C-series cameras) # 7) Michael Meissner private communication # 8) Shingo Noguchi, PhotoXP (http://www.daifukuya.com/photoxp/) @@ -21,7 +21,7 @@ # 13) Chris Shaw private communication (E-3) # 14) Viktor Lushnikov private communication (E-400) # 15) Yrjo Rauste private communication (E-30) -# 16) Godfrey DiGiorgi private communcation (E-P1) + http://forums.dpreview.com/forums/read.asp?message=33187567 +# 16) Godfrey DiGiorgi private communication (E-P1) + http://forums.dpreview.com/forums/read.asp?message=33187567 # 17) Martin Hibers private communication # 18) Tomasz Kawecki private communication # 19) Brad Grier private communication @@ -39,7 +39,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::APP12; -$VERSION = '2.54'; +$VERSION = '2.65'; sub PrintLensInfo($$$); @@ -106,8 +106,10 @@ my %olympusLensTypes = ( '0 30 10' => 'Olympus M.Zuiko Digital ED 45mm F1.2 Pro', #IB '0 31 00' => 'Olympus Zuiko Digital ED 12-60mm F2.8-4.0 SWD', #7 '0 32 00' => 'Olympus Zuiko Digital ED 14-35mm F2.0 SWD', #PH + '0 32 10' => 'Olympus M.Zuiko Digital ED 12-200mm F3.5-6.3', #IB '0 33 00' => 'Olympus Zuiko Digital 25mm F2.8', #PH '0 34 00' => 'Olympus Zuiko Digital ED 9-18mm F4.0-5.6', #7 + '0 34 10' => 'Olympus M.Zuiko Digital ED 12-45mm F4.0 Pro', #IB '0 35 00' => 'Olympus Zuiko Digital 14-54mm F2.8-3.5 II', #PH # Sigma lenses '1 01 00' => 'Sigma 18-50mm F3.5-5.6 DC', #8 @@ -168,10 +170,20 @@ my %olympusLensTypes = ( '2 26 10' => 'Lumix G 25mm F1.7 Asph.', #NJ '2 27 10' => 'Leica DG Vario-Elmar 100-400mm F4.0-6.3 Asph. Power OIS', #NJ '2 28 10' => 'Lumix G Vario 12-60mm F3.5-5.6 Asph. Power OIS', #NJ + '2 29 10' => 'Leica DG Summilux 12mm F1.4 Asph.', #IB + '2 30 10' => 'Leica DG Vario-Elmarit 12-60mm F2.8-4 Asph. Power OIS', #IB + '2 32 10' => 'Lumix G Vario 100-300mm F4.0-5.6 II', #PH + '2 33 10' => 'Lumix G X Vario 12-35mm F2.8 II Asph. Power OIS', #IB + '2 34 10' => 'Lumix G Vario 35-100mm F2.8 II', #forum3833 + '2 35 10' => 'Leica DG Vario-Elmarit 8-18mm F2.8-4 Asph.', #IB + '2 36 10' => 'Leica DG Elmarit 200mm F2.8 Power OIS', #IB + '2 37 10' => 'Leica DG Vario-Elmarit 50-200mm F2.8-4 Asph. Power OIS', #IB + '2 38 10' => 'Leica DG Vario-Summilux 10-25mm F1.7 Asph.', #IB '3 01 00' => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.', #11 '3 02 00' => 'Leica D Summilux 25mm F1.4 Asph.', #11 # Tamron lenses '5 01 10' => 'Tamron 14-150mm F3.5-5.8 Di III', #NJ (model C001) + # '65535 07 40' - Seen for LUMIX S 16-35/F4 on Panasonic DC-S1H (ref PH) ); # lookup for Olympus camera types (ref PH) @@ -363,6 +375,7 @@ my %olympusCameraTypes = ( D4587 => 'TG-860', D4591 => 'TG-870', D4593 => 'TG-5', #IB + D4603 => 'TG-6', #IB D4809 => 'C2500L', D4842 => 'E-10', D4856 => 'C-1', @@ -406,6 +419,10 @@ my %olympusCameraTypes = ( S0067 => 'E-M1MarkII', S0068 => 'E-M10MarkIII', S0076 => 'E-PL9', #IB + S0080 => 'E-M1X', #IB + S0085 => 'E-PL10', #IB + S0089 => 'E-M5MarkIII', + S0092 => 'E-M1MarkIII', #IB SR45 => 'D220', SR55 => 'D320L', SR83 => 'D340L', @@ -730,8 +747,8 @@ my %indexInfo = ( Name => 'CameraID', Format => 'string', # this really should have been a string }, - 0x020b => { Name => 'EpsonImageWidth', Writable => 'int16u' }, #PH - 0x020c => { Name => 'EpsonImageHeight', Writable => 'int16u' }, #PH + 0x020b => { Name => 'EpsonImageWidth', Writable => 'int32u' }, #PH + 0x020c => { Name => 'EpsonImageHeight', Writable => 'int32u' }, #PH 0x020d => { Name => 'EpsonSoftware', Writable => 'string' }, #PH 0x0280 => { #PH %Image::ExifTool::previewImageTagInfo, @@ -754,9 +771,17 @@ my %indexInfo = ( 0x0303 => { Name => 'WhiteBalanceBracket', Writable => 'int16u' }, #11 0x0304 => { Name => 'WhiteBalanceBias', Writable => 'int16u' }, #11 # 0x0305 => 'PrintMatching', ? #11 + 0x0400 => { #IB + Name => 'SensorArea', + Condition => '$$self{TIFF_TYPE} eq "ERF"', + Writable => 'undef', + Format => 'int16u', + Count => 4, + Notes => 'found in Epson ERF images', + }, 0x0401 => { #IB Name => 'BlackLevel', - Condition => '$format eq "int32u" and $count == 4', + Condition => '$$self{TIFF_TYPE} eq "ERF"', Writable => 'int32u', Count => 4, Notes => 'found in Epson ERF images', @@ -819,6 +844,7 @@ my %indexInfo = ( TagTable => 'Image::ExifTool::PrintIM::Main', }, }, + # 0x0e80 - undef[256] - offset 0x30: uint16[2] WB_RGBLevels = val[0]*561,65536,val[1]*431 (ref IB) 0x0f00 => { Name => 'DataDump', Writable => 0, @@ -1054,6 +1080,7 @@ my %indexInfo = ( 0x1035 => { #6 Name => 'PreviewImageValid', Writable => 'int32u', + DelValue => 0, PrintConv => { 0 => 'No', 1 => 'Yes' }, }, 0x1036 => { #6 @@ -1576,14 +1603,14 @@ my %indexInfo = ( Writable => 'int8u', Count => 6, Notes => q{ - 6 numbers: 0. Make, 1. Unknown, 2. Model, 3. Sub-model, 4-5. Unknown. Only + 6 numbers: 1. Make, 2. Unknown, 3. Model, 4. Sub-model, 5-6. Unknown. Only the Make, Model and Sub-model are used to identify the lens type }, SeparateTable => 'LensType', # Have seen these values for the unknown numbers: - # 1: 0 - # 4: 0, 2(Olympus lenses for which I have also seen 0 for this number) - # 5: 0, 16(new Lumix lenses) + # 2: 0 + # 5: 0, 2(Olympus lenses for which I have also seen 0 for this number) + # 6: 0, 16(new Lumix lenses) ValueConv => 'my @a=split(" ",$val); sprintf("%x %.2x %.2x",@a[0,2,3])', # set unknown values to zero when writing ValueConvInv => 'my @a=split(" ",$val); hex($a[0])." 0 ".hex($a[1])." ".hex($a[2])." 0 0"', @@ -1648,7 +1675,7 @@ my %indexInfo = ( Writable => 'int8u', Count => 6, Notes => q{ - 6 numbers: 0. Make, 1. Unknown, 2. Model, 3. Sub-model, 4-5. Unknown. Only + 6 numbers: 1. Make, 2. Unknown, 3. Model, 4. Sub-model, 5-6. Unknown. Only the Make and Model are used to identify the extender }, ValueConv => 'my @a=split(" ",$val); sprintf("%x %.2x",@a[0,2])', @@ -1680,6 +1707,7 @@ my %indexInfo = ( 0 => 'None', 2 => 'Simple E-System', 3 => 'E-System', + 4 => 'E-System (body powered)', #forum9740 }, }, 0x1001 => { #6 @@ -1697,6 +1725,8 @@ my %indexInfo = ( 7 => 'FL-36R', #11 9 => 'FL-14', #11 11 => 'FL-600R', #11 + 13 => 'FL-LM3', #forum9740 + 15 => 'FL-900R', #7 }, }, 0x1002 => { #6 @@ -2448,7 +2478,7 @@ my %indexInfo = ( 3 => 'Bottom to Top', 4 => 'Top to Bottom', ); - return ($a{$a} || "Unknown ($a)") . ', Shot ' . $b; + return(($a{$a} || "Unknown ($a)") . ', Shot ' . $b); }, }, 0x603 => { #PH/4 @@ -2481,10 +2511,29 @@ my %indexInfo = ( Count => 2, PrintConv => { '0 0' => 'No', + '3 2' => 'ND2 (1EV)', #IB + '3 4' => 'ND4 (2EV)', #IB + '3 8' => 'ND8 (3EV)', #IB + '3 16' => 'ND16 (4EV)', #IB + '3 32' => 'ND32 (5EV)', #IB '5 4' => 'HDR1', #forum8906 '6 4' => 'HDR2', #forum8906 - #'8 8' - seen this for the E-M1mkII + '8 8' => 'Tripod high resolution', #IB + '9 2' => 'Focus-stacked (2 images)', #IB + '9 3' => 'Focus-stacked (3 images)', #IB + '9 4' => 'Focus-stacked (4 images)', #IB + '9 5' => 'Focus-stacked (5 images)', #IB + '9 6' => 'Focus-stacked (6 images)', #IB + '9 7' => 'Focus-stacked (7 images)', #IB '9 8' => 'Focus-stacked (8 images)', + '9 9' => 'Focus-stacked (9 images)', #IB + '9 10' => 'Focus-stacked (10 images)', #IB + '9 11' => 'Focus-stacked (11 images)', #IB + '9 12' => 'Focus-stacked (12 images)', #IB + '9 13' => 'Focus-stacked (13 images)', #IB + '9 14' => 'Focus-stacked (14 images)', #IB + '9 15' => 'Focus-stacked (15 images)', #IB + '11 16' => 'Hand-held high resolution', #IB }, }, 0x900 => { #11 @@ -3161,7 +3210,7 @@ my %indexInfo = ( Writable => 'int16s', RawConv => '($val and $val ne "-32768") ? $val : undef', # ignore 0 and -32768 # ValueConv => '-2*(($val/135)**2)+55', #11 - ValueConv => '84 - 3 * $val / 26', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5423.0.html + ValueConv => '84 - 3 * $val / 26', #https://exiftool.org/forum/index.php/topic,5423.0.html ValueConvInv => 'int((84 - $val) * 26 / 3 + 0.5)', PrintConv => 'sprintf("%.1f C",$val)', PrintConvInv => '$val=~s/ ?C$//; $val', @@ -3668,6 +3717,7 @@ my %indexInfo = ( }, 0x7f => { Name => 'DateTimeOriginal', #(NC) + Description => 'Date/Time Original', Format => 'string[24]', Groups => { 2 => 'Time' }, PrintConv => '$self->ConvertDateTime($val)', @@ -3871,6 +3921,17 @@ my %indexInfo = ( Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ZoomedPreviewImage"); }, }, + # this is actually for PanasonicRaw tags, but it uses the lens lookup here + LensType => { + Require => { + 0 => 'LensTypeMake', + 1 => 'LensTypeModel', + }, + Notes => 'based on tags found in some Panasonic RW2 images', + SeparateTable => 'LensType', + ValueConv => '"$val[0] $val[1]"', + PrintConv => \%olympusLensTypes, + }, ); # add our composite tags @@ -3898,7 +3959,7 @@ sub ExtenderStatus($$$) $lensType =~ / F(\d+(\.\d+)?)/ or return 1; # If the maximum aperture at the maximum focal length is greater than the # known max/max aperture of the lens, then the extender must be attached - return ($maxAperture - $1 > 0.2) ? 1 : 2; + return(($maxAperture - $1 > 0.2) ? 1 : 2); } #------------------------------------------------------------------------------ @@ -3979,7 +4040,7 @@ Olympus or Epson maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/OpenEXR.pm b/src/Image-ExifTool/lib/Image/ExifTool/OpenEXR.pm index cf1d67b5..2d2d2b3e 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/OpenEXR.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/OpenEXR.pm @@ -62,7 +62,7 @@ my %formatType = ( Groups => { 2 => 'Location' }, PrintConv => q{ $val = int($val * 10) / 10; - return ($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level"; + return(($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level"); }, }, aperture => { PrintConv => 'sprintf("%.1f",$val)' }, @@ -70,6 +70,7 @@ my %formatType = ( chromaticities => { }, capDate => { Name => 'DateTimeOriginal', + Description => 'Date/Time Original', Groups => { 2 => 'Time' }, PrintConv => '$self->ConvertDateTime($val)', }, @@ -158,7 +159,7 @@ sub ProcessEXR($$) my $raf = $$dirInfo{RAF}; my $verbose = $et->Options('Verbose'); my $binary = $et->Options('Binary') || $verbose; - my ($buff, $buf2, $dim); + my ($buff, $dim); # verify this is a valid RIFF file return 0 unless $raf->Read($buff, 8) == 8; @@ -196,7 +197,7 @@ sub ProcessEXR($$) $name = 'Invalid'; } } - $tagInfo = { Name => $name, WasAdded => 1 }; + $tagInfo = { Name => $name }; AddTagToTable($tagTablePtr, $tag, $tagInfo); $et->VPrint(0, $$et{INDENT}, "[adding $tag]\n"); } @@ -301,7 +302,7 @@ information from OpenEXR images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Opus.pm b/src/Image-ExifTool/lib/Image/ExifTool/Opus.pm new file mode 100644 index 00000000..c5508e76 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Opus.pm @@ -0,0 +1,98 @@ +#------------------------------------------------------------------------------ +# File: Opus.pm +# +# Description: Read Ogg Opus audio meta information +# +# Revisions: 2016/07/14 - P. Harvey Created +# +# References: 1) https://www.opus-codec.org/docs/ +# 2) https://wiki.xiph.org/OggOpus +# 3) https://tools.ietf.org/pdf/rfc7845.pdf +#------------------------------------------------------------------------------ + +package Image::ExifTool::Opus; + +use strict; +use vars qw($VERSION); + +$VERSION = '1.00'; + +# Opus metadata types +%Image::ExifTool::Opus::Main = ( + NOTES => q{ + Information extracted from Ogg Opus files. See + L<https://www.opus-codec.org/docs/> for the specification. + }, + 'OpusHead' => { + Name => 'Header', + SubDirectory => { TagTable => 'Image::ExifTool::Opus::Header' }, + }, + 'OpusTags' => { + Name => 'Comments', + SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' }, + }, +); + +%Image::ExifTool::Opus::Header = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Audio' }, + 0 => 'OpusVersion', + 1 => 'AudioChannels', + # 2 => 'PreSkip' (int16u) + 4 => { + Name => 'SampleRate', + Format => 'int32u', + }, + 8 => { + Name => 'OutputGain', + Format => 'int16u', + ValueConv => '10 ** ($val/5120)', + }, +); + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Opus - Read Ogg Opus audio meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to extract meta +information from Ogg Opus audio files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://www.opus-codec.org/docs/> + +=item L<https://wiki.xiph.org/OggOpus> + +=item L<https://tools.ietf.org/pdf/rfc7845.pdf> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/Opus Tags>, +L<Image::ExifTool::TagNames/Ogg Tags>, +L<Image::ExifTool::TagNames/Vorbis Tags>, +L<Image::ExifTool::TagNames/FLAC Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PCX.pm b/src/Image-ExifTool/lib/Image/ExifTool/PCX.pm new file mode 100644 index 00000000..7e4d746a --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/PCX.pm @@ -0,0 +1,138 @@ +#------------------------------------------------------------------------------ +# File: PCX.pm +# +# Description: Read metadata from PC Paintbrush files +# +# Revisions: 2018/12/12 - P. Harvey Created +# +# References: 1) http://qzx.com/pc-gpe/pcx.txt +# 2) https://www.fileformat.info/format/pcx/corion.htm +#------------------------------------------------------------------------------ + +package Image::ExifTool::PCX; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.00'; + +# PCX info +%Image::ExifTool::PCX::Main = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' }, + NOTES => 'Tags extracted from PC Paintbrush images.', + DATAMEMBER => [ 0x04, 0x05 ], + 0x00 => { + Name => 'Manufacturer', + PrintConv => { 10 => 'ZSoft' }, + }, + 0x01 => { + Name => 'Software', + PrintConv => { + 0 => 'PC Paintbrush 2.5', + 2 => 'PC Paintbrush 2.8 (with palette)', + 3 => 'PC Paintbrush 2.8 (without palette)', + 4 => 'PC Paintbrush for Windows', + 5 => 'PC Paintbrush 3.0+', + }, + }, + 0x02 => { Name => 'Encoding', PrintConv => { 1 => 'RLE' } }, + 0x03 => 'BitsPerPixel', + 0x04 => { + Name => 'LeftMargin', + Format => 'int16u', + RawConv => '$$self{LeftMargin} = $val', + }, + 0x06 => { + Name => 'TopMargin', + Format => 'int16u', + RawConv => '$$self{TopMargin} = $val', + }, + 0x08 => { + Name => 'ImageWidth', + Format => 'int16u', + Notes => 'adjusted for LeftMargin', + ValueConv => '$val - $$self{LeftMargin} + 1', + }, + 0x0a => { + Name => 'ImageHeight', + Format => 'int16u', + Notes => 'adjusted for TopMargin', + ValueConv => '$val - $$self{TopMargin} + 1', + }, + 0x0c => 'XResolution', + 0x0e => 'YResolution', + 0x41 => 'ColorPlanes', + 0x42 => { Name => 'BytesPerLine', Format => 'int16u' }, + 0x44 => { + Name => 'ColorMode', + PrintConv => { + 0 => 'n/a', + 1 => 'Color Palette', + 2 => 'Grayscale', + }, + }, + 0x46 => { Name => 'ScreenWidth', Format => 'int16u', RawConv => '$val or undef' }, + 0x48 => { Name => 'ScreenHeight', Format => 'int16u', RawConv => '$val or undef' }, +); + +#------------------------------------------------------------------------------ +# Extract information from a PCX image +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid PCX file +sub ProcessPCX($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my $buff; + return 0 unless $raf->Read($buff, 0x50) == 0x50 and + $buff =~ /^\x0a[\0-\x05]\x01[\x01\x02\x04\x08].{64}[\0-\x02]/s; + SetByteOrder('II'); + $et->SetFileType(); + my %dirInfo = ( DirName => 'PCX', DataPt => \$buff ); + my $tagTablePtr = GetTagTable('Image::ExifTool::PCX::Main'); + return $et->ProcessBinaryData(\%dirInfo, $tagTablePtr); +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::PCX - Read metadata from PC Paintbrush files + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains routines required by Image::ExifTool to extract +information from PC Paintbrush (PCX) files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<http://qzx.com/pc-gpe/pcx.txt> + +=item L<https://www.fileformat.info/format/pcx/corion.htm> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/PCX Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PDF.pm b/src/Image-ExifTool/lib/Image/ExifTool/PDF.pm index 2dd97200..75b97423 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PDF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PDF.pm @@ -21,7 +21,7 @@ use vars qw($VERSION $AUTOLOAD $lastFetched); use Image::ExifTool qw(:DataAccess :Utils); require Exporter; -$VERSION = '1.46'; +$VERSION = '1.49'; sub FetchObject($$$$); sub ExtractObject($$;$$); @@ -95,7 +95,7 @@ my %supportedFilter = ( WRITABLE => 'string', # set PRIORITY to 0 so most recent Info dictionary takes precedence # (Acrobat Pro bug? doesn't use same object/generation number for - # new Info dictionary when doing incrmental update) + # new Info dictionary when doing incremental update) PRIORITY => 0, NOTES => q{ As well as the tags listed below, the PDF specification allows for @@ -271,6 +271,13 @@ my %supportedFilter = ( %Image::ExifTool::PDF::ColorSpace = ( DefaultRGB => { SubDirectory => { TagTable => 'Image::ExifTool::PDF::DefaultRGB' }, + ConvertToDict => 1, # (not seen yet, but just in case) + }, + DefaultCMYK => { + SubDirectory => { TagTable => 'Image::ExifTool::PDF::DefaultRGB' }, + # hack: this is stored as an array instead of a dictionary in my + # sample, so convert to a dictionary to extract the ICCBased element + ConvertToDict => 1, }, Cs1 => { SubDirectory => { TagTable => 'Image::ExifTool::PDF::Cs1' }, @@ -303,7 +310,7 @@ my %supportedFilter = ( EXTRACT_UNKNOWN => 0, # extract known but numbered tags (Im1, Im2, etc) Im => { Notes => q{ - the ExtractEmbedded option enables information to be extracted from these + the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option enables information to be extracted from these embedded images }, SubDirectory => { TagTable => 'Image::ExifTool::PDF::Im' }, @@ -313,7 +320,7 @@ my %supportedFilter = ( # tags in PDF Im# dictionary %Image::ExifTool::PDF::Im = ( NOTES => q{ - Information extracted from embedded images with the ExtractEmbedded option. + Information extracted from embedded images with the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option. The EmbeddedImage and its metadata are extracted only for JPEG and Jpeg2000 image formats. }, @@ -337,7 +344,7 @@ my %supportedFilter = ( EXTRACT_UNKNOWN => 0, # extract known but numbered tags (MC0, MC1, etc) MC => { Notes => q{ - the ExtractEmbedded option enables information to be extracted from these + the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option enables information to be extracted from these embedded metadata dictionaries }, SubDirectory => { TagTable => 'Image::ExifTool::PDF::MC' }, @@ -397,7 +404,7 @@ my %supportedFilter = ( }, AIPrivateData => { Notes => q{ - the ExtractEmbedded option enables information to be extracted from embedded + the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option enables information to be extracted from embedded PostScript documents in the AIPrivateData# and AIPDFPrivateData# streams }, JoinStreams => 1, # join streams from numbered tags and process as one @@ -684,6 +691,41 @@ sub LocateObject($$) return $offset; } +#------------------------------------------------------------------------------ +# Check that the correct object is located at the specified file offset +# Inputs: 0) ExifTool ref, 1) object name, 2) object reference string, 3) file offset +# Returns: first non-blank line at start of object, or undef on error +sub CheckObject($$$$) +{ + my ($et, $tag, $ref, $offset) = @_; + my ($data, $obj, $dat, $pat); + + my $raf = $$et{RAF}; + $raf->Seek($offset+$$et{PDFBase}, 0) or $et->Warn("Bad $tag offset"), return undef; + # verify that we are reading the expected object + $raf->ReadLine($data) or $et->Warn("Error reading $tag data"), return undef; + ($obj = $ref) =~ s/R/obj/; + unless ($data =~ s/^$obj//) { + # handle cases where other whitespace characters are used in the object ID string + while ($data =~ /^\d+(\s+\d+)?\s*$/) { + $raf->ReadLine($dat); + $data .= $dat; + } + ($pat = $obj) =~ s/ /\\s+/g; + unless ($data =~ s/$pat//) { + $tag = ucfirst $tag; + $et->Warn("$tag object ($obj) not found at offset $offset"); + return undef; + } + } + # read the first line of data from the object (ignoring blank lines and comments) + for (;;) { + last if $data =~ /\S/ and $data !~ /^\s*%/; + $raf->ReadLine($data) or $et->Warn("Error reading $tag data"), return undef; + } + return $data; +} + #------------------------------------------------------------------------------ # Fetch indirect object from file (from inside a stream if required) # Inputs: 0) ExifTool object reference, 1) object reference string, @@ -737,7 +779,7 @@ sub FetchObject($$$$) return undef; } # extract the object at the specified index in the stream - # (offsets in table are in sequential order, so we can subract from + # (offsets in table are in sequential order, so we can subtract from # the next offset to get the object length) $offset = $$table[$i + 1]; my $len = ($$table[$i + 3] || length($$obj{_stream})) - $offset; @@ -746,21 +788,11 @@ sub FetchObject($$$$) undef $lastFetched if $cryptStream; return ExtractObject($et, \$data); } - my $raf = $$et{RAF}; - $raf->Seek($offset+$$et{PDFBase}, 0) or $et->Warn("Bad $tag offset"), return undef; - # verify that we are reading the expected object - $raf->ReadLine($data) or $et->Warn("Error reading $tag data"), return undef; - ($obj = $ref) =~ s/R/obj/; - unless ($data =~ s/^$obj//) { - $et->Warn("$tag object ($obj) not found at $offset"); - return undef; - } - # read the first line of data for the object (skipping comments if necessary) - for (;;) { - last if $data =~ /\S/ and $data !~ /^\s*%/; - $raf->ReadLine($data) or $et->Warn("Error reading $tag data"), return undef; - } - return ExtractObject($et, \$data, $raf, $xref); + # load the start of the object + $data = CheckObject($et, $tag, $ref, $offset); + return undef unless defined $data; + + return ExtractObject($et, \$data, $$et{RAF}, $xref); } #------------------------------------------------------------------------------ @@ -948,22 +980,11 @@ sub ExtractObject($$;$$) # get the location of the object specifying the length # (compressed objects are not allowed) my $offset = LocateObject($xref, $length) or return $dict; - $offset or $et->Warn('Bad Length object'), return $dict; - $raf->Seek($offset+$$et{PDFBase}, 0) or $et->Warn('Bad Length offset'), return $dict; - # verify that we are reading the expected object - $raf->ReadLine($data) or $et->Warn('Error reading Length data'), return $dict; - $length =~ s/R/obj/; - unless ($data =~ /^$length\s+(\d+)?/) { - $et->Warn("Length object ($length) not found at $offset"); - return $dict; - } - if (defined $1) { - $length = $1; - } else { - $raf->ReadLine($data) or $et->Warn('Error reading stream Length'), return $dict; - $data =~ /^\s*(\d+)/ or $et->Warn('Stream length not found'), return $dict; - $length = $1; - } + $offset or $et->Warn('Bad stream Length object'), return $dict; + $data = CheckObject($et, 'stream Length', $length, $offset); + defined $data or return $dict; + $data =~ /^\s*(\d+)/ or $et->Warn('Stream Length not found'), return $dict; + $length = $1; $raf->Seek($oldpos, 0); # restore position to start of stream } # extract the trailing stream data @@ -1869,7 +1890,15 @@ sub ProcessDict($$$$;$$) # process the subdirectory my @subDicts; if (ref $val eq 'ARRAY') { - @subDicts = @{$val}; + # hack to convert array to dictionary if necessary + if ($$tagInfo{ConvertToDict} and @$val == 2 and not ref $$val[0]) { + my $tg = $$val[0]; + $tg =~ s(^/)(); # remove name + my %dict = ( _tags => [ $tg ], $tg => $$val[1] ); + @subDicts = ( \%dict ); + } else { + @subDicts = @{$val}; + } } else { @subDicts = ( $val ); } @@ -2089,7 +2118,7 @@ sub ReadPDF($$) $$et{PDFBase} = length $1 and $et->Warn('PDF header is not at start of file',1); $pdfVer = $2; $et->SetFileType(); # set the FileType tag - $et->Warn("May not be able to read a PDF version $pdfVer file") if $pdfVer >= 2.0; + $et->Warn("The PDF $pdfVer specification is held hostage by the ISO") if $pdfVer >= 2.0; # store PDFVersion tag my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Root'); $et->HandleTag($tagTablePtr, 'Version', $pdfVer); @@ -2174,6 +2203,9 @@ XRef: $raf->Read($buff, 20) == 20 or return -6; $buff =~ /^\s*(\d{10}) (\d{5}) (f|n)/s or return -4; my $num = $start + $i; + # locate object to generate entry from stream if necessary + # (must do this before we test $xref{$num}) + LocateAnyObject(\%xref, $num) if $xref{dicts}; # save offset for newest copy of all objects # (or next object number for free objects) unless (defined $xref{$num}) { @@ -2346,7 +2378,7 @@ including AESV2 (AES-128) and AESV3 (AES-256). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PGF.pm b/src/Image-ExifTool/lib/Image/ExifTool/PGF.pm index 8c525378..f56f1a7f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PGF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PGF.pm @@ -119,7 +119,7 @@ information from Progressive Graphics File (PGF) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PICT.pm b/src/Image-ExifTool/lib/Image/ExifTool/PICT.pm index 776883d8..873ccb0a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PICT.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PICT.pm @@ -1095,13 +1095,13 @@ sub ProcessPICT($$) @hdr = unpack('x2n5', $buff); $op = pop @hdr; # check for PICT version 1 format - if ($op eq 0x1101) { + if ($op == 0x1101) { $vers = 1; undef $extended; last; } # check for PICT version 2 format - if ($op eq 0x0011) { + if ($op == 0x0011) { $raf->Read($buff, 28) == 28 or return 0; if ($buff =~ /^\x02\xff\x0c\x00\xff\xff/) { $vers = 2; @@ -1174,7 +1174,7 @@ sub ProcessPICT($$) } last unless $tagInfo; } - if ($op eq 0xff) { + if ($op == 0xff) { $verbose and print $out "End of picture\n"; $success = 1; last; @@ -1236,7 +1236,7 @@ Verbose or the Unknown option. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PLIST.pm b/src/Image-ExifTool/lib/Image/ExifTool/PLIST.pm index 53dfcfe8..c014895c 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PLIST.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PLIST.pm @@ -438,7 +438,7 @@ This module decodes both the binary and XML-based PLIST format. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PLUS.pm b/src/Image-ExifTool/lib/Image/ExifTool/PLUS.pm new file mode 100644 index 00000000..4c60e641 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/PLUS.pm @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------------------ +# File: PLUS.pm +# +# Description: PLUS (Picture Licensing Universal System) tags +# +# Revisions: 2016/05/18 - P. Harvey Created +# +# References: 1) http://www.useplus.com/useplus/standards.asp +#------------------------------------------------------------------------------ + +package Image::ExifTool::PLUS; + +use strict; +use vars qw($VERSION); +use Image::ExifTool::XMP; + +$VERSION = '1.00'; + +sub ValidateMediaSummary($); + +#------------------------------------------------------------------------------ +# PLUS (Picture Licensing Universal System) + +# PLUS vocabulary conversions +my %plusVocab = ( + ValueConv => '$val =~ s{http://ns.useplus.org/ldf/vocab/}{}; $val', + ValueConvInv => '"http://ns.useplus.org/ldf/vocab/$val"', +); + +# PLUS License Data Format 1.2.1 structures +# (this seems crazy to me -- why did they define different ID/Name structures +# for each field rather than just re-using the same structure?) +my %plusLicensee = ( + STRUCT_NAME => 'Licensee', + NAMESPACE => 'plus', + # all "rdf:type" properties removed in version 1.2.1 + # (idiots. Why did they put them there in the first place? -- it required + # a special patch for ExifTool to support these, and now they are gone!) + # TYPE => 'plus:LicenseeDetail', (removed in 1.2.1) + LicenseeID => { }, + LicenseeName=> { }, +); +my %plusEndUser = ( + STRUCT_NAME => 'EndUser', + NAMESPACE => 'plus', + # TYPE => 'plus:EndUserDetail', (removed in 1.2.1) + EndUserID => { }, + EndUserName => { }, +); +my %plusLicensor = ( + STRUCT_NAME => 'Licensor', + NAMESPACE => 'plus', + # TYPE => 'plus:LicensorDetail', (removed in 1.2.1) + LicensorID => { }, + LicensorName => { }, + LicensorStreetAddress => { }, + LicensorExtendedAddress => { }, + LicensorCity => { }, + LicensorRegion => { }, + LicensorPostalCode => { }, + LicensorCountry => { }, + LicensorTelephoneType1 => { + %plusVocab, + PrintConv => { + 'work' => 'Work', + 'cell' => 'Cell', + 'fax' => 'FAX', + 'home' => 'Home', + 'pager' => 'Pager', + }, + }, + LicensorTelephone1 => { }, + LicensorTelephoneType2 => { + %plusVocab, + PrintConv => { + 'work' => 'Work', + 'cell' => 'Cell', + 'fax' => 'FAX', + 'home' => 'Home', + 'pager' => 'Pager', + }, + }, + LicensorTelephone2 => { }, + LicensorEmail => { }, + LicensorURL => { }, +); +my %plusCopyrightOwner = ( + STRUCT_NAME => 'CopyrightOwner', + NAMESPACE => 'plus', + # TYPE => 'plus:CopyrightOwnerDetail', (removed in 1.2.1) + CopyrightOwnerID => { }, + CopyrightOwnerName => { }, +); +my %plusImageCreator = ( + STRUCT_NAME => 'ImageCreator', + NAMESPACE => 'plus', + # TYPE => 'plus:ImageCreatorDetail', (removed in 1.2.1) + ImageCreatorID => { }, + ImageCreatorName => { }, +); +my %plusImageSupplier = ( + STRUCT_NAME => 'ImageSupplier', + NAMESPACE => 'plus', + # TYPE => 'plus:ImageSupplierDetail', (removed in 1.2.1) + ImageSupplierID => { }, + ImageSupplierName => { }, +); + +# Media Matrix 1.1.1 decoding +my %mediaMatrix = ( + Notes => q{ + The lookup below is used to add human-readable descriptions to Media Matrix + ID's in PLUS Media Summary Codes. + }, + OTHER => sub { + my ($val, $inv, $conv) = @_; + $val = uc $val; # convert to upper case + if ($inv) { + # prepare MediaSummaryCode for writing + $val =~ s/\(.*?\)//sg; # remove descriptions + $val =~ s/^\s*?PLUS\s+(V[0-9]+)\s+(U[0-9]+)\s*;/|PLUS|$1|$2|/s; # reformat header + $val =~ tr/;/|/; # use "|" as separator instead of ";" + $val =~ tr/0-9A-Z|//dc; # remove extraneous characters + $val .= '|' unless $val =~ /\|$/; # add terminating "|" + ValidateMediaSummary($val) or return undef; + } elsif ($val =~ /^\|PLUS\|(.*?)\|(.*?)\|(.*)/s) { + # add human-readable descriptions + my ($ver,$num,$code) = ($1,$2,$3); + $ver .= " (LDF Version $1.$2)" if $ver =~ /V0*(\d+)(\d{2})$/; + $num .= " ($1 Media Usages:)" if $num =~ /U0*(\d+)/; + $code =~ tr/0-9A-Z|//dc; # remove extraneous characters + $val = "PLUS $ver $num"; + while ($code =~ /(\d[A-Z]{3})/g) { + my $mmid = $1; + if (defined $$conv{$mmid}) { + $val .= " $mmid ($$conv{$mmid})"; + } elsif ($mmid =~ /^1I([A-Z])([A-Z])/) { # decode Usage Item count + my $n = (ord($1)-65) * 26 + ord($2)-65 + 1; + # (add a separator before each new Media Usage Code) + $val .= "; $mmid ($n Usage Items:)"; + } elsif ($mmid =~ /^1UN([A-Z])/) { # decode Usage Number + $val .= " (Usage Number $1)"; + } else { + $val .= " $mmid"; + } + } + } + return $val; + }, + # 1 - Usage + '1IAA' => '1 Usage Item:', + '1IAB' => '2 Usage Items:', + '1IAC' => '3 Usage Items:', + '1IAD' => '4 Usage Items:', + '1IAE' => '5 Usage Items:', + # ... + '1UNA' => 'Usage Number A', + '1UNB' => 'Usage Number B', + '1UNC' => 'Usage Number C', + '1UND' => 'Usage Number D', + '1UNE' => 'Usage Number E', + # ... + # 2 - Media + '2BOB' => 'Advertising|Periodicals|Magazine, Consumer|Printed', + '2ACE' => 'Advertising|Periodicals|Magazine, Consumer|Internet Website', + '2GEN' => 'Advertising|Periodicals|Magazine, Consumer|Internet Downloadable File', + '2ADS' => 'Advertising|Periodicals|Magazine, Consumer|Internet Email', + '2GIB' => 'Advertising|Periodicals|Magazine, Consumer|All Internet Distribution Formats', + '2GHI' => 'Advertising|Periodicals|Magazine, Consumer|Recordable Media', + '2GEY' => 'Advertising|Periodicals|Magazine, Consumer|All Electronic Distribution Formats', + '2HAT' => 'Advertising|Periodicals|Magazine, Trade|Printed', + '2HAG' => 'Advertising|Periodicals|Magazine, Trade|Internet Website', + '2HAE' => 'Advertising|Periodicals|Magazine, Trade|Internet Downloadable File', + '2AFT' => 'Advertising|Periodicals|Magazine, Trade|Internet Email', + '2HAJ' => 'Advertising|Periodicals|Magazine, Trade|All Internet Distribution Formats', + '2AGE' => 'Advertising|Periodicals|Magazine, Trade|Recordable Media', + '2HAH' => 'Advertising|Periodicals|Magazine, Trade|All Electronic Distribution Formats', + '2JAR' => 'Advertising|Periodicals|Magazine, Corporate|Printed', + '2GIN' => 'Advertising|Periodicals|Magazine, Corporate|Internet Website', + '2GIE' => 'Advertising|Periodicals|Magazine, Corporate|Internet Downloadable File', + '2AGO' => 'Advertising|Periodicals|Magazine, Corporate|Internet Email', + '2GNU' => 'Advertising|Periodicals|Magazine, Corporate|All Internet Distribution Formats', + '2GIP' => 'Advertising|Periodicals|Magazine, Corporate|Recordable Media', + '2GIT' => 'Advertising|Periodicals|Magazine, Corporate|All Electronic Distribution Formats', + '2DEB' => 'Advertising|Periodicals|Magazine, Education|Printed', + '2GUM' => 'Advertising|Periodicals|Magazine, Education|Internet Website', + '2GUL' => 'Advertising|Periodicals|Magazine, Education|Internet Downloadable File', + '2AHA' => 'Advertising|Periodicals|Magazine, Education|Internet Email', + '2GYP' => 'Advertising|Periodicals|Magazine, Education|All Internet Distribution Formats', + '2GUV' => 'Advertising|Periodicals|Magazine, Education|Recordable Media', + '2GUY' => 'Advertising|Periodicals|Magazine, Education|All Electronic Distribution Formats', + '2CUS' => 'Advertising|Periodicals|Magazine, Custom Published|Printed', + '2GOR' => 'Advertising|Periodicals|Magazine, Custom Published|Internet Website', + '2GOS' => 'Advertising|Periodicals|Magazine, Custom Published|Internet Downloadable File', + '2AIL' => 'Advertising|Periodicals|Magazine, Custom Published|Internet Email', + '2GOX' => 'Advertising|Periodicals|Magazine, Custom Published|All Internet Distribution Formats', + '2ALP' => 'Advertising|Periodicals|Magazine, Custom Published|Recordable Media', + '2AMI' => 'Advertising|Periodicals|Magazine, Custom Published|All Electronic Distribution Formats', + '2BEN' => 'Advertising|Periodicals|Magazine, Advertorial|Printed', + '2BAP' => 'Advertising|Periodicals|Magazine, Advertorial|Internet Website', + '2BAM' => 'Advertising|Periodicals|Magazine, Advertorial|Internet Downloadable File', + '2BOP' => 'Advertising|Periodicals|Magazine, Advertorial|Internet Email', + '2GOB' => 'Advertising|Periodicals|Magazine, Advertorial|All Internet Distribution Formats', + '2DUH' => 'Advertising|Periodicals|Magazine, Advertorial|All Electronic Distribution Formats', + '2DUP' => 'Advertising|Periodicals|Magazine Reprints, All Types|Printed', + '2HAS' => 'Advertising|Periodicals|Magazine Reprints, All Types|Internet Website', + '2HAP' => 'Advertising|Periodicals|Magazine Reprints, All Types|Internet Downloadable File', + '2AMP' => 'Advertising|Periodicals|Magazine Reprints, All Types|Internet Email', + '2HEH' => 'Advertising|Periodicals|Magazine Reprints, All Types|All Internet Distribution Formats', + '2HAW' => 'Advertising|Periodicals|Magazine Reprints, All Types|Recordable Media', + '2HAY' => 'Advertising|Periodicals|Magazine Reprints, All Types|All Electronic Distribution Formats', + '2MOO' => 'Advertising|Periodicals|Magazine, All Types|Printed', + '2ANA' => 'Advertising|Periodicals|Magazine, All Types|Internet Website', + '2GOO' => 'Advertising|Periodicals|Magazine, All Types|Recordable Media', + '2ANY' => 'Advertising|Periodicals|Magazine, All Types|Internet Downloadable File', + '2APE' => 'Advertising|Periodicals|Magazine, All Types|Internet Email', + '2APT' => 'Advertising|Periodicals|Magazine, All Types|All Internet Distribution Formats', + '2ARK' => 'Advertising|Periodicals|Magazine, All Types|All Electronic Distribution Formats', + '2KEG' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|Printed', + '2HOB' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|Internet Website', + '2HOD' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|Internet Downloadable File', + '2ARM' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|Internet Email', + '2HMM' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|All Internet Distribution Formats', + '2HOE' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|Recordable Media', + '2HIS' => 'Advertising|Periodicals|Newspaper, Weekly Supplement|All Electronic Distribution Formats', + '2KEN' => 'Advertising|Periodicals|Newspaper, Tabloid|Printed', + '2HOY' => 'Advertising|Periodicals|Newspaper, Tabloid|Internet Website', + '2HUH' => 'Advertising|Periodicals|Newspaper, Tabloid|All Internet Distribution Formats', + '2ASH' => 'Advertising|Periodicals|Newspaper, Tabloid|Internet Downloadable File', + '2BAY' => 'Advertising|Periodicals|Newspaper, Tabloid|Internet Email', + '2HUE' => 'Advertising|Periodicals|Newspaper, Tabloid|Recordable Media', + '2HOW' => 'Advertising|Periodicals|Newspaper, Tabloid|All Electronic Distribution Formats', + '2NEW' => 'Advertising|Periodicals|Newspaper, All Types|Printed', + '2HID' => 'Advertising|Periodicals|Newspaper, All Types|Internet Website', + '2HIE' => 'Advertising|Periodicals|Newspaper, All Types|Internet Downloadable File', + '2BED' => 'Advertising|Periodicals|Newspaper, All Types|Internet Email', + '2HIC' => 'Advertising|Periodicals|Newspaper, All Types|All Internet Distribution Formats', + '2HIM' => 'Advertising|Periodicals|Newspaper, All Types|Recordable Media', + '2HEY' => 'Advertising|Periodicals|Newspaper, All Types|All Electronic Distribution Formats', + '2JAY' => 'Advertising|Periodicals|Newsletter, All Types|Printed', + '2HES' => 'Advertising|Periodicals|Newsletter, All Types|Internet Website', + '2HEP' => 'Advertising|Periodicals|Newsletter, All Types|Internet Downloadable File', + '2HEW' => 'Advertising|Periodicals|Newsletter, All Types|All Internet Distribution Formats', + '2BID' => 'Advertising|Periodicals|Newsletter, All Types|Internet Email', + '2HET' => 'Advertising|Periodicals|Newsletter, All Types|Recordable Media', + '2HEN' => 'Advertising|Periodicals|Newsletter, All Types|All Electronic Distribution Formats', + '2BAH' => 'Advertising|Periodicals|Quarterly Report|Printed', + '2HUT' => 'Advertising|Periodicals|Quarterly Report|Internet Website', + '2HUP' => 'Advertising|Periodicals|Quarterly Report|Internet Downloadable File', + '2BAL' => 'Advertising|Periodicals|Quarterly Report|Internet Email', + '2JEE' => 'Advertising|Periodicals|Quarterly Report|All Internet Distribution Formats', + '2HYP' => 'Advertising|Periodicals|Quarterly Report|Recordable Media', + '2JAG' => 'Advertising|Periodicals|Quarterly Report|All Electronic Distribution Formats', + '2ANN' => 'Advertising|Periodicals|Annual Report|Printed', + '2FON' => 'Advertising|Periodicals|Annual Report|Internet Website', + '2FOH' => 'Advertising|Periodicals|Annual Report|Internet Downloadable File', + '2FOP' => 'Advertising|Periodicals|Annual Report|Internet Email', + '2FOY' => 'Advertising|Periodicals|Annual Report|All Internet Distribution Formats', + '2BAS' => 'Advertising|Periodicals|Annual Report|Recordable Media', + '2FOU' => 'Advertising|Periodicals|Annual Report|All Electronic Distribution Formats', + '2KIP' => 'Advertising|Periodicals|Program Advertising|Printed', + '2DEE' => 'Advertising|Periodicals|Wrapper|Printed', + '2FUD' => 'Advertising|Periodicals|Cover Wrap|Printed', + '2FUB' => 'Advertising|Periodicals|Belly Band|Printed', + '2BAT' => 'Advertising|Periodicals|Free Standing Insert, All Insert Types|Printed', + '2HIP' => 'Advertising|Periodicals|Free Standing Insert, Advertorial Insert|Printed', + '2BAG' => 'Advertising|Periodicals|All Periodical Types|Printed', + '2FIZ' => 'Advertising|Periodicals|All Periodical Types|Internet Website', + '2BOD' => 'Advertising|Periodicals|All Periodical Types|Internet Downloadable File', + '2BOW' => 'Advertising|Periodicals|All Periodical Types|Internet Email', + '2FOB' => 'Advertising|Periodicals|All Periodical Types|All Internet Distribution Formats', + '2FIR' => 'Advertising|Periodicals|All Periodical Types|Recordable Media', + '2FLU' => 'Advertising|Periodicals|All Periodical Types|All Electronic Distribution Formats', + '2EDH' => 'Advertising|Marketing Materials|Artist\'s Reference, All Types|Printed', + '2ECU' => 'Advertising|Marketing Materials|Artist\'s Reference, All Types|All Internet Distribution Formats', + '2DOT' => 'Advertising|Marketing Materials|Artist\'s Reference, All Types|All Electronic Distribution Formats', + '2MMA' => 'Advertising|Marketing Materials|Bill Insert|Printed', + '2MMB' => 'Advertising|Marketing Materials|Blow In Card|Printed', + '2MMC' => 'Advertising|Marketing Materials|Bound-in Insert|Printed', + '2MMD' => 'Advertising|Marketing Materials|Broadside|Printed', + '2EGG' => 'Advertising|Marketing Materials|Brochure|Printed', + '2EFF' => 'Advertising|Marketing Materials|Brochure|Internet Downloadable File', + '2EFS' => 'Advertising|Marketing Materials|Brochure|Internet Email', + '2EFT' => 'Advertising|Marketing Materials|Brochure|Recordable Media', + '2MME' => 'Advertising|Marketing Materials|Buckslip|Printed', + '2MMF' => 'Advertising|Marketing Materials|Business Card|Printed', + '2MMG' => 'Advertising|Marketing Materials|Business Envelope|Printed', + '2BIZ' => 'Advertising|Marketing Materials|Card, Business Greeting Card|Printed', + '2MMI' => 'Advertising|Marketing Materials|Business Invitation|Printed', + '2MMJ' => 'Advertising|Marketing Materials|Business Reply Card|Printed', + '2MMK' => 'Advertising|Marketing Materials|Business Reply Envelope|Printed', + '2MML' => 'Advertising|Marketing Materials|Business Stationery|Printed', + '2FIG' => 'Advertising|Marketing Materials|Catalog|Printed', + '2ELL' => 'Advertising|Marketing Materials|Catalog|Internet Downloadable File', + '2ELS' => 'Advertising|Marketing Materials|Catalog|Internet Email', + '2ELF' => 'Advertising|Marketing Materials|Catalog|Recordable Media', + '2EDU' => 'Advertising|Marketing Materials|CD ROM|Recordable Media', + '2MMM' => 'Advertising|Marketing Materials|Compliment Slip|Printed', + '2MMN' => 'Advertising|Marketing Materials|Coupon|Printed', + '2EGO' => 'Advertising|Marketing Materials|Coupon|Internet Downloadable File', + '2ENG' => 'Advertising|Marketing Materials|Coupon|Internet Email', + '2ENS' => 'Advertising|Marketing Materials|Coupon|Recordable Media', + '2MMP' => 'Advertising|Marketing Materials|Coupon Packs|Printed', + '2DVA' => 'Advertising|Marketing Materials|DVD|Recordable Media', + '2MMQ' => 'Advertising|Marketing Materials|Flyaway Card|Printed', + '2FLY' => 'Advertising|Marketing Materials|Flyer|Printed', + '2MMR' => 'Advertising|Marketing Materials|Leaflet|Printed', + '2MMS' => 'Advertising|Marketing Materials|Magalog|Printed', + '2END' => 'Advertising|Marketing Materials|Magalog|Internet Downloadable File', + '2EON' => 'Advertising|Marketing Materials|Magalog|Internet Email', + '2FAX' => 'Advertising|Marketing Materials|Magalog|Recordable Media', + '2MMT' => 'Advertising|Marketing Materials|One Sheet|Printed', + '2MMU' => 'Advertising|Marketing Materials|Onsert|Printed', + '2MMV' => 'Advertising|Marketing Materials|Polybag|Printed', + '2BUN' => 'Advertising|Marketing Materials|Promo Card|Printed', + '2MMW' => 'Advertising|Marketing Materials|Promotional Calendar, One Page|Printed', + '2FAS' => 'Advertising|Marketing Materials|Promotional Calendar, One Page|Internet Downloadable File', + '2FAY' => 'Advertising|Marketing Materials|Promotional Calendar, One Page|Internet Email', + '2GUT' => 'Advertising|Marketing Materials|Promotional Calendar, One Page|Recordable Media', + '2EWE' => 'Advertising|Marketing Materials|Promotional Calendar, One Page|All Electronic Distribution Formats', + '2YAM' => 'Advertising|Marketing Materials|Promotional Calendar, Multi-Page|Printed', + '2ESS' => 'Advertising|Marketing Materials|Promotional Calendar, Multi-Page|Internet Downloadable File', + '2ETA' => 'Advertising|Marketing Materials|Promotional Calendar, Multi-Page|Internet Email', + '2HAD' => 'Advertising|Marketing Materials|Promotional Calendar, Multi-Page|Recordable Media', + '2FET' => 'Advertising|Marketing Materials|Promotional E-card|Internet Email', + '2FEU' => 'Advertising|Marketing Materials|Promotional E-card|All Internet Distribution Formats', + '2FEH' => 'Advertising|Marketing Materials|Promotional E-card|Recordable Media', + '2FEN' => 'Advertising|Marketing Materials|Promotional E-card|Internet Downloadable File', + '2MMX' => 'Advertising|Marketing Materials|Promotional Envelope|Printed', + '2NUT' => 'Advertising|Marketing Materials|Promotional Postcard|Printed', + '2KAF' => 'Advertising|Marketing Materials|Public Relations, Press Kit|Printed', + '2JUT' => 'Advertising|Marketing Materials|Public Relations, Press Kit|Internet Website', + '2JUN' => 'Advertising|Marketing Materials|Public Relations, Press Kit|Internet Downloadable File', + '2JUS' => 'Advertising|Marketing Materials|Public Relations, Press Kit|Internet Email', + '2JOW' => 'Advertising|Marketing Materials|Public Relations, Press Kit|All Internet Distribution Formats', + '2JOB' => 'Advertising|Marketing Materials|Public Relations, Press Kit|Recordable Media', + '2JOE' => 'Advertising|Marketing Materials|Public Relations, Press Kit|All Electronic Distribution Formats', + '2KAB' => 'Advertising|Marketing Materials|Public Relations, Press Kit|Television Broadcast', + '2KEX' => 'Advertising|Marketing Materials|Public Relations, Press Release|Printed', + '2KEA' => 'Advertising|Marketing Materials|Public Relations, Press Release|Internet Website', + '2KAT' => 'Advertising|Marketing Materials|Public Relations, Press Release|Internet Downloadable File', + '2KAY' => 'Advertising|Marketing Materials|Public Relations, Press Release|Internet Email', + '2KAS' => 'Advertising|Marketing Materials|Public Relations, Press Release|Recordable Media', + '2KID' => 'Advertising|Marketing Materials|Public Relations, Press Release|All Electronic Distribution Formats', + '2KEF' => 'Advertising|Marketing Materials|Public Relations, Press Release|Television Broadcast', + '2JIB' => 'Advertising|Marketing Materials|Public Relations, All Types|Printed', + '2MMY' => 'Advertising|Marketing Materials|Sales Kit|Printed', + '2MMZ' => 'Advertising|Marketing Materials|Self Mailer|Printed', + '2JAM' => 'Advertising|Marketing Materials|All Marketing Material Types|Printed', + '2HAM' => 'Advertising|Marketing Materials|All Marketing Material Types|Internet Downloadable File', + '2DYE' => 'Advertising|Marketing Materials|All Marketing Material Types|Internet Email', + '2DUO' => 'Advertising|Marketing Materials|All Marketing Material Types|Recordable Media', + '2BEG' => 'Advertising|Book|Retail Book, Directory|Printed', + '2EAC' => 'Advertising|Book|Retail Book, Directory|E-Book in Internet Website', + '2EAD' => 'Advertising|Book|Retail Book, Directory|E-Book in Internet Downloadable File', + '2EAE' => 'Advertising|Book|Retail Book, Directory|All E-Book Internet Distribution Formats', + '2EAF' => 'Advertising|Book|Retail Book, Directory|E-Book on Recordable Media', + '2EAG' => 'Advertising|Book|Retail Book, Directory|All E-Book Distribution Formats', + '2ELM' => 'Advertising|Book|Textbook, All Types|Printed', + '2EAH' => 'Advertising|Book|Textbook, All Types|E-Book in Internet Website', + '2EAJ' => 'Advertising|Book|Textbook, All Types|E-Book in Internet Downloadable File', + '2EAK' => 'Advertising|Book|Textbook, All Types|All E-Book Internet Distribution Formats', + '2EAL' => 'Advertising|Book|Textbook, All Types|E-Book on Recordable Media', + '2EAM' => 'Advertising|Book|Textbook, All Types|All E-Book Distribution Formats', + '2HOG' => 'Advertising|Book|All Book Types|Printed', + '2EAN' => 'Advertising|Book|All Book Types|All E-Book Internet Distribution Formats', + '2EAP' => 'Advertising|Book|All Book Types|All E-Book Distribution Formats', + '2HEM' => 'Advertising|Display|Billboard, Bulletin|Printed', + '2BUR' => 'Advertising|Display|Billboard, Bulletin|Electronic Display', + '2DAG' => 'Advertising|Display|Billboard, Spectacular|Printed', + '2DAD' => 'Advertising|Display|Billboard, Spectacular|Electronic Display', + '2DAK' => 'Advertising|Display|Billboard, Wallscape|Printed', + '2DAH' => 'Advertising|Display|Billboard, Wallscape|Electronic Display', + '2DAB' => 'Advertising|Display|Billboard, Rotating Billboard|Printed', + '2BLD' => 'Advertising|Display|Billboard, Building Wrap|Printed', + '2BYS' => 'Advertising|Display|Billboard, Mobile Billboard|Printed', + '2BYE' => 'Advertising|Display|Billboard, Mobile Billboard|Electronic Display', + '2BIL' => 'Advertising|Display|Billboard, All Types|Printed', + '2BUD' => 'Advertising|Display|Billboard, All Types|Electronic Display', + '2BRR' => 'Advertising|Display|Banner, Backdrop|Printed', + '2BUB' => 'Advertising|Display|Banner, Background|Printed', + '2BRA' => 'Advertising|Display|Banner, Airborne Display|Printed', + '2BRO' => 'Advertising|Display|Banner, All Types|Printed', + '2BAN' => 'Advertising|Display|Banner, All Types|Electronic Display', + '2CAR' => 'Advertising|Display|Shopping Cart|Printed', + '2CRT' => 'Advertising|Display|Shopping Cart|Electronic Display', + '2FAD' => 'Advertising|Display|Poster, Movie Poster|Printed', + '2HON' => 'Advertising|Display|Poster, Movie Poster|Electronic Display', + '2DIB' => 'Advertising|Display|Poster, Door Side Poster|Printed', + '2DEY' => 'Advertising|Display|Poster, Door Side Poster|Electronic Display', + '2DEV' => 'Advertising|Display|Poster, Corporate Poster|Printed', + '2DEN' => 'Advertising|Display|Poster, Corporate Poster|Electronic Display', + '2ELE' => 'Advertising|Display|Poster, Elevator Advertising|Printed', + '2DID' => 'Advertising|Display|Poster, Elevator Advertising|Electronic Display', + '2DRY' => 'Advertising|Display|Poster, Restroom Poster|Printed', + '2WET' => 'Advertising|Display|Poster, Restroom Poster|Electronic Display', + '2DEL' => 'Advertising|Display|Poster, Backlit Print|Printed', + '2DEX' => 'Advertising|Display|Poster, Display Chrome|Printed', + '2FAT' => 'Advertising|Display|Poster, All Types|Printed', + '2DAW' => 'Advertising|Display|Poster, All Types|Electronic Display', + '2MOB' => 'Advertising|Display|Store Display, In-Store Poster|Printed', + '2DIT' => 'Advertising|Display|Store Display, In-Store Poster|Electronic Display', + '2FOG' => 'Advertising|Display|Store Display, All Display Types|Printed', + '2DIN' => 'Advertising|Display|Store Display, All Display Types|Electronic Display', + '2HOT' => 'Advertising|Display|Terminal Advertising, Airport Display|Printed', + '2JOU' => 'Advertising|Display|Terminal Advertising, Airport Display|Electronic Display', + '2DOM' => 'Advertising|Display|Terminal Advertising, Bus Stop Advertising|Printed', + '2DOL' => 'Advertising|Display|Terminal Advertising, Bus Stop Advertising|Electronic Display', + '2DOR' => 'Advertising|Display|Terminal Advertising, Ferry Terminal Advertising|Printed', + '2DON' => 'Advertising|Display|Terminal Advertising, Ferry Terminal Advertising|Electronic Display', + '2TAN' => 'Advertising|Display|Terminal Advertising, Shelter Advertising|Printed', + '2DOS' => 'Advertising|Display|Terminal Advertising, Shelter Advertising|Electronic Display', + '2DUB' => 'Advertising|Display|Terminal Advertising, Station Poster|Printed', + '2DOW' => 'Advertising|Display|Terminal Advertising, Station Poster|Electronic Display', + '2DUG' => 'Advertising|Display|Terminal Advertising, Subway Terminal Advertising|Printed', + '2DUE' => 'Advertising|Display|Terminal Advertising, Subway Terminal Advertising|Electronic Display', + '2DUN' => 'Advertising|Display|Terminal Advertising, Train Terminal Advertising|Printed', + '2DUI' => 'Advertising|Display|Terminal Advertising, Train Terminal Advertising|Electronic Display', + '2JOY' => 'Advertising|Display|Terminal Advertising, All Types|Printed', + '2DOE' => 'Advertising|Display|Terminal Advertising, All Types|Electronic Display', + '2TAX' => 'Advertising|Display|Transit Advertising, Taxi Advertising|Printed', + '2BUS' => 'Advertising|Display|Transit Advertising, Bus Panel|Printed', + '2TRC' => 'Advertising|Display|Transit Advertising, Bus Panel|Electronic Display', + '2TRE' => 'Advertising|Display|Transit Advertising, Bus Poster|Printed', + '2BPE' => 'Advertising|Display|Transit Advertising, Bus Poster|Electronic Display', + '2TRG' => 'Advertising|Display|Transit Advertising, Bus Rear Display|Printed', + '2TRF' => 'Advertising|Display|Transit Advertising, Bus Rear Display|Electronic Display', + '2TRN' => 'Advertising|Display|Transit Advertising, Bus Wrap|Printed', + '2TRM' => 'Advertising|Display|Transit Advertising, Bus Wrap|Electronic Display', + '2TRJ' => 'Advertising|Display|Transit Advertising, Subway Advertising|Printed', + '2TRI' => 'Advertising|Display|Transit Advertising, Subway Advertising|Electronic Display', + '2TRL' => 'Advertising|Display|Transit Advertising, Train Advertising|Printed', + '2TRK' => 'Advertising|Display|Transit Advertising, Train Advertising|Electronic Display', + '2TRQ' => 'Advertising|Display|Transit Advertising, Commercial Vehicles|Printed', + '2TRR' => 'Advertising|Display|Transit Advertising, Commercial Vehicles|Electronic Display', + '2FER' => 'Advertising|Display|Transit Advertising, Ferry Advertising|Printed', + '2TRH' => 'Advertising|Display|Transit Advertising, Ferry Advertising|Electronic Display', + '2TRA' => 'Advertising|Display|Transit Advertising, All Types|Printed', + '2TRB' => 'Advertising|Display|Transit Advertising, All Types|Electronic Display', + '2DAM' => 'Advertising|Display|Event, Stadium Advertising|Printed', + '2DAL' => 'Advertising|Display|Event, Stadium Advertising|Electronic Display', + '2DIS' => 'Advertising|Display|Event, Trade Show Display|Printed', + '2DAP' => 'Advertising|Display|Event, Trade Show Display|Electronic Display', + '2BIG' => 'Advertising|Display|All Display Types|Printed', + '2BOG' => 'Advertising|Display|All Display Types|Electronic Display', + '2BOY' => 'Advertising|Art|Art Display, Display Print|Printed', + '2ART' => 'Advertising|Art|Art Display, All Art Types|Printed', + '2BEL' => 'Advertising|Art|Art Display, All Art Types|Internet Website', + '2BEY' => 'Advertising|Art|Art Display, All Art Types|All Internet Distribution Formats', + '2BOS' => 'Advertising|Art|Art Display, All Art Types|Electronic Display', + '2BIS' => 'Advertising|Art|Art Display, All Art Types|All Electronic Distribution Formats', + '2ADH' => 'Advertising|Point of Purchase|Adhesive Tag|Printed', + '2BOT' => 'Advertising|Point of Purchase|Bottlenecker|Printed', + '2CAS' => 'Advertising|Point of Purchase|Case Card|Printed', + '2COU' => 'Advertising|Point of Purchase|Counter Card|Printed', + '2BUY' => 'Advertising|Point of Purchase|Floor Graphic|Printed', + '2TAG' => 'Advertising|Point of Purchase|Hang Tag|Printed', + '2GYM' => 'Advertising|Point of Purchase|Kiosk, Interactive Kiosk|Printed', + '2GUN' => 'Advertising|Point of Purchase|Kiosk, Interactive Kiosk|Electronic Display', + '2JUG' => 'Advertising|Point of Purchase|Kiosk, Telephone Kiosk|Printed', + '2FIN' => 'Advertising|Point of Purchase|Kiosk, All Types|Printed', + '2KIO' => 'Advertising|Point of Purchase|Kiosk, All Types|Electronic Display', + '2MEN' => 'Advertising|Point of Purchase|Menu|Printed', + '2TAL' => 'Advertising|Point of Purchase|Shelf Talker|Printed', + '2TIN' => 'Advertising|Point of Purchase|Slip Case|Printed', + '2WAX' => 'Advertising|Point of Purchase|Table Tent|Printed', + '2BIN' => 'Advertising|Point of Purchase|All Point of Purchase Types|Printed', + '2BIB' => 'Advertising|Point of Purchase|All Point of Purchase Types|Electronic Display', + '2BAR' => 'Advertising|Point of Purchase|All Point of Purchase Types|All Electronic Distribution Formats', + '2MAR' => 'Advertising|Website|Web Page, Design Element|Internet Website', + '2MAX' => 'Advertising|Website|Web Page, Design Element|All Internet Distribution Formats', + '2MAS' => 'Advertising|Website|Web Page, Design Element|Recordable Media', + '2MAW' => 'Advertising|Website|Web Page, Design Element|All Electronic Distribution Formats', + '2MED' => 'Advertising|Website|Web Page, Web Banner Ad|Internet Website', + '2MEW' => 'Advertising|Website|Web Page, Web Banner Ad|All Internet Distribution Formats', + '2MEG' => 'Advertising|Website|Web Page, Web Banner Ad|Recordable Media', + '2MEM' => 'Advertising|Website|Web Page, Web Banner Ad|All Electronic Distribution Formats', + '2JWL' => 'Advertising|Website|Web Page, Web Interstitial Ad|Internet Website', + '2MIG' => 'Advertising|Website|Web Page, Web Interstitial Ad|All Internet Distribution Formats', + '2MIB' => 'Advertising|Website|Web Page, Web Interstitial Ad|Recordable Media', + '2MID' => 'Advertising|Website|Web Page, Web Interstitial Ad|All Electronic Distribution Formats', + '2WEB' => 'Advertising|Website|Web Page, All Types|Internet Website', + '2KUE' => 'Advertising|Website|Web Page, All Types|All Internet Distribution Formats', + '2MAC' => 'Advertising|Website|Web Page, All Types|Recordable Media', + '2MAE' => 'Advertising|Website|Web Page, All Types|All Electronic Distribution Formats', + '2MIL' => 'Advertising|Website|Webcast, All Types|Internet Website', + '2EMA' => 'Advertising|Email|All Email Types|Internet Email', + '2ZUS' => 'Advertising|Mobile|All Mobile Types|Mobile', + '2FUR' => 'Advertising|Live Presentation|Sales Presentation|Projected Display', + '2EYE' => 'Advertising|Live Presentation|Panel Presentation|Projected Display', + '2TOE' => 'Advertising|Live Presentation|Trade Show Presentation|Projected Display', + '2JAW' => 'Advertising|Live Presentation|Stage Performance|Projected Display', + '2EAR' => 'Advertising|Live Presentation|All Live Presentation Types|All Electronic Distribution Formats', + '2FID' => 'Advertising|Merchandise|Apparel, T-Shirts|Printed or Woven', + '2FEZ' => 'Advertising|Merchandise|Apparel, General Apparel|Printed or Woven', + '2FIE' => 'Advertising|Merchandise|Folder|Printed', + '2AAY' => 'Advertising|All Media Types|Promotional Reproduction of Licensed Usage in Context|All Distribution Formats', + '2AAA' => 'Advertising|All Media Types|All Formats|All Distribution Formats', + '2GEM' => 'Editorial|Periodicals|Magazine, Consumer|Printed', + '2GDW' => 'Editorial|Periodicals|Magazine, Consumer|Internet Website', + '2GDY' => 'Editorial|Periodicals|Magazine, Consumer|Internet Downloadable File', + '2KIN' => 'Editorial|Periodicals|Magazine, Consumer|Internet Email', + '2GEA' => 'Editorial|Periodicals|Magazine, Consumer|All Internet Distribution Formats', + '2GDV' => 'Editorial|Periodicals|Magazine, Consumer|Recordable Media', + '2GDZ' => 'Editorial|Periodicals|Magazine, Consumer|All Electronic Distribution Formats', + '2MOM' => 'Editorial|Periodicals|Magazine, Trade|Printed', + '2MOW' => 'Editorial|Periodicals|Magazine, Trade|Internet Website', + '2MUT' => 'Editorial|Periodicals|Magazine, Trade|Internet Downloadable File', + '2NAB' => 'Editorial|Periodicals|Magazine, Trade|Internet Email', + '2NAG' => 'Editorial|Periodicals|Magazine, Trade|All Internet Distribution Formats', + '2GFD' => 'Editorial|Periodicals|Magazine, Trade|Recordable Media', + '2NOB' => 'Editorial|Periodicals|Magazine, Trade|All Electronic Distribution Formats', + '2MAY' => 'Editorial|Periodicals|Magazine, Education|Printed', + '2GEP' => 'Editorial|Periodicals|Magazine, Education|Internet Website', + '2GEQ' => 'Editorial|Periodicals|Magazine, Education|Internet Downloadable File', + '2NOW' => 'Editorial|Periodicals|Magazine, Education|Internet Email', + '2GES' => 'Editorial|Periodicals|Magazine, Education|All Internet Distribution Formats', + '2GEK' => 'Editorial|Periodicals|Magazine, Education|Recordable Media', + '2GER' => 'Editorial|Periodicals|Magazine, Education|All Electronic Distribution Formats', + '2MOP' => 'Editorial|Periodicals|Magazine, Custom Published|Printed', + '2GEF' => 'Editorial|Periodicals|Magazine, Custom Published|Internet Website', + '2GEG' => 'Editorial|Periodicals|Magazine, Custom Published|Internet Downloadable File', + '2NUN' => 'Editorial|Periodicals|Magazine, Custom Published|Internet Email', + '2GEI' => 'Editorial|Periodicals|Magazine, Custom Published|All Internet Distribution Formats', + '2GEC' => 'Editorial|Periodicals|Magazine, Custom Published|Recordable Media', + '2GEH' => 'Editorial|Periodicals|Magazine, Custom Published|All Electronic Distribution Formats', + '2MEL' => 'Editorial|Periodicals|Magazine, Partworks|Printed', + '2GEV' => 'Editorial|Periodicals|Magazine, Partworks|Internet Website', + '2GEW' => 'Editorial|Periodicals|Magazine, Partworks|Internet Downloadable File', + '2TAB' => 'Editorial|Periodicals|Magazine, Partworks|Internet Email', + '2GFB' => 'Editorial|Periodicals|Magazine, Partworks|All Internet Distribution Formats', + '2GEZ' => 'Editorial|Periodicals|Magazine, Partworks|Recordable Media', + '2GFA' => 'Editorial|Periodicals|Magazine, Partworks|All Electronic Distribution Formats', + '2WIG' => 'Editorial|Periodicals|Scholarly Journal|Printed', + '2GGF' => 'Editorial|Periodicals|Scholarly Journal|Internet Website', + '2GGG' => 'Editorial|Periodicals|Scholarly Journal|Internet Downloadable File', + '2TAD' => 'Editorial|Periodicals|Scholarly Journal|Internet Email', + '2GGI' => 'Editorial|Periodicals|Scholarly Journal|All Internet Distribution Formats', + '2GGD' => 'Editorial|Periodicals|Scholarly Journal|Recordable Media', + '2GGH' => 'Editorial|Periodicals|Scholarly Journal|All Electronic Distribution Formats', + '2MAG' => 'Editorial|Periodicals|Magazine, All Types|Printed', + '2GDP' => 'Editorial|Periodicals|Magazine, All Types|Internet Website', + '2GDM' => 'Editorial|Periodicals|Magazine, All Types|Internet Downloadable File', + '2GDQ' => 'Editorial|Periodicals|Magazine, All Types|Internet Email', + '2GDT' => 'Editorial|Periodicals|Magazine, All Types|All Internet Distribution Formats', + '2GDR' => 'Editorial|Periodicals|Magazine, All Types|Recordable Media', + '2GDS' => 'Editorial|Periodicals|Magazine, All Types|All Electronic Distribution Formats', + '2JET' => 'Editorial|Periodicals|Newspaper, All Types|Printed', + '2GFN' => 'Editorial|Periodicals|Newspaper, All Types|Internet Website', + '2GFP' => 'Editorial|Periodicals|Newspaper, All Types|Internet Downloadable File', + '2TAJ' => 'Editorial|Periodicals|Newspaper, All Types|Internet Email', + '2GFR' => 'Editorial|Periodicals|Newspaper, All Types|All Internet Distribution Formats', + '2GFM' => 'Editorial|Periodicals|Newspaper, All Types|Recordable Media', + '2GFQ' => 'Editorial|Periodicals|Newspaper, All Types|All Electronic Distribution Formats', + '2TUB' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|Printed', + '2GFW' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|Internet Website', + '2GFY' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|Internet Downloadable File', + '2TAO' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|Internet Email', + '2GFV' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|All Internet Distribution Formats', + '2GFS' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|Recordable Media', + '2GFU' => 'Editorial|Periodicals|Newspaper, Weekly Supplement|All Electronic Distribution Formats', + '2FAN' => 'Editorial|Periodicals|Newspaper, Tabloid|Printed', + '2TEX' => 'Editorial|Periodicals|Newspaper, Tabloid|Internet Website', + '2GGA' => 'Editorial|Periodicals|Newspaper, Tabloid|Internet Downloadable File', + '2TIP' => 'Editorial|Periodicals|Newspaper, Tabloid|Internet Email', + '2TON' => 'Editorial|Periodicals|Newspaper, Tabloid|All Internet Distribution Formats', + '2TIE' => 'Editorial|Periodicals|Newspaper, Tabloid|Recordable Media', + '2TOT' => 'Editorial|Periodicals|Newspaper, Tabloid|All Electronic Distribution Formats', + '2TOM' => 'Editorial|Periodicals|Newsletter|Printed', + '2GFH' => 'Editorial|Periodicals|Newsletter|Internet Website', + '2GFI' => 'Editorial|Periodicals|Newsletter|Internet Downloadable File', + '2NEL' => 'Editorial|Periodicals|Newsletter|Internet Email', + '2GFK' => 'Editorial|Periodicals|Newsletter|All Internet Distribution Formats', + '2GFG' => 'Editorial|Periodicals|Newsletter|Recordable Media', + '2GFJ' => 'Editorial|Periodicals|Newsletter|All Electronic Distribution Formats', + '2BUG' => 'Editorial|Book|Retail Book, Children\'s Book|Printed', + '2EPC' => 'Editorial|Book|Retail Book, Children\'s Book|E-Book in Internet Website', + '2EBE' => 'Editorial|Book|Retail Book, Children\'s Book|E-Book in Internet Downloadable File', + '2EGB' => 'Editorial|Book|Retail Book, Children\'s Book|E-Book in Internet Email', + '2EKB' => 'Editorial|Book|Retail Book, Children\'s Book|All E-Book Internet Distribution Formats', + '2ERB' => 'Editorial|Book|Retail Book, Children\'s Book|E-Book on Recordable Media', + '2EGC' => 'Editorial|Book|Retail Book, Children\'s Book|All E-Book Distribution Formats', + '2TAE' => 'Editorial|Book|Retail Book, Coffee Table Book|Printed', + '2TAV' => 'Editorial|Book|Retail Book, Concept Book|Printed', + '2EPD' => 'Editorial|Book|Retail Book, Concept Book|E-Book in Internet Website', + '2EBF' => 'Editorial|Book|Retail Book, Concept Book|E-Book in Internet Downloadable File', + '2EGD' => 'Editorial|Book|Retail Book, Concept Book|E-Book in Internet Email', + '2EKC' => 'Editorial|Book|Retail Book, Concept Book|All E-Book Internet Distribution Formats', + '2ERC' => 'Editorial|Book|Retail Book, Concept Book|E-Book on Recordable Media', + '2EGE' => 'Editorial|Book|Retail Book, Concept Book|All E-Book Distribution Formats', + '2DIR' => 'Editorial|Book|Retail Book, Directory|Printed', + '2EPE' => 'Editorial|Book|Retail Book, Directory|E-Book in Internet Website', + '2EBG' => 'Editorial|Book|Retail Book, Directory|E-Book in Internet Downloadable File', + '2ERD' => 'Editorial|Book|Retail Book, Directory|E-Book on Recordable Media', + '2YEA' => 'Editorial|Book|Retail Book, Directory|All Electronic Distribution Formats', + '2EAB' => 'Editorial|Book|Retail Book, Directory|All E-Book Distribution Formats', + '2HAN' => 'Editorial|Book|Retail Book, Handbook|Printed', + '2EPF' => 'Editorial|Book|Retail Book, Handbook|E-Book in Internet Website', + '2EBH' => 'Editorial|Book|Retail Book, Handbook|E-Book in Internet Downloadable File', + '2EGH' => 'Editorial|Book|Retail Book, Handbook|E-Book in Internet Email', + '2EKD' => 'Editorial|Book|Retail Book, Handbook|All E-Book Internet Distribution Formats', + '2ERF' => 'Editorial|Book|Retail Book, Handbook|E-Book on Recordable Media', + '2EGJ' => 'Editorial|Book|Retail Book, Handbook|All E-Book Distribution Formats', + '2HIL' => 'Editorial|Book|Retail Book, Hi-lo Book|Printed', + '2EPG' => 'Editorial|Book|Retail Book, Hi-lo Book|E-Book in Internet Website', + '2EBI' => 'Editorial|Book|Retail Book, Hi-lo Book|E-Book in Internet Downloadable File', + '2EGK' => 'Editorial|Book|Retail Book, Hi-lo Book|E-Book in Internet Email', + '2EKE' => 'Editorial|Book|Retail Book, Hi-lo Book|All E-Book Internet Distribution Formats', + '2ERG' => 'Editorial|Book|Retail Book, Hi-lo Book|E-Book on Recordable Media', + '2EGL' => 'Editorial|Book|Retail Book, Hi-lo Book|All E-Book Distribution Formats', + '2WAB' => 'Editorial|Book|Retail Book, Illustrated Book|Printed', + '2EPH' => 'Editorial|Book|Retail Book, Illustrated Book|E-Book in Internet Website', + '2EBJ' => 'Editorial|Book|Retail Book, Illustrated Book|E-Book in Internet Downloadable File', + '2EGM' => 'Editorial|Book|Retail Book, Illustrated Book|E-Book in Internet Email', + '2EKF' => 'Editorial|Book|Retail Book, Illustrated Book|All E-Book Internet Distribution Formats', + '2ERH' => 'Editorial|Book|Retail Book, Illustrated Book|E-Book on Recordable Media', + '2EGN' => 'Editorial|Book|Retail Book, Illustrated Book|All E-Book Distribution Formats', + '2WHA' => 'Editorial|Book|Retail Book, Illustrated Guide|Printed', + '2EPJ' => 'Editorial|Book|Retail Book, Illustrated Guide|E-Book in Internet Website', + '2EBL' => 'Editorial|Book|Retail Book, Illustrated Guide|E-Book in Internet Downloadable File', + '2EGP' => 'Editorial|Book|Retail Book, Illustrated Guide|E-Book in Internet Email', + '2EKG' => 'Editorial|Book|Retail Book, Illustrated Guide|All E-Book Internet Distribution Formats', + '2ERI' => 'Editorial|Book|Retail Book, Illustrated Guide|E-Book on Recordable Media', + '2EGQ' => 'Editorial|Book|Retail Book, Illustrated Guide|All E-Book Distribution Formats', + '2EGR' => 'Editorial|Book|Retail Book, Illustrated Guide|All E-Book Distribution Formats', + '2MAN' => 'Editorial|Book|Retail Book, Manual|Printed', + '2EPK' => 'Editorial|Book|Retail Book, Manual|E-Book in Internet Website', + '2EBM' => 'Editorial|Book|Retail Book, Manual|E-Book in Internet Downloadable File', + '2EGS' => 'Editorial|Book|Retail Book, Manual|E-Book in Internet Email', + '2EKH' => 'Editorial|Book|Retail Book, Manual|All E-Book Internet Distribution Formats', + '2ERJ' => 'Editorial|Book|Retail Book, Manual|E-Book on Recordable Media', + '2EGT' => 'Editorial|Book|Retail Book, Manual|All E-Book Distribution Formats', + '2YAP' => 'Editorial|Book|Retail Book, Novelty Book|Printed', + '2EPL' => 'Editorial|Book|Retail Book, Novelty Book|E-Book in Internet Website', + '2EBN' => 'Editorial|Book|Retail Book, Novelty Book|E-Book in Internet Downloadable File', + '2EGV' => 'Editorial|Book|Retail Book, Novelty Book|E-Book in Internet Email', + '2EKJ' => 'Editorial|Book|Retail Book, Novelty Book|All E-Book Internet Distribution Formats', + '2ERK' => 'Editorial|Book|Retail Book, Novelty Book|E-Book on Recordable Media', + '2EGW' => 'Editorial|Book|Retail Book, Novelty Book|All E-Book Distribution Formats', + '2YEN' => 'Editorial|Book|Retail Book, Postcard Book|Printed', + '2EPM' => 'Editorial|Book|Retail Book, Postcard Book|E-Book in Internet Website', + '2EBP' => 'Editorial|Book|Retail Book, Postcard Book|E-Book in Internet Downloadable File', + '2EGY' => 'Editorial|Book|Retail Book, Postcard Book|E-Book in Internet Email', + '2EKK' => 'Editorial|Book|Retail Book, Postcard Book|All E-Book Internet Distribution Formats', + '2ERL' => 'Editorial|Book|Retail Book, Postcard Book|E-Book on Recordable Media', + '2EGZ' => 'Editorial|Book|Retail Book, Postcard Book|All E-Book Distribution Formats', + '2YOK' => 'Editorial|Book|Retail Book, Young Adult Book|Printed', + '2EPN' => 'Editorial|Book|Retail Book, Young Adult Book|E-Book in Internet Website', + '2EBQ' => 'Editorial|Book|Retail Book, Young Adult Book|E-Book in Internet Downloadable File', + '2EJB' => 'Editorial|Book|Retail Book, Young Adult Book|E-Book in Internet Email', + '2EKL' => 'Editorial|Book|Retail Book, Young Adult Book|All E-Book Internet Distribution Formats', + '2ERM' => 'Editorial|Book|Retail Book, Young Adult Book|E-Book on Recordable Media', + '2EJC' => 'Editorial|Book|Retail Book, Young Adult Book|All E-Book Distribution Formats', + '2BOO' => 'Editorial|Book|Retail Book, All Types|Printed', + '2EPB' => 'Editorial|Book|Retail Book, All Types|E-Book in Internet Website', + '2EBC' => 'Editorial|Book|Retail Book, All Types|E-Book in Internet Downloadable File', + '2EJD' => 'Editorial|Book|Retail Book, All Types|E-Book in Internet Email', + '2EKM' => 'Editorial|Book|Retail Book, All Types|All E-Book Internet Distribution Formats', + '2ERN' => 'Editorial|Book|Retail Book, All Types|E-Book on Recordable Media', + '2EJE' => 'Editorial|Book|Retail Book, All Types|All E-Book Distribution Formats', + '2EEL' => 'Editorial|Book|Textbook, Compendium|Printed', + '2EPQ' => 'Editorial|Book|Textbook, Compendium|E-Book in Internet Website', + '2EBS' => 'Editorial|Book|Textbook, Compendium|E-Book in Internet Downloadable File', + '2EJF' => 'Editorial|Book|Textbook, Compendium|E-Book in Internet Email', + '2EKN' => 'Editorial|Book|Textbook, Compendium|All E-Book Internet Distribution Formats', + '2ERP' => 'Editorial|Book|Textbook, Compendium|E-Book on Recordable Media', + '2EJJ' => 'Editorial|Book|Textbook, Compendium|All E-Book Distribution Formats', + '2EMU' => 'Editorial|Book|Textbook, Course Pack|Printed', + '2GBN' => 'Editorial|Book|Textbook, Course Pack|Internet Website', + '2GBM' => 'Editorial|Book|Textbook, Course Pack|Internet Downloadable File', + '2ZOO' => 'Editorial|Book|Textbook, Course Pack|Internet Email', + '2GBQ' => 'Editorial|Book|Textbook, Course Pack|All Internet Distribution Formats', + '2ZOA' => 'Editorial|Book|Textbook, Course Pack|Recordable Media', + '2GBP' => 'Editorial|Book|Textbook, Course Pack|All Distribution Formats', + '2BEE' => 'Editorial|Book|Textbook, Middle Reader|Printed', + '2EPR' => 'Editorial|Book|Textbook, Middle Reader|E-Book in Internet Website', + '2EBT' => 'Editorial|Book|Textbook, Middle Reader|E-Book in Internet Downloadable File', + '2EJK' => 'Editorial|Book|Textbook, Middle Reader|E-Book in Internet Email', + '2EKP' => 'Editorial|Book|Textbook, Middle Reader|All E-Book Internet Distribution Formats', + '2ERQ' => 'Editorial|Book|Textbook, Middle Reader|E-Book on Recordable Media', + '2EJL' => 'Editorial|Book|Textbook, Middle Reader|All E-Book Distribution Formats', + '2BOA' => 'Editorial|Book|Textbook, Student Edition|Printed', + '2EPS' => 'Editorial|Book|Textbook, Student Edition|E-Book in Internet Website', + '2EBV' => 'Editorial|Book|Textbook, Student Edition|E-Book in Internet Downloadable File', + '2EJM' => 'Editorial|Book|Textbook, Student Edition|E-Book in Internet Email', + '2EKQ' => 'Editorial|Book|Textbook, Student Edition|All E-Book Internet Distribution Formats', + '2ERS' => 'Editorial|Book|Textbook, Student Edition|E-Book on Recordable Media', + '2EJN' => 'Editorial|Book|Textbook, Student Edition|All E-Book Distribution Formats', + '2FOX' => 'Editorial|Book|Textbook, All Types|Printed', + '2EPP' => 'Editorial|Book|Textbook, All Types|E-Book in Internet Website', + '2EBR' => 'Editorial|Book|Textbook, All Types|E-Book in Internet Downloadable File', + '2EGA' => 'Editorial|Book|Textbook, All Types|E-Book in Internet Email', + '2EKR' => 'Editorial|Book|Textbook, All Types|All E-Book Internet Distribution Formats', + '2ERT' => 'Editorial|Book|Textbook, All Types|E-Book on Recordable Media', + '2EJP' => 'Editorial|Book|Textbook, All Types|All E-Book Distribution Formats', + '2GBZ' => 'Editorial|Book|Textbook Ancillary Materials, Educational Film Set|Projected Display', + '2YET' => 'Editorial|Book|Textbook Ancillary Materials, Packaging For Recordable Media|Printed', + '2YUM' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|Printed', + '2EPZ' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|E-Book in Internet Website', + '2EBA' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|E-Book in Internet Downloadable File', + '2EJQ' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|E-Book in Internet Email', + '2EKS' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|All E-Book Internet Distribution Formats', + '2ERU' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|E-Book on Recordable Media', + '2EJR' => 'Editorial|Book|Textbook Ancillary Materials, Lab Manual|All E-Book Distribution Formats', + '2YAK' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|Printed', + '2EPT' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|E-Book in Internet Website', + '2EBW' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|E-Book in Internet Downloadable File', + '2EJS' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|E-Book in Internet Email', + '2EKT' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|All E-Book Internet Distribution Formats', + '2ERV' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|E-Book on Recordable Media', + '2EJT' => 'Editorial|Book|Textbook Ancillary Materials, Teachers\' Edition|All E-Book Distribution Formats', + '2ZOT' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|Printed', + '2EPW' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|E-Book in Internet Website', + '2EBD' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|E-Book in Internet Downloadable File', + '2EJV' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|E-Book in Internet Email', + '2EKU' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|All E-Book Internet Distribution Formats', + '2ERW' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|E-Book on Recordable Media', + '2EJW' => 'Editorial|Book|Textbook Ancillary Materials, Teacher\'s Manual|All E-Book Distribution Formats', + '2GEE' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|Printed', + '2EPY' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|E-Book in Internet Website', + '2EBB' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|E-Book in Internet Downloadable File', + '2EJY' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|E-Book in Internet Email', + '2EKV' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|All E-Book Internet Distribution Formats', + '2ERY' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|E-Book on Recordable Media', + '2EJZ' => 'Editorial|Book|Textbook Ancillary Materials, Workbook|All E-Book Distribution Formats', + '2ELK' => 'Editorial|Book|Textbook Ancillary Materials, All Ancillary Types|Printed', + '2GBY' => 'Editorial|Book|Textbook Ancillary Materials, All Ancillary Types|All Internet Distribution Formats', + '2GBW' => 'Editorial|Book|Textbook Ancillary Materials, All Ancillary Types|All Distribution Formats', + '2NAY' => 'Editorial|Book|Reference Book, Encyclopedia|Printed', + '2EAQ' => 'Editorial|Book|Reference Book, Encyclopedia|E-Book in Internet Website', + '2EMB' => 'Editorial|Book|Reference Book, Encyclopedia|E-Book in Internet Downloadable File', + '2EMC' => 'Editorial|Book|Reference Book, Encyclopedia|All E-Book Internet Distribution Formats', + '2EMD' => 'Editorial|Book|Reference Book, Encyclopedia|E-Book on Recordable Media', + '2NAH' => 'Editorial|Book|Reference Book, Encyclopedia|All Electronic Distribution Formats', + '2NIP' => 'Editorial|Book|Reference Book, Telephone Book|Printed', + '2EMF' => 'Editorial|Book|Reference Book, Telephone Book|E-Book in Internet Website', + '2EMG' => 'Editorial|Book|Reference Book, Telephone Book|E-Book in Internet Downloadable File', + '2EMH' => 'Editorial|Book|Reference Book, Telephone Book|All E-Book Internet Distribution Formats', + '2EMI' => 'Editorial|Book|Reference Book, Telephone Book|E-Book on Recordable Media', + '2EMJ' => 'Editorial|Book|Reference Book, Telephone Book|All E-Book Distribution Formats', + '2DOG' => 'Editorial|Book|Reference Book, All Types|Printed', + '2EMK' => 'Editorial|Book|Reference Book, All Types|E-Book in Internet Website', + '2EML' => 'Editorial|Book|Reference Book, All Types|E-Book in Internet Downloadable File', + '2EMM' => 'Editorial|Book|Reference Book, All Types|All E-Book Internet Distribution Formats', + '2EMN' => 'Editorial|Book|Reference Book, All Types|E-Book on Recordable Media', + '2EMP' => 'Editorial|Book|Reference Book, All Types|All E-Book Distribution Formats', + '2DEW' => 'Editorial|Book|Trade Book, All Types|Printed', + '2EPV' => 'Editorial|Book|Trade Book, All Types|E-Book in Internet Website', + '2EMQ' => 'Editorial|Book|Trade Book, All Types|E-Book in Internet Downloadable File', + '2EMR' => 'Editorial|Book|Trade Book, All Types|E-Book in Internet Email', + '2EMS' => 'Editorial|Book|Trade Book, All Types|All E-Book Internet Distribution Formats', + '2ERA' => 'Editorial|Book|Trade Book, All Types|E-Book on Recordable Media', + '2EMT' => 'Editorial|Book|Trade Book, All Types|All E-Book Distribution Formats', + '2MOG' => 'Editorial|Book|All Book Types|Printed', + '2EPA' => 'Editorial|Book|All Book Types|E-Book in Internet Website', + '2EBK' => 'Editorial|Book|All Book Types|E-Book in Internet Downloadable File', + '2EJU' => 'Editorial|Book|All Book Types|E-Book in Internet Email', + '2EKA' => 'Editorial|Book|All Book Types|All E-Book Internet Distribution Formats', + '2ERZ' => 'Editorial|Book|All Book Types|E-Book on Recordable Media', + '2EJA' => 'Editorial|Book|All Book Types|All E-Book Distribution Formats', + '2MOR' => 'Editorial|Book|Artist\'s Reference, All Types|Printed', + '2EKW' => 'Editorial|Book|Artist\'s Reference, All Types|All E-Book Internet Distribution Formats', + '2EMV' => 'Editorial|Book|Artist\'s Reference, All Types|All E-Book Distribution Formats', + '2GAL' => 'Editorial|Display|Gallery Exhibition|Printed', + '2GDJ' => 'Editorial|Display|Gallery Exhibition|Electronic Display', + '2MUS' => 'Editorial|Display|Museum Display|Printed', + '2GDK' => 'Editorial|Display|Museum Display|Electronic Display', + '2EAU' => 'Editorial|Display|Poster, Educational Poster|Printed', + '2GHG' => 'Editorial|Website|Web Page, Body Content|Internet Website', + '2GHK' => 'Editorial|Website|Web Page, Body Content|All Internet Distribution Formats', + '2GHH' => 'Editorial|Website|Web Page, Body Content|Recordable Media', + '2GHJ' => 'Editorial|Website|Web Page, Body Content|All Electronic Distribution Formats', + '2GHB' => 'Editorial|Website|Web Page, All Types|Internet Website', + '2GHF' => 'Editorial|Website|Web Page, All Types|All Internet Distribution Formats', + '2GHC' => 'Editorial|Website|Web Page, All Types|Recordable Media', + '2GHD' => 'Editorial|Website|Web Page, All Types|All Electronic Distribution Formats', + '2GHA' => 'Editorial|Website|Webcast, All Types|Internet Website', + '2ZAG' => 'Editorial|Mobile|All Mobile Types|Mobile', + '2GGM' => 'Editorial|Merchandise|CD ROM|Recordable Media', + '2DVE' => 'Editorial|Merchandise|DVD|Recordable Media', + '2AAE' => 'Editorial|All Media Types|All Formats|All Distribution Formats', + '2ZIG' => 'Products|Mobile|Wallpaper|Mobile', + '2ZIP' => 'Products|Mobile|Game, All Types|Mobile', + '2ZAP' => 'Products|Mobile|Entertainment Programming|Mobile', + '2ZEN' => 'Products|Mobile|Computer Software|Mobile', + '2ZAM' => 'Products|Mobile|All Mobile Types|Mobile', + '2ADD' => 'Products|Merchandise|Address Book|Printed', + '2ANT' => 'Products|Merchandise|Anthology|Printed', + '2APP' => 'Products|Merchandise|Apparel, General Apparel|Printed or Woven', + '2TST' => 'Products|Merchandise|Apparel, T-Shirts|Printed or Woven', + '2BIO' => 'Products|Merchandise|Birthday Book|Printed', + '2BLA' => 'Products|Merchandise|Blank Note Book|Printed', + '2ATM' => 'Products|Merchandise|Card, ATM Card|Printed', + '2BNK' => 'Products|Merchandise|Card, Bank Card|Printed', + '2CRE' => 'Products|Merchandise|Card, Credit Card|Printed', + '2BIT' => 'Products|Merchandise|Card, Debit Card|Printed', + '2GFT' => 'Products|Merchandise|Card, Gift Card|Printed', + '2GRE' => 'Products|Merchandise|Card, Greeting Card|Printed', + '2HER' => 'Products|Merchandise|Card, Hero Card|Printed', + '2CRD' => 'Products|Merchandise|Card, Other Card|Printed', + '2ATT' => 'Products|Merchandise|Card, Phone Card|Printed', + '2CDR' => 'Products|Merchandise|CD ROM|Recordable Media', + '2CHK' => 'Products|Merchandise|Check|Printed', + '2BAK' => 'Products|Merchandise|Computer Software|Internet Downloadable File', + '2BAU' => 'Products|Merchandise|Computer Software|Internet Email', + '2BAV' => 'Products|Merchandise|Computer Software|All Internet Distribution Formats', + '2BAJ' => 'Products|Merchandise|Computer Software|Recordable Media', + '2WAR' => 'Products|Merchandise|Computer Software|All Electronic Distribution Formats', + '2GIG' => 'Products|Merchandise|Datebook|Printed', + '2DIA' => 'Products|Merchandise|Diary|Printed', + '2BAZ' => 'Products|Merchandise|Diary|Internet Downloadable File', + '2BBA' => 'Products|Merchandise|Diary|Internet Email', + '2BAW' => 'Products|Merchandise|Diary|Recordable Media', + '2HUB' => 'Products|Merchandise|Double Postcard|Printed', + '2DVD' => 'Products|Merchandise|DVD|Recordable Media', + '2EAT' => 'Products|Merchandise|Edible Media|Printed', + '2FOL' => 'Products|Merchandise|Folder|Printed', + '2GAB' => 'Products|Merchandise|Game, Computer Game|Internet Downloadable File', + '2GAH' => 'Products|Merchandise|Game, Computer Game|Internet Email', + '2GAE' => 'Products|Merchandise|Game, Computer Game|All Internet Distribution Formats', + '2GAG' => 'Products|Merchandise|Game, Computer Game|Recordable Media', + '2GAN' => 'Products|Merchandise|Game, Computer Game|All Electronic Distribution Formats', + '2GAP' => 'Products|Merchandise|Game, All Types|Printed', + '2GAT' => 'Products|Merchandise|Game, All Types|Internet Downloadable File', + '2GAS' => 'Products|Merchandise|Game, All Types|Internet Email', + '2GAD' => 'Products|Merchandise|Game, All Types|All Internet Distribution Formats', + '2GAR' => 'Products|Merchandise|Game, All Types|Recordable Media', + '2GAM' => 'Products|Merchandise|Game, All Types|All Electronic Distribution Formats', + '2BOX' => 'Products|Merchandise|Gift Box|Printed', + '2GIF' => 'Products|Merchandise|Gift Certificate|Printed', + '2WRP' => 'Products|Merchandise|Gift Wrap|Printed', + '2JIG' => 'Products|Merchandise|Jigsaw Puzzle|Printed', + '2JIN' => 'Products|Merchandise|Jigsaw Puzzle|Internet Downloadable File', + '2JIL' => 'Products|Merchandise|Jigsaw Puzzle|Recordable Media', + '2JRN' => 'Products|Merchandise|Journal|Printed', + '2MAP' => 'Products|Merchandise|Map|Printed', + '2MAD' => 'Products|Merchandise|Map|Internet Downloadable File', + '2MET' => 'Products|Merchandise|Map|Internet Email', + '2MIM' => 'Products|Merchandise|Map|All Internet Distribution Formats', + '2MIR' => 'Products|Merchandise|Map|Recordable Media', + '2MAB' => 'Products|Merchandise|Map|All Electronic Distribution Formats', + '2MOU' => 'Products|Merchandise|Mouse Pad|Printed', + '2MUG' => 'Products|Merchandise|Mugs|Printed', + '2NOV' => 'Products|Merchandise|Novelty Products|Printed', + '2MCH' => 'Products|Merchandise|Other Merchandise|Printed', + '2ALB' => 'Products|Merchandise|Photo Album|Printed', + '2MAT' => 'Products|Merchandise|Placemat|Printed', + '2MRP' => 'Products|Merchandise|Plates|Printed', + '2TOP' => 'Products|Merchandise|Poster, Retail Poster|Printed', + '2FUN' => 'Products|Merchandise|Playing Cards|Printed', + '2CLO' => 'Products|Merchandise|Retail Calendar, One Page|Printed', + '2CAL' => 'Products|Merchandise|Retail Calendar, Multi-Page|Printed', + '2BCJ' => 'Products|Merchandise|Retail Calendar, Multi-Page|Internet Downloadable File', + '2BCI' => 'Products|Merchandise|Retail Calendar, Multi-Page|Internet Email', + '2BCH' => 'Products|Merchandise|Retail Calendar, Multi-Page|All Internet Distribution Formats', + '2BCF' => 'Products|Merchandise|Retail Calendar, Multi-Page|Recordable Media', + '2BCG' => 'Products|Merchandise|Retail Calendar, Multi-Page|All Electronic Distribution Formats', + '2FAR' => 'Products|Merchandise|Retail Postcard|Printed', + '2FIB' => 'Products|Merchandise|Screen Saver|Internet Downloadable File', + '2GEL' => 'Products|Merchandise|Screen Saver|Internet Email', + '2TOD' => 'Products|Merchandise|Screen Saver|All Internet Distribution Formats', + '2WRY' => 'Products|Merchandise|Screen Saver|Recordable Media', + '2HEX' => 'Products|Merchandise|Screen Saver|All Electronic Distribution Formats', + '2KEP' => 'Products|Merchandise|Souvenir|Printed', + '2WEE' => 'Products|Merchandise|Stamp|Printed', + '2WIT' => 'Products|Merchandise|Stationery|Printed', + '2TIC' => 'Products|Merchandise|Sticker|Printed', + '2FEM' => 'Products|Merchandise|Textiles|Printed or Woven', + '2TKT' => 'Products|Merchandise|Ticket|Printed', + '2TOY' => 'Products|Merchandise|Toy|Printed', + '2TRD' => 'Products|Merchandise|Trading Cards|Printed', + '2TUA' => 'Products|Merchandise|Virtual Reality|Recordable Media', + '2WAL' => 'Products|Merchandise|Wallpaper|Printed', + '2MER' => 'Products|Merchandise|All Merchandise Types|Printed', + '2BAB' => 'Products|Art|Artist\'s Reference, Tattoo|Printed', + '2DVL' => 'Products|Product Packaging|Packaging For Recordable Media, Liner Notes|Printed', + '2DVP' => 'Products|Product Packaging|Packaging For Recordable Media, All Packaging Types|Printed', + '2FRA' => 'Products|Product Packaging|Picture Frame Insert|Printed', + '2EVE' => 'Products|Product Packaging|Retail Packaging, All Packaging Types|Printed', + '2WHO' => 'Products|Product Packaging|Wholesale Packaging, All Packaging Types|Printed', + '2DAY' => 'Products|Product Packaging|All Product Packaging Types|Printed', + '2AAP' => 'Products|All Media Types|All Formats|All Distribution Formats', + '2TUX' => 'Internal Company Use|Periodicals|Magazine, Custom Published|Printed', + '2BIC' => 'Internal Company Use|Periodicals|Magazine, Custom Published|Intranet and Extranet Website', + '2BIF' => 'Internal Company Use|Periodicals|Magazine, Custom Published|Intranet and Extranet Downloadable File', + '2FOE' => 'Internal Company Use|Periodicals|Magazine, Custom Published|Internet Email', + '2BII' => 'Internal Company Use|Periodicals|Magazine, Custom Published|All Intranet and Extranet Distribution Formats', + '2BIA' => 'Internal Company Use|Periodicals|Magazine, Custom Published|Recordable Media', + '2BIH' => 'Internal Company Use|Periodicals|Magazine, Custom Published|All Electronic Distribution Formats', + '2FRO' => 'Internal Company Use|Comp Use|All Comp Types|Printed', + '2FPO' => 'Internal Company Use|Comp Use|All Comp Types|All Electronic Distribution Formats', + '2GED' => 'Internal Company Use|Internal Review|All Review Types|Printed', + '2GID' => 'Internal Company Use|Internal Review|All Review Types|All Electronic Distribution Formats', + '2GOA' => 'Internal Company Use|Promotional Materials|Corporate Brochure|Printed', + '2BHH' => 'Internal Company Use|Promotional Materials|Corporate Brochure|Intranet and Extranet Downloadable File', + '2BHI' => 'Internal Company Use|Promotional Materials|Corporate Brochure|Intranet and Extranet Email', + '2BHG' => 'Internal Company Use|Promotional Materials|Corporate Brochure|Recordable Media', + '2BHN' => 'Internal Company Use|Promotional Materials|Corporate Calendar|Printed', + '2BHL' => 'Internal Company Use|Promotional Materials|Corporate Calendar|Intranet and Extranet Downloadable File', + '2BHM' => 'Internal Company Use|Promotional Materials|Corporate Calendar|Intranet and Extranet Email', + '2BHK' => 'Internal Company Use|Promotional Materials|Corporate Calendar|Recordable Media', + '2BHY' => 'Internal Company Use|Promotional Materials|Corporate Folder|Printed', + '2BHQ' => 'Internal Company Use|Promotional Materials|Card, Corporate Card|Printed', + '2BHT' => 'Internal Company Use|Promotional Materials|Card, Corporate Card|Intranet and Extranet Downloadable File', + '2BHU' => 'Internal Company Use|Promotional Materials|Card, Corporate Card|Intranet and Extranet Email', + '2BHS' => 'Internal Company Use|Promotional Materials|Card, Corporate Card|Recordable Media', + '2BHZ' => 'Internal Company Use|Promotional Materials|CD ROM|Recordable Media', + '2DVI' => 'Internal Company Use|Promotional Materials|DVD|Recordable Media', + '2BHV' => 'Internal Company Use|Promotional Materials|Sales Kit|All Electronic Distribution Formats', + '2BHW' => 'Internal Company Use|Promotional Materials|Training Materials|Printed', + '2BJN' => 'Internal Company Use|Website|Web Page, Content Body|Intranet and Extranet Website', + '2FAB' => 'Internal Company Use|Website|Web Page, Content Body|Recordable Media', + '2FAC' => 'Internal Company Use|Website|Web Page, Content Body|All Electronic Distribution Formats', + '2FAH' => 'Internal Company Use|Website|Web Page, Design Element|Intranet and Extranet Website', + '2FAI' => 'Internal Company Use|Website|Web Page, Design Element|Recordable Media', + '2FAJ' => 'Internal Company Use|Website|Web Page, Design Element|All Electronic Distribution Formats', + '2NET' => 'Internal Company Use|Website|Web Page, All Types|Intranet and Extranet Website', + '2BJL' => 'Internal Company Use|Website|Web Page, All Types|Recordable Media', + '2BJK' => 'Internal Company Use|Website|Web Page, All Types|All Electronic Distribution Formats', + '2BJH' => 'Internal Company Use|Website|Webcast, All Types|Intranet and Extranet Website', + '2WAN' => 'Internal Company Use|Website|All Website Types|Intranet and Extranet Website', + '2BHD' => 'Internal Company Use|Email|All Email Types|Intranet and Extranet Email', + '2ZUM' => 'Internal Company Use|Mobile|All Mobile Types|Mobile', + '2BHF' => 'Internal Company Use|Live Presentation|Internal Presentation|Projected Display', + '2BHB' => 'Internal Company Use|Art|Art Display, Display Print|Printed', + '2GOY' => 'Internal Company Use|Art|Art Display, All Art Types|Printed', + '2HAO' => 'Internal Company Use|Art|Art Display, All Art Types|Electronic Display', + '2AAI' => 'Internal Company Use|All Media Types|All Formats|All Distribution Formats', + '2TVC' => 'Motion Picture & TV|Television Programming|Commercial|Television Broadcast', + '2TEB' => 'Motion Picture & TV|Television Programming|Commercial|Internet Downloadable File', + '2TEC' => 'Motion Picture & TV|Television Programming|Commercial|All Internet Distribution Formats', + '2TEG' => 'Motion Picture & TV|Television Programming|Commercial|Recordable Media', + '2TVD' => 'Motion Picture & TV|Television Programming|Commercial|All Electronic Distribution Formats', + '2TVE' => 'Motion Picture & TV|Television Programming|Infomercial|Television Broadcast', + '2TEH' => 'Motion Picture & TV|Television Programming|Infomercial|Internet Downloadable File', + '2TEJ' => 'Motion Picture & TV|Television Programming|Infomercial|All Internet Distribution Formats', + '2TEK' => 'Motion Picture & TV|Television Programming|Infomercial|Recordable Media', + '2TVF' => 'Motion Picture & TV|Television Programming|Infomercial|All Electronic Distribution Formats', + '2TVG' => 'Motion Picture & TV|Television Programming|On-Air Promotion|Television Broadcast', + '2TEL' => 'Motion Picture & TV|Television Programming|On-Air Promotion|Internet Downloadable File', + '2TEM' => 'Motion Picture & TV|Television Programming|On-Air Promotion|All Internet Distribution Formats', + '2TEP' => 'Motion Picture & TV|Television Programming|On-Air Promotion|Recordable Media', + '2TVH' => 'Motion Picture & TV|Television Programming|On-Air Promotion|All Electronic Distribution Formats', + '2TVI' => 'Motion Picture & TV|Television Programming|Documentary Program|Television Broadcast', + '2TER' => 'Motion Picture & TV|Television Programming|Documentary Program|Internet Downloadable File', + '2TES' => 'Motion Picture & TV|Television Programming|Documentary Program|All Internet Distribution Formats', + '2TET' => 'Motion Picture & TV|Television Programming|Documentary Program|Recordable Media', + '2TVJ' => 'Motion Picture & TV|Television Programming|Documentary Program|All Electronic Distribution Formats', + '2TVA' => 'Motion Picture & TV|Television Programming|All Television Advertising Types|Television Broadcast', + '2TEA' => 'Motion Picture & TV|Television Programming|All Television Advertising Types|Internet Downloadable File', + '2TEQ' => 'Motion Picture & TV|Television Programming|All Television Advertising Types|All Internet Distribution Formats', + '2TED' => 'Motion Picture & TV|Television Programming|All Television Advertising Types|Recordable Media', + '2TVB' => 'Motion Picture & TV|Television Programming|All Television Advertising Types|All Electronic Distribution Formats', + '2TVK' => 'Motion Picture & TV|Television Programming|Educational Program|Television Broadcast', + '2TEU' => 'Motion Picture & TV|Television Programming|Educational Program|Internet Downloadable File', + '2TEV' => 'Motion Picture & TV|Television Programming|Educational Program|All Internet Distribution Formats', + '2TEW' => 'Motion Picture & TV|Television Programming|Educational Program|Recordable Media', + '2TVL' => 'Motion Picture & TV|Television Programming|Educational Program|All Electronic Distribution Formats', + '2TVM' => 'Motion Picture & TV|Television Programming|Entertainment Program|Television Broadcast', + '2TEY' => 'Motion Picture & TV|Television Programming|Entertainment Program|Internet Downloadable File', + '2TEZ' => 'Motion Picture & TV|Television Programming|Entertainment Program|All Internet Distribution Formats', + '2TLA' => 'Motion Picture & TV|Television Programming|Entertainment Program|Recordable Media', + '2TVN' => 'Motion Picture & TV|Television Programming|Entertainment Program|All Electronic Distribution Formats', + '2TVY' => 'Motion Picture & TV|Television Programming|Made For TV Movie|Television Broadcast', + '2TLC' => 'Motion Picture & TV|Television Programming|Made For TV Movie|Internet Downloadable File', + '2TLB' => 'Motion Picture & TV|Television Programming|Made For TV Movie|All Internet Distribution Formats', + '2TLD' => 'Motion Picture & TV|Television Programming|Made For TV Movie|Recordable Media', + '2TVP' => 'Motion Picture & TV|Television Programming|Made For TV Movie|All Electronic Distribution Formats', + '2TEF' => 'Motion Picture & TV|Television Programming|News Program, Flash|Television Broadcast', + '2TVS' => 'Motion Picture & TV|Television Programming|News Program|Television Broadcast', + '2TLE' => 'Motion Picture & TV|Television Programming|News Program|Internet Downloadable File', + '2TLF' => 'Motion Picture & TV|Television Programming|News Program|All Internet Distribution Formats', + '2TLG' => 'Motion Picture & TV|Television Programming|News Program|Recordable Media', + '2TVT' => 'Motion Picture & TV|Television Programming|News Program|All Electronic Distribution Formats', + '2TLH' => 'Motion Picture & TV|Television Programming|Non Broadcast Pilot|Recordable Media', + '2TLJ' => 'Motion Picture & TV|Television Programming|Non Broadcast Pilot|Projected Display', + '2TVU' => 'Motion Picture & TV|Television Programming|Non-Profit Program|Television Broadcast', + '2TLK' => 'Motion Picture & TV|Television Programming|Non-Profit Program|Internet Downloadable File', + '2TLL' => 'Motion Picture & TV|Television Programming|Non-Profit Program|All Internet Distribution Formats', + '2TLM' => 'Motion Picture & TV|Television Programming|Non-Profit Program|Recordable Media', + '2TVV' => 'Motion Picture & TV|Television Programming|Non-Profit Program|All Electronic Distribution Formats', + '2TLR' => 'Motion Picture & TV|Television Programming|Prop|Television Broadcast', + '2TLN' => 'Motion Picture & TV|Television Programming|Prop|Internet Downloadable File', + '2TLP' => 'Motion Picture & TV|Television Programming|Prop|All Internet Distribution Formats', + '2TLQ' => 'Motion Picture & TV|Television Programming|Prop|Recordable Media', + '2TVW' => 'Motion Picture & TV|Television Programming|Prop|All Electronic Distribution Formats', + '2TLV' => 'Motion Picture & TV|Television Programming|Set Decor|Television Broadcast', + '2TLS' => 'Motion Picture & TV|Television Programming|Set Decor|Internet Downloadable File', + '2TLT' => 'Motion Picture & TV|Television Programming|Set Decor|All Internet Distribution Formats', + '2TLU' => 'Motion Picture & TV|Television Programming|Set Decor|Recordable Media', + '2TVQ' => 'Motion Picture & TV|Television Programming|Set Decor|All Electronic Distribution Formats', + '2KOA' => 'Motion Picture & TV|Television Programming|Artist\'s Reference, All Types|Projected Display', + '2KOB' => 'Motion Picture & TV|Television Programming|Artist\'s Reference, All Types|Internet Downloadable File', + '2KOI' => 'Motion Picture & TV|Television Programming|Artist\'s Reference, All Types|All Internet Distribution Formats', + '2KOP' => 'Motion Picture & TV|Television Programming|Artist\'s Reference, All Types|Recordable Media', + '2KOR' => 'Motion Picture & TV|Television Programming|Artist\'s Reference, All Types|All Electronic Distribution Formats', + '2KOS' => 'Motion Picture & TV|Television Programming|Artist\'s Reference, All Types|Television Broadcast', + '2TEE' => 'Motion Picture & TV|Television Programming|All Editorial Television Types|Television Broadcast', + '2TLW' => 'Motion Picture & TV|Television Programming|All Editorial Television Types|Internet Downloadable File', + '2TLY' => 'Motion Picture & TV|Television Programming|All Editorial Television Types|All Internet Distribution Formats', + '2TLZ' => 'Motion Picture & TV|Television Programming|All Editorial Television Types|Recordable Media', + '2TVZ' => 'Motion Picture & TV|Television Programming|All Editorial Television Types|All Electronic Distribution Formats', + '2JOT' => 'Motion Picture & TV|Motion Picture|In Theater Commercial|Projected Display', + '2ATE' => 'Motion Picture & TV|Motion Picture|Movie Trailer|Projected Display', + '2MPP' => 'Motion Picture & TV|Motion Picture|Movie Trailer|Internet Downloadable File', + '2BET' => 'Motion Picture & TV|Motion Picture|Movie Trailer|All Internet Distribution Formats', + '2DIG' => 'Motion Picture & TV|Motion Picture|Movie Trailer|Recordable Media', + '2AID' => 'Motion Picture & TV|Motion Picture|Movie Trailer|All Electronic Distribution Formats', + '2MPF' => 'Motion Picture & TV|Motion Picture|Movie Trailer|Television Broadcast', + '2JOG' => 'Motion Picture & TV|Motion Picture|Documentary Film|Projected Display', + '2MPM' => 'Motion Picture & TV|Motion Picture|Documentary Film|Internet Downloadable File', + '2TUG' => 'Motion Picture & TV|Motion Picture|Documentary Film|All Internet Distribution Formats', + '2TRY' => 'Motion Picture & TV|Motion Picture|Documentary Film|Recordable Media', + '2DOC' => 'Motion Picture & TV|Motion Picture|Documentary Film|All Electronic Distribution Formats', + '2MPD' => 'Motion Picture & TV|Motion Picture|Documentary Film|Television Broadcast', + '2FEA' => 'Motion Picture & TV|Motion Picture|Feature Film|Projected Display', + '2MPN' => 'Motion Picture & TV|Motion Picture|Feature Film|Internet Downloadable File', + '2WAG' => 'Motion Picture & TV|Motion Picture|Feature Film|All Internet Distribution Formats', + '2WIN' => 'Motion Picture & TV|Motion Picture|Feature Film|Recordable Media', + '2FIL' => 'Motion Picture & TV|Motion Picture|Feature Film|All Electronic Distribution Formats', + '2MPE' => 'Motion Picture & TV|Motion Picture|Feature Film|Television Broadcast', + '2WIZ' => 'Motion Picture & TV|Motion Picture|Short Film|Projected Display', + '2MPS' => 'Motion Picture & TV|Motion Picture|Short Film|Internet Downloadable File', + '2ASK' => 'Motion Picture & TV|Motion Picture|Short Film|All Internet Distribution Formats', + '2AIM' => 'Motion Picture & TV|Motion Picture|Short Film|Recordable Media', + '2FIT' => 'Motion Picture & TV|Motion Picture|Short Film|All Electronic Distribution Formats', + '2MPI' => 'Motion Picture & TV|Motion Picture|Short Film|Television Broadcast', + '2MPG' => 'Motion Picture & TV|Motion Picture|Prop|Television Broadcast', + '2HOP' => 'Motion Picture & TV|Motion Picture|Prop|Projected Display', + '2MPQ' => 'Motion Picture & TV|Motion Picture|Prop|Internet Downloadable File', + '2HIT' => 'Motion Picture & TV|Motion Picture|Prop|All Internet Distribution Formats', + '2FRY' => 'Motion Picture & TV|Motion Picture|Prop|Recordable Media', + '2EFX' => 'Motion Picture & TV|Motion Picture|Prop|All Electronic Distribution Formats', + '2MPH' => 'Motion Picture & TV|Motion Picture|Set Decor|Television Broadcast', + '2MPR' => 'Motion Picture & TV|Motion Picture|Set Decor|Internet Downloadable File', + '2JAB' => 'Motion Picture & TV|Motion Picture|Set Decor|All Internet Distribution Formats', + '2HUG' => 'Motion Picture & TV|Motion Picture|Set Decor|Recordable Media', + '2HUM' => 'Motion Picture & TV|Motion Picture|Set Decor|All Electronic Distribution Formats', + '2ARC' => 'Motion Picture & TV|Motion Picture|Set Decor|Projected Display', + '2TAP' => 'Motion Picture & TV|Motion Picture|Artist\'s Reference, All Types|Projected Display', + '2MPL' => 'Motion Picture & TV|Motion Picture|Artist\'s Reference, All Types|Internet Downloadable File', + '2NOD' => 'Motion Picture & TV|Motion Picture|Artist\'s Reference, All Types|All Internet Distribution Formats', + '2MIX' => 'Motion Picture & TV|Motion Picture|Artist\'s Reference, All Types|Recordable Media', + '2NAP' => 'Motion Picture & TV|Motion Picture|Artist\'s Reference, All Types|All Electronic Distribution Formats', + '2MPC' => 'Motion Picture & TV|Motion Picture|Artist\'s Reference, All Types|Television Broadcast', + '2FIX' => 'Motion Picture & TV|Motion Picture|All Motion Picture Types|Projected Display', + '2MPJ' => 'Motion Picture & TV|Motion Picture|All Motion Picture Types|Internet Downloadable File', + '2DIP' => 'Motion Picture & TV|Motion Picture|All Motion Picture Types|All Internet Distribution Formats', + '2MOV' => 'Motion Picture & TV|Motion Picture|All Motion Picture Types|Recordable Media', + '2MPA' => 'Motion Picture & TV|Motion Picture|All Motion Picture Types|Television Broadcast', + '2ACT' => 'Motion Picture & TV|Motion Picture|All Motion Picture Types|All Electronic Distribution Formats', + '2MPB' => 'Motion Picture & TV|Music Video|All Music Video Types|Television Broadcast', + '2MPK' => 'Motion Picture & TV|Music Video|All Music Video Types|Internet Downloadable File', + '2BER' => 'Motion Picture & TV|Music Video|All Music Video Types|Recordable Media', + '2BES' => 'Motion Picture & TV|Music Video|All Music Video Types|All Internet Distribution Formats', + '2TVR' => 'Motion Picture & TV|Music Video|All Music Video Types|All Electronic Distribution Formats', + '2AAM' => 'Motion Picture & TV|All Media Types|All Formats|All Distribution Formats', + '2WED' => 'Personal Use|Personal Review|All Review Types|Printed', + '2DIM' => 'Personal Use|Personal Review|All Review Types|All Electronic Distribution Formats', + '2BFR' => 'Personal Use|Website|Web Page, All Types|Internet Website', + '2BFU' => 'Personal Use|Website|Web Page, All Types|All Internet Distribution Formats', + '2BFS' => 'Personal Use|Website|Web Page, All Types|Recordable Media', + '2BFT' => 'Personal Use|Website|Web Page, All Types|All Electronic Distribution Formats', + '2ZIT' => 'Personal Use|Mobile|Wallpaper|Mobile', + '2ZOB' => 'Personal Use|Mobile|All Mobile Types|Mobile', + '2BFN' => 'Personal Use|Art|Art Display, Display Print|Printed', + '2KIT' => 'Personal Use|Art|Art Display, All Art Types|Printed', + '2BFJ' => 'Personal Use|Art|Art Display, All Art Types|Internet Website', + '2BFI' => 'Personal Use|Art|Art Display, All Art Types|All Internet Distribution Formats', + '2BFK' => 'Personal Use|Art|Art Display, All Art Types|Electronic Display', + '2BFH' => 'Personal Use|Art|Art Display, All Art Types|All Electronic Distribution Formats', + '2TAT' => 'Personal Use|Art|Artist\'s Reference, Tattoo|Printed', + '2BFP' => 'Personal Use|Art|Study Print, Educational|Printed', + '2AAU' => 'Personal Use|All Media Types|All Formats|All Distribution Formats', + '2AAB' => 'All Categories|Book|All Book Types|All Distribution Formats', + '2AAD' => 'All Categories|Display|All Display Types|All Distribution Formats', + '2AAT' => 'All Categories|Marketing Materials|All Marketing Material Types|All Distribution Formats', + '2AAH' => 'All Categories|Merchandise|All Merchandise Types|All Distribution Formats', + '2AAL' => 'All Categories|Mobile|All Mobile Types|All Distribution Formats', + '2AAX' => 'All Categories|Motion Picture|All Motion Picture Types|All Distribution Formats', + '2AAV' => 'All Categories|Music Video|All Music Video Types|All Distribution Formats', + '2AAC' => 'All Categories|Periodicals|All Periodical Types|All Distribution Formats', + '2AAR' => 'All Categories|Point of Purchase|All Point Of Purchase Types|All Distribution Formats', + '2AAG' => 'All Categories|Product Packaging|All Product Packaging Types|All Distribution Formats', + '2AAN' => 'All Categories|Television Programming|All Television Programming Types|All Distribution Formats', + '2BAA' => 'All Categories|Website|All Web Page Types|All Distribution Formats', + '2ALL' => 'All Categories|All Media Types|All Formats|All Distribution Formats', + '2UNL' => 'Unlicensed|Not Applicable|Not Applicable|Not Applicable', + # 3P - Placement + '3PAA' => 'Any Placements on All Pages', + '3PXX' => 'Not Applicable or None', + '3PUL' => 'Any Placements', + '3PNQ' => 'Single Placement in Content Body', + '3PPU' => 'Single Placement on Title Page', + '3PQT' => 'Single Placement on Table Of Contents', + '3PQA' => 'Single Placement as Frontispiece', + '3PQI' => 'Single Placement on Preface', + '3PPW' => 'Single Placement as Forward', + '3PSA' => 'Single Placement as Front Matter', + '3PNI' => 'Single Placement as Chapter Opener', + '3PQN' => 'Single Placement as Vignette', + '3PRT' => 'Single Placement on Pop Up', + '3PNZ' => 'Single Placement in Bibliography', + '3PQZ' => 'Single Placement on Index', + '3PQG' => 'Single Placement on Any Interior Page', + '3PSR' => 'Single Placement on Inside Cover', + '3PQE' => 'Single Placement on Spine', + '3PSL' => 'Single Placement on Flap', + '3PSP' => 'Single Placement on Back Cover', + '3PNN' => 'Single Placement on Front Cover', + '3PTL' => 'Single Placement on Front Cover And Back Cover', + '3PPA' => 'Single Placement on Dust Jacket', + '3PTD' => 'Single Placements on Interior, Covers and Jacket', + '3PRY' => 'Multiple Placements in Content Body', + '3PRL' => 'Multiple Placements on Any Interior Pages', + '3PSU' => 'Multiple Placements on Inside Cover', + '3PQS' => 'Multiple Placements on Back Cover', + '3PRZ' => 'Multiple Placements on Front Cover', + '3PTM' => 'Multiple Placements on Front Cover And Back Cover', + '3PTC' => 'Multiple Placements on Dust Jacket', + '3PTE' => 'Multiple Placements on Interior, Covers and Jacket', + '3PST' => 'Single Placement on Any Interior Page', + '3PPK' => 'Single Placement on Inside Cover', + '3PNR' => 'Single Placement on Back Cover', + '3PRB' => 'Single Placement on Front Cover', + '3PUD' => 'Single Placement on Back Cover Or Interior Page', + '3PTB' => 'Single Placement on Front Cover And Interior Page', + '3PUF' => 'Single Placement on Front Cover Or Back Cover', + '3PNF' => 'Single Placement on Front Cover And Back Cover', + '3PTP' => 'Single Placement on Any Cover And Interior Page', + '3PQW' => 'Multiple Placements on Any Interior Pages', + '3PNY' => 'Multiple Placements on Inside Cover', + '3PNC' => 'Multiple Placements on Back Cover', + '3PPV' => 'Multiple Placements on Front Cover', + '3PRG' => 'Multiple Placements on Front Cover And Back Cover', + '3PTN' => 'Multiple Placements on Any Covers And Interior Pages', + '3PQX' => 'Single Placement on Any Interior Page', + '3PTF' => 'Single Placement on Section Opener Page', + '3PNT' => 'Single Placement on Front Page', + '3PTH' => 'Single Placement on Section Opener and Front Page', + '3PSY' => 'Multiple Placements on Any Interior Pages', + '3PTG' => 'Multiple Placements on Section Opener Page', + '3PTI' => 'Multiple Placements on Section Opener and Front Page', + '3PPM' => 'Multiple Placements on Any Pages', + '3PQJ' => 'Single Placement on Wrap Around Cover', + '3PQB' => 'Multiple Placements on Wrap Around Cover', + '3PRS' => 'Single Placement in Content Body', + '3PRI' => 'Single Placement as Colophon', + '3PRC' => 'Single Placement on Table Of Contents', + '3PQQ' => 'Single Placement as Unit Opener', + '3PND' => 'Single Placement as Chapter Opener', + '3PQF' => 'Single Placements in Bibliography', + '3PRN' => 'Single Placement on Any Interior Page', + '3PQH' => 'Single Placement on Back Cover', + '3PSJ' => 'Single Placement on Front Cover', + '3PTJ' => 'Single Placement on Any Covers And Interior Pages', + '3PRD' => 'Multiple Placements in Content Body', + '3PSM' => 'Multiple Placements on Any Interior Pages', + '3PSN' => 'Multiple Placements on Back Cover', + '3PPF' => 'Multiple Placements on Front Cover', + '3PTK' => 'Multiple Placements on Any Covers And Interior Pages', + '3PNE' => 'Single Placement on Front Side', + '3PQC' => 'Single Placement on Back Side', + '3PPL' => 'Single Placement on Both Sides', + '3PNV' => 'Multiple Placements on Front Side', + '3PSB' => 'Multiple Placements on Back Side', + '3PQK' => 'Multiple Placements on Both Sides', + '3PTA' => 'Single Placement on One Side', + '3PNB' => 'Multiple Placements on One Side', + '3PRQ' => 'Single Placement on Screen', + '3PSD' => 'Multiple Placements on Screen', + '3PPH' => 'Single Placement on Inside', + '3PSQ' => 'Single Placement on Back Side', + '3PRU' => 'Single Placement on Front Side', + '3PNP' => 'Single Placement on Both Sides', + '3PRK' => 'Multiple Placements on Inside', + '3PQM' => 'Multiple Placements on Back Side', + '3PNK' => 'Multiple Placements on Front Side', + '3PRV' => 'Multiple Placements on Both Sides', + '3PRH' => 'Single Placement on Any Interior Page', + '3PSH' => 'Single Placement on Back Cover', + '3PQY' => 'Single Placement on Front Cover', + '3PRM' => 'Single Placement on Front Cover And Back Cover', + '3PTQ' => 'Single Placement on Any Covers And Interior Pages', + '3PRF' => 'Multiple Placements on Any Interior Pages', + '3PSF' => 'Multiple Placements on Back Cover', + '3PRJ' => 'Multiple Placements on Front Cover', + '3PPP' => 'Multiple Placements on Front Cover And Interior Pages', + '3PSS' => 'Multiple Placements on Front Cover And Back Cover', + '3PTR' => 'Multiple Placements on Any Covers And Interior Pages', + '3PSW' => 'Single Placement on Item', + '3PNL' => 'Multiple Placements on Item', + '3PPX' => 'Single Placement on Packaging Exterior|Front', + '3PUJ' => 'Single Placement on Packaging Exterior|Back or Side', + '3PPD' => 'Single Placement in Packaging Interior', + '3PSI' => 'Multiple Placements on Packaging Exterior|Front', + '3PUH' => 'Multiple Placements on Packaging Exterior|Back or Side', + '3PPC' => 'Multiple Placements in Packaging Interior', + '3PTS' => 'Single Placement Anywhere On Packaging', + '3PTT' => 'Multiple Placements Anywhere On Packaging', + '3PNW' => 'Single Placement in Body Of Program', + '3PQU' => 'Single Placement in Closing Sequence', + '3PRR' => 'Single Placement in Title Sequence', + '3PTV' => 'Single Placement in Any Part', + '3PPZ' => 'Multiple Placements in Body Of Program', + '3PPN' => 'Multiple Placements in Closing Sequence', + '3PSV' => 'Multiple Placements in Title Sequence', + '3PTU' => 'Multiple Placements in Any Part', + '3PRP' => 'Single Placement in Body Of Advertisement', + '3PPJ' => 'Multiple Placements in Body Of Advertisement', + '3PPR' => 'Single Placement in Any Part', + '3PRW' => 'Multiple Placements in Any Part', + '3PQD' => 'Single Placement on Secondary Page', + '3PQP' => 'Single Placement on Pop Up', + '3PPS' => 'Single Placement on Landing Page', + '3PPG' => 'Single Placement on Splash Page', + '3PPY' => 'Single Placement on Home Page', + '3PTY' => 'Single Placement on Home Page And Secondary Pages', + '3PTW' => 'Single Placement on Any Pages', + '3PSZ' => 'Multiple Placements on Secondary Pages', + '3PNJ' => 'Multiple Placements on Pop Ups', + '3PPI' => 'Multiple Placements on Landing Pages', + '3PNS' => 'Multiple Placements on Splash Pages', + '3PNU' => 'Multiple Placements on Home Page', + '3PPQ' => 'Multiple Placements on Home Page And Secondary Pages', + '3PTZ' => 'Multiple Placements on Any Pages', + '3PPE' => 'Single Placement as Flash', + '3PNM' => 'Single Placement in Body Of Program', + '3PPB' => 'Single Placement in Closing Sequence', + '3PSC' => 'Single Placement in Title Sequence', + '3PUC' => 'Single Placement in Any Part', + '3PNX' => 'Multiple Placements as Flash', + '3PNH' => 'Multiple Placements in Body Of Program', + '3PQL' => 'Multiple Placements in Closing Sequence', + '3PSK' => 'Multiple Placements in Title Sequence', + '3PUB' => 'Multiple Placements in Any Part', + # 4S - Size + '4SAA' => 'Any Size Image|Any Size Media', + '4SXX' => 'Not Applicable or None', + '4SUL' => 'Any Sizes', + '4SJA' => 'Up To 1/16 Page|Any Size Page', + '4SBN' => 'Up To 1/8 Page Image|Any Size Page', + '4SJB' => 'Up To 1/4 Page Image|Any Size Page', + '4SEU' => 'Up To 1/3 Page Image|Any Size Page', + '4SEJ' => 'Up To 1/2 Page Image|Any Size Page', + '4SMG' => 'Up To 3/4 Page Image|Any Size Page', + '4SAG' => 'Up To Full Page Image|Any Size Page', + '4SFI' => 'Up To 2 Page Image|Any Size Pages', + '4SJZ' => 'Up To 3 Page Image|Any Size Pages', + '4SFG' => 'Up To 4 Page Image|Any Size Pages', + '4SBP' => 'Any Size Image|Any Size Page', + '4SGF' => 'Up To 1/4 Page Image|Up To 1/4 Page Ad', + '4SCH' => 'Up To 1/4 Page Image|Up To 1/2 Page Ad', + '4SIY' => 'Up To 1/4 Page Image|Up To Full Page Ad', + '4SCV' => 'Up To 1/2 Page Image|Up To 1/2 Page Ad', + '4SLY' => 'Up To 1/2 Page Image|Up To Full Page Ad', + '4SBU' => 'Up To 1/2 Page Image|Up To 2 Page Ad', + '4SCP' => 'Up To Full Page Image|Up To Full Page Ad', + '4SGL' => 'Up To Full Page Image|Up To 2 Page Ad', + '4SGM' => 'Up To Full Page Image|Any Size Ad', + '4SMB' => 'Up To 2 Page Image|Up To 2 Page Ad', + '4SFR' => 'Up To 2 Page Image|Any Size Ad', + '4SKP' => 'Any Size Image|Any Size Ad', + '4SBK' => 'Up To 1/16 Page Image|Any Size Page', + '4SJS' => 'Up To 1/8 Page Image|Any Size Page', + '4SLV' => 'Up To 1/4 Page Image|Any Size Page', + '4SGW' => 'Up To 1/2 Page Image|Any Size Page', + '4SKD' => 'Up To Full Page Image|Any Size Page', + '4SFJ' => 'Up To 2 Page Image|Any Size Pages', + '4SLA' => 'Any Size Image|Any Size Pages', + '4SKE' => 'Up To 1/8 Page Image|Any Size Page', + '4SAK' => 'Up To 1/4 Page Image|Any Size Page', + '4SLD' => 'Up To 1/2 Page Image|Any Size Page', + '4SJV' => 'Up To Full Page Image|Any Size Page', + '4SJU' => 'Up To 2 Page Image|Any Size Pages', + '4SIW' => 'Any Size Image|Any Size Pages', + '4SAL' => 'Up To 1/4 Area Image|Up To Full Area Media', + '4SJM' => 'Up To 1/2 Area Image|Up To Full Area Media', + '4SKZ' => 'Up To Full Area Image|Up To Full Area Media', + '4SCN' => 'Up To 1/8 Page Image|Up To Full Page Media', + '4SLW' => 'Up To 1/4 Page Image|Up To Full Page Media', + '4SIZ' => 'Up To 1/2 Page Image|Up To Full Page Media', + '4SAC' => 'Up To Full Page Image|Up To Full Page Media', + '4SFX' => 'Up To 8 x 10 Inch Image|Any Size Media', + '4SFP' => 'Up To 11 x 14 Inch Image|Any Size Media', + '4SMV' => 'Any Size Image|Any Size Media', + '4SJD' => 'Up To 21 x 30 cm Image|Any Size Media', + '4SFQ' => 'Up To 30 x 42 cm Image|Any Size Media', + '4SJK' => 'Any Size Image|Up To Full Card', + '4SEQ' => 'Up To 5 x 5 Inch Image|Up To 40 x 40 Inch Media', + '4SIV' => 'Up To 10 x 10 Inch Image|Up To 40 x 40 Inch Media', + '4SCE' => 'Up To 20 x 20 Inch Image|Up To 40 x 40 Inch Media', + '4SDP' => 'Up To 30x 30 Inch Image|Up To 40 x 40 Inch Media', + '4SCT' => 'Up To 40 x 40 Inch Image|Up To 40 x 40 Inch Media', + '4SBJ' => 'Up To 20 x 20 cm Image|Up To 100 x 100 cm Media', + '4SKI' => 'Up To 30 x 30 cm Image|Up To 100 x 100 cm Media', + '4SJW' => 'Up To 40 x 40 cm Image|Up To 100 x 100 cm Media', + '4SCB' => 'Up To 50 x 50 cm Image|Up To 100 x 100 cm Media', + '4SAT' => 'Up To 75 x 75 cm Image|Up To 100 x 100 cm Media', + '4SCI' => 'Up To 100 x 100 cm Image|Up To 100 x 100 cm Media', + '4SGP' => 'Any Size Image|Any Size Media', + '4SIX' => 'Up To 1/4 Area Image|Up To 11 x 36 Foot Display', + '4SHA' => 'Up To 1/4 Area Image|Up To 10 x 40 Foot Display', + '4SGU' => 'Up To 1/4 Area Image|Up To 14 x 48 Foot Display', + '4SAJ' => 'Up To 1/2 Area Image|Up To 11 x 36 Foot Display', + '4SDX' => 'Up To 1/2 Area Image|Up To 10 x 40 Foot Display', + '4SCR' => 'Up To 1/2 Area Image|Up To 14 x 48 Foot Display', + '4SFM' => 'Up To Full Area Image|Up To 11 x 36 Foot Display', + '4SKV' => 'Up To Full Area Image|Up To 10 x 40 Foot Display', + '4SGE' => 'Up To Full Area Image|Up To 14 x 48 Foot Display', + '4SMW' => 'Up To Full Area Image|Any Size Display', + '4SJI' => 'Up To 1/4 Area Image|Up To 4 x 8 Foot Media', + '4SBI' => 'Up To 1/4 Area Image|Up To 10 x 8 Foot Media', + '4SIM' => 'Up To 1/4 Area Image|Up To 12 x 24 Foot Media', + '4SFF' => 'Up To 1/4 Area Image|Any Size Media', + '4SAX' => 'Up To 1/2 Area Image|Up To 4 x 8 Foot Media', + '4SLI' => 'Up To 1/2 Area Image|Up To 10 x 8 Foot Media', + '4SLS' => 'Up To 1/2 Area Image|Up To 12 x 24 Foot Media', + '4SMK' => 'Up To 1/2 Area Image|Any Size Media', + '4SLG' => 'Up To Full Area Image|Up To 4 x 8 Foot Media', + '4SAN' => 'Up To Full Area Image|Up To 10 x 8 Foot Media', + '4SDI' => 'Up To Full Area Image|Up To 12 x 24 Foot Media', + '4SML' => 'Up To Full Area Image|Any Size Media', + '4SKF' => 'Up To 1/4 Area Image|Up To 672 Square Foot Display', + '4SKR' => 'Up To 1/4 Area Image|Up To 1,200 Square Foot Display', + '4SLK' => 'Up To 1/4 Area Image|Up To 2,400 Square Foot Display', + '4SJQ' => 'Up To 1/4 Area Image|Up To 4,800 Square Foot Display', + '4SEY' => 'Up To 1/4 Area Image|Up To 10,000 Square Foot Display', + '4SFE' => 'Up To 1/4 Area Image|Any Size Display', + '4SKS' => 'Up To 1/2 Area Image|Up To 672 Square Foot Display', + '4SGS' => 'Up To 1/2 Area Image|Up To 1,200 Square Foot Display', + '4SMA' => 'Up To 1/2 Area Image|Up To 2,400 Square Foot Display', + '4SAF' => 'Up To 1/2 Area Image|Up To 4,800 Square Foot Display', + '4SAW' => 'Up To 1/2 Area Image|Up To 10,000 Square Foot Display', + '4SAQ' => 'Up To 1/2 Area Image|Any Size Display', + '4SLN' => 'Up To Full Area Image|Up To 672 Square Foot Display', + '4SDS' => 'Up To Full Area Image|Up To 1,200 Square Foot Display', + '4SIT' => 'Up To Full Area Image|Up To 2,400 Square Foot Display', + '4SGX' => 'Up To Full Area Image|Up To 4,800 Square Foot Display', + '4SBD' => 'Up To Full Area Image|Up To 10,000 Square Foot Display', + '4SBF' => 'Up To Full Area Image|Any Size Display', + '4SDD' => 'Up To 1/4 Area Image|Up To 4 Sheet Display', + '4SBC' => 'Up To 1/4 Area Image|Up To 8 Sheet Display', + '4SLJ' => 'Up To 1/4 Area Image|Up To 12 Sheet Display', + '4SAD' => 'Up To 1/4 Area Image|Up To 16 Sheet Display', + '4SEA' => 'Up To 1/4 Area Image|Up To 30 Sheet Display', + '4SCD' => 'Up To 1/4 Area Image|Up To 48 Sheet Display', + '4SKX' => 'Up To 1/4 Area Image|Up To 96 Sheet Display', + '4SMN' => 'Up To 1/4 Area Image|Any Size Display', + '4SDU' => 'Up To 1/2 Area Image|Up To 4 Sheet Display', + '4SBL' => 'Up To 1/2 Area Image|Up To 8 Sheet Display', + '4SER' => 'Up To 1/2 Area Image|Up To 12 Sheet Display', + '4SEN' => 'Up To 1/2 Area Image|Up To 16 Sheet Display', + '4SLP' => 'Up To 1/2 Area Image|Up To 30 Sheet Display', + '4SGQ' => 'Up To 1/2 Area Image|Up To 48 Sheet Display', + '4SDF' => 'Up To 1/2 Area Image|Up To 96 Sheet Display', + '4SMP' => 'Up To 1/2 Area Image|Any Size Display', + '4SFL' => 'Up To Full Area Image|Up To 4 Sheet Display', + '4SFS' => 'Up To Full Area Image|Up To 8 Sheet Display', + '4SIF' => 'Up To Full Area Image|Up To 12 Sheet Display', + '4SIS' => 'Up To Full Area Image|Up To 16 Sheet Display', + '4SFD' => 'Up To Full Area Image|Up To 30 Sheet Display', + '4SFU' => 'Up To Full Area Image|Up To 48 Sheet Display', + '4SDK' => 'Up To Full Area Image|Up To 96 Sheet Display', + '4SMQ' => 'Up To Full Area Image|Any Size Display', + '4SKA' => 'Up To 1/4 Area Image|Up To 20 x 30 Inch Media', + '4SIK' => 'Up To 1/4 Area Image|Up To 24 x 36 Inch Media', + '4SFK' => 'Up To 1/4 Area Image|Up To 30 x 40 Inch Media', + '4SDV' => 'Up To 1/4 Area Image|Up To 40 x 60 Inch Media', + '4SMX' => 'Up To 1/4 Area Image|Any Size Media', + '4SEF' => 'Up To 1/4 Area Image|Up To A1 Media', + '4SCJ' => 'Up To 1/4 Area Image|Up To B1 Media', + '4SJG' => 'Up To 1/4 Area Image|Up To A0 Media', + '4SIP' => 'Up To 1/4 Area Image|Up To B0 Media', + '4SKU' => 'Up To 1/2 Area Image|Up To 20 x 30 Inch Media', + '4SAS' => 'Up To 1/2 Area Image|Up To 24 x 36 Inch Media', + '4SGB' => 'Up To 1/2 Area Image|Up To 30 x 40 Inch Media', + '4SBQ' => 'Up To 1/2 Area Image|Up To 40 x 60 Inch Media', + '4SMY' => 'Up To 1/2 Area Image|Any Size Media', + '4SKJ' => 'Up To 1/2 Area Image|Up To A1 Media', + '4SAM' => 'Up To 1/2 Area Image|Up To B1 Media', + '4SDZ' => 'Up To 1/2 Area Image|Up To A0 Media', + '4SGT' => 'Up To 1/2 Area Image|Up To B0 Media', + '4SKN' => 'Up To Full Area Image|Up To 20 x 30 Inch Media', + '4SIQ' => 'Up To Full Area Image|Up To 24 x 36 Inch Media', + '4SLT' => 'Up To Full Area Image|Up To 30 x 40 Inch Media', + '4SDN' => 'Up To Full Area Image|Up To 40 x 60 Inch Media', + '4SMZ' => 'Up To Full Area Image|Any Size Media', + '4SBH' => 'Up To Full Area Image|Up To A1 Media', + '4SLU' => 'Up To Full Area Image|Up To B1 Media', + '4SEL' => 'Up To Full Area Image|Up To A0 Media', + '4SBM' => 'Up To Full Area Image|Up To B0 Media', + '4SIH' => 'Up To 1/4 Area Image|Up To 24 x 30 Inch Display', + '4SKW' => 'Up To 1/4 Area Image|Up To 30 x 40 Inch Display', + '4SDM' => 'Up To 1/4 Area Image|Up To 27 x 85 Inch Display', + '4SJP' => 'Up To 1/4 Area Image|Up To 60 x 40 Inch Display', + '4SIB' => 'Up To 1/4 Area Image|Up To 69 x 48 Inch Display', + '4SDH' => 'Up To 1/4 Area Image|Up To 27 x 141 Inch Display', + '4SJL' => 'Up To 1/4 Area Image|Up To 30 x 240 Inch Display', + '4SLQ' => 'Up To 1/4 Area Image|Up To B1 Display', + '4SLL' => 'Up To 1/4 Area Image|Up To A0 Display', + '4SEI' => 'Up To 1/4 Area Image|Up To B0 Display', + '4SBA' => 'Up To 1/2 Area Image|Up To 24 x 30 Inch Display', + '4SCL' => 'Up To 1/2 Area Image|Up To 30 x 40 Inch Display', + '4SIC' => 'Up To 1/2 Area Image|Up To 27 x 85 Inch Display', + '4SBY' => 'Up To 1/2 Area Image|Up To 60 x 40 Inch Display', + '4SFZ' => 'Up To 1/2 Area Image|Up To 27 x 141 Inch Display', + '4SAU' => 'Up To 1/2 Area Image|Up To 26 x 241 Inch Display', + '4SBR' => 'Up To 1/2 Area Image|Up To 30 x 240 Inch Display', + '4SCC' => 'Up To 1/2 Area Image|Up To B1 Display', + '4SAB' => 'Up To 1/2 Area Image|Up To A0 Display', + '4SLX' => 'Up To 1/2 Area Image|Up To B0 Display', + '4SGI' => 'Up To Full Area Image|Up To 24 x 30 Inch Display', + '4SBT' => 'Up To Full Area Image|Up To 30 x 40 Inch Display', + '4SGK' => 'Up To Full Area Image|Up To 27 x 85 Inch Display', + '4SIL' => 'Up To Full Area Image|Up To 60 x 40 Inch Display', + '4SAH' => 'Up To Full Area Image|Up To 69 x 48 Inch Display', + '4SGA' => 'Up To Full Area Image|Up To 27 x 141 Inch Display', + '4SDR' => 'Up To Full Area Image|Up To 26 x 241 Inch Display', + '4SID' => 'Up To Full Area Image|Up To 30 x 240 Inch Display', + '4SCX' => 'Up To Full Area Image|Any Size Display', + '4SGR' => 'Up To Full Area Image|Up To B1 Display', + '4SEC' => 'Up To Full Area Image|Up To A0 Display', + '4SET' => 'Up To Full Area Image|Up To B0 Display', + '4SKT' => 'Up To 1/4 Area Image|Up To 43 x 62 Inch Display', + '4SEW' => 'Up To 1/4 Area Image|Up To 48 x 71 Inch Display', + '4SEH' => 'Up To 1/4 Area Image|Up To 43 x 126 Inch Display', + '4SBS' => 'Up To 1/4 Area Image|Up To 83 x 135 Inch Display', + '4SMR' => 'Up To 1/4 Area Image|Any Size Display', + '4SJX' => 'Up To 1/4 Area Image|Up To B0 Display', + '4SAY' => 'Up To 1/2 Area Image|Up To 43 x 62 Inch Display', + '4SKY' => 'Up To 1/2 Area Image|Up To 48 x 71 Inch Display', + '4SBV' => 'Up To 1/2 Area Image|Up To 43 x 126 Inch Display', + '4SEP' => 'Up To 1/2 Area Image|Up To 83 x 135 Inch Display', + '4SNG' => 'Up To 1/2 Area Image|Any Size Display', + '4SAZ' => 'Up To 1/2 Area Image|Up To B0 Display', + '4SDW' => 'Up To Full Area Image|Up To 43 x 62 Inch Display', + '4SFW' => 'Up To Full Area Image|Up To 48 x 71 Inch Display', + '4SGN' => 'Up To Full Area Image|Up To 43 x 126 Inch Display', + '4SBX' => 'Up To Full Area Image|Up To 83 x 135 Inch Display', + '4SNO' => 'Up To Full Area Image|Any Size Display', + '4SKK' => 'Up To Full Area Image|Up To B0 Display', + '4SAP' => 'Up To 1/4 Screen Image|Up To 32 Inch Screen', + '4SEK' => 'Up To 1/4 Screen Image|Up To 63 Inch Screen', + '4SLZ' => 'Up To 1/4 Screen Image|Up To 10 Diagonal Foot Screen', + '4SIE' => 'Up To 1/4 Screen Image|Up To 30 Diagonal Foot Screen', + '4SEM' => 'Up To 1/4 Screen Image|Up To 100 Diagonal Foot Screen', + '4SGJ' => 'Up To 1/2 Screen Image|Up To 32 Inch Screen', + '4SBE' => 'Up To 1/2 Screen Image|Up To 63 Inch Screen', + '4SIJ' => 'Up To 1/2 Screen Image|Up To 10 Diagonal Foot Screen', + '4SGY' => 'Up To 1/2 Screen Image|Up To 30 Diagonal Foot Screen', + '4SDQ' => 'Up To 1/2 Screen Image|Up To 100 Diagonal Foot Screen', + '4SBZ' => 'Up To Full Screen Image|Up To 32 Inch Screen', + '4SJF' => 'Up To Full Screen Image|Up To 63 Inch Screen', + '4SLE' => 'Up To Full Screen Image|Up To 10 Diagonal Foot Screen', + '4SJY' => 'Up To Full Screen Image|Up To 30 Diagonal Foot Screen', + '4SKC' => 'Up To Full Screen Image|Up To 100 Diagonal Foot Screen', + '4SDL' => 'Up To Full Screen Image|Any Size Screen', + '4SFA' => 'Up To 1/4 Area Image|Any Size Item', + '4SCG' => 'Up To 1/2 Area Image|Any Size Item', + '4SLR' => 'Up To Full Area Image|Any Size Item', + '4SGZ' => 'Up To 3 x 4.5 Inch Image|Any Size Media', + '4SFH' => 'Up To 5 x 7 Inch Image|Any Size Media', + '4SCU' => 'Up To 6 x 9 Inch Image|Any Size Media', + '4SLF' => 'Up To 8 x 10 Inch Image|Any Size Media', + '4SAV' => 'Up To 8 x 12 Inch Image|Any Size Media', + '4SKB' => 'Up To 11 x 14 Inch Image|Any Size Media', + '4SAE' => 'Up To 14 x 20 Inch Image|Any Size Media', + '4SEZ' => 'Up To 16 x 20 Inch Image|Any Size Media', + '4SDB' => 'Up To 20 x 24 Inch Image|Any Size Media', + '4SDG' => 'Up To 24 x 30 Inch Image|Any Size Media', + '4SDE' => 'Up To 30 x 40 Inch Image|Any Size Media', + '4SJE' => 'Up To 38 x 50 Inch Image|Any Size Media', + '4SCM' => 'Up To 40 x 60 Inch Image|Any Size Media', + '4SIN' => 'Any Size Image|Any Size Media', + '4SDA' => 'Up To 11 x 15 cm Image|Any Size Media', + '4SME' => 'Up To 13 x 18 cm Image|Any Size Media', + '4SFC' => 'Up To 15 x 21 cm Image|Any Size Media', + '4SIG' => 'Up To 18 x 25 cm Image|Any Size Media', + '4SEV' => 'Up To 21 x 30 cm Image|Any Size Media', + '4SJJ' => 'Up To 25 x 36 cm Image|Any Size Media', + '4SMD' => 'Up To 25 x 36 cm Image|Any Size Media', + '4SLH' => 'Up To 30 x 42 cm Image|Any Size Media', + '4SEE' => 'Up To 42 x 60 cm Image|Any Size Media', + '4SDC' => 'Up To 50 x 71 cm Image|Any Size Media', + '4SDY' => 'Up To 60 x 85 cm Image|Any Size Media', + '4SCQ' => 'Up To 70 x 100 cm Image|Any Size Media', + '4SMF' => 'Up To 85 x 119 cm Image|Any Size Media', + '4SJC' => 'Up To 100 x 142 cm Image|Any Size Media', + '4SFN' => 'Up To 1/4 Area Image|Up To 25 x 13 Inch Media', + '4SLC' => 'Up To 1/4 Area Image|Up To 50 x 24 Inch Media', + '4SIR' => 'Up To 1/4 Area Image|Up To 26 x 53 Inch Media', + '4SDT' => 'Up To 1/4 Area Image|Up To 46 x 60 Inch Media', + '4SFB' => 'Up To 1/4 Area Image|Up To 138 x 53 Inch Media', + '4SGV' => 'Up To 1/2 Area Image|Up To 25 x 13 Inch Media', + '4SJR' => 'Up To 1/2 Area Image|Up To 50 x 24 Inch Media', + '4SKL' => 'Up To 1/2 Area Image|Up To 26 x 53 Inch Media', + '4SEX' => 'Up To 1/2 Area Image|Up To 46 x 60 Inch Media', + '4SBW' => 'Up To 1/2 Area Image|Up To 138 x 53 Inch Media', + '4SJN' => 'Up To Full Area Image|Up To 25 x 13 Inch Media', + '4SKH' => 'Up To Full Area Image|Up To 50 x 24 Inch Media', + '4SKM' => 'Up To Full Area Image|Up To 26 x 53 Inch Media', + '4SGG' => 'Up To Full Area Image|Up To 46 x 60 Inch Media', + '4SDJ' => 'Up To Full Area Image|Up To 138 x 53 Inch Media', + '4SCZ' => 'Up To 1/4 Screen Image|Up To 15 Inch Screen', + '4SCS' => 'Up To 1/4 Screen Image|Up To 21 Inch Screen', + '4SMS' => 'Up To 1/4 Screen Image|Any Size Screen', + '4SED' => 'Up To 1/2 Screen Image|Up To 15 Inch Screen', + '4SFV' => 'Up To 1/2 Screen Image|Up To 21 Inch Screen', + '4SMT' => 'Up To 1/2 Screen Image|Any Size Screen', + '4SCY' => 'Up To Full Screen Image|Up To 15 Inch Screen', + '4SEB' => 'Up To Full Screen Image|Up To 21 Inch Screen', + '4SMU' => 'Up To Full Screen Image|Any Size Screen', + '4SGH' => 'Up To 1/4 Screen Image|Any Size Screen', + '4SGC' => 'Up To 1/2 Screen Image|Any Size Screen', + '4SES' => 'Up To Full Screen Image|Any Size Screen', + '4SKQ' => 'Up To 1/4 Area Image|Up To 180 x 150 Pixels Ad', + '4SCA' => 'Up To 1/4 Area Image|Up To 468 x 60 Pixels Ad', + '4SCK' => 'Up To 1/4 Area Image|Up To 728 x 90 Pixels Ad', + '4SCF' => 'Up To 1/4 Area Image|Up To 300 x 600 Pixels Ad', + '4SIU' => 'Up To 1/4 Area Image|Up To Full Screen Ad', + '4SAI' => 'Up To 1/2 Area Image|Up To 180 x 150 Pixels Ad', + '4SII' => 'Up To 1/2 Area Image|Up To 468 x 60 Pixels Ad', + '4SCW' => 'Up To 1/2 Area Image|Up To 728 x 90 Pixels Ad', + '4SLM' => 'Up To 1/2 Area Image|Up To 300 x 600 Pixels Ad', + '4SFT' => 'Up To 1/2 Area Image|Up To Full Screen Ad', + '4SJT' => 'Up To Full Area Image|Up To 180 x 150 Pixels Ad', + '4SGD' => 'Up To Full Area Image|Up To 468 x 60 Pixels Ad', + '4SAR' => 'Up To Full Area Image|Up To 728 x 90 Pixels Ad', + '4SEG' => 'Up To Full Area Image|Up To 300 x 600 Pixels Ad', + '4SBG' => 'Any Size Image|Up To Full Screen Ad', + '4SMH' => 'Up To 150 x 150 Pixels Image|Any Size Screen', + '4SMJ' => 'Up To 300 x 600 Pixels Image|Any Size Screen', + '4SKG' => 'Any Size Image|Any Size Screen', + # 5V - Version + '5VAA' => 'All Versions', + '5VXX' => 'Not Applicable or None', + '5VUL' => 'Any Versions', + '5VVM' => 'Single Print Version', + '5VVB' => 'Multiple Print Versions', + '5VUP' => 'Single Version', + '5VUY' => 'Multiple Versions', + '5VVC' => 'Single Paperback Edition', + '5VUK' => 'Single Hardcover Edition', + '5VVH' => 'Single Edition in All Binding Formats', + '5VVK' => 'Multiple Paperback Editions', + '5VUU' => 'Multiple Hardcover Editions', + '5VVL' => 'Multiple Editions in All Binding Formats', + '5VUZ' => 'Single Issue', + '5VVJ' => 'Multiple Issues', + '5VUG' => 'Single Edition', + '5VVG' => 'Multiple Editions', + # 6Q - Quantity + '6QAA' => 'Any Quantity', + '6QXX' => 'Not Applicable or None', + '6QUL' => 'Any Quantity', + '6QAU' => 'One|Print Run', + '6QDA' => 'Up To 10|Print Run', + '6QEY' => 'Up To 100|Print Run', + '6QBA' => 'Up To 1,000|Print Run', + '6QCW' => 'Up To 5,000|Print Run', + '6QEC' => 'Up To 10,000|Print Run', + '6QFD' => 'Up To 25,000|Print Run', + '6QBH' => 'Up To 40,000|Print Run', + '6QFR' => 'Up To 50,000|Print Run', + '6QDQ' => 'Up To 100,000|Print Run', + '6QBG' => 'Up To 250,000|Print Run', + '6QEN' => 'Up To 500,000|Print Run', + '6QDL' => 'Any Quantity Of|Print Run', + '6QBU' => 'One|Copy', + '6QDR' => 'Up To 10|Total Circulation', + '6QFU' => 'Up To 25|Total Circulation', + '6QFV' => 'Up To 50|Total Circulation', + '6QEJ' => 'Up To 100|Total Circulation', + '6QFW' => 'Up To 250|Total Circulation', + '6QFY' => 'Up To 500|Total Circulation', + '6QCD' => 'Up To 1,000|Total Circulation', + '6QFZ' => 'Up To 2,500|Total Circulation', + '6QAT' => 'Up To 5,000|Total Circulation', + '6QBB' => 'Up To 10,000|Total Circulation', + '6QFS' => 'Up To 25,000|Total Circulation', + '6QAN' => 'Up To 50,000|Total Circulation', + '6QCS' => 'Up To 100,000|Total Circulation', + '6QDT' => 'Up To 250,000|Total Circulation', + '6QCI' => 'Up To 500,000|Total Circulation', + '6QCN' => 'Up To 1 Million|Total Circulation', + '6QCK' => 'Up To 2 Million|Total Circulation', + '6QCL' => 'Up To 3 Million|Total Circulation', + '6QAV' => 'Up To 5 Million|Total Circulation', + '6QDK' => 'Up To 10 Million|Total Circulation', + '6QGB' => 'Up To 25 Million|Total Circulation', + '6QGC' => 'Up To 50 Million|Total Circulation', + '6QEV' => 'Any Quantity Of|Circulation', + '6QFI' => 'One|Reprint', + '6QDG' => 'Up To 10|Reprints', + '6QCB' => 'Up To 100|Reprints', + '6QAY' => 'Up To 1,000|Reprints', + '6QBF' => 'Up To 10,000|Reprints', + '6QCU' => 'Any Quantity Of|Reprints', + '6QEH' => 'One|Print Run', + '6QDH' => 'Up To 10|Print Run', + '6QAZ' => 'Up To 100|Print Run', + '6QFB' => 'Up To 1,000|Print Run', + '6QAQ' => 'Up To 5,000|Print Run', + '6QEG' => 'Up To 10,000|Print Run', + '6QBV' => 'Up To 25,000|Print Run', + '6QCG' => 'Up To 50,000|Print Run', + '6QAH' => 'Up To 100,000|Print Run', + '6QDE' => 'Up To 250,000|Print Run', + '6QDJ' => 'Up To 500,000|Print Run', + '6QCZ' => 'Up To 1 Million|Print Run', + '6QCT' => 'Up To 2 Million|Print Run', + '6QAR' => 'Up To 3 Million|Print Run', + '6QDC' => 'Up To 5 Million|Print Run', + '6QDU' => 'Up To 10 Million|Print Run', + '6QEU' => 'Any Quantity Of|Print Run', + '6QFT' => 'One|Copy', + '6QDI' => 'One|Display', + '6QDY' => 'Up To 5|Displays', + '6QFJ' => 'Up To 10|Displays', + '6QEL' => 'Up To 25|Displays', + '6QBD' => 'Up To 50|Displays', + '6QAE' => 'Up To 100|Displays', + '6QCE' => 'Up To 250|Displays', + '6QAP' => 'Up To 500|Displays', + '6QBY' => 'Up To 1,000|Displays', + '6QBC' => 'Up To 2,500|Displays', + '6QET' => 'Up To 5,000|Displays', + '6QFF' => 'Up To 10,000|Displays', + '6QDS' => 'Up To 25,000|Displays', + '6QES' => 'Up To 50,000|Displays', + '6QDZ' => 'Up To 100,000|Displays', + '6QBW' => 'Up To 250,000|Displays', + '6QAX' => 'Up To 500,000|Displays', + '6QDB' => 'Up To 1 Million|Displays', + '6QEK' => 'Up To 2 Million|Displays', + '6QFA' => 'Up To 3 Million|Displays', + '6QCJ' => 'Up To 5 Million|Displays', + '6QFQ' => 'Any Quantity Of|Displays', + '6QCX' => 'One|Display', + '6QBP' => 'Up To 5|Displays', + '6QAL' => 'Up To 10|Displays', + '6QDX' => 'Up To 25|Displays', + '6QEM' => 'Up To 50|Displays', + '6QEA' => 'Up To 100|Displays', + '6QFG' => 'Up To 250|Displays', + '6QAG' => 'Up To 500|Displays', + '6QEI' => 'Any Quantity Of|Displays', + '6QEP' => 'One|Copy', + '6QEX' => 'Two|Copies', + '6QCF' => 'Three|Copies', + '6QBK' => 'Four|Copies', + '6QBL' => 'Five|Copies', + '6QCP' => 'Up To 10|Copies', + '6QDV' => 'Up To 50|Copies', + '6QCM' => 'Up To 100|Copies', + '6QAI' => 'Up To 500|Copies', + '6QAS' => 'Up To 1,000|Copies', + '6QDW' => 'Up To 5,000|Copies', + '6QCQ' => 'Up To 10,000|Copies', + '6QAM' => 'Any Quantity Of|Copies', + '6QBE' => 'One|Copy', + '6QFC' => 'Up To 5|Copies', + '6QEB' => 'Up To 10|Copies', + '6QGD' => 'Up To 25|Copies', + '6QGE' => 'Up To 50|Copies', + '6QCR' => 'Up To 100|Copies', + '6QCA' => 'Up To 250|Copies', + '6QBS' => 'Up To 500|Copies', + '6QDF' => 'Up To 1,000|Copies', + '6QEW' => 'Up To 2,500|Copies', + '6QFE' => 'Up To 5,000|Copies', + '6QEE' => 'Up To 10,000|Copies', + '6QBT' => 'Up To 25,000|Copies', + '6QDP' => 'Up To 50,000|Copies', + '6QDN' => 'Up To 100,000|Copies', + '6QFN' => 'Any Quantity Of|Copies', + '6QFH' => 'Up To 10,000|Viewers', + '6QCV' => 'Up To 100,000|Viewers', + '6QBN' => 'Up To 1 Million|Viewers', + '6QFP' => 'Up To 10 Million|Viewers', + '6QBI' => 'Up To 100 Million|Viewers', + '6QBQ' => 'Any Quantity Of|Viewers', + '6QAB' => 'Up To 10,000|Impressions', + '6QBR' => 'Up To 100,000|Impressions', + '6QCY' => 'Up To 1 Million|Impressions', + '6QBM' => 'Up To 10 Million|Impressions', + '6QFM' => 'Any Quantity Of|Impressions', + '6QDD' => 'Up To 100|Viewers', + '6QEQ' => 'Up To 1,000|Viewers', + '6QEZ' => 'Up To 10,000|Viewers', + '6QBZ' => 'Up To 100,000|Viewers', + '6QCC' => 'Any Quantity Of|Viewers', + '6QCH' => 'One|Copy', + '6QAW' => 'Up To 5|Copies', + '6QAK' => 'Up To 10|Copies', + '6QFL' => 'Up To 100|Copies', + '6QAC' => 'Up To 1,000|Copies', + '6QAD' => 'Up To 10,000|Copies', + '6QEF' => 'Up To 25,000|Copies', + '6QAF' => 'Up To 50,000|Copies', + '6QED' => 'Up To 100,000|Copies', + '6QFK' => 'Up To 250,000|Copies', + '6QDM' => 'Up To 500,000|Copies', + '6QBX' => 'Up To 1 Million|Copies', + '6QER' => 'Any Quantity Of|Copies', + # 7D - Duration + '7DAA' => 'In Perpetuity', + '7DXX' => 'Not Applicable or None', + '7DUL' => 'Any Durations', + '7DUT' => 'Up To 10 Years', + '7DUS' => 'Up To 6 Months', + '7DUV' => 'Up To 6 Months', + '7DUW' => 'Up To 1 Year', + '7DUY' => 'Up To 3 Years', + '7DUZ' => 'Up To 5 Years', + '7DUQ' => 'Up To 10 Years', + '7DXC' => 'Up To 1 Day', + '7DXL' => 'Up To 1 Week', + '7DXH' => 'Life Of Publication', + '7DYF' => 'Up To 1 Day', + '7DWL' => 'Up To 1 Week', + '7DYJ' => 'Up To 2 Weeks', + '7DXF' => 'Up To 1 Month', + '7DZF' => 'Up To 2 Months', + '7DWC' => 'Up To 3 Months', + '7DWW' => 'Up To 6 Months', + '7DZA' => 'Up To 1 Year', + '7DZP' => 'Up To 2 Years', + '7DZJ' => 'Up To 3 Years', + '7DZK' => 'Up To 5 Years', + '7DZL' => 'Up To 10 Years', + '7DWS' => 'Life Of Publication', + '7DXZ' => 'Up To 3 Months', + '7DXW' => 'Up To 6 Months', + '7DXD' => 'Up To 1 Year', + '7DYS' => 'Life Of Publication', + '7DYM' => 'Up To 1 Year', + '7DWE' => 'Up To 2 Years', + '7DYL' => 'Up To 3 Years', + '7DWV' => 'Up To 5 Years', + '7DWB' => 'Up To 7 Years', + '7DYY' => 'Up To 10 Years', + '7DWG' => 'Up To 15 Years', + '7DXA' => 'Full Term Of Copyright', + '7DXT' => 'Up To 1 Day', + '7DXB' => 'Up To 1 Week', + '7DYI' => 'Up To 1 Month', + '7DWI' => 'Up To 1 Year', + '7DZM' => 'Up To 2 Years', + '7DZN' => 'Up To 3 Years', + '7DYV' => 'Life Of Event', + '7DXQ' => 'Up To 1 Year', + '7DZH' => 'Up To 2 Years', + '7DXP' => 'Up To 3 Years', + '7DYD' => 'Up To 5 Years', + '7DWU' => 'Up To 7 Years', + '7DXG' => 'Up To 10 Years', + '7DXV' => 'Up To 15 Years', + '7DWR' => 'In Perpetuity', + '7DXM' => 'Up To 1 Year', + '7DWK' => 'Up To 2 Years', + '7DXS' => 'In Perpetuity', + '7DYG' => 'Up To 1 Day', + '7DZD' => 'Up To 1 Week', + '7DWP' => 'Up To 13 Weeks', + '7DYT' => 'Up To 26 Weeks', + '7DWT' => 'Up To 52 Weeks', + '7DYA' => 'Up To 5 Years', + '7DXR' => 'Up To 10 Years', + '7DXI' => 'In Perpetuity', + '7DYW' => 'Up To 1 Day', + '7DYP' => 'Up To 1 Week', + '7DWJ' => 'Up To 1 Month', + '7DYE' => 'Up To 3 Months', + '7DYX' => 'Up To 6 Months', + '7DXE' => 'Up To 1 Year', + '7DWZ' => 'Up To 2 Years', + '7DZB' => 'Up To 3 Years', + '7DYN' => 'Up To 5 Years', + '7DYC' => 'Up To 10 Years', + '7DXY' => 'Up To 15 Years', + '7DWM' => 'In Perpetuity', + '7DYZ' => 'Up To 1 Day', + '7DXK' => 'Up To 1 Month', + '7DWY' => 'Up To 3 Months', + '7DYB' => 'Up To 6 Months', + '7DZG' => 'Up To 1 Year', + '7DYK' => 'Up To 2 Years', + '7DYQ' => 'In Perpetuity', + # 8R - Region + '8RAA' => 'Worldwide', + '8RXX' => 'Not Applicable or None', + '8RUL' => 'Any Regions', + '8RWA' => 'Broad International Region|Worldwide Excluding Northern America', + '8RWB' => 'Broad International Region|Worldwide Excluding USA', + '8RWC' => 'Broad International Region|Worldwide Excluding USA and Europe', + '8RWD' => 'Broad International Region|Worldwide Excluding Europe', + '8RWE' => 'Broad International Region|Worldwide Excluding USA and UK', + '8RWF' => 'Broad International Region|Worldwide Excluding UK', + '8RWG' => 'Broad International Region|All English Speaking Countries', + '8RWH' => 'Broad International Region|All English Speaking Countries Excluding USA', + '8RAH' => 'Broad International Region|All Spanish Speaking Countries', + '8RWI' => 'Broad International Region|All Spanish Speaking Countries Excluding USA', + '8RFY' => 'Broad International Region|All Americas', + '8REK' => 'Broad International Region|Europe, Middle East and Africa', + '8RWJ' => 'Broad International Region|USA, Canada and Mexico', + '8RQV' => 'Northern America|One Minor City, Up To 250,000 Population', + '8RQT' => 'Northern America|One Major City, Over 250,000 Population', + '8RQU' => 'Northern America|One Metropolitan Area, Adjoining Cities', + '8RRJ' => 'Northern America|One State Or Province', + '8RYK' => 'Northern America|Up To 3 States Or Provinces', + '8RCD' => 'Northern America|Up To 5 States Or Provinces', + '8RGJ' => 'Northern America|All Northern American Countries', + '8RCE' => 'Northern America|USA and Canada', + '8RHQ' => 'Northern America|USA', + '8RCA' => 'Northern America|Canada', + '8RHJ' => 'Northern America|USA-Central', + '8RHP' => 'Northern America|USA-Midwest', + '8RHR' => 'Northern America|USA-Northeast', + '8RHS' => 'Northern America|USA-Pacific Northwest', + '8RHW' => 'Northern America|USA-Southeast', + '8RHX' => 'Northern America|USA-Southwest', + '8RIA' => 'Northern America|USA-West', + '8RHY' => 'Northern America|USA-Minor Outlying Islands', + '8RUK' => 'Northern America|USA-All Territories, Protectorates, Dependencies, Outposts', + '8RBK' => 'Northern America|Canada-British Columbia', + '8RUM' => 'Northern America|Canada-Prairies', + '8RUN' => 'Northern America|Canada-Atlantic Provinces', + '8RCJ' => 'Northern America|Canada-Ontario', + '8RUP' => 'Northern America|Canada-Quebec', + '8RUQ' => 'Northern America|Canada-Northern Territories', + '8RBM' => 'Northern America|Bermuda', + '8RGL' => 'Northern America|Greenland', + '8RPM' => 'Northern America|Saint Pierre and Miquelon', + '8RQL' => 'Europe|One Minor City, Up To 250,000 Population', + '8RQJ' => 'Europe|One Major City, Over 250,000 Population', + '8RQK' => 'Europe|One Metropolitan Area, Adjoining Cities', + '8RRF' => 'Europe|One State Or Province', + '8RYF' => 'Europe|Up To 3 States Or Provinces', + '8RYG' => 'Europe|Up To 5 States Or Provinces', + '8RDU' => 'Europe|All Europe', + '8REL' => 'Europe|All European Union Countries', + '8REI' => 'Europe|All United Kingdom', + '8REJ' => 'Europe|All Western Europe', + '8RED' => 'Europe|All Northern Europe', + '8REB' => 'Europe|All European Mediterranean Countries', + '8REA' => 'Europe|All Eastern Europe', + '8RDW' => 'Europe|All Baltic States', + '8RDX' => 'Europe|All Benelux', + '8RDY' => 'Europe|All Caucasian States', + '8REF' => 'Europe|All Scandinavia', + '8RAX' => 'Europe|Aland Islands', + '8RAL' => 'Europe|Albania', + '8RAD' => 'Europe|Andorra', + '8RAM' => 'Europe|Armenia', + '8RAT' => 'Europe|Austria', + '8RAZ' => 'Europe|Azerbaijan', + '8RBY' => 'Europe|Belarus', + '8RBE' => 'Europe|Belgium', + '8RBA' => 'Europe|Bosnia and Herzegovina', + '8RBG' => 'Europe|Bulgaria', + '8RDR' => 'Europe|Croatia', + '8RCY' => 'Europe|Cyprus', + '8RCZ' => 'Europe|Czech Republic', + '8RDK' => 'Europe|Denmark', + '8REM' => 'Europe|England', + '8REE' => 'Europe|Estonia', + '8RDS' => 'Europe|Faeroe Islands', + '8RFI' => 'Europe|Finland', + '8RFR' => 'Europe|France', + '8RGE' => 'Europe|Georgia', + '8RDE' => 'Europe|Germany', + '8RGI' => 'Europe|Gibraltar', + '8RGR' => 'Europe|Greece', + '8RGG' => 'Europe|Guernsey', + '8RHU' => 'Europe|Hungary', + '8RIS' => 'Europe|Iceland', + '8RIE' => 'Europe|Ireland', + '8RIM' => 'Europe|Isle Of Man', + '8RIT' => 'Europe|Italy', + '8RJE' => 'Europe|Jersey', + '8RLV' => 'Europe|Latvia', + '8RLI' => 'Europe|Liechtenstein', + '8RLT' => 'Europe|Lithuania', + '8RLU' => 'Europe|Luxembourg', + '8RMK' => 'Europe|Macedonia', + '8RMT' => 'Europe|Malta', + '8RMD' => 'Europe|Moldova', + '8RMC' => 'Europe|Monaco', + '8RNL' => 'Europe|Netherlands', + '8RUH' => 'Europe|Northern Ireland', + '8RNO' => 'Europe|Norway', + '8RPL' => 'Europe|Poland', + '8RPT' => 'Europe|Portugal', + '8RRO' => 'Europe|Romania', + '8RRU' => 'Europe|Russian Federation', + '8RSM' => 'Europe|San Marino', + '8REN' => 'Europe|Scotland', + '8RCS' => 'Europe|Serbia and Montenegro', + '8RSK' => 'Europe|Slovakia', + '8RSI' => 'Europe|Slovenia', + '8RES' => 'Europe|Spain', + '8RSE' => 'Europe|Sweden', + '8RCH' => 'Europe|Switzerland', + '8RUA' => 'Europe|Ukraine', + '8RUI' => 'Europe|Wales', + '8RDT' => 'Europe|Vatican City State', + '8RQF' => 'Asia|One Minor City, Up To 250,000 Population', + '8RQD' => 'Asia|One Major City, Over 250,000 Population', + '8RQE' => 'Asia|One Metropolitan Area, Adjoining Cities', + '8RRC' => 'Asia|One State Or Province', + '8RAV' => 'Asia|Up To 3 States Or Provinces', + '8RYD' => 'Asia|Up To 5 States Or Provinces', + '8RDB' => 'Asia|All Asia', + '8RDC' => 'Asia|All Central Asia', + '8RCP' => 'Asia|All Eastern Asia', + '8RDG' => 'Asia|All Southern Asia', + '8RDH' => 'Asia|All Southeastern Asia', + '8RBD' => 'Asia|Bangladesh', + '8RBT' => 'Asia|Bhutan', + '8RBN' => 'Asia|Brunei Darussalam', + '8RKH' => 'Asia|Cambodia', + '8RCN' => 'Asia|All China', + '8RUB' => 'Asia|China-East', + '8RAY' => 'Asia|China-Northeast', + '8RUC' => 'Asia|China-North', + '8RUD' => 'Asia|China-South Central', + '8RUF' => 'Asia|China-Southwest', + '8RHK' => 'Asia|Hong Kong', + '8RIN' => 'Asia|India', + '8RID' => 'Asia|Indonesia', + '8RJP' => 'Asia|Japan', + '8RKZ' => 'Asia|Kazakhstan', + '8RKP' => 'Asia|North Korea', + '8RKR' => 'Asia|South Korea', + '8RKG' => 'Asia|Kyrgyzstan', + '8RLA' => 'Asia|Laos', + '8RMO' => 'Asia|Macao', + '8RMY' => 'Asia|Malaysia', + '8RMV' => 'Asia|Maldives', + '8RMN' => 'Asia|Mongolia', + '8RMM' => 'Asia|Myanmar', + '8RNP' => 'Asia|Nepal', + '8RPK' => 'Asia|Pakistan', + '8RPH' => 'Asia|Philippines', + '8RSG' => 'Asia|Singapore', + '8RTW' => 'Asia|Taiwan', + '8RTJ' => 'Asia|Tajikistan', + '8RTH' => 'Asia|Thailand', + '8RDA' => 'Asia|Tibet', + '8RTL' => 'Asia|Timor-Leste', + '8RTM' => 'Asia|Turkmenistan', + '8RUZ' => 'Asia|Uzbekistan', + '8RVN' => 'Asia|Viet Nam', + '8RQO' => 'Latin America and Caribbean|One Minor City, Up To 250,000 Population', + '8RQM' => 'Latin America and Caribbean|One Major City, Over 250,000 Population', + '8RQN' => 'Latin America and Caribbean|One Metropolitan Area, Adjoining Cities', + '8RRG' => 'Latin America and Caribbean|One State Or Province', + '8RYH' => 'Latin America and Caribbean|Up To 3 States Or Provinces', + '8RYI' => 'Latin America and Caribbean|Up To 5 States Or Provinces', + '8RAC' => 'Latin America and Caribbean|All Latin America and Caribbean', + '8RUJ' => 'Latin America and Caribbean|All Latin America', + '8RFZ' => 'Latin America and Caribbean|All Caribbean', + '8RFS' => 'Latin America and Caribbean|All South America', + '8RGC' => 'Latin America and Caribbean|All Central America', + '8RFT' => 'Latin America and Caribbean|All Andean Countries', + '8RFU' => 'Latin America and Caribbean|All Southern Cone', + '8RFV' => 'Latin America and Caribbean|All Amazonia', + '8RAI' => 'Latin America and Caribbean|Anguilla', + '8RAG' => 'Latin America and Caribbean|Antigua and Barbuda', + '8RAR' => 'Latin America and Caribbean|Argentina', + '8RAW' => 'Latin America and Caribbean|Aruba', + '8RBS' => 'Latin America and Caribbean|Bahamas', + '8RBB' => 'Latin America and Caribbean|Barbados', + '8RBZ' => 'Latin America and Caribbean|Belize', + '8RGZ' => 'Latin America and Caribbean|Bequia', + '8RBO' => 'Latin America and Caribbean|Bolivia', + '8RHA' => 'Latin America and Caribbean|Bonaire', + '8RBR' => 'Latin America and Caribbean|Brazil', + '8RHB' => 'Latin America and Caribbean|British Virgin Islands', + '8RKY' => 'Latin America and Caribbean|Cayman Islands', + '8RCL' => 'Latin America and Caribbean|Chile', + '8RCO' => 'Latin America and Caribbean|Colombia', + '8RCR' => 'Latin America and Caribbean|Costa Rica', + '8RCU' => 'Latin America and Caribbean|Cuba', + '8RHC' => 'Latin America and Caribbean|Curacao', + '8RDM' => 'Latin America and Caribbean|Dominica', + '8RDO' => 'Latin America and Caribbean|Dominican Republic', + '8REC' => 'Latin America and Caribbean|Ecuador', + '8RSV' => 'Latin America and Caribbean|El Salvador', + '8RFK' => 'Latin America and Caribbean|Falkland Islands, Malvinas', + '8RGF' => 'Latin America and Caribbean|French Guiana', + '8RGD' => 'Latin America and Caribbean|Grenada', + '8RGP' => 'Latin America and Caribbean|Guadeloupe', + '8RGT' => 'Latin America and Caribbean|Guatemala', + '8RGY' => 'Latin America and Caribbean|Guyana', + '8RHT' => 'Latin America and Caribbean|Haiti', + '8RHN' => 'Latin America and Caribbean|Honduras', + '8RJM' => 'Latin America and Caribbean|Jamaica', + '8RMQ' => 'Latin America and Caribbean|Martinique', + '8RMX' => 'Latin America and Caribbean|Mexico', + '8RMS' => 'Latin America and Caribbean|Montserrat', + '8RAN' => 'Latin America and Caribbean|Netherlands Antilles', + '8RNI' => 'Latin America and Caribbean|Nicaragua', + '8RPA' => 'Latin America and Caribbean|Panama', + '8RPY' => 'Latin America and Caribbean|Paraguay', + '8RFQ' => 'Latin America and Caribbean|Patagonia', + '8RPE' => 'Latin America and Caribbean|Peru', + '8RPR' => 'Latin America and Caribbean|Puerto Rico', + '8RHD' => 'Latin America and Caribbean|Saba', + '8RHE' => 'Latin America and Caribbean|Saint Barthelemy', + '8RHF' => 'Latin America and Caribbean|Saint Eustatius', + '8RKN' => 'Latin America and Caribbean|Saint Kitts and Nevis', + '8RLC' => 'Latin America and Caribbean|Saint Lucia', + '8RHG' => 'Latin America and Caribbean|Saint Martin', + '8RVC' => 'Latin America and Caribbean|Saint Vincent and The Grenadines', + '8RSR' => 'Latin America and Caribbean|Suriname', + '8RTT' => 'Latin America and Caribbean|Trinidad and Tobago', + '8RTC' => 'Latin America and Caribbean|Turks and Caicos Islands', + '8RHH' => 'Latin America and Caribbean|U.S. Virgin Islands', + '8RUY' => 'Latin America and Caribbean|Uruguay', + '8RVE' => 'Latin America and Caribbean|Venezuela', + '8RQZ' => 'Oceania|One Minor City, Up To 250,000 Population', + '8RQW' => 'Oceania|One Major City, Over 250,000 Population', + '8RQY' => 'Oceania|One Metropolitan Area, Adjoining Cities', + '8RRK' => 'Oceania|One State Or Province', + '8RYL' => 'Oceania|Up To 3 States Or Provinces', + '8RYM' => 'Oceania|Up To 5 States Or Provinces', + '8RCT' => 'Oceania|All Oceania', + '8RUR' => 'Oceania|All Australia and New Zealand', + '8RUS' => 'Oceania|All Oceania excluding Australia and New Zealand', + '8RAU' => 'Oceania|Australia', + '8RAS' => 'Oceania|American Samoa', + '8RCX' => 'Oceania|Christmas Island', + '8RCC' => 'Oceania|Cocos, Keeling Islands', + '8RKM' => 'Oceania|Comoros', + '8RCK' => 'Oceania|Cook Islands', + '8RFJ' => 'Oceania|Fiji', + '8RPF' => 'Oceania|French Polynesia', + '8RGU' => 'Oceania|Guam', + '8RKI' => 'Oceania|Kiribati', + '8RMG' => 'Oceania|Madagascar', + '8RMH' => 'Oceania|Marshall Islands', + '8RMU' => 'Oceania|Mauritius', + '8RFM' => 'Oceania|Micronesia', + '8RFF' => 'Oceania|Midway Islands', + '8RNR' => 'Oceania|Nauru', + '8RNC' => 'Oceania|New Caledonia', + '8RNZ' => 'Oceania|New Zealand', + '8RNU' => 'Oceania|Niue', + '8RNF' => 'Oceania|Norfolk Island', + '8RMP' => 'Oceania|Northern Mariana Islands', + '8RPW' => 'Oceania|Palau', + '8RPG' => 'Oceania|Papua New Guinea', + '8RPN' => 'Oceania|Pitcairn Islands', + '8RFH' => 'Oceania|Rapa Nui, Easter Island', + '8RWS' => 'Oceania|Samoa', + '8RSC' => 'Oceania|Seychelles', + '8RSB' => 'Oceania|Solomon Islands', + '8RLK' => 'Oceania|Sri Lanka', + '8RFL' => 'Oceania|Tahiti', + '8RTK' => 'Oceania|Tokelau', + '8RTO' => 'Oceania|Tonga', + '8RTV' => 'Oceania|Tuvalu', + '8RVU' => 'Oceania|Vanuatu', + '8RFP' => 'Oceania|Wallis and Futuna', + '8RQS' => 'Middle East|One Minor City, Up To 250,000 Population', + '8RQP' => 'Middle East|One Major City, Over 250,000 Population', + '8RQR' => 'Middle East|One Metropolitan Area, Adjoining Cities', + '8RRH' => 'Middle East|One State Or Province', + '8RYJ' => 'Middle East|Up To 3 States Or Provinces', + '8RBX' => 'Middle East|Up To 5 States Or Provinces', + '8REX' => 'Middle East|All Middle East', + '8REY' => 'Middle East|All Middle Eastern Gulf States', + '8RIB' => 'Middle East|All Middle Eastern Mediterranean Countries', + '8RAF' => 'Middle East|Afghanistan', + '8RBH' => 'Middle East|Bahrain', + '8RIR' => 'Middle East|Iran', + '8RIQ' => 'Middle East|Iraq', + '8RIL' => 'Middle East|Israel', + '8RJO' => 'Middle East|Jordan', + '8RKW' => 'Middle East|Kuwait', + '8RLB' => 'Middle East|Lebanon', + '8ROM' => 'Middle East|Oman', + '8REV' => 'Middle East|Palestinian Authority', + '8RQA' => 'Middle East|Qatar', + '8RSA' => 'Middle East|Saudi Arabia', + '8RSY' => 'Middle East|Syria', + '8RTR' => 'Middle East|Turkey', + '8RAE' => 'Middle East|United Arab Emirates', + '8RYE' => 'Middle East|Yemen', + '8RQC' => 'Africa|One Minor City, Up To 250,000 Population', + '8RQX' => 'Africa|One Major City, Over 250,000 Population', + '8RQB' => 'Africa|One Metropolitan Area, Adjoining Cities', + '8RRB' => 'Africa|One State Or Province', + '8RYB' => 'Africa|Up To 3 States Or Provinces', + '8RYC' => 'Africa|Up To 5 States Or Provinces', + '8RAJ' => 'Africa|All Africa', + '8RAK' => 'Africa|All African Mediterranean Countries', + '8RAP' => 'Africa|All Central Africa', + '8RAQ' => 'Africa|All Eastern Africa', + '8RBC' => 'Africa|All Southern Africa', + '8RBL' => 'Africa|All Western Africa', + '8RDZ' => 'Africa|Algeria', + '8RAO' => 'Africa|Angola', + '8RBP' => 'Africa|Ascension Island', + '8RBJ' => 'Africa|Benin', + '8RBW' => 'Africa|Botswana', + '8RBF' => 'Africa|Burkina Faso', + '8RBI' => 'Africa|Burundi', + '8RCM' => 'Africa|Cameroon', + '8RCV' => 'Africa|Cape Verde', + '8RCF' => 'Africa|Central African Republic', + '8RTD' => 'Africa|Chad', + '8RCG' => 'Africa|Congo', + '8RCI' => 'Africa|Cote D\'Ivoire', + '8RDJ' => 'Africa|Djibouti', + '8REG' => 'Africa|Egypt', + '8RGQ' => 'Africa|Equatorial Guinea', + '8RER' => 'Africa|Eritrea', + '8RET' => 'Africa|Ethiopia', + '8RGA' => 'Africa|Gabon', + '8RGM' => 'Africa|Gambia', + '8RGH' => 'Africa|Ghana', + '8RGN' => 'Africa|Guinea', + '8RGW' => 'Africa|Guinea-Bissau', + '8RKE' => 'Africa|Kenya', + '8RLS' => 'Africa|Lesotho', + '8RLR' => 'Africa|Liberia', + '8RLY' => 'Africa|Libyan Arab Jamahiriya', + '8RMW' => 'Africa|Malawi', + '8RML' => 'Africa|Mali', + '8RMR' => 'Africa|Mauritania', + '8RYT' => 'Africa|Mayotte', + '8RMA' => 'Africa|Morocco', + '8RMZ' => 'Africa|Mozambique', + '8RNA' => 'Africa|Namibia', + '8RNE' => 'Africa|Niger', + '8RNG' => 'Africa|Nigeria', + '8RRE' => 'Africa|Reunion', + '8RRW' => 'Africa|Rwanda', + '8RSH' => 'Africa|Saint Helena', + '8RST' => 'Africa|Sao Tome and Principe', + '8RSN' => 'Africa|Senegal', + '8RSL' => 'Africa|Sierra Leone', + '8RSO' => 'Africa|Somalia', + '8RZA' => 'Africa|South Africa', + '8RSD' => 'Africa|Sudan', + '8RSZ' => 'Africa|Swaziland', + '8RTZ' => 'Africa|Tanzania, United Republic Of', + '8RTG' => 'Africa|Togo', + '8RTN' => 'Africa|Tunisia', + '8RUG' => 'Africa|Uganda', + '8REH' => 'Africa|Western Sahara', + '8RZM' => 'Africa|Zambia', + '8RZW' => 'Africa|Zimbabwe', + '8RBQ' => 'Other Regions|Antarctica', + '8RCB' => 'Other Regions|All Arctic and Arctic Ocean Islands', + '8RFB' => 'Other Regions|All Northern Atlantic Ocean Islands', + '8RFW' => 'Other Regions|All Southern Atlantic Ocean Islands', + '8RFX' => 'Other Regions|All Southern Indian Ocean Islands', + '8REU' => 'Other Regions|All French Southern Territories', + '8RDQ' => 'Other Regions|All British Indian Ocean Territories', + # 8L - Language + '8LAA' => 'All Languages', + '8LXX' => 'Not Applicable or None', + '8LUL' => 'Any Languages', + '8LOL' => 'Any One Language', + '8LEN' => 'English', + '8LAF' => 'Afrikaans', + '8LAR' => 'Arabic', + '8LBO' => 'Bosnian', + '8LBU' => 'Bulgarian', + '8LCA' => 'Chinese-Cantonese', + '8LCH' => 'Chinese-Mandarin', + '8LCP' => 'Chinese-Other', + '8LCR' => 'Croatian', + '8LCZ' => 'Czech', + '8LDA' => 'Danish', + '8LDU' => 'Dutch', + '8LES' => 'Estonian', + '8LFI' => 'Finnish', + '8LFR' => 'French', + '8LGE' => 'German', + '8LGR' => 'Greek', + '8LHE' => 'Hebrew', + '8LHI' => 'Hindi', + '8LHU' => 'Hungarian', + '8LIC' => 'Icelandic', + '8LIN' => 'Indonesian', + '8LIG' => 'Irish Gaelic', + '8LIT' => 'Italian', + '8LJA' => 'Japanese', + '8LKO' => 'Korean', + '8LLA' => 'Latvian', + '8LMG' => 'Mongolian', + '8LNO' => 'Norwegian', + '8LPO' => 'Polish', + '8LPR' => 'Portuguese', + '8LRO' => 'Romanian', + '8LRU' => 'Russian', + '8LSG' => 'Scottish Gaelic', + '8LSE' => 'Serbian', + '8LSI' => 'Sindhi', + '8LSV' => 'Slovakian', + '8LSL' => 'Slovenian', + '8LSP' => 'Spanish', + '8LSH' => 'Swahili', + '8LSZ' => 'Swazi', + '8LSW' => 'Swedish', + '8LTA' => 'Tagalog', + '8LTH' => 'Thai', + '8LTU' => 'Turkish', + '8LUR' => 'Ukrainian', + '8LYI' => 'Yiddish', + '8LOT' => 'Other Language', + # 8I - Industry + '8IAA' => 'All Industries', + '8IXX' => 'Not Applicable or None', + '8IUL' => 'Any Industries', + '8IAD' => 'Advertising and Marketing', + '8IAG' => 'Agriculture, Farming and Horticulture', + '8IAT' => 'Airline Transportation', + '8IAL' => 'Alcohol', + '8IAR' => 'Architecture and Engineering', + '8IAE' => 'Arts and Entertainment', + '8IAU' => 'Automotive', + '8IAV' => 'Aviation', + '8IBA' => 'Baby and Childcare', + '8IBE' => 'Beauty and Personal Care', + '8IBI' => 'Biotechnology', + '8IBR' => 'Broadcast Media', + '8ICO' => 'Business Consulting and Services', + '8ICH' => 'Chemicals', + '8ICE' => 'Communications Equipment and Services', + '8IHS' => 'Computer Hardware, Software and Peripherals', + '8ICC' => 'Construction and Contracting', + '8IAP' => 'Consumer Appliances and Electronics', + '8ICG' => 'Counseling', + '8IEC' => 'Ecology, Environmental and Conservation', + '8IED' => 'Education', + '8IEM' => 'Employment Training and Recruitment', + '8IEN' => 'Energy, Utilities and Fuel', + '8IEV' => 'Events and Conventions', + '8IFA' => 'Fashion', + '8IFI' => 'Financial Services and Banking', + '8IFB' => 'Food and Beverage Processing', + '8IFL' => 'Food and Beverage Retail', + '8IFS' => 'Food Services', + '8IFO' => 'Forestry and Wood Products', + '8IFR' => 'Freight and Warehousing', + '8IFU' => 'Furniture', + '8IGA' => 'Games, Toys and Hobbies', + '8IGI' => 'Gaming Industry', + '8IGL' => 'Gardening and Landscaping', + '8IGO' => 'Government and Politics', + '8IGR' => 'Graphic Design', + '8IGC' => 'Greeting Card', + '8IHI' => 'Heavy Industry', + '8IHO' => 'Home Improvement', + '8IHH' => 'Hotels and Hospitality', + '8IHA' => 'Household Appliances', + '8IHC' => 'Household Cleaning Products', + '8IIM' => 'Industry and Manufacturing', + '8IIT' => 'Information Technologies', + '8IIN' => 'Insurance', + '8IIS' => 'Internet Services', + '8ILS' => 'Legal Services', + '8IME' => 'Medical and Healthcare', + '8IMS' => 'Microelectronics and Semiconductors', + '8IMW' => 'Military and Weapons', + '8IMM' => 'Mining and Metals', + '8IMU' => 'Music', + '8INP' => 'Not For Profit, Social, Charitable', + '8IOP' => 'Office Products', + '8IOG' => 'Oil and Gas', + '8IOI' => 'Other Industry', + '8IPO' => 'Personal Use Only', + '8IPP' => 'Pet Products and Services', + '8IPS' => 'Pharmaceuticals and Supplements', + '8IPT' => 'Printing and Reprographics', + '8IPR' => 'Public Relations', + '8IPM' => 'Publishing Media', + '8IRE' => 'Real Estate', + '8IRR' => 'Religion and Religious Services', + '8ISM' => 'Retail Sales and Marketing', + '8IRM' => 'Retail Merchandise', + '8ISS' => 'Safety and Security', + '8ISC' => 'Sciences', + '8ISH' => 'Shipping', + '8ISO' => 'Software', + '8ISF' => 'Sports, Fitness and Recreation', + '8ITE' => 'Telecommunications', + '8ITX' => 'Textiles and Apparel', + '8ITB' => 'Tobacco', + '8ITR' => 'Travel and Tourism', + # 9E - Exclusivity + '9EXX' => 'Not Applicable or None', + '9ENE' => 'Non-Exclusive', + '9EXC' => 'All Exclusive', + '9EIN' => 'Exclusivity For Industry', + '9EME' => 'Exclusivity For Media', + '9ELA' => 'Exclusivity For Language', + '9ERE' => 'Exclusivity For Region' +); + +# PLUS License Data Format 1.2.0 (plus) (ref 1) +%Image::ExifTool::PLUS::XMP = ( + %Image::ExifTool::XMP::xmpTableDefaults, + GROUPS => { 0 => 'XMP', 1 => 'XMP-plus', 2 => 'Author' }, + NAMESPACE => 'plus', + NOTES => q{ + PLUS (Picture Licensing Universal System) License Data Format 1.2.1 XMP + tags. Note that all controlled-vocabulary tags in this table (ie. tags with + a fixed set of values) have raw values which begin with + "http://ns.useplus.org/ldf/vocab/", but to reduce clutter this prefix has + been removed from the values shown below. See L<http://ns.useplus.org/> for + the complete specification. + }, + Version => { Name => 'PLUSVersion' }, + Licensee => { + FlatName => '', + Struct => \%plusLicensee, + List => 'Seq', + }, + EndUser => { + FlatName => '', + Struct => \%plusEndUser, + List => 'Seq', + }, + Licensor => { + FlatName => '', + Struct => \%plusLicensor, + List => 'Seq', + }, + LicensorNotes => { Writable => 'lang-alt' }, + MediaSummaryCode => { + SeparateTable => 'MediaMatrix', + PrintConv => \%mediaMatrix, + }, + LicenseStartDate => { %Image::ExifTool::XMP::dateTimeInfo, Groups => { 2 => 'Time'} }, + LicenseEndDate => { %Image::ExifTool::XMP::dateTimeInfo, Groups => { 2 => 'Time'} }, + MediaConstraints => { Writable => 'lang-alt' }, + RegionConstraints => { Writable => 'lang-alt' }, + ProductOrServiceConstraints => { Writable => 'lang-alt' }, + ImageFileConstraints => { + List => 'Bag', + %plusVocab, + PrintConv => { + 'IF-MFN' => 'Maintain File Name', + 'IF-MID' => 'Maintain ID in File Name', + 'IF-MMD' => 'Maintain Metadata', + 'IF-MFT' => 'Maintain File Type', + }, + }, + ImageAlterationConstraints => { + List => 'Bag', + %plusVocab, + PrintConv => { + 'AL-CRP' => 'No Cropping', + 'AL-FLP' => 'No Flipping', + 'AL-RET' => 'No Retouching', + 'AL-CLR' => 'No Colorization', + 'AL-DCL' => 'No De-Colorization', + 'AL-MRG' => 'No Merging', + }, + }, + ImageDuplicationConstraints => { + %plusVocab, + PrintConv => { + 'DP-NDC' => 'No Duplication Constraints', + 'DP-LIC' => 'Duplication Only as Necessary Under License', + 'DP-NOD' => 'No Duplication', + }, + }, + ModelReleaseStatus => { + %plusVocab, + PrintConv => { + 'MR-NON' => 'None', + 'MR-NAP' => 'Not Applicable', + 'MR-UMR' => 'Unlimited Model Releases', + 'MR-LMR' => 'Limited or Incomplete Model Releases', + }, + }, + ModelReleaseID => { List => 'Bag' }, + MinorModelAgeDisclosure => { + %plusVocab, + PrintConv => { + 'AG-UNK' => 'Age Unknown', + 'AG-A25' => 'Age 25 or Over', + 'AG-A24' => 'Age 24', + 'AG-A23' => 'Age 23', + 'AG-A22' => 'Age 22', + 'AG-A21' => 'Age 21', + 'AG-A20' => 'Age 20', + 'AG-A19' => 'Age 19', + 'AG-A18' => 'Age 18', + 'AG-A17' => 'Age 17', + 'AG-A16' => 'Age 16', + 'AG-A15' => 'Age 15', + 'AG-U14' => 'Age 14 or Under', + }, + }, + PropertyReleaseStatus => { + %plusVocab, + PrintConv => { + 'PR-NON' => 'None', + 'PR-NAP' => 'Not Applicable', + 'PR-UPR' => 'Unlimited Property Releases', + 'PR-LPR' => 'Limited or Incomplete Property Releases', + }, + }, + PropertyReleaseID => { List => 'Bag' }, + OtherConstraints => { Writable => 'lang-alt' }, + CreditLineRequired => { + %plusVocab, + PrintConv => { + 'CR-NRQ' => 'Not Required', + 'CR-COI' => 'Credit on Image', + 'CR-CAI' => 'Credit Adjacent To Image', + 'CR-CCA' => 'Credit in Credits Area', + }, + }, + AdultContentWarning => { + %plusVocab, + PrintConv => { + 'CW-NRQ' => 'Not Required', + 'CW-AWR' => 'Adult Content Warning Required', + 'CW-UNK' => 'Unknown', + }, + }, + OtherLicenseRequirements => { Writable => 'lang-alt' }, + TermsAndConditionsText => { Writable => 'lang-alt' }, + TermsAndConditionsURL => { }, + OtherConditions => { Writable => 'lang-alt' }, + ImageType => { + %plusVocab, + PrintConv => { + 'TY-PHO' => 'Photographic Image', + 'TY-ILL' => 'Illustrated Image', + 'TY-MCI' => 'Multimedia or Composited Image', + 'TY-VID' => 'Video', + 'TY-OTR' => 'Other', + }, + }, + LicensorImageID => { }, + FileNameAsDelivered => { }, + ImageFileFormatAsDelivered => { + %plusVocab, + PrintConv => { + 'FF-JPG' => 'JPEG Interchange Formats (JPG, JIF, JFIF)', + 'FF-TIF' => 'Tagged Image File Format (TIFF)', + 'FF-GIF' => 'Graphics Interchange Format (GIF)', + 'FF-RAW' => 'Proprietary RAW Image Format', + 'FF-DNG' => 'Digital Negative (DNG)', + 'FF-EPS' => 'Encapsulated PostScript (EPS)', + 'FF-BMP' => 'Windows Bitmap (BMP)', + 'FF-PSD' => 'Photoshop Document (PSD)', + 'FF-PIC' => 'Macintosh Picture (PICT)', + 'FF-PNG' => 'Portable Network Graphics (PNG)', + 'FF-WMP' => 'Windows Media Photo (HD Photo)', + 'FF-OTR' => 'Other', + }, + }, + ImageFileSizeAsDelivered => { + %plusVocab, + PrintConv => { + 'SZ-U01' => 'Up to 1 MB', + 'SZ-U10' => 'Up to 10 MB', + 'SZ-U30' => 'Up to 30 MB', + 'SZ-U50' => 'Up to 50 MB', + 'SZ-G50' => 'Greater than 50 MB', + }, + }, + CopyrightStatus => { + %plusVocab, + PrintConv => { + 'CS-PRO' => 'Protected', + 'CS-PUB' => 'Public Domain', + 'CS-UNK' => 'Unknown', + }, + }, + CopyrightRegistrationNumber => { }, + FirstPublicationDate => { %Image::ExifTool::XMP::dateTimeInfo, Groups => { 2 => 'Time'} }, + CopyrightOwner => { + FlatName => '', + Struct => \%plusCopyrightOwner, + List => 'Seq', + }, + CopyrightOwnerImageID => { }, + ImageCreator => { + FlatName => '', + Struct => \%plusImageCreator, + List => 'Seq', + }, + ImageCreatorImageID => { }, + ImageSupplier => { + FlatName => '', + Struct => \%plusImageSupplier, + List => 'Seq', + }, + ImageSupplierImageID => { }, + LicenseeImageID => { }, + LicenseeImageNotes => { Writable => 'lang-alt' }, + OtherImageInfo => { Writable => 'lang-alt' }, + LicenseID => { }, + LicensorTransactionID => { List => 'Bag' }, + LicenseeTransactionID => { List => 'Bag' }, + LicenseeProjectReference=> { List => 'Bag' }, + LicenseTransactionDate => { %Image::ExifTool::XMP::dateTimeInfo, Groups => { 2 => 'Time'} }, + Reuse => { + %plusVocab, + PrintConv => { + 'RE-REU' => 'Repeat Use', + 'RE-NAP' => 'Not Applicable', + }, + }, + OtherLicenseDocuments => { List => 'Bag' }, + OtherLicenseInfo => { Writable => 'lang-alt' }, + # Note: these are Bag's of lang-alt lists -- a nested list tag! + Custom1 => { List => 'Bag', Writable => 'lang-alt' }, + Custom2 => { List => 'Bag', Writable => 'lang-alt' }, + Custom3 => { List => 'Bag', Writable => 'lang-alt' }, + Custom4 => { List => 'Bag', Writable => 'lang-alt' }, + Custom5 => { List => 'Bag', Writable => 'lang-alt' }, + Custom6 => { List => 'Bag', Writable => 'lang-alt' }, + Custom7 => { List => 'Bag', Writable => 'lang-alt' }, + Custom8 => { List => 'Bag', Writable => 'lang-alt' }, + Custom9 => { List => 'Bag', Writable => 'lang-alt' }, + Custom10 => { List => 'Bag', Writable => 'lang-alt' }, +); + +#------------------------------------------------------------------------------ +# Validate Media Summary Code +# Inputs: 0) Media Usage Code +# Returns: true if OK, false on severe error +# - issues warning for detected format problems +# - repairs some repairable problems +sub ValidateMediaSummary($) +{ + my $val = shift; + + my @a = split /\|/, $val; + @a >= 4 and $a[0] eq '' or warn("Not a valid Media Summary Code\n"), return 0; + $a[1] eq 'PLUS' or warn("Unrecognized Media Usage standard\n"), return 0; + $a[2] =~ /^V(\d+)/ or warn("Unrecognized Media Usage version\n"); + $a[3] =~ /^U(\d+)/ or warn("Invalid Media Usage count\n"), return 0; + my $numUsages = $1; + my ($i, $j); + unless ($numUsages == @a - 4) { + warn("Fixed incorrect number of Media Usages\n"); + $numUsages = @a - 4; + $a[3] = sprintf('U%.3d', $numUsages); + } + for ($i=1; $i<=$numUsages; ++$i) { + my $usage = $a[$i + 3]; + $usage =~ /^1I([A-Z])([A-Z])/ or warn("Missing Media Usage $i item count\n"), return 0; + length($usage) % 4 and warn("Incorrect Media Usage $i length\n"), return 0; + my $numItems = (ord($1)-65) * 26 + ord($2)-65 + 1; + unless (length($usage) == 4 * ($numItems + 1)) { + $numItems = length($usage) / 4 - 1; + warn("Fixed incorrect Media Usage $i item count\n"); + $a[$i+3] = '1I' . chr(65 + int($numItems / 26)) . chr($numItems % 26) . substr($usage, 4); + } + for ($j=1; $j<=$numItems; ++$j) { + my $item = substr($usage, $j*4, 4); + $item =~ /^\d[A-Z]{3}$/ or warn(qq(Invalid item "$item" for Media Usage $i\n)), return 0; + } + } + $_[0] = join('|', @a) . '|' if $Image::ExifTool::evalWarning; + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::PLUS - PLUS (Picture Licensing Universal System) tags + +=head1 DESCRIPTION + +Definitions for PLUS (Picture Licensing Universal System) tags. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<http://www.useplus.com/useplus/standards.asp> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/PLUS Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PNG.pm b/src/Image-ExifTool/lib/Image/ExifTool/PNG.pm index c25962ce..c2f9603c 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PNG.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PNG.pm @@ -19,6 +19,15 @@ # decompress then decode the ASCII/hex profile information before # you can edit it, then you have to ASCII/hex-encode, recompress # and calculate a CRC before you can write it out again. gaaaak. +# +# Although XMP is allowed after the IDAT chunk according to the +# PNG specifiction, some apps (Apple Spotlight and Preview for +# OS X 10.8.5 and Adobe Photoshop CC 14.0) ignore it unless it +# comes before IDAT. As of version 11.58, ExifTool uses a 2-pass +# writing algorithm to allow it to be compatible with XMP after +# IDAT while writing it before IDAT. (PNG and EXIF are still +# written after IDAT.) As of version 11.63, this strategy is +# applied to all text chunks (tEXt, zTXt and iTXt). #------------------------------------------------------------------------------ package Image::ExifTool::PNG; @@ -27,7 +36,7 @@ use strict; use vars qw($VERSION $AUTOLOAD %stdCase); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.46'; +$VERSION = '1.54'; sub ProcessPNG_tEXt($$$); sub ProcessPNG_iTXt($$$); @@ -78,6 +87,14 @@ my %pngMap = ( # color type of current image $Image::ExifTool::PNG::colorType = -1; +# data and text chunk types +my %isDatChunk = ( IDAT => 1, JDAT => 1, JDAA => 1 ); +my %isTxtChunk = ( tEXt => 1, zTXt => 1, iTXt => 1 ); + +# chunks that we shouldn't move other chunks across (ref 3) +my %noLeapFrog = ( SAVE => 1, SEEK => 1, IHDR => 1, JHDR => 1, IEND => 1, MEND => 1, + DHDR => 1, BASI => 1, CLON => 1, PAST => 1, SHOW => 1, MAGN => 1 ); + # PNG chunks %Image::ExifTool::PNG::Main = ( WRITE_PROC => \&Image::ExifTool::DummyWriteProc, @@ -93,6 +110,19 @@ $Image::ExifTool::PNG::colorType = -1; it is specifically deleted with C<-Trailer:All=>. When reading, a minor warning is issued if this trailer exists, and ExifTool will attempt to parse this data as additional PNG chunks. + + Also according to the PNG specification, there is no restriction on the + location of text-type chunks (tEXt, zTXt and iTXt). However, certain + utilities (including some Apple and Adobe utilities) won't read the XMP iTXt + chunk if it comes after the IDAT chunk, and at least one utility won't read + other text chunks here. For this reason, when writing, ExifTool 11.63 and + later create new text chunks (including XMP) before IDAT, and move existing + text chunks to before IDAT. + + The PNG format contains CRC checksums that are validated when reading with + either the L<Verbose|../ExifTool.html#Verbose> or L<Validate|../ExifTool.html#Validate> option. When writing, these checksums are + validated by default, but the L<FastScan|../ExifTool.html#FastScan> option may be used to bypass this + check if speed is more of a concern. }, bKGD => { Name => 'BackgroundColor', @@ -351,14 +381,17 @@ $Image::ExifTool::PNG::colorType = -1; 0 => { Name => 'PixelsPerUnitX', Format => 'int32u', + Notes => 'default 2834', }, 4 => { Name => 'PixelsPerUnitY', Format => 'int32u', + Notes => 'default 2834', }, 8 => { Name => 'PixelUnits', PrintConv => { 0 => 'Unknown', 1 => 'meters' }, + Notes => 'default meters', }, ); @@ -427,10 +460,10 @@ my %unreg = ( Notes => 'unregistered' ); These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image. By default ExifTool writes new string-value tags as as uncompressed tEXt, or - compressed zTXt if the Compress (-z) option is used and Compress::Zlib is + compressed zTXt if the L<Compress|../ExifTool.html#Compress> (-z) option is used and Compress::Zlib is available. Alternate language tags and values containing special characters (unless the Latin character set is used) are written as iTXt, and compressed - if the Compress option is used and Compress::Zlib is available. Raw profile + if the L<Compress|../ExifTool.html#Compress> option is used and Compress::Zlib is available. Raw profile information is always created as compressed zTXt if Compress::Zlib is available, or tEXt otherwise. Standard XMP is written as uncompressed iTXt. @@ -502,9 +535,7 @@ my %unreg = ( Notes => 'unregistered' ); XMP specification, and is where ExifTool will add a new XMP chunk if the image didn't already contain XMP }, - SubDirectory => { - TagTable => 'Image::ExifTool::XMP::Main', - }, + SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, }, 'Raw profile type APP1' => [ { @@ -588,7 +619,7 @@ my %unreg = ( Notes => 'unregistered' ); GROUPS => { 2 => 'Image' }, FORMAT => 'int32u', NOTES => q{ - Tags found in the Animation Conrol chunk. See + Tags found in the Animation Control chunk. See L<https://wiki.mozilla.org/APNG_Specification> for details. }, 0 => { @@ -792,7 +823,7 @@ sub FoundPNG($$$$;$$$$) my $processed; if ($$tagInfo{SubDirectory}) { if ($$et{OPTIONS}{Validate} and $$tagInfo{NonStandard}) { - $et->Warn("Non-standard $$tagInfo{NonStandard} in PNG $tag chunk", 1); + $et->WarnOnce("Non-standard $$tagInfo{NonStandard} in PNG $tag chunk", 1); } my $subdir = $$tagInfo{SubDirectory}; my $dirName = $$subdir{DirName} || $tagName; @@ -830,23 +861,11 @@ sub FoundPNG($$$$;$$$$) return 1 unless $$et{EDIT_DIRS}{$dirName}; $$outBuff = $et->WriteDirectory(\%subdirInfo, $subTable); if ($tagName eq 'XMP' and $$outBuff) { - if ($$et{FoundIDAT} and $$et{DEL_GROUP}{XMP}) { - $et->VPrint(0,' Deleting XMP'); - $$outBuff = ''; - } else { - # make sure the XMP is marked as read-only - Image::ExifTool::XMP::ValidateXMP($outBuff,'r'); - } + # make sure the XMP is marked as read-only + Image::ExifTool::XMP::ValidateXMP($outBuff,'r'); } DoneDir($et, $dirName, $outBuff, $$tagInfo{NonStandard}); } else { - # issue warning for standard XMP after IDAT (PNGEarlyXMP option) - if ($tagName eq 'XMP' and not $$tagInfo{NonStandard} and - $$et{FoundIDAT} and $$et{FoundIDAT} == 2) - { - $et->Warn('XMP found after PNG IDAT'); - $$et{FoundIDAT} = 1; - } $processed = $et->ProcessDirectory(\%subdirInfo, $subTable, $processProc); } $compressed = 1; # pretend this is compressed since it is binary data @@ -872,9 +891,7 @@ sub FoundPNG($$$$;$$$$) { # write new value for this tag if necessary my $newVal; - if ($$et{DEL_GROUP}{PNG} or $$et{PNGDoneTag}{$tag} or - $$et{PNGDoneTag}{ucfirst $tag}) - { + if ($$et{DEL_GROUP}{PNG}){ # remove this tag now, but keep in ADD_PNG list to add back later $isOverwriting = 1; } else { @@ -1055,7 +1072,7 @@ sub ProcessProfile($$$) $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr, \&Image::ExifTool::WriteTIFF); $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff; - DoneDir($et, 'IFD0', $outBuff); + DoneDir($et, 'IFD0', $outBuff, $$tagInfo{NonStandard}); } else { $processed = $et->ProcessTIFF(\%dirInfo); } @@ -1069,7 +1086,7 @@ sub ProcessProfile($$$) return 1 unless $$editDirs{XMP}; $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr); $$outBuff and $$outBuff = $Image::ExifTool::xmpAPP1hdr . $$outBuff; - DoneDir($et, 'XMP', $outBuff, 1); + DoneDir($et, 'XMP', $outBuff, $$tagInfo{NonStandard}); } else { $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr); } @@ -1085,7 +1102,7 @@ sub ProcessProfile($$$) } $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr, \&Image::ExifTool::WriteTIFF); - DoneDir($et, 'IFD0', $outBuff); + DoneDir($et, 'IFD0', $outBuff, $$tagInfo{NonStandard}); } else { $processed = $et->ProcessTIFF(\%dirInfo); } @@ -1148,6 +1165,7 @@ sub ProcessPNG_tEXt($$$) my ($et, $dirInfo, $tagTablePtr) = @_; my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2; my $outBuff = $$dirInfo{OutBuff}; + $$et{INDENT} = substr($$et{INDENT}, 0, -2) if $$et{OPTIONS}{Verbose}; return FoundPNG($et, $tagTablePtr, $tag, $val, undef, $outBuff, 'Latin'); } @@ -1166,6 +1184,7 @@ sub ProcessPNG_iTXt($$$) # set compressed flag so we will decompress it in FoundPNG() $compressed and $compressed = 2 + $meth; my $outBuff = $$dirInfo{OutBuff}; + $$et{INDENT} = substr($$et{INDENT}, 0, -2) if $$et{OPTIONS}{Verbose}; return FoundPNG($et, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'UTF8', $lang); } @@ -1234,14 +1253,13 @@ sub ProcessPNG($$) my $datChunk = ''; my $datCount = 0; my $datBytes = 0; - my ($sig, $err); + my $fastScan = $et->Options('FastScan'); + my ($n, $sig, $err, $hbuf, $dbuf, $cbuf); + my ($wasHdr, $wasEnd, $wasDat, $doTxt, @txtOffset); # check to be sure this is a valid PNG/MNG/JNG image return 0 unless $raf->Read($sig,8) == 8 and $pngLookup{$sig}; - $$raf{NoBuffer} = 1 if $et->Options('FastScan'); # disable buffering in FastScan mode - - my $earlyXMP = $et->Options('PNGEarlyXMP'); if ($outfile) { delete $$et{TextChunkType}; Write($outfile, $sig) or $err = 1 if $outfile; @@ -1249,16 +1267,11 @@ sub ProcessPNG($$) $$et{ADD_PNG} = $et->GetNewTagInfoHash( \%Image::ExifTool::PNG::Main, \%Image::ExifTool::PNG::TextualData); - # NOTE: PNGDoneTag and PNGDoneDir are used to keep track of metadata added - # before the PNG IEND chunk is encountered. Currently this is implemented - # only for XMP (written before IDAT with the PNGEarlyXMP option), but - # may be implemented in the future for other types - PH - $$et{PNGDoneTag} = { }; - $$et{PNGDoneDir} = { }; # initialize with same directories, with PNG tags taking priority $et->InitWriteDirs(\%pngMap,'PNG'); - # write XMP before IDAT if we would delete it later anyway - $earlyXMP = 1 if $$et{DEL_GROUP}{XMP}; + } else { + # disable buffering in FastScan mode + $$raf{NoBuffer} = 1 if $fastScan; } my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}}; $et->SetFileType($fileType); # set the FileType tag @@ -1269,13 +1282,37 @@ sub ProcessPNG($$) $mngTablePtr = GetTagTable('Image::ExifTool::MNG::Main'); } my $verbose = $et->Options('Verbose'); + my $validate = $et->Options('Validate'); my $out = $et->Options('TextOut'); - my ($hbuf, $dbuf, $cbuf, $wasHdr, $wasEnd); + + # scan ahead to find offsets of all text chunks after IDAT + if ($outfile) { + while ($raf->Read($hbuf,8) == 8) { + my ($len, $chunk) = unpack('Na4',$hbuf); + last if $len > 0x7fffffff; + if ($wasDat) { + last if $noLeapFrog{$chunk}; # (don't move text across these chunks) + push @txtOffset, $raf->Tell() - 8 if $isTxtChunk{$chunk}; + } elsif ($isDatChunk{$chunk}) { + $wasDat = $chunk; + } + $raf->Seek($len + 4, 1) or last; # skip chunk data + } + $raf->Seek(8,0) or $et->Error('Error seeking in file'), return -1; + undef $wasDat; + } # process the PNG/MNG/JNG chunks undef $noCompressLib; for (;;) { - my $n = $raf->Read($hbuf,8); + if ($doTxt) { + # read text chunks that were found after IDAT so we can write them before + $raf->Seek(shift(@txtOffset), 0) or $et->Error('Seek error'), last; + # (this is the IDAT offset if @txtOffset is now empty) + undef $doTxt unless @txtOffset; + } + $n = $raf->Read($hbuf,8); # read chunk header + if ($wasEnd) { last unless $n; # stop now if normal end of PNG $et->WarnOnce("Trailer data after $fileType $endChunk chunk", 1); @@ -1291,31 +1328,54 @@ sub ProcessPNG($$) last; } if ($verbose) { + print $out " Moving $chunk from after IDAT ($len bytes)\n" if $doTxt; # don't dump image data chunks in verbose mode (only give count instead) if ($datCount and $chunk ne $datChunk) { my $s = $datCount > 1 ? 's' : ''; print $out "$fileType $datChunk ($datCount chunk$s, total $datBytes bytes)\n"; $datCount = $datBytes = 0; - $datChunk = ''; } - if ($chunk =~ /^(IDAT|JDAT|JDAA)$/) { - $datChunk = $chunk; - $datCount++; - $datBytes += $len; + } + unless ($wasHdr) { + if ($chunk eq $hdrChunk) { + $wasHdr = 1; + } elsif ($hdrChunk eq 'IHDR' and $chunk eq 'CgBI') { + $et->Warn('Non-standard PNG image (Apple iPhone format)'); + } else { + $et->Warn("$fileType image did not start with $hdrChunk"); + last; + } + } + if ($outfile and ($isDatChunk{$chunk} or $chunk eq $endChunk) and @txtOffset) { + # continue processing here after we move the text chunks from after IDAT + push @txtOffset, $raf->Tell() - 8; + $doTxt = 1; # process text chunks now + next; + } + if ($isDatChunk{$chunk}) { + if ($fastScan and $fastScan >= 2) { + $et->VPrint(0,"End processing at $chunk chunk due to FastScan=$fastScan setting"); + last; } + $datChunk = $chunk; + $datCount++; + $datBytes += $len; + $wasDat = $chunk; + } else { + $datChunk = ''; } if ($outfile) { - if ($chunk eq $endChunk) { - # add any new chunks immediately before the IEND/MEND chunk - AddChunks($et, $outfile) or $err = 1; - } elsif ($chunk eq 'PLTE' or $chunk eq 'IDAT') { - if ($chunk eq 'IDAT') { - # add XMP before IDAT if specified - AddChunks($et, $outfile, 'XMP') or $err = 1 if $earlyXMP; - # pHYs comes before IDAT - AddChunks($et, $outfile, 'PNG-pHYs') or $err = 1; - } - # iCCP chunk must come before PLTE and IDAT + # add text chunks (including XMP) before any data chunk end chunk + if ($datChunk or $chunk eq $endChunk) { + # write iCCP chunk now if requested because AddChunks will try + # to add it as a text profile chunk if this isn't successful + # (ie. if Compress::Zlib wasn't available) + Add_iCCP($et, $outfile); + AddChunks($et, $outfile) or $err = 1; # all all text chunks + # add EXIF before end chunk if not found already + AddChunks($et, $outfile, 'IFD0') if $chunk eq $endChunk; + } elsif ($chunk eq 'PLTE') { + # iCCP chunk must come before PLTE (and IDAT, handled above) # (ignore errors -- will add later as text profile if this fails) Add_iCCP($et, $outfile); } @@ -1350,47 +1410,65 @@ sub ProcessPNG($$) } next; } - # set FoundIDAT flag: 1=after IDAT, 2=after IDAT and warn about late XMP - $$et{FoundIDAT} = $earlyXMP ? 2 : 1 if $chunk eq 'IDAT'; + if ($datChunk) { + # skip over data chunks if possible + unless ($verbose or $validate or $outfile) { + $raf->Seek($len + 4, 1) or $et->Warn('Seek error'), last; + next; + } + } elsif ($wasDat and $isTxtChunk{$chunk}) { + my $msg; + if (not $outfile) { + $msg = 'may be ignored by some readers'; + } elsif (defined $doTxt) { # $doTxt == 0 if we crossed a noLeapFrog chunk + $msg = "can't be moved"; # (but could be deleted then added back again) + } else { + $msg = 'fixed'; + } + $et->WarnOnce("Text chunk(s) found after $$et{FileType} $wasDat ($msg)", 1); + } # read chunk data and CRC unless ($raf->Read($dbuf,$len)==$len and $raf->Read($cbuf, 4)==4) { $et->Warn("Corrupted $fileType image") unless $wasEnd; last; } - unless ($wasHdr) { - if ($chunk eq $hdrChunk) { - $wasHdr = 1; - } elsif ($hdrChunk eq 'IHDR' and $chunk eq 'CgBI') { - $et->Warn('Non-standard PNG image (Apple iPhone format)'); - } else { - $et->Warn("$fileType image did not start with $hdrChunk"); - last; - } - } - if ($verbose) { + if ($verbose or $validate or ($outfile and not $fastScan)) { # check CRC when in verbose mode (since we don't care about speed) my $crc = CalculateCRC(\$hbuf, undef, 4); $crc = CalculateCRC(\$dbuf, $crc); - $crc == unpack('N',$cbuf) or $et->Warn("Bad CRC for $chunk chunk") unless $wasEnd; + unless ($crc == unpack('N',$cbuf)) { + my $msg = "Bad CRC for $chunk chunk"; + $outfile ? $et->Error($msg, 1) : $et->Warn($msg); + } if ($datChunk) { Write($outfile, $hbuf, $dbuf, $cbuf) or $err = 1 if $outfile; next; } - print $out "$fileType $chunk ($len bytes):\n"; - $et->VerboseDump(\$dbuf, Addr => $raf->Tell() - $len - 4) if $verbose > 2; + # just skip over any text chunk found after IDAT + if ($outfile and $wasDat) { + if ($isTxtChunk{$chunk} and not defined $doTxt) { + ++$$et{CHANGED} if $$et{FORCE_WRITE}{PNG}; + print $out " Deleting $chunk that was moved ($len bytes)\n" if $verbose; + next; + } + # done moving text if we hit one of these chunks + $doTxt = 0 if $noLeapFrog{$chunk}; + } + if ($verbose) { + print $out "$fileType $chunk ($len bytes):\n"; + $et->VerboseDump(\$dbuf, Addr => $raf->Tell() - $len - 4) if $verbose > 2; + } } - # translate case of chunk name if necessary - if (not $$tagTablePtr{$chunk}) { + # translate case of chunk names that have changed since the first implementation + if (not $$tagTablePtr{$chunk} and $stdCase{lc $chunk}) { my $stdChunk = $stdCase{lc $chunk}; - if ($stdChunk) { - if ($outfile and ($$et{EDIT_DIRS}{IFD0} or $stdChunk !~ /^[ez]xif$/i)) { - $et->Warn("Changed $chunk chunk to $stdChunk", 1); - ++$$et{CHANGED}; - } else { - $et->Warn("$chunk chunk should be $stdChunk", 1); - } - $chunk = $stdCase{lc $chunk}; + if ($outfile and ($$et{EDIT_DIRS}{IFD0} or $stdChunk !~ /^[ez]xif$/i)) { + $et->Warn("Changed $chunk chunk to $stdChunk", 1); + ++$$et{CHANGED}; + } else { + $et->Warn("$chunk chunk should be $stdChunk", 1); } + $chunk = $stdCase{lc $chunk}; } # only extract information from chunks in our tables my ($theBuff, $outBuff); @@ -1442,7 +1520,7 @@ and JNG (JPEG Network Graphics) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PPM.pm b/src/Image-ExifTool/lib/Image/ExifTool/PPM.pm index 5ae32d11..0f27c6cb 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PPM.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PPM.pm @@ -143,7 +143,7 @@ BitMap) images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PSP.pm b/src/Image-ExifTool/lib/Image/ExifTool/PSP.pm index b139a9b3..cd275a6f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PSP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PSP.pm @@ -284,7 +284,7 @@ information from Paint Shop Pro images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Palm.pm b/src/Image-ExifTool/lib/Image/ExifTool/Palm.pm index 97026e88..017aa414 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Palm.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Palm.pm @@ -379,7 +379,7 @@ KF7 and KF8 books (AZW and AZW3). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Panasonic.pm b/src/Image-ExifTool/lib/Image/ExifTool/Panasonic.pm index 125b840f..414b75a3 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Panasonic.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Panasonic.pm @@ -20,11 +20,13 @@ # 14) Carl Bretteville private communication (M9) # 15) Zdenek Mihula private communication (TZ8) # 16) Olaf Ulrich private communication -# 17) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4922.0.html +# 17) https://exiftool.org/forum/index.php/topic,4922.0.html # 18) Thomas Modes private communication (G6) -# 19) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,5533.0.html +# 19) https://exiftool.org/forum/index.php/topic,5533.0.html # 20) Bernd-Michael Kemper private communication (DMC-GX80/85) # 21) Klaus Homeister forum post +# 22) Daniel Beichl private communication (G9) +# 23) Tim Gray private communication (M10 Monochrom) # JD) Jens Duttke private communication (TZ3,FZ30,FZ50) #------------------------------------------------------------------------------ @@ -35,7 +37,7 @@ use vars qw($VERSION %leicaLensTypes); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '2.03'; +$VERSION = '2.09'; sub ProcessLeicaLEIC($$$); sub WhiteBalanceConv($;$$); @@ -107,7 +109,8 @@ sub WhiteBalanceConv($;$$); 39 => 'Macro-Elmar-M 90mm f/4', # 11633/11634 '39 0' => 'Tele-Elmar-M 135mm f/4 (II)',# 11861 40 => 'Macro-Adapter M', # 14409 - '41 3' => 'Apo-Summicron-M 50mm f/2 Asph', #16 + 41 => 'Apo-Summicron-M 50mm f/2 ASPH.', #IB + '41 3' => 'Apo-Summicron-M 50mm f/2 ASPH.', #16 42 => 'Tri-Elmar-M 28-35-50mm f/4 ASPH.',# 11625 '42 1' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 28mm)', '42 2' => 'Tri-Elmar-M 28-35-50mm f/4 ASPH. (at 35mm)', @@ -122,8 +125,9 @@ sub WhiteBalanceConv($;$$); 50 => 'Elmar-M 24mm f/3.8 ASPH.', # ? (ref 11) 51 => 'Super-Elmar-M 21mm f/3.4 Asph', # ? (ref 16, frameSelectorBits=1) '51 2' => 'Super-Elmar-M 14mm f/3.8 Asph', # ? (ref 16) - 52 => 'Super-Elmar-M 18mm f/3.8 ASPH.', # ? (ref PH/11) - '53 2' => 'Apo-Telyt-M 135mm f/3.4', #16 + 52 => 'Apo-Telyt-M 18mm f/3.8 ASPH.', # ? (ref PH/11) + 53 => 'Apo-Telyt-M 135mm f/3.4', #IB + '53 2' => 'Apo-Telyt-M 135mm f/3.4', #16 '53 3' => 'Apo-Summicron-M 50mm f/2 (VI)', #LR 58 => 'Noctilux-M 75mm f/1.25 ASPH.', # ? (ref IB) ); @@ -250,7 +254,7 @@ my %shootingMode = ( 83 => 'Clear Night Portrait', #18 84 => 'Soft Image of a Flower', #18 85 => 'Appetizing Food', #18 - 86 => 'Cute Desert', #18 + 86 => 'Cute Dessert', #18 87 => 'Freeze Animal Motion', #18 88 => 'Clear Sports Shot', #18 89 => 'Monochrome', #18 @@ -312,6 +316,7 @@ my %shootingMode = ( 14 => 'Manual 3', #forum9296 15 => 'Manual 4', #forum9296 # also seen 18,26 (forum9296) + 19 => 'Auto (cool)', #PH (Leica C-Lux) }, }, 0x07 => { @@ -348,6 +353,7 @@ my %shootingMode = ( '0 16' => '3-area (high speed)', # (FZ8) '0 23' => '23-area', #PH (FZ47,NC) '0 49' => '49-area', #20 + '0 225' => '225-area', #22 '1 0' => 'Spot Focusing', # (FZ8) '1 1' => '5-area', # (FZ8) '16' => 'Normal?', # (only mode for DMC-LC20) @@ -361,6 +367,7 @@ my %shootingMode = ( '32 3' => '3-area (right)?', # (DMC-L1 guess) '64 0' => 'Face Detect', '128 0' => 'Spot Focusing 2', #18 + '240 0' => 'Tracking', #22 }, }, ], @@ -633,8 +640,13 @@ my %shootingMode = ( 2 => 'High (+1)', 3 => 'Lowest (-2)', #JD 4 => 'Highest (+2)', #JD - # 65531 - seen for LX100/FZ2500 "NR1" test shots at imaging-resource (PH) - # 0 - seen for FZ2500 "NR6D" test shots (PH) + 5 => '+5', #PH (NC) + 6 => '+6', # (NC) seen for DC-S1/S1R (IB) + 65531 => '-5', # LX100/FZ2500 "NR1" test shots at imaging-resource (PH) + 65532 => '-4', + 65533 => '-3', + 65534 => '-2', + 65535 => '-1', }, }, 0x2e => { #4 @@ -645,7 +657,7 @@ my %shootingMode = ( 2 => '10 s', 3 => '2 s', 4 => '10 s / 3 pictures', #17 - # 258 - seen for FZ2500,TZ90 (PH) + # 258 - seen for FZ2500,TZ90,LeicaCLux (PH) }, }, # 0x2f - values: 1 (LZ6,FX10K) @@ -714,6 +726,7 @@ my %shootingMode = ( }, # 0x37 - values: 0,1,2 (LZ6, 0 for movie preview); 257 (FX10K); 0,256 (TZ5, 0 for movie preview) # 0x38 - values: 0,1,2 (LZ6, same as 0x37); 1,2 (FX10K); 0,256 (TZ5, 0 for movie preview) + # - changes with noise reduction for DC-S1 0x39 => { #7 (L1/L10) Name => 'Contrast', Format => 'int16s', @@ -1258,6 +1271,34 @@ my %shootingMode = ( Writable => 'int16u', PrintConv => { 0 => 'Off', 1 => 'Auto' }, }, + # Note: LensTypeMake and LensTypeModel are combined into a Composite LensType tag + # defined in Olympus.pm which has the same values as Olympus:LensType + 0xc4 => { #PH + Name => 'LensTypeMake', + Condition => '$format eq "int16u" and $$valPt ne "\xff\xff"', # (ignore make 65535 for now) + Writable => 'int16u', + }, + 0xc5 => { #PH + Name => 'LensTypeModel', + Condition => '$format eq "int16u"', + Writable => 'int16u', + RawConv => q{ + return undef unless $val; + require Image::ExifTool::Olympus; # (to load Composite LensID) + return $val; + }, + ValueConv => '$_=sprintf("%.4x",$val); s/(..)(..)/$2 $1/; $_', + ValueConvInv => '$val =~ s/(..) (..)/$2$1/; hex($val)', + }, + 0xd1 => { #PH + Name => 'ISO', + RawConv => '$val > 0xfffffff0 ? undef : $val', + Writable => 'int32u', + }, + 0xd6 => { #PH (DC-S1) + Name => 'NoiseReductionStrength', + Writable => 'rational64s', + }, 0x0e00 => { Name => 'PrintIM', Description => 'Print Image Matching', @@ -1885,7 +1926,7 @@ my %shootingMode = ( Writable => 'int32u', }, 0x311 => { - Name => 'ExternalSensorBrightnessValue', + Name => 'ExternalSensorBrightnessValue', Condition => '$$self{Model} =~ /Typ 006/', Notes => 'Leica S only', Format => 'rational64s', # (may be incorrectly unsigned in JPEG images) @@ -1928,7 +1969,7 @@ my %shootingMode = ( WRITE_PROC => \&Image::ExifTool::Exif::WriteExif, CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' }, - NOTES => 'This information is written by the Leica S (Typ 007).', + NOTES => 'This information is written by the Leica S (Typ 007) and M10 models.', 0x304 => { Name => 'FocusDistance', Notes => 'focus distance in mm for most models, but cm for others', @@ -1949,6 +1990,27 @@ my %shootingMode = ( PrintConvInv => '$val', }, # 0x340 - ImageUniqueID + 0x34c => { #23 + Name => 'UserProfile', + Writable => 'string', + }, + 0x359 => { #23 + Name => 'ISOSelected', + Writable => 'int32s', + PrintConv => { + 0 => 'Auto', + OTHER => sub { return shift; }, + }, + }, + 0x35a => { #23 + Name => 'FNumber', + Writable => 'int32s', + ValueConv => '$val / 1000', + ValueConvInv => '$val * 1000', + PrintConv => 'sprintf("%.1f", $val)', + PrintConvInv => '$val', + }, + # 0x357 int32u - 0=DNG, 3162=JPG (ref 23) ); # Type 2 tags (ref PH) @@ -2428,7 +2490,7 @@ sub ProcessLeicaLEIC($$$) #------------------------------------------------------------------------------ # Process MakerNote trailer written by Leica S2 # Inputs: 0) ExifTool object ref, 1) new absolute position of Leica trailer when writing -# Returns: On success: 1 when reading, directory data when writing; othewise undef +# Returns: On success: 1 when reading, directory data when writing; otherwise undef # Notes: # - may be called twice for a file if the first call doesn't succeed # - must leave RAF position unchanged @@ -2616,7 +2678,7 @@ Panasonic and Leica maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PanasonicRaw.pm b/src/Image-ExifTool/lib/Image/ExifTool/PanasonicRaw.pm index 4cb1c954..e259c201 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PanasonicRaw.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PanasonicRaw.pm @@ -6,7 +6,7 @@ # Revisions: 2009/03/24 - P. Harvey Created # 2009/05/12 - PH Added RWL file type (same format as RW2) # -# References: 1) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,1542.0.html +# References: 1) https://exiftool.org/forum/index.php/topic,1542.0.html # 2) http://www.cybercom.net/~dcoffin/dcraw/ # 3) http://syscall.eu/#pana # 4) Klaus Homeister private communication @@ -21,7 +21,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.23'; +$VERSION = '1.25'; sub ProcessJpgFromRaw($$$); sub WriteJpgFromRaw($$$); @@ -187,10 +187,13 @@ my %panasonicWhiteBalance = ( #forum9396 Protected => 1, # 2 - RAW DMC-FZ8/FZ18 # 3 - RAW DMC-L10 - # 4 - RW2 for most other models, including G9 normal resolution and YUNEEC CGO4 + # 4 - RW2 for most other models, including G9 in "pixel shift off" mode and YUNEEC CGO4 # (must add 15 to black levels for RawFormat == 4) - # 5 - RW2 DC-GH5s and G9 HiRes - # missing - DMC-LX1/FZ30/FZ50/L1/LX1/LX2 + # 5 - RW2 DC-GH5s; G9 in "pixel shift on" mode + # 6 - RW2 DC-S1, DC-S1r in "pixel shift off" mode + # 7 - RW2 DC-S1r (and probably DC-S1, have no raw samples) in "pixel shift on" mode + # not used - DMC-LX1/FZ30/FZ50/L1/LX1/LX2 + # (modes 5 and 7 are lossless) }, 0x2e => { #JD Name => 'JpgFromRaw', # (writable directory!) @@ -271,6 +274,7 @@ my %panasonicWhiteBalance = ( #forum9396 0x11c => { #forum9373 Name => 'Gamma', Writable => 'int16u', + # unfortunately it seems that the scaling factor varies with model... ValueConv => '$val / ($val >= 1024 ? 1024 : ($val >= 256 ? 256 : 100))', ValueConvInv => 'int($val * 256 + 0.5)', }, @@ -496,7 +500,31 @@ my %panasonicWhiteBalance = ( #forum9396 Writable => 'int32u', PrintConv => { 0 => 'No', 1 => 'Yes' }, }, - # 1201 - LensStyle? ref forum9394 + # Note: LensTypeMake and LensTypeModel are combined into a Composite LensType tag + # defined in Olympus.pm which has the same values as Olympus:LensType + 0x1201 => { #IB + Name => 'LensTypeMake', + Condition => '$format eq "int16u"', + Writable => 'int16u', + # when format is int16u, these values have been observed: + # 0 - Olympus or unknown lens + # 2 - Leica or Lumix lens + # when format is int32u (S models), these values have been observed (ref IB): + # 256 - Leica lens + # 257 - Lumix lens + }, + 0x1202 => { #IB + Name => 'LensTypeModel', + Condition => '$format eq "int16u"', + Writable => 'int16u', + RawConv => q{ + return undef unless $val; + require Image::ExifTool::Olympus; # (to load Composite LensID) + return $val; + }, + ValueConv => '$_=sprintf("%.4x",$val); s/(..)(..)/$2 $1/; $_', + ValueConvInv => '$val =~ s/(..) (..)/$2$1/; hex($val)', + }, 0x1203 => { #4 Name => 'FocalLengthIn35mmFormat', Writable => 'int16u', @@ -790,7 +818,10 @@ sub ProcessJpgFromRaw($$$) $out = $et->Options('TextOut'); print $out '--- DOC1:JpgFromRaw ',('-'x56),"\n"; } + # fudge HtmlDump base offsets to show as a stand-alone JPEG + $$et{BASE_FUDGE} = $$et{BASE}; my $rtnVal = $et->ProcessJPEG(\%dirInfo); + $$et{BASE_FUDGE} = 0; # restore necessary variables for continued RW2/RWL processing $$et{BASE} = 0; $$et{FILE_TYPE} = 'TIFF'; @@ -823,7 +854,7 @@ write meta information in Panasonic/Leica RAW, RW2 and RWL images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Parrot.pm b/src/Image-ExifTool/lib/Image/ExifTool/Parrot.pm new file mode 100644 index 00000000..a67db62c --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Parrot.pm @@ -0,0 +1,751 @@ +#------------------------------------------------------------------------------ +# File: Parrot.pm +# +# Description: Read timed metadata from Parrot drone videos +# +# Revisions: 2019-10-23 - P. Harvey Created +# +# References: 1) https://developer.parrot.com/docs/pdraw/metadata.html +#------------------------------------------------------------------------------ + +package Image::ExifTool::Parrot; + +use strict; +use vars qw($VERSION); + +$VERSION = '1.00'; + +sub Process_mett($$$); + +# tags found in Parrot 'mett' timed metadata (ref 1) +%Image::ExifTool::Parrot::mett = ( + PROCESS_PROC => \&Process_mett, + # put the 'P' records first in the documentation + VARS => { SORT_PROC => sub { my ($a,$b)=@_; $a=~s/P/A/; $b=~s/P/A/; $a cmp $b } }, + NOTES => q{ + Streaming metadata found in Parrot drone videos. See + L<https://developer.parrot.com/docs/pdraw/metadata.html> for the + specification. + }, + P1 => { + Name => 'ParrotV1', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::V1' }, + }, + P2 => { + Name => 'ParrotV2', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::V2' }, + }, + P3 => { + Name => 'ParrotV3', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::V3' }, + }, + E1 => { + Name => 'ParrotTimeStamp', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::TimeStamp' }, + }, + E2 => { + Name => 'ParrotFollowMe', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::FollowMe' }, + }, + E3 => { + Name => 'ParrotAutomation', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::Automation' }, + }, +); + +# tags found in the Parrot 'mett' V1 timed metadata (ref 1) [untested] +%Image::ExifTool::Parrot::V1 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + NOTES => 'Parrot version 1 streaming metadata.', + GROUPS => { 2 => 'Location' }, + 4 => { + Name => 'DroneYaw', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', # convert from rad to deg + }, + 6 => { + Name => 'DronePitch', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', + }, + 8 => { + Name => 'DroneRoll', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', + }, + 10 => { + Name => 'CameraPan', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', + }, + 12 => { + Name => 'CameraTilt', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', + }, + 14 => { + Name => 'FrameView', # (W,X,Y,Z) + Format => 'int16s[4]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x1000 foreach @a; "@a"', + }, + 22 => { + Name => 'ExposureTime', + Groups => { 2 => 'Camera' }, + Format => 'int16s', + ValueConv => '$val / 0x100 / 1000', + PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', + }, + 24 => { + Name => 'ISO', + Groups => { 2 => 'Camera' }, + Format => 'int16s', + }, + 26 => { + Name => 'WifiRSSI', + Groups => { 2 => 'Device' }, + Format => 'int8s', + PrintConv => '"$val dBm"', + }, + 27 => { + Name => 'Battery', + Groups => { 2 => 'Device' }, + PrintConv => '"$val %"', + }, + 28 => { + Name => 'GPSLatitude', + Format => 'int32s', + ValueConv => '$val / 0x100000', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 32 => { + Name => 'GPSLongitude', + Format => 'int32s', + ValueConv => '$val / 0x100000', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 36 => { + Name => 'GPSAltitude', + Format => 'int32s', + Mask => 0xffffff00, + ValueConv => '$val / 0x100', + PrintConv => 'sprintf("%.3f m", $val)', + }, + 36.1 => { + Name => 'GPSSatellites', # (SV count) + Format => 'int32s', + Mask => 0xff, + }, + 40 => { + Name => 'AltitudeFromTakeOff', + Format => 'int32s', + ValueConv => '$val / 0x10000', + PrintConv => 'sprintf("%.3f m", $val)', + }, + 44 => { + Name => 'DistanceFromHome', + Format => 'int32u', + ValueConv => '$val / 0x10000', + }, + 48 => { + Name => 'SpeedX', + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 50 => { + Name => 'SpeedY', + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 52 => { + Name => 'SpeedZ', + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 54 => { + Name => 'Binning', + Groups => { 2 => 'Device' }, + Mask => 0x80, + }, + 54.1 => { + Name => 'FlyingState', + Groups => { 2 => 'Device' }, + Mask => 0x7f, + PrintConv => { + 0 => 'Landed', + 1 => 'Taking Off', + 2 => 'Hovering', + 3 => 'Flying', + 4 => 'Landing', + 5 => 'Emergency', + }, + }, + 55 => { + Name => 'Animation', + Groups => { 2 => 'Device' }, + Mask => 0x80, + }, + 55.1 => { + Name => 'PilotingMode', + Groups => { 2 => 'Device' }, + Mask => 0x7f, + PrintConv => { + 0 => 'Manual', + 1 => 'Return Home', + 2 => 'Flight Plan', + 3 => 'Follow Me', + }, + }, +); + +# tags found in the Parrot 'mett' V2 timed metadata (ref 1) [untested] +%Image::ExifTool::Parrot::V2 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + Groups => { 2 => 'Location' }, + NOTES => 'Parrot version 2 basic streaming metadata.', + 4 => { + Name => 'Elevation', + Notes => 'estimated distance from ground', + Format => 'int32s', + ValueConv => '$val / 0x10000', + PrintConv => 'sprintf("%.3f m", $val)', + }, + 8 => { + Name => 'GPSLatitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 12 => { + Name => 'GPSLongitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 16 => { + Name => 'GPSAltitude', + Format => 'int32s', + Mask => 0xffffff00, + ValueConv => '$val / 0x100', + PrintConv => 'sprintf("%.3f m", $val)', + }, + 16.1 => { + Name => 'GPSSatellites', # (SV count) + Format => 'int32s', + Mask => 0xff, + }, + 20 => { + Name => 'GPSVelocityNorth', # (m/s) + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 22 => { + Name => 'GPSVelocityEast', # (m/s) + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 24 => { + Name => 'GPSVelocityDown', # (m/s) + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 26 => { + Name => 'AirSpeed', # (m/s) + Format => 'int16s', + RawConv => '$val < 0 ? undef : $val', + ValueConv => '$val / 0x100', + }, + 28 => { + Name => 'DroneQuaternion', # (W,X,Y,Z) + Format => 'int16s[4]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x4000 foreach @a; "@a"', + }, + 36 => { + Name => 'FrameView', # (W,X,Y,Z) + Format => 'int16s[4]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x4000 foreach @a; "@a"', + }, + 44 => { + Name => 'CameraPan', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', # convert from rad to deg + }, + 46 => { + Name => 'CameraTilt', + Format => 'int16s', + ValueConv => '$val / 0x1000 * 180 / 3.14159', + }, + 48 => { + Name => 'ExposureTime', + Groups => { 2 => 'Camera' }, + Format => 'int16u', + ValueConv => '$val / 0x100 / 1000', + PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', + }, + 50 => { + Name => 'ISO', + Groups => { 2 => 'Camera' }, + Format => 'int16u', + }, + 52 => { + Name => 'Binning', + Groups => { 2 => 'Device' }, + Mask => 0x80, + }, + 52.1 => { + Name => 'FlyingState', + Groups => { 2 => 'Device' }, + Mask => 0x7f, + PrintConv => { + 0 => 'Landed', + 1 => 'Taking Off', + 2 => 'Hovering', + 3 => 'Flying', + 4 => 'Landing', + 5 => 'Emergency', + 6 => 'User Takeoff', + 7 => 'Motor Ramping', + 8 => 'Emergency Landing', + }, + }, + 53 => { + Name => 'Animation', + Groups => { 2 => 'Device' }, + Mask => 0x80, + }, + 53.1 => { + Name => 'PilotingMode', + Groups => { 2 => 'Device' }, + Mask => 0x7f, + PrintConv => { + 0 => 'Manual', + 1 => 'Return Home', + 2 => 'Flight Plan', + 3 => 'Follow Me / Tracking', # (same as 'Tracking') + 4 => 'Magic Carpet', + 5 => 'Move To', + }, + }, + 54 => { + Name => 'WifiRSSI', + Groups => { 2 => 'Device' }, + Format => 'int8s', + PrintConv => '"$val dBm"', + }, + 55 => { + Name => 'Battery', + Groups => { 2 => 'Device' }, + PrintConv => '"$val %"', + }, +); + +# tags found in the Parrot 'mett' V3 timed metadata (ref 1) +%Image::ExifTool::Parrot::V3 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + NOTES => 'Parrot version 3 basic streaming metadata.', + 4 => { + Name => 'Elevation', + Notes => 'estimated distance from ground', + Format => 'int32s', + ValueConv => '$val / 0x10000', + PrintConv => 'sprintf("%.3f m", $val)', + }, + 8 => { + Name => 'GPSLatitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 12 => { + Name => 'GPSLongitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 16 => { + Name => 'GPSAltitude', + Format => 'int32s', + Mask => 0xffffff00, + ValueConv => '$val / 0x100', + PrintConv => 'sprintf("%.3f m", $val)', + }, + 16.1 => { + Name => 'GPSSatellites', # (SV count) + Format => 'int32s', + Mask => 0xff, + }, + 20 => { + Name => 'GPSVelocityNorth', # (m/s) + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 22 => { + Name => 'GPSVelocityEast', # (m/s) + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 24 => { + Name => 'GPSVelocityDown', # (m/s) + Format => 'int16s', + ValueConv => '$val / 0x100', + }, + 26 => { + Name => 'AirSpeed', # (m/s) + Format => 'int16s', + RawConv => '$val < 0 ? undef : $val', + ValueConv => '$val / 0x100', + }, + 28 => { + Name => 'DroneQuaternion', # (W,X,Y,Z) + Format => 'int16s[4]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x4000 foreach @a; "@a"', + }, + 36 => { + Name => 'FrameBaseView', # (W,X,Y,Z without pan/tilt) + Format => 'int16s[4]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x4000 foreach @a; "@a"', + }, + 44 => { + Name => 'FrameView', # (W,X,Y,Z) + Format => 'int16s[4]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x4000 foreach @a; "@a"', + }, + 52 => { + Name => 'ExposureTime', + Groups => { 2 => 'Camera' }, + Format => 'int16u', + ValueConv => '$val / 0x100 / 1000', + PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', + }, + 54 => { + Name => 'ISO', + Groups => { 2 => 'Camera' }, + Format => 'int16u', + }, + 56 => { + Name => 'RedBalance', + Groups => { 2 => 'Camera' }, + Format => 'int16u', + ValueConv => '$val / 0x4000', + }, + 58 => { + Name => 'BlueBalance', + Groups => { 2 => 'Camera' }, + Format => 'int16u', + ValueConv => '$val / 0x4000', + }, + 60 => { + Name => 'FOV', # (degrees) + Description => 'Field Of View', + Notes => 'horizontal and vertical field of view in degrees', + Groups => { 2 => 'Image' }, + Format => 'int16u[2]', + ValueConv => 'my @a = split " ",$val; $_ /= 0x100 foreach @a; "@a"', + }, + 64 => { + Name => 'LinkGoodput', + Groups => { 2 => 'Device' }, + Format => 'int32u', + Mask => 0xffffff00, + PrintConv => '"$val kbit/s"', + }, + 64.1 => { + Name => 'LinkQuality', + Groups => { 2 => 'Device' }, + Format => 'int32u', + Notes => '0-5', + Mask => 0xff, + }, + 68 => { + Name => 'WifiRSSI', + Groups => { 2 => 'Device' }, + Format => 'int8s', + PrintConv => '"$val dBm"', + }, + 69 => { + Name => 'Battery', + Groups => { 2 => 'Device' }, + PrintConv => '"$val %"', + }, + 70 => { + Name => 'Binning', + Groups => { 2 => 'Device' }, + Mask => 0x80, + }, + 70.1 => { + Name => 'FlyingState', + Groups => { 2 => 'Device' }, + Mask => 0x7f, + PrintConv => { + 0 => 'Landed', + 1 => 'Taking Off', + 2 => 'Hovering', + 3 => 'Flying', + 4 => 'Landing', + 5 => 'Emergency', + 6 => 'User Takeoff', + 7 => 'Motor Ramping', + 8 => 'Emergency Landing', + }, + }, + 71 => { + Name => 'Animation', + Groups => { 2 => 'Device' }, + Mask => 0x80, + }, + 71.1 => { + Name => 'PilotingMode', + Groups => { 2 => 'Device' }, + Mask => 0x7f, + PrintConv => { + 0 => 'Manual', + 1 => 'Return Home', + 2 => 'Flight Plan', + 3 => 'Follow Me / Tracking', # (same as 'Tracking') + 4 => 'Magic Carpet', + 5 => 'Move To', + }, + }, +); + +# tags found in the Parrot 'mett' E1 timestamp timed metadata (ref 1) +%Image::ExifTool::Parrot::TimeStamp = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + NOTES => 'Parrot streaming metadata timestamp extension.', + GROUPS => { 2 => 'Time' }, + 4 => { + Name => 'TimeStamp', + Format => 'int64u', + ValueConv => '$val / 1e6', + }, +); + +# tags found in the Parrot 'mett' E2 follow-me timed metadata (ref 1) [untested] +%Image::ExifTool::Parrot::FollowMe = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + NOTES => 'Parrot streaming metadata follow-me extension.', + 4 => { + Name => 'GPSTargetLatitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + }, + 8 => { + Name => 'GPSTargetLongitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + }, + 12 => { + Name => 'GPSTargetAltitude', + Format => 'int32s', + ValueConv => '$val / 0x10000', + }, + 16 => { + Name => 'Follow-meMode', + Groups => { 2 => 'Device' }, + PrintConv => { BITMASK => { + 0 => 'Follow-me enabled', + 1 => 'Follow-me', # (0=Look-at-me! auggh. see AutomationFlags below) + 2 => 'Angle locked', + }}, + }, + 17 => { + Name => 'Follow-meAnimation', + Groups => { 2 => 'Device' }, + PrintConv => { + 0 => 'None', + 1 => 'Orbit', + 2 => 'Boomerang', + 3 => 'Parabola', + 4 => 'Zenith', + }, + }, +); + +# tags found in the Parrot 'mett' E3 automation timed metadata (ref 1) +%Image::ExifTool::Parrot::Automation = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + NOTES => 'Parrot streaming metadata automation extension.', + 4 => { + Name => 'GPSFramingLatitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + }, + 8 => { + Name => 'GPSFramingLongitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + }, + 12 => { + Name => 'GPSFramingAltitude', + Format => 'int32s', + ValueConv => '$val / 0x10000', + }, + 16 => { + Name => 'GPSDestLatitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + }, + 20 => { + Name => 'GPSDestLongitude', + Format => 'int32s', + ValueConv => '$val / 0x400000', + }, + 24 => { + Name => 'GPSDestAltitude', + Format => 'int32s', + ValueConv => '$val / 0x10000', + }, + 28 => { + Name => 'AutomationAnimation', + Groups => { 2 => 'Device' }, + PrintConv => { + 0 => 'None', + 1 => 'Orbit', + 2 => 'Boomerang', + 3 => 'Parabola', + 4 => 'Dolly Slide', + 5 => 'Dolly Zoom', + 6 => 'Reveal Vertical', + 7 => 'Reveal Horizontal', + 8 => 'Candle', + 9 => 'Flip Front', + 10 => 'Flip Back', + 11 => 'Flip Left', + 12 => 'Flip Right', + 13 => 'Twist Up', + 14 => 'Position Twist Up', + }, + }, + 29 => { + Name => 'AutomationFlags', + Groups => { 2 => 'Device' }, + PrintConv => { BITMASK => { + 0 => 'Follow-me enabled', + 1 => 'Look-at-me enabled', # (really? opposite sense to Follow-meMode above!) + 2 => 'Angle locked', + }}, + }, +); + +%Image::ExifTool::Parrot::Composite = ( + GPSDateTime => { + Description => 'GPS Date/Time', + Groups => { 2 => 'Time' }, + SubDoc => 1, + Require => { + 0 => 'Parrot:GPSLatitude', # (avoids creating this tag for other videos) + 1 => 'Main:CreateDate', + 2 => 'SampleTime', + }, + ValueConv => q{ + my $time = $val[1]; + my $diff = $val[2]; + # handle time zone and shift to UTC + if ($time =~ s/([-+])(\d{1,2}):?(\d{2})$//) { + my $secs = (($2 * 60) + $3) * 60; + $secs *= -1 if $1 eq '+'; + $diff += $secs; + } elsif ($time !~ s/Z$//) { + # shift from local time + $diff += GetUnixTime($time, 1) - GetUnixTime($time); + } + my $sign = ($diff =~ s/^-// ? '-' : ''); + $time .= '.000'; # add decimal seconds + ShiftTime($time, "${sign}0:0:$diff"); + return $time . 'Z'; + }, + PrintConv => '$self->ConvertDateTime($val)', + }, +); + +# add our composite tags +Image::ExifTool::AddCompositeTags('Image::ExifTool::Parrot'); + + +#------------------------------------------------------------------------------ +# Parse Parrot 'mett' timed metadata +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +# (this metadata design is really stupid -- you need to know the size of the base structures) +sub Process_mett($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dataPos = $$dirInfo{DataPos}; + my $dirEnd = length $$dataPt; + my $pos = $$dirInfo{DirStart} || 0; + + $et->VerboseDir('Parrot mett', undef, $dirEnd); + + while ($pos + 4 < $dirEnd) { + my ($id, $nwords) = unpack("x${pos}a2n", $$dataPt); + my $size; + if ($id !~ /^[EP]\d/) { + # no ID so this should be a 60-byte V1 recording record, otherwise give up + last unless $dirEnd == 60; + $id = 'P1'; # generate a fake ID + # ignore the first 4 of the record so the fields will align with + # the other V1 records (unfortunately, this means that we won't + # decode the V1 recording frame timestamp, but oh well) + $pos += 4; + $size = $dirEnd - $pos; + # must override size for P3 and P3 records since it includes the extensions (augh!) + } elsif ($id eq 'P2') { + $size = 56; + } elsif ($id eq 'P3') { + $size = 72; + } else { + $size = $nwords * 4 + 4; + } + last if $pos + $size > $dirEnd; + $et->HandleTag($tagTbl, $id, undef, + DataPt => $dataPt, + DataPos => $dataPos, + Start => $pos, + Size => $size, + ); + $pos += $size; + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Parrot - Read timed metadata from Parrot drone videos + +=head1 SYNOPSIS + +This module is loaded automatically by Image::ExifTool when required. + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to interpret +timed metadata from the 'mett' frame found in Parrot drone MP4 videos. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://developer.parrot.com/docs/pdraw/metadata.html> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/Parrot Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Pentax.pm b/src/Image-ExifTool/lib/Image/ExifTool/Pentax.pm index b98f94c5..e082a6fb 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Pentax.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Pentax.pm @@ -37,11 +37,11 @@ # 22) Bozi (K10D, http://www.cpanforum.com/posts/8480) # 23) Akos Szalkai (https://rt.cpan.org/Ticket/Display.html?id=43743) # 24) Albert Bogner private communication -# 26) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3444.0.html -# 27) http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3833.0.html -# 28) Klaus Homeister http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4803.0.html +# 26) https://exiftool.org/forum/index.php/topic,3444.0.html +# 27) https://exiftool.org/forum/index.php/topic,3833.0.html +# 28) Klaus Homeister https://exiftool.org/forum/index.php/topic,4803.0.html # 29) Louis Granboulan private communication (K-5II) -# 30) http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=5433 +# 30) https://exiftool.org/forum/index.php?topic=5433 # 31) Andras Salamon private communication (K-70) # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication @@ -58,7 +58,7 @@ use Image::ExifTool::Exif; use Image::ExifTool::GPS; use Image::ExifTool::HP; -$VERSION = '3.24'; +$VERSION = '3.30'; sub CryptShutterCount($$); sub PrintFilter($$$); @@ -146,7 +146,7 @@ sub DecodeAFPoints($$$$;$); '3 44.3' => 'Sigma 17-70mm F2.8-4.5 DC Macro', #(Bart Hickman) '3 44.4' => 'Sigma 18-50mm F3.5-5.6 DC', #4 '3 44.5' => 'Sigma 17-35mm F2.8-4 EX DG', #29 - '3 44.6' => 'Tamron 35-90mm F4 AF', #12 + '3 44.6' => 'Tamron 35-90mm F4-5.6 AF', #12 (added "-5.6", ref IB) '3 44.7' => 'Sigma AF 18-35mm F3.5-4.5 Aspherical', #29 '3 46' => 'Sigma or Samsung Lens (3 46)', '3 46.1' => 'Sigma APO 70-200mm F2.8 EX', @@ -178,6 +178,7 @@ sub DecodeAFPoints($$$$;$); '4 2' => 'smc PENTAX-FA 80-320mm F4.5-5.6', '4 3' => 'smc PENTAX-FA 43mm F1.9 Limited', '4 6' => 'smc PENTAX-FA 35-80mm F4-5.6', + '4 8' => 'Irix 150mm F2.8 Macro', #exiv2 issue 1084 '4 9' => 'Irix 11mm F4 Firefly', #27 '4 10' => 'Irix 15mm F2.4', #27 '4 12' => 'smc PENTAX-FA 50mm F1.4', #17 @@ -304,8 +305,9 @@ sub DecodeAFPoints($$$$;$); '7 243' => 'smc PENTAX-DA 70mm F2.4 Limited', #PH '7 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #16 '8 0' => 'Sigma 50-150mm F2.8 II APO EX DC HSM', #forum2997 - '8 3' => 'Sigma AF 18-125mm F3.5-5.6 DC', #29 + '8 3' => 'Sigma 18-125mm F3.8-5.6 DC HSM', #forum10167 '8 4' => 'Sigma 50mm F1.4 EX DG HSM', #Artur private communication + '8 6' => 'Sigma 4.5mm F2.8 EX DC Fisheye', #IB '8 7' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #Exiv2 '8 8' => 'Sigma 18-250mm F3.5-6.3 DC OS HSM', #27 '8 11' => 'Sigma 10-20mm F3.5 EX DC HSM', #27 @@ -316,6 +318,7 @@ sub DecodeAFPoints($$$$;$); '8 16' => 'Sigma 70-200mm F2.8 EX DG Macro HSM II', #26 '8 17' => 'Sigma 50-500mm F4.5-6.3 DG OS HSM', #(Heike Herrmann) (also APO, ref 26) '8 18' => 'Sigma 8-16mm F4.5-5.6 DC HSM', #forum2998 + '8 20' => 'Sigma 18-50mm F2.8-4.5 DC HSM', #IB '8 21' => 'Sigma 17-50mm F2.8 EX DC OS HSM', #26 '8 22' => 'Sigma 85mm F1.4 EX DG HSM', #26 '8 23' => 'Sigma 70-200mm F2.8 APO EX DG OS HSM', #27 @@ -334,6 +337,8 @@ sub DecodeAFPoints($$$$;$); '8 62' => 'HD PENTAX-D FA 24-70mm F2.8 ED SDM WR', #PH '8 63' => 'HD PENTAX-D FA 15-30mm F2.8 ED SDM WR', #PH '8 64' => 'HD PENTAX-D FA* 50mm F1.4 SDM AW', #27 + '8 65' => 'HD PENTAX-D FA 70-210mm F4 ED SDM WR', #PH + '8 196' => 'HD PENTAX-DA* 11-18mm F2.8 ED DC AW', #29 '8 197' => 'HD PENTAX-DA 55-300mm F4.5-6.3 ED PLM WR RE', #29 '8 198' => 'smc PENTAX-DA L 18-50mm F4-5.6 DC WR RE', #29 '8 199' => 'HD PENTAX-DA 18-50mm F4-5.6 DC WR RE', #29 @@ -394,6 +399,10 @@ sub DecodeAFPoints($$$$;$); '21 7' => '07 Mount Shield 11.5mm F9', #PH (NC) '21 8' => '08 Wide Zoom 3.8-5.9mm F3.7-4', #PH (NC) '21 233' => 'Adapter Q for K-mount Lens', #29 +# +# Ricoh lenses +# + '31 1' => 'GR Lens', #PH (GR III 28mm F2.8) ); # Pentax model ID codes - PH @@ -533,6 +542,7 @@ my %pentaxModelID = ( 0x13092 => 'K-1', #IB (Ricoh) 0x1309c => 'K-3 II', #29 (Ricoh) 0x131f0 => 'WG-M2', # (Ricoh) + 0x1320e => 'GR III', # (Ricoh) 0x13222 => 'K-70', #29 (Ricoh) 0x1322c => 'KP', #29 (Ricoh) 0x13240 => 'K-1 Mark II', # (Ricoh) @@ -1118,6 +1128,8 @@ my %binaryDataAttrs = ( 3 => 'Manual', 4 => 'Super Macro', #JD 5 => 'Pan Focus', + # 8 - seen for Ricoh GR III + # 9 - seen for Ricoh GR III 16 => 'AF-S (Focus-priority)', #17 17 => 'AF-C (Focus-priority)', #17 18 => 'AF-A (Focus-priority)', #PH (educated guess) @@ -1128,6 +1140,8 @@ my %binaryDataAttrs = ( 273 => 'AF-C (Release-priority)', #PH (K-5,K-3) 274 => 'AF-A (Release-priority)', #PH (K-3) 288 => 'Contrast-detect (Release-priority)', #PH (K-01) + # 32777 (0x8009) - seen for Ricoh GR III + # 32779 (0x800b) - seen for Ricoh GR III }, },{ Name => 'FocusMode', @@ -1552,12 +1566,27 @@ my %binaryDataAttrs = ( 'Saturation', 'Sharpness', 'Contrast', 'Hue' or 'HighLowKey' followed by '+1', '+2' or '+3' for step size }, - # 1=.3ev, 2=.7, 3=1.0, ... 10=.5ev, 11=1.5, ... - ValueConv => [ '$val<10 ? $val/3 : $val-9.5' ], - ValueConvInv => [ 'abs($val-int($val)-.5)>0.05 ? int($val*3+0.5) : int($val+10)' ], + # 1=.3ev, 2=.7, 3=1.0 ... 10=.5, 11=1.5, ... 4096=0, 4097=0.5 ... 8192=0, 8193=0.3 + # (models like K-1 and K-5 use 0x1000 and 0x2000 to indicate 1/2 and 1/3 EV step + # size -- convert this as a fraction so we can recognize this format when writing) + ValueConv => [ q{ + return $val / 3 if $val < 10; + return $val - 9.5 if $val < 20; + return ($val - 0x1000) . '/2' if $val & 0x1000; + return ($val - 0x2000) . '/3' if $val & 0x2000; + return $val; # (shouldn't happen) + }], + ValueConvInv => [ q{ + if ($val =~ s{/(\d+)$}{}) { + return $val + 0x1000 if $1 == 2; + return $val + 0x2000 if $1 == 3; + return undef; + } + return abs($val-int($val)-.5)>0.05 ? int($val*3+0.5) : int($val+10); + }], PrintConv => sub { my @v = split(' ', shift); - $v[0] = sprintf('%.1f', $v[0]) if $v[0]; + $v[0] = sprintf('%.1f', $v[0]) if $v[0] and $v[0]!~m{/}; if ($v[1]) { my %s = (1=>'WB-BA',2=>'WB-GM',3=>'Saturation',4=>'Sharpness', 5=>'Contrast',6=>'Hue',7=>'HighLowKey'); @@ -2103,6 +2132,8 @@ my %binaryDataAttrs = ( 9 => 'Radiant', # (Q) 10 => 'Cross Processing', #31 (K-70) 11 => 'Flat', #31 (K-70) + # 256 - seen for GR III + # 262 - seen for GR III }, }, 0x0050 => { #PH @@ -2187,6 +2218,7 @@ my %binaryDataAttrs = ( 16 => '16 (K-1)', #PH 17 => '17 (K-70)', #29 18 => '18 (KP)', #PH + 19 => '19 (GR III)', #PH }, }, 0x0067 => { #PH (K-5) @@ -2418,6 +2450,7 @@ my %binaryDataAttrs = ( '1 0' => 'Slow', '2 0' => 'Standard', '3 0' => 'Fast', + # '1 108' - seen for GR III }, }, 0x007b => { #PH (K-5) @@ -2522,7 +2555,13 @@ my %binaryDataAttrs = ( 0x0088 => { #PH Name => 'NeutralDensityFilter', Writable => 'int8u', - PrintConv => { 0 => 'Off', 1 => 'On' }, + Count => -1, + PrintConv => { + 0 => 'Off', + 1 => 'On', + '0 2' => 'Off (0 2)', #PH (NC, GR III) + '1 2' => 'On (1 2)', #PH (NC, GR III) + }, }, 0x008b => { #PH (LS465) Name => 'ISO', @@ -2660,7 +2699,7 @@ my %binaryDataAttrs = ( SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo' }, },{ Name => 'LensInfo', - Condition => '$count != 90 and $count != 91 and $count != 80 and $count != 128', + Condition => '$count != 90 and $count != 91 and $count != 80 and $count != 128 and $count != 168', SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo2' }, },{ Name => 'LensInfo', # 645D @@ -2675,6 +2714,7 @@ my %binaryDataAttrs = ( Condition => '$count == 80 or $count == 128', SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo5' }, } + # ($count == 168 - Ricoh GR III) ], 0x0208 => [ #PH { @@ -2809,7 +2849,7 @@ my %binaryDataAttrs = ( Name => 'HuffmanTable', Flags => [ 'Unknown', 'Binary' ], Writable => 0, - Notes => 'found in K10D, K20D and K2000D PEF images', + Notes => 'found in K10D, K20D and K2000 PEF images', }, 0x0221 => { #28 Name => 'KelvinWB', @@ -3313,7 +3353,7 @@ my %binaryDataAttrs = ( 8 => { Name => 'ExposureBracketStepSize', # This is set even when Exposure Bracket is Off (and the K10D - # displays Ò---Ó as the step size when you press the EB button) - DaveN + # displays "---" as the step size when you press the EB button) - DaveN # because the last value is remembered and if you turn Exposure Bracket # on the step size goes back to what it was before. PrintConv => { @@ -4269,15 +4309,15 @@ my %binaryDataAttrs = ( Name => 'LC3', %lensCode, }, - 5 => { # LC4 = abberation correction, near distance data + 5 => { # LC4 = aberration correction, near distance data Name => 'LC4', %lensCode, }, - 6 => { # LC5 = light color abberation correction data + 6 => { # LC5 = light color aberration correction data Name => 'LC5', %lensCode, }, - 7 => { # LC6 = open abberation data + 7 => { # LC6 = open aberration data Name => 'LC6', %lensCode, }, @@ -4556,6 +4596,7 @@ my %binaryDataAttrs = ( # *istDS and K100D, but I'm not sure what this means - PH # I've also seen: 0x42 (K2000), 0xf2 (K-7,K-r,K-5), 0x12,0x22 (K-x) - PH PrintConv => { + 1 => 'Camera Battery', #PH (NC, GR III) 2 => 'Body Battery', 3 => 'Grip Battery', 4 => 'External Power Supply', #PH @@ -5251,7 +5292,7 @@ my %binaryDataAttrs = ( NOTES => q{ The parameters associated with each type of digital filter are unique, and these settings are also extracted with the DigitalFilter tag. Information - is not extracted for filters that are "Off" unless the Unknown option is + is not extracted for filters that are "Off" unless the L<Unknown|../ExifTool.html#Unknown> option is used. }, 0 => { @@ -5298,6 +5339,7 @@ my %binaryDataAttrs = ( Mask => 0x0f, PrintHex => 0, PrintConv => { + 0 => 'n/a', #PH (NC, GR III) 1 => 'Horizontal (normal)', 2 => 'Rotate 180', 3 => 'Rotate 90 CW', @@ -6231,7 +6273,7 @@ tags, and everyone who helped contribute to the LensType values. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PhaseOne.pm b/src/Image-ExifTool/lib/Image/ExifTool/PhaseOne.pm index 8b1cd8ad..ef9024d8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PhaseOne.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PhaseOne.pm @@ -15,7 +15,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.05'; +$VERSION = '1.06'; sub WritePhaseOne($$$); sub ProcessPhaseOne($$$); @@ -260,6 +260,7 @@ my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' ); CHECK_PROC => \&Image::ExifTool::Exif::CheckExif, GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, TAG_PREFIX => 'SensorCalibration', + WRITE_GROUP => 'PhaseOne', VARS => { ENTRY_SIZE => 12 }, # (entries do not contain a format field) 0x0400 => { Name => 'SensorDefects', @@ -435,7 +436,7 @@ sub WritePhaseOne($$$) # nothing to do if we aren't changing any PhaseOne tags my $newTags = $et->GetNewTagInfoHash($tagTablePtr); - return undef unless %$newTags or $$et{DropTags}; + return undef unless %$newTags or $$et{DropTags} or $$et{EDIT_DIRS}{PhaseOne}; my $dataPt = $$dirInfo{DataPt}; my $dataPos = $$dirInfo{DataPos} || 0; @@ -710,7 +711,7 @@ One maker notes. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PhotoCD.pm b/src/Image-ExifTool/lib/Image/ExifTool/PhotoCD.pm index 6a2d9916..16d55822 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PhotoCD.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PhotoCD.pm @@ -13,9 +13,8 @@ package Image::ExifTool::PhotoCD; use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -use Image::ExifTool::Exif; # (for Composite:ImageSize) -$VERSION = '1.02'; +$VERSION = '1.03'; sub ProcessExtData($$$); @@ -485,7 +484,7 @@ information from Kodak Photo CD Image Pac (PCD) files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PhotoMechanic.pm b/src/Image-ExifTool/lib/Image/ExifTool/PhotoMechanic.pm index 83de14b5..9454471f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PhotoMechanic.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PhotoMechanic.pm @@ -15,7 +15,7 @@ use Image::ExifTool::Exif; use Image::ExifTool::IPTC; use Image::ExifTool::XMP; -$VERSION = '1.05'; +$VERSION = '1.06'; sub ProcessPhotoMechanic($$); @@ -200,7 +200,7 @@ sub ProcessPhotoMechanic($$) if (defined $newBuff) { $newPt = \$newBuff; # write out the modified trailer my $pad = 0x800 - length($newBuff); - if ($pad > 0 and not $et->Options('Compact')) { + if ($pad > 0 and not $$et{OPTIONS}{Compact}{NoPadding}) { # pad out to 2kB like PhotoMechanic does $newBuff .= "\0" x $pad; } @@ -236,7 +236,7 @@ write information written by the Camera Bits Photo Mechanic software. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Photoshop.pm b/src/Image-ExifTool/lib/Image/ExifTool/Photoshop.pm index 5d93c4fb..de4bb740 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Photoshop.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Photoshop.pm @@ -28,7 +28,7 @@ use strict; use vars qw($VERSION $AUTOLOAD $iptcDigestInfo); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.62'; +$VERSION = '1.64'; sub ProcessPhotoshop($$$); sub WritePhotoshop($$$); @@ -545,7 +545,7 @@ my %unicodeString = ( PrintConv => 'sprintf("%d%%",$val)', }, # tags extracted from additional layer information (tag ID's are real) - # - must be able to accomodate a blank entry to preserve the list ordering + # - must be able to accommodate a blank entry to preserve the list ordering luni => { Name => 'LayerUnicodeNames', List => 1, @@ -675,9 +675,18 @@ sub ProcessLayersAndMask($$$) # check for Lr16 block if layers length is 0 (ref https://forums.adobe.com/thread/1540914) if ($len == 0 and $num == 0) { $raf->Read($data,10) == 10 or return 0; - if ($data =~/^..8BIMLr16/s) { + if ($data =~ /^..8BIMLr16/s) { $raf->Read($data, $psiz+2) == $psiz+2 or return 0; $len = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0); + } elsif ($data =~ /^..8BIMMt16/s) { # (have seen Mt16 before Lr16, ref PH) + $raf->Read($data, $psiz) == $psiz or return 0; + $raf->Read($data, 8) == 8 or return 0; + if ($data eq '8BIMLr16') { + $raf->Read($data, $psiz+2) == $psiz+2 or return 0; + $len = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0); + } else { + $raf->Seek(-18-$psiz, 1) or return 0; + } } else { $raf->Seek(-10, 1) or return 0; } @@ -819,7 +828,7 @@ sub ProcessDocumentData($$$) my $raf = $$dirInfo{RAF}; my $dirLen = $$dirInfo{DirLen}; my $pos = 36; # length of header - my $buff; + my ($buff, $n, $err); $et->VerboseDir('Photoshop Document Data', undef, $dirLen); unless ($raf) { @@ -838,27 +847,26 @@ sub ProcessDocumentData($$$) } my $psb = ($1 eq 'V0002'); my %dinfo = ( DataPt => \$buff ); - my ($n, $setOrder); $$et{IsPSB} = $psb; # set PSB flag (needed when handling Layers directory) while ($pos + 12 <= $dirLen) { - $raf->Read($buff, 8) == 8 or last; + $raf->Read($buff, 8) == 8 or $err = 'Error reading document data', last; # set byte order according to byte order of first signature SetByteOrder($buff =~ /^(8BIM|8B64)/ ? 'MM' : 'II') if $pos == 36; $buff = pack 'N*', unpack 'V*', $buff if GetByteOrder() eq 'II'; my $sig = substr($buff, 0, 4); - last unless $sig eq '8BIM' or $sig eq '8B64'; # verify signature + $sig eq '8BIM' or $sig eq '8B64' or $err = 'Bad photoshop resource', last; # verify signature my $tag = substr($buff, 4, 4); if ($psb and $tag =~ /^(LMsk|Lr16|Lr32|Layr|Mt16|Mt32|Mtrn|Alph|FMsk|lnk2|FEid|FXid|PxSD)$/) { - last if $pos + 16 > $dirLen; - $raf->Read($buff, 8) == 8 or last; + $pos + 16 > $dirLen and $err = 'Short PSB resource', last; + $raf->Read($buff, 8) == 8 or $err = 'Error reading PSB resource', last; $n = Get64u(\$buff, 0); $pos += 4; } else { - $raf->Read($buff, 4) == 4 or last; + $raf->Read($buff, 4) == 4 or $err = 'Error reading PSD resource', last; $n = Get32u(\$buff, 0); } $pos += 12; - last if $pos + $n > $dirLen; + $pos + $n > $dirLen and $err = 'Truncated photoshop resource', last; my $pad = (4 - ($n & 3)) & 3; # number of padding bytes my $tagInfo = $$tagTablePtr{$tag}; if ($tagInfo or $verbose) { @@ -866,20 +874,21 @@ sub ProcessDocumentData($$$) my $fpos = $raf->Tell() + $n + $pad; my $subTable = GetTagTable($$tagInfo{SubDirectory}{TagTable}); $et->ProcessDirectory({ RAF => $raf, DirLen => $n }, $subTable); - $raf->Seek($fpos, 0) or last; + $raf->Seek($fpos, 0) or $err = 'Seek error', last; } else { $dinfo{DataPos} = $raf->Tell(); $dinfo{Start} = 0; $dinfo{Size} = $n; - $raf->Read($buff, $n) == $n or last; + $raf->Read($buff, $n) == $n or $err = 'Error reading photoshop resource', last; $et->HandleTag($tagTablePtr, $tag, undef, %dinfo); - $raf->Seek($pad, 1) or last; + $raf->Seek($pad, 1) or $err = 'Seek error', last; } } else { - $raf->Seek($n + $pad, 1) or last; + $raf->Seek($n + $pad, 1) or $err = 'Seek error', last; } $pos += $n + $pad; # step to start of next structure } + $err and $et->Warn($err); return 1; } @@ -911,6 +920,9 @@ sub ProcessPhotoshop($$$) } } } + if ($$et{FILE_TYPE} eq 'JPEG' and $$dirInfo{Parent} ne 'APP13') { + $$et{LOW_PRIORITY_DIR}{'*'} = 1; # lower priority of all these tags + } SetByteOrder('MM'); # Photoshop is always big-endian $verbose and $et->VerboseDir('Photoshop', 0, $$dirInfo{DirLen}); @@ -975,6 +987,7 @@ sub ProcessPhotoshop($$$) $size += 1 if $size & 0x01; # size is padded to an even # bytes $pos += $size; } + delete $$et{LOW_PRIORITY_DIR}{'*'}; return $success; } @@ -1123,7 +1136,7 @@ be preserved when copying Photoshop information via user-defined tags. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PostScript.pm b/src/Image-ExifTool/lib/Image/ExifTool/PostScript.pm index 65481b8f..5380df29 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PostScript.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PostScript.pm @@ -16,7 +16,7 @@ use strict; use vars qw($VERSION $AUTOLOAD); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.43'; +$VERSION = '1.44'; sub WritePS($$); sub ProcessPS($$;$); @@ -89,12 +89,12 @@ sub ProcessPS($$;$); SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main', }, - Notes => 'extracted with ExtractEmbedded option', + Notes => 'extracted with L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option', }, EmbeddedFileName => { Notes => q{ not a real tag ID, but the file name from a BeginDocument statement. - Extracted with document metadata when ExtractEmbedded option is used + Extracted with document metadata when L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option is used }, }, # AI metadata (most with a single leading '%') @@ -208,9 +208,9 @@ sub GetInputRecordSeparator($) $a = pos($data), pos($data) = 0 if $data =~ /\x0a/g; $d = pos($data) if $data =~ /\x0d/g; my $diff = $a - $d; - if ($diff eq 1) { + if ($diff == 1) { $sep = "\x0d\x0a"; - } elsif ($diff eq -1) { + } elsif ($diff == -1) { $sep = "\x0a\x0d"; } elsif ($diff > 0) { $sep = "\x0d"; @@ -221,6 +221,97 @@ sub GetInputRecordSeparator($) return $sep; } +#------------------------------------------------------------------------------ +# Split into lines ending in any CR, LF or CR+LF combination +# (this is annoying, and could be avoided if EPS files didn't mix linefeeds!) +# Inputs: 0) data pointer, 1) reference to lines array +# Notes: Fills @$lines with lines from splitting $$dataPt +sub SplitLine($$) +{ + my ($dataPt, $lines) = @_; + for (;;) { + my $endl; + # find the position of the first LF (\x0a) + $endl = pos($$dataPt), pos($$dataPt) = 0 if $$dataPt =~ /\x0a/g; + if ($$dataPt =~ /\x0d/g) { # find the first CR (\x0d) + if (defined $endl) { + # (remember, CR+LF is a DOS newline...) + $endl = pos($$dataPt) if pos($$dataPt) < $endl - 1; + } else { + $endl = pos($$dataPt); + } + } elsif (not defined $endl) { + push @$lines, $$dataPt; + last; + } + if (length $$dataPt == $endl) { + push @$lines, $$dataPt; + last; + } else { + # continue to split into separate lines + push @$lines, substr($$dataPt, 0, $endl); + $$dataPt = substr($$dataPt, $endl); + } + } +} + +#------------------------------------------------------------------------------ +# check to be sure we haven't read past end of PS data in DOS-style file +# Inputs: 0) RAF ref (with PSEnd member), 1) data ref +# - modifies data and sets RAF to EOF if end of PS is reached +sub CheckPSEnd($$) +{ + my ($raf, $dataPt) = @_; + my $pos = $raf->Tell(); + if ($pos >= $$raf{PSEnd}) { + $raf->Seek(0, 2); # seek to end of file so we can't read any more + $$dataPt = substr($$dataPt, 0, length($$dataPt) - $pos + $$raf{PSEnd}) if $pos > $$raf{PSEnd}; + } +} + +#------------------------------------------------------------------------------ +# Read next line from EPS file +# Inputs: 0) RAF ref (with PSEnd member if Postscript ends before end of file) +# 1) array of lines from file +# Returns: true on success +sub GetNextLine($$) +{ + my ($raf, $lines) = @_; + my ($data, $changedNL); + my $altnl = ($/ eq "\x0d") ? "\x0a" : "\x0d"; + for (;;) { + $raf->ReadLine($data) or last; + $$raf{PSEnd} and CheckPSEnd($raf, \$data); + # split line if it contains other newline sequences + if ($data =~ /$altnl/) { + if (length($data) > 500000 and IsPC()) { + # patch for Windows memory problem + unless ($changedNL) { + $changedNL = $/; + $/ = $altnl; + $altnl = $changedNL; + $raf->Seek(-length($data), 1); + next; + } + } else { + # split into separate lines + # push @$lines, split /$altnl/, $data, -1; + # if (@$lines == 2 and $$lines[1] eq $/) { + # # handle case of DOS newline data inside file using Unix newlines + # $$lines[0] .= pop @$lines; + # } + # split into separate lines if necessary + SplitLine(\$data, $lines); + } + } else { + push @$lines, $data; + } + $/ = $changedNL if $changedNL; + return 1; + } + return 0; +} + #------------------------------------------------------------------------------ # Decode comment from PostScript file # Inputs: 0) comment string, 1) RAF ref, 2) reference to lines array @@ -233,22 +324,7 @@ sub DecodeComment($$$;$) $val =~ s/\x0d*\x0a*$//; # remove trailing CR, LF or CR/LF # check for continuation comments for (;;) { - unless (@$lines) { - my $buff; - $raf->ReadLine($buff) or last; - my $altnl = $/ eq "\x0d" ? "\x0a" : "\x0d"; - if ($buff =~ /$altnl/) { - chomp $buff if $/ eq "\x0d\x0a"; # remove DOS newline before splitting - # split into separate lines - @$lines = split /$altnl/, $buff, -1; - # handle case of DOS newline data inside file using Unix newlines - @$lines = ( $$lines[0] . $$lines[1] ) if @$lines == 2 and $$lines[1] eq $/; - # add back trailing DOS newline if necessary - @$lines ? @$lines[-1] .= $/ : push @$lines, $/ if $/ eq "\x0d\x0a"; - } else { - push @$lines, $buff; - } - } + @$lines or GetNextLine($raf, $lines) or last; last unless $$lines[0] =~ /^%%\+/; # is the next line a continuation? $$dataPt .= $$lines[0] if $dataPt; # add to data if necessary $$lines[0] =~ s/\x0d*\x0a*$//; # remove trailing CR, LF or CR/LF @@ -371,11 +447,13 @@ sub ProcessPS($$;$) # - save DOS header then seek ahead and check PS header $raf->Read($dos, 26) == 26 or return 0; SetByteOrder('II'); - unless ($raf->Seek(Get32u(\$dos, 0), 0) and + my $psStart = Get32u(\$dos, 0); + unless ($raf->Seek($psStart, 0) and $raf->Read($data, 4) == 4 and $data eq '%!PS') { return PSErr($et, 'invalid header'); } + $$raf{PSEnd} = $psStart + Get32u(\$dos, 4); # set end of PostScript data in RAF } else { # check for PostScript font file (PFA or PFB) my $d2; @@ -487,7 +565,7 @@ sub ProcessPS($$;$) if ($mode) { if (not $endToken) { $buff .= $data; - next unless $data =~ m{<\?xpacket end=.(w|r).\?>($/|$)}; + next unless $data =~ m{<\?xpacket end=.(w|r).\?>(\n|\r|$)}; } elsif ($data !~ /^$endToken/i) { if ($mode eq 'XMP') { $buff .= $data; @@ -565,7 +643,7 @@ sub ProcessPS($$;$) $buff = $data; undef $endToken; # no end token (just look for xpacket end) # XMP could be contained in a single line (if newlines are different) - next unless $data =~ m{<\?xpacket end=.(w|r).\?>($/|$)}; + next unless $data =~ m{<\?xpacket end=.(w|r).\?>(\n|\r|$)}; } elsif ($data =~ /^%%?(\w+): ?(.*)/s and $$tagTablePtr{$1}) { my ($tag, $val) = ($1, $2); # only allow 'ImageData' and AI tags to have single leading '%' @@ -699,7 +777,7 @@ This code reads meta information from EPS (Encapsulated PostScript), PS =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/PrintIM.pm b/src/Image-ExifTool/lib/Image/ExifTool/PrintIM.pm index 79cf88cb..fcf3cf95 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/PrintIM.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/PrintIM.pm @@ -112,7 +112,7 @@ Print Image Matching meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Qualcomm.pm b/src/Image-ExifTool/lib/Image/ExifTool/Qualcomm.pm index 12438dc6..ed327f6e 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Qualcomm.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Qualcomm.pm @@ -1331,7 +1331,7 @@ information from the APP7 Qualcomm segment in JPEG images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/QuickTime.pm b/src/Image-ExifTool/lib/Image/ExifTool/QuickTime.pm index 4573a72d..a89b199a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/QuickTime.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/QuickTime.pm @@ -32,17 +32,21 @@ # 20) https://developer.apple.com/legacy/library/documentation/quicktime/reference/QT7-1_Update_Reference/QT7-1_Update_Reference.pdf # 21) Francois Bonzon private communication # 22) https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html +# 23) http://atomicparsley.sourceforge.net/mpeg-4files.html +# 24) https://github.com/sergiomb2/libmp4v2/wiki/iTunesMetadata +# 25) https://cconcolato.github.io/mp4ra/atoms.html +# 26) https://github.com/SamsungVR/android_upload_sdk/blob/master/SDKLib/src/main/java/com/samsung/msca/samsungvr/sdk/UserVideo.java #------------------------------------------------------------------------------ package Image::ExifTool::QuickTime; use strict; -use vars qw($VERSION $AUTOLOAD); +use vars qw($VERSION $AUTOLOAD %stringEncoding); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::GPS; -$VERSION = '2.20'; +$VERSION = '2.45'; sub ProcessMOV($$;$); sub ProcessKeys($$$); @@ -52,19 +56,34 @@ sub ProcessEncodingParams($$$); sub ProcessSampleDesc($$$); sub ProcessHybrid($$$); sub ProcessRights($$$); -sub Process_mebx($$$); # (in QuickTimeStream.pl) +# ++vvvvvvvvvvvv++ (in QuickTimeStream.pl) +sub Process_mebx($$$); +sub Process_3gf($$$); +sub Process_gps0($$$); +sub Process_gsen($$$); +sub ProcessRIFFTrailer($$$); +sub ProcessTTAD($$$); +sub ProcessNMEA($$$); +sub SaveMetaKeys($$$); +# ++^^^^^^^^^^^^++ sub ParseItemLocation($$); +sub ParseContentDescribes($$); sub ParseItemInfoEntry($$); sub ParseItemPropAssoc($$); sub FixWrongFormat($); sub GetMatrixStructure($$); sub ConvertISO6709($); +sub ConvInvISO6709($); sub ConvertChapterList($); sub PrintChapter($); sub PrintGPSCoordinates($); -sub UnpackLang($); +sub PrintInvGPSCoordinates($); +sub UnpackLang($;$); +sub WriteKeys($$$); sub WriteQuickTime($$$); sub WriteMOV($$); +sub GetLangInfo($$); +sub CheckQTValue($$$); # MIME types for all entries in the ftypLookup with file extensions # (defaults to 'video/mp4' if not found in this lookup) @@ -87,6 +106,7 @@ my %mimeLookup = ( HEIC => 'image/heic', HEVC => 'image/heic-sequence', HEIF => 'image/heif', + AVIF => 'image/avif', #PH (NC) CRX => 'video/x-canon-crx', # (will get overridden) ); @@ -186,6 +206,8 @@ my %ftypLookup = ( 'hevc' => 'High Efficiency Image Format HEVC sequence (.HEICS)', # image/heic-sequence 'mif1' => 'High Efficiency Image Format still image (.HEIF)', # image/heif 'msf1' => 'High Efficiency Image Format sequence (.HEIFS)', # image/heif-sequence + 'heix' => 'High Efficiency Image Format still image (.HEIF)', # image/heif (ref PH, Canon 1DXmkIII) + 'avif' => 'AV1 Image File Format (.AVIF)', # image/avif 'crx ' => 'Canon Raw (.CRX)', #PH (CR3 or CRM; use Canon CompressorVersion to decide) ); @@ -197,7 +219,9 @@ my %timeInfo = ( RawConv => q{ my $offset = (66 * 365 + 17) * 24 * 3600; return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC}; - $self->WarnOnce('Patched incorrect time zero for QuickTime date/time tag',1) if $val; + if ($val and not $$self{IsWriting}) { + $self->WarnOnce('Patched incorrect time zero for QuickTime date/time tag',1); + } return $val; }, Shift => 'Time', @@ -223,15 +247,9 @@ my %unknownInfo = ( ); # parsing for most of the 3gp udta language text boxes my %langText = ( - RawConv => sub { - my ($val, $self) = @_; - return '<err>' unless length $val >= 6; - my $lang = UnpackLang(Get16u(\$val, 4)); - $lang = $lang ? "($lang) " : ''; - $val = substr($val, 6); # isolate string - $val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/; - return $lang . $val; - }, + Notes => 'used in 3gp videos', + IText => 6, + Avoid => 1, ); # 4-character Vendor ID codes (ref PH) @@ -258,7 +276,7 @@ my %vendorID = ( ); # QuickTime data atom encodings for string types (ref 12) -my %stringEncoding = ( +%stringEncoding = ( 1 => 'UTF8', 2 => 'UTF16', 3 => 'ShiftJIS', @@ -372,21 +390,35 @@ my %channelLabel = ( # properties which don't get inherited from the parent my %dontInherit = ( ispe => 1, # size of parent may be different + hvcC => 1, # (likely redundant) ); +# tags that may be duplicated and directories that may contain duplicate tags +# (used only to avoid warnings when Validate-ing) +my %dupTagOK = ( mdat => 1, trak => 1, free => 1, infe => 1, sgpd => 1, dimg => 1, CCDT => 1, + sbgp => 1, csgm => 1, uuid => 1, cdsc => 1, maxr => 1, '----' => 1 ); +my %dupDirOK = ( ipco => 1, '----' => 1 ); + # the usual atoms required to decode timed metadata with the ExtractEmbedded option -my %eeStd = ( stco => 1, co64 => 1, stsz => 1, stz2 => 1, stsc => 1, stts => 1 ); +my %eeStd = ( stco => 'stbl', co64 => 'stbl', stsz => 'stbl', stz2 => 'stbl', + stsc => 'stbl', stts => 'stbl' ); -# boxes for the various handler types that we want to save when ExtractEmbedded is enabled +# boxes and their containers for the various handler types that we want to save +# when the ExtractEmbedded is enabled (currently only the 'gps ' container name is +# used, but others have been checked against all available sample files and may be +# useful in the future if the names are used for different boxes on other locations) my %eeBox = ( # (note: vide is only processed if specific atoms exist in the VideoSampleDesc) - vide => { %eeStd, JPEG => 1 }, # (add avcC to parse H264 stream) + vide => { %eeStd, + JPEG => 'stsd', + # avcC => 'stsd', # (uncomment to parse H264 stream) + }, text => { %eeStd }, meta => { %eeStd }, sbtl => { %eeStd }, data => { %eeStd }, camm => { %eeStd }, # (Insta360) - '' => { 'gps ' => 1 }, # (no handler -- top level box) + '' => { 'gps ' => 'moov' }, # (no handler -- in top level 'moov' box) ); # QuickTime atoms @@ -394,31 +426,6 @@ my %eeBox = ( PROCESS_PROC => \&ProcessMOV, WRITE_PROC => \&WriteQuickTime, # (only needs to be defined for directories to process when writing) GROUPS => { 2 => 'Video' }, - NOTES => q{ - The QuickTime format is used for many different types of audio, video and - image files (most notably, MOV/MP4 videos and HEIC/CR3 images). Exiftool - extracts standard meta information a variety of audio, video and image - parameters, as well as proprietary information written by many camera - models. Tags with a question mark after their name are not extracted unless - the Unknown option is set. - - ExifTool currently has a very limited ability to write metadata in - QuickTime-format videos. It can edit/create/delete any XMP tags, but may - only be used to edit certain date/time tags and the video orientation in - native QuickTime metadata. - - According to the specification, many QuickTime date/time tags should be - stored as UTC. Unfortunately, digital cameras often store local time values - instead (presumably because they don't know the time zone). For this - reason, by default ExifTool does not assume a time zone for these values. - However, if the QuickTimeUTC API option is set, then ExifTool will assume - these values are properly stored as UTC, and will convert them to local time - when extracting. - - See - L<http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html> - for the official specification. - }, meta => { # 'meta' is found here in my Sony ILCE-7S MP4 sample - PH Name => 'Meta', SubDirectory => { @@ -426,12 +433,21 @@ my %eeBox = ( Start => 4, # skip 4-byte version number header }, }, + meco => { #ISO14496-12:2015 + Name => 'OtherMeta', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::OtherMeta' }, + }, free => [ { Name => 'KodakFree', # (found in Kodak M5370 MP4 videos) Condition => '$$valPt =~ /^\0\0\0.Seri/s', SubDirectory => { TagTable => 'Image::ExifTool::Kodak::Free' }, + },{ + Name => 'Pittasoft', + # (Pittasoft Blackview dashcam MP4 videos) + Condition => '$$valPt =~ /^\0\0..(cprt|sttm|ptnm|ptrh|thum|gps |3gf )/s', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Pittasoft' }, },{ Unknown => 1, Binary => 1, @@ -449,6 +465,17 @@ my %eeBox = ( Condition => '$$valPt =~ /^\0.{3}(CNDB|CNCV|CNMN|CNFV|CNTH|CNDM)/s', SubDirectory => { TagTable => 'Image::ExifTool::Canon::Skip' }, }, + { + Name => 'PreviewImage', # (found in DuDuBell M1 dashcam MOV files) + Groups => { 2 => 'Preview' }, + Condition => '$$valPt =~ /^.{12}\xff\xd8\xff/', + Binary => 1, + RawConv => q{ + my $len = Get32u(\$val, 8); + return undef unless length($val) >= $len + 12; + return substr($val, 12, $len); + }, + }, { Name => 'Skip', Unknown => 1, Binary => 1 }, ], wide => { Unknown => 1, Binary => 1 }, @@ -481,21 +508,22 @@ my %eeBox = ( }, # mfra - movie fragment random access: contains tfra (track fragment random access), and # mfro (movie fragment random access offset) (ref 5) - mdat => { Name => 'MovieData', Unknown => 1, Binary => 1 }, + mdat => { Name => 'MediaData', Unknown => 1, Binary => 1 }, 'mdat-size' => { - Name => 'MovieDataSize', + Name => 'MediaDataSize', Notes => q{ not a real tag ID, this tag represents the size of the 'mdat' data in bytes and is used in the AvgBitrate calculation }, }, - 'mdat-offset' => 'MovieDataOffset', + 'mdat-offset' => 'MediaDataOffset', junk => { Unknown => 1, Binary => 1 }, #8 uuid => [ { #9 (MP4 files) Name => 'XMP', # *** this is where ExifTool writes XMP in MP4 videos (as per XMP spec) *** Condition => '$$valPt=~/^\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac/', + WriteGroup => 'XMP', # (write main XMP tags here) SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main', Start => 16, @@ -519,10 +547,28 @@ my %eeBox = ( }, # "\x98\x7f\xa3\xdf\x2a\x85\x43\xc0\x8f\x8f\xd9\x7c\x47\x1e\x8e\xea" - unknown data in Flip videos { #PH (Canon CR3) - Name => 'UUID-Preview', - Condition => '$$valPt=~/^\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16/', + Name => 'UUID-Canon2', + WriteLast => 1, # MUST come after mdat or DPP will drop mdat when writing! + Condition => '$$valPt=~/^\x21\x0f\x16\x87\x91\x49\x11\xe4\x81\x11\x00\x24\x21\x31\xfc\xe4/', + SubDirectory => { + TagTable => 'Image::ExifTool::Canon::uuid2', + Start => 16, + }, + }, + { #PH (Canon CR3) Name => 'PreviewImage', + Condition => '$$valPt=~/^\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16/', Groups => { 2 => 'Preview' }, + # 0x00 - undef[16]: UUID + # 0x10 - int32u[2]: "0 1" (version and/or item count?) + # 0x18 - int32u: PRVW atom size + # 0x20 - int32u: 'PRVW' + # 0x30 - int32u: 0 + # 0x34 - int16u: 1 + # 0x36 - int16u: image width + # 0x38 - int16u: image height + # 0x3a - int16u: 1 + # 0x3c - int32u: preview length RawConv => '$val = substr($val, 0x30); $self->ValidateImage(\$val, $tag)', }, { #8 @@ -591,6 +637,36 @@ my %eeBox = ( }, # meta - proprietary XML information written by some Flip cameras - PH # beam - 16 bytes found in an iPhone video + IDIT => { #PH (written by DuDuBell M1, VSYS M6L dashcams) + Name => 'DateTimeOriginal', + Description => 'Date/Time Original', + Groups => { 2 => 'Time' }, + Format => 'string', # (removes trailing "\0") + Shift => 'Time', + Writable => 1, + Permanent => 1, + DelValue => '0000-00-00T00:00:00+0000', + ValueConv => '$val=~tr/-/:/; $val', + ValueConvInv => '$val=~s/(\d+):(\d+):/$1-$2-/; $val', + PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', + }, + gps0 => { #PH (DuDuBell M1, VSYS M6L) + Name => 'GPSTrack', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Stream', + ProcessProc => \&Process_gps0, + }, + }, + gsen => { #PH (DuDuBell M1, VSYS M6L) + Name => 'GSensor', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Stream', + ProcessProc => \&Process_gsen, + }, + }, + # gpsa - seen hex "01 20 00 00" (DuDuBell M1, VSYS M6L) + # gsea - 20 bytes hex "05 00's..." (DuDuBell M1) "05 08 02 01 ..." (VSYS M6L) ); # MPEG-4 'ftyp' atom @@ -685,8 +761,8 @@ my %eeBox = ( # v216 => "Uncompressed Y'CbCr, 10, 12, 14, or 16-bit 4:2:2", # v410 => "Uncompressed Y'CbCr, 10-bit 4:4:4", # v210 => "Uncompressed Y'CbCr, 10-bit 4:2:2", +# hvc1 => 'HEVC', #PH # }, - # (HEVC-encoded videos have a CompressorID of 'hvc1') }, 10 => { Name => 'VendorID', @@ -766,9 +842,10 @@ my %eeBox = ( # mjqt - default quantization table for MJPEG # mjht - default Huffman table for MJPEG # csgm ? (seen in hevc video) - # CMP1 - 52 bytes (Canon CR3) - # JPEG - 4 bytes all 0 (Canon CR3) - # free - (Canon CR3) + CMP1 => { # Canon CR3 + Name => 'CMP1', + SubDirectory => { TagTable => 'Image::ExifTool::Canon::CMP1' }, + }, CDI1 => { # Canon CR3 Name => 'CDI1', SubDirectory => { @@ -776,6 +853,8 @@ my %eeBox = ( Start => 4, }, }, + # JPEG - 4 bytes all 0 (Canon CR3) + # free - (Canon CR3) # # spherical video v2 stuff (untested) # @@ -922,6 +1001,7 @@ my %eeBox = ( }, trak => { Name => 'Track', + CanCreate => 0, # don't create this atom SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Track' }, }, udta => { @@ -971,6 +1051,10 @@ my %eeBox = ( Unknown => 1, Binary => 1, }, + meco => { #ISO14496-12:2015 + Name => 'OtherMeta', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::OtherMeta' }, + }, # prfl - Profile (ref 12) # clip - clipping --> contains crgn (clip region) (ref 12) # mvex - movie extends --> contains mehd (movie extends header), trex (track extends) (ref 14) @@ -982,11 +1066,26 @@ my %eeBox = ( PROCESS_PROC => \&ProcessMOV, WRITE_PROC => \&WriteQuickTime, GROUPS => { 2 => 'Video' }, - # mfhd - movie fragment header + mfhd => { + Name => 'MovieFragmentHeader', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieFragHdr' }, + }, traf => { Name => 'TrackFragment', SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackFragment' }, }, + meta => { #ISO14496-12:2015 + Name => 'Meta', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Meta' }, + }, +); + +# (ref CFFMediaFormat-2_1.pdf) +%Image::ExifTool::QuickTime::MovieFragHdr = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Video' }, + FORMAT => 'int32u', + 1 => 'MovieFragmentSequence', ); # (ref CFFMediaFormat-2_1.pdf) @@ -994,6 +1093,10 @@ my %eeBox = ( PROCESS_PROC => \&ProcessMOV, WRITE_PROC => \&WriteQuickTime, GROUPS => { 2 => 'Video' }, + meta => { #ISO14496-12:2015 + Name => 'Meta', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Meta' }, + }, # tfhd - track fragment header # edts - edits --> contains elst (edit list) (ref PH) # tfdt - track fragment base media decode time @@ -1115,11 +1218,12 @@ my %eeBox = ( { #https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md Name => 'SphericalVideoXML', Condition => '$$valPt=~/^\xff\xcc\x82\x63\xf8\x55\x4a\x93\x88\x14\x58\x7a\x02\x52\x1f\xdd/', - Flags => [ 'Binary', 'BlockExtract' ], - Writable => 0, + WriteGroup => 'GSpherical', # write only GSpherical XMP tags here + HandlerType => 'vide', # only write in video tracks SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main', Start => 16, + WriteProc => 'Image::ExifTool::XMP::WriteGSpherical', }, }, { @@ -1127,6 +1231,10 @@ my %eeBox = ( %unknownInfo, }, ], + meco => { #ISO14492-12:2015 pg 83 + Name => 'OtherMeta', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::OtherMeta' }, + }, # edts - edits --> contains elst (edit list) # clip - clipping --> contains crgn (clip region) # matt - track matt --> contains kmat (compressed matt) @@ -1230,17 +1338,30 @@ my %eeBox = ( %Image::ExifTool::QuickTime::UserData = ( PROCESS_PROC => \&ProcessMOV, WRITE_PROC => \&WriteQuickTime, - GROUPS => { 2 => 'Video' }, + CHECK_PROC => \&CheckQTValue, + GROUPS => { 1 => 'UserData', 2 => 'Video' }, + WRITABLE => 1, + PREFERRED => 1, # (preferred over Keys tags when writing) + FORMAT => 'string', + WRITE_GROUP => 'UserData', + LANG_INFO => \&GetLangInfo, NOTES => q{ Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language - text. Alternate language tags are accessed by adding a dash followed by the - language/country code to the tag name. ExifTool will extract any - multi-language user data tags found, even if they don't exist in this table. + text. Alternate language tags are accessed by adding a dash followed by a + 3-character ISO 639-2 language code to the tag name. ExifTool will extract + any multi-language user data tags found, even if they aren't in this table. + Note when creating new tags, + L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> tags are + preferred over these, so to create the tag when a same-named ItemList tag + exists, either "UserData" must be specified (eg. C<-UserData:Artist=Monet> + on the command line), or the PREFERRED level must be changed via + L<the config file|../config.html#PREF>. }, "\xa9cpy" => { Name => 'Copyright', Groups => { 2 => 'Author' } }, "\xa9day" => { Name => 'ContentCreateDate', Groups => { 2 => 'Time' }, + Shift => 'Time', # handle values in the form "2010-02-12T13:27:14-0800" (written by Apple iPhone) ValueConv => q{ require Image::ExifTool::XMP; @@ -1248,7 +1369,14 @@ my %eeBox = ( $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary return $val; }, + ValueConvInv => q{ + require Image::ExifTool::XMP; + $val = Image::ExifTool::XMP::FormatXMPDate($val); + $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon + return $val; + }, PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, "\xa9ART" => 'Artist', #PH (iTunes 8.0.2) "\xa9alb" => 'Album', #PH (iTunes 8.0.2) @@ -1285,7 +1413,6 @@ my %eeBox = ( "\xa9prf" => 'Performers', "\xa9prk" => 'PerformerKeywords', #12 "\xa9prl" => 'PerformerURL', - "\xa9dir" => 'Director', #12 "\xa9req" => 'Requirements', "\xa9snk" => 'SubtitleKeywords', #12 "\xa9snm" => 'Subtitle', #12 @@ -1295,12 +1422,14 @@ my %eeBox = ( "\xa9swr" => 'SoftwareVersion', #12 "\xa9too" => 'Encoder', #PH (NC) "\xa9trk" => 'Track', #PH (NC) - "\xa9wrt" => 'Composer', + "\xa9wrt" => { Name => 'Composer', Avoid => 1 }, # ("\xa9com" is preferred in UserData) "\xa9xyz" => { #PH (iPhone 3GS) Name => 'GPSCoordinates', Groups => { 2 => 'Location' }, ValueConv => \&ConvertISO6709, + ValueConvInv => \&ConvInvISO6709, PrintConv => \&PrintGPSCoordinates, + PrintConvInv => \&PrintInvGPSCoordinates, }, # \xa9 tags written by DJI Phantom 3: (ref PH) "\xa9xsp" => 'SpeedX', #PH (guess) @@ -1317,7 +1446,12 @@ my %eeBox = ( "\xa9dji" => { Name => 'UserData_dji', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 }, "\xa9res" => { Name => 'UserData_res', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 }, "\xa9uid" => { Name => 'UserData_uid', Format => 'undef', Binary => 1, Unknown => 1, Hidden => 1 }, - "\xa9mdl" => { Name => 'Model', Format => 'string', Notes => 'non-standard-format DJI tag' }, + "\xa9mdl" => { + Name => 'Model', + Notes => 'non-standard-format DJI tag', + Format => 'string', + Avoid => 1, + }, # end DJI tags name => 'Name', WLOC => { @@ -1362,12 +1496,14 @@ my %eeBox = ( hinv => 'HintVersion', #PH (guess) XMP_ => { #PH (Adobe CS3 Bridge) Name => 'XMP', + WriteGroup => 'XMP', # (write main tags here) # *** this is where ExifTool writes XMP in MOV videos (as per XMP spec) *** SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' }, }, # the following are 3gp tags, references: # http://atomicparsley.sourceforge.net # http://www.3gpp.org/ftp/tsg_sa/WG4_CODEC/TSGS4_25/Docs/ + # (note that all %langText tags are Avoid => 1) cprt => { Name => 'Copyright', %langText, Groups => { 2 => 'Author' } }, auth => { Name => 'Author', %langText, Groups => { 2 => 'Author' } }, titl => { Name => 'Title', %langText }, @@ -1481,7 +1617,7 @@ my %eeBox = ( }, }, # tsel - TrackSelection (ref 17) - # Apple tags (ref 16) + # Apple tags (ref 16[dead] -- see ref 25 instead) angl => { Name => 'CameraAngle', Format => 'string' }, # (NC) clfn => { Name => 'ClipFileName', Format => 'string' }, # (NC) clid => { Name => 'ClipID', Format => 'string' }, # (NC) @@ -1489,27 +1625,39 @@ my %eeBox = ( cmnm => { # (NC) Name => 'Model', Description => 'Camera Model Name', + Avoid => 1, Format => 'string', # (necessary to remove the trailing NULL) }, date => { # (NC) Name => 'DateTimeOriginal', + Description => 'Date/Time Original', Groups => { 2 => 'Time' }, + Shift => 'Time', ValueConv => q{ require Image::ExifTool::XMP; $val = Image::ExifTool::XMP::ConvertXMPDate($val); $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary return $val; }, + ValueConvInv => q{ + require Image::ExifTool::XMP; + $val = Image::ExifTool::XMP::FormatXMPDate($val); + $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon + return $val; + }, PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, manu => { # (SX280) Name => 'Make', + Avoid => 1, # (with Canon there are 6 unknown bytes before the model: "\0\0\0\0\x15\xc7") RawConv => '$val=~s/^\0{4}..//s; $val=~s/\0.*//; $val', }, modl => { # (Samsung GT-S8530, Canon SX280) Name => 'Model', Description => 'Camera Model Name', + Avoid => 1, # (with Canon there are 6 unknown bytes before the model: "\0\0\0\0\x15\xc7") RawConv => '$val=~s/^\0{4}..//s; $val=~s/\0.*//; $val', }, @@ -1523,7 +1671,7 @@ my %eeBox = ( Name => 'TrackType', # set flag to process this as international text # even though the tag ID doesn't start with 0xa9 - IText => 1, + IText => 4, # IText with 4-byte header }, chpl => { # (Nero chapter list) Name => 'ChapterList', @@ -1661,6 +1809,7 @@ my %eeBox = ( CNMN => { Name => 'Model', #PH (EOS 550D) Description => 'Camera Model Name', + Avoid => 1, Format => 'string', # (necessary to remove the trailing NULL) }, CNFV => { Name => 'FirmwareVersion', Format => 'string' }, #PH (EOS 550D) @@ -1706,12 +1855,13 @@ my %eeBox = ( }, # ---- GoPro ---- (ref PH) GoPr => 'GoProType', # (Hero3+) - FIRM => 'FirmwareVersion', # (Hero4) + FIRM => { Name => 'FirmwareVersion', Avoid => 1 }, # (Hero4) LENS => 'LensSerialNumber', # (Hero4) CAME => { # (Hero4) Name => 'SerialNumberHash', Description => 'Camera Serial Number Hash', ValueConv => 'unpack("H*",$val)', + ValueConvInv => 'pack("H*",$val)', }, # SETT? 12 bytes (Hero4) # MUID? 32 bytes (Hero4, starts with serial number hash) @@ -1726,6 +1876,7 @@ my %eeBox = ( # free (all zero) "\xa9TSC" => 'StartTimeScale', # (Hero6) "\xa9TSZ" => 'StartTimeSampleSize', # (Hero6) + "\xa9TIM" => 'StartTimecode', #PH (NC) # --- HTC ---- htcb => { Name => 'HTCBinary', @@ -1736,10 +1887,10 @@ my %eeBox = ( Name => 'KodakDcMD', SubDirectory => { TagTable => 'Image::ExifTool::Kodak::DcMD' }, }, - SNum => { Name => 'SerialNumber', Groups => { 2 => 'Camera' } }, - ptch => { Name => 'Pitch', Format => 'rational64s' }, # Units?? - _yaw => { Name => 'Yaw', Format => 'rational64s' }, # Units?? - roll => { Name => 'Roll', Format => 'rational64s' }, # Units?? + SNum => { Name => 'SerialNumber', Avoid => 1, Groups => { 2 => 'Camera' } }, + ptch => { Name => 'Pitch', Format => 'rational64s', Avoid => 1 }, # Units?? + _yaw => { Name => 'Yaw', Format => 'rational64s', Avoid => 1 }, # Units?? + roll => { Name => 'Roll', Format => 'rational64s', Avoid => 1 }, # Units?? _cx_ => { Name => 'CX', Format => 'rational64s', Unknown => 1 }, _cy_ => { Name => 'CY', Format => 'rational64s', Unknown => 1 }, rads => { Name => 'Rads', Format => 'rational64s', Unknown => 1 }, @@ -1909,8 +2060,32 @@ my %eeBox = ( # @etc - 4 bytes all zero (Samsung WB30F) # saut - 4 bytes all zero (Samsung SM-N900T) # smrd - string "TRUEBLUE" (Samsung SM-C101) + # ---- TomTom Bandit Action Cam ---- + TTMD => { + Name => 'TomTomMetaData', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TomTom' }, + }, + # ---- Samsung Gear 360 ---- + vrot => { + Name => 'AccelerometerData', + Notes => q{ + accelerometer readings for each frame of the video, expressed as sets of + yaw, pitch and roll angles in degrees + }, + Format => 'rational64s', + ValueConv => '$val =~ s/^-?\d+ //; \$val', # (ignore leading version/size words) + }, + # m360 - 8 bytes "0 0 0 0 0 0 0 1" + # opax - 164 bytes unknown (center and affine arrays? ref 26) + # opai - 32 bytes (maybe contains a serial number starting at byte 16? - PH) (rgb gains, degamma, gamma? ref 26) + # intv - 16 bytes all zero # ---- Unknown ---- # CDET - 128 bytes (unknown origin) + # mtyp - 4 bytes all zero (some drone video) + # kgrf - 8 bytes all zero ? (in udta inside trak atom) + # kgcg - 128 bytes 0's and 1's + # kgsi - 4 bytes "00 00 00 80" + # FIEL - 18 bytes "FIEL\0\x01\0\0\0..." # # other 3rd-party tags # (ref http://code.google.com/p/mp4parser/source/browse/trunk/isoparser/src/main/resources/isoparser-default.properties?r=814) @@ -1943,6 +2118,26 @@ my %eeBox = ( # 4 - values: 12 ); +# TomTom Bandit Action Cam metadata (ref PH) +%Image::ExifTool::QuickTime::TomTom = ( + PROCESS_PROC => \&ProcessMOV, + GROUPS => { 2 => 'Video' }, + NOTES => 'Tags found in TomTom Bandit Action Cam MP4 videos.', + TTAD => { + Name => 'TomTomAD', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Stream', + ProcessProc => \&Image::ExifTool::QuickTime::ProcessTTAD, + }, + }, + TTHL => { Name => 'TomTomHL', Binary => 1, Unknown => 1 }, # (mostly zeros) + # (TTID values are different for each video) + TTID => { Name => 'TomTomID', ValueConv => 'unpack("x4H*",$val)' }, + TTVI => { Name => 'TomTomVI', Format => 'int32u', Unknown => 1 }, # seen: "0 1 61 508 508" + # TTVD seen: "normal 720p 60fps 60fps 16/9 wide 1x" + TTVD => { Name => 'TomTomVD', ValueConv => 'my @a = ($val =~ /[\x20-\x7f]+/g); "@a"' }, +); + # User-specific media data atoms (ref 11) %Image::ExifTool::QuickTime::UserMedia = ( PROCESS_PROC => \&ProcessMOV, @@ -1955,16 +2150,22 @@ my %eeBox = ( # User-specific media data atoms (ref 11) %Image::ExifTool::QuickTime::MetaData = ( - PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessMetaData, + PROCESS_PROC => \&ProcessMetaData, GROUPS => { 2 => 'Video' }, TAG_PREFIX => 'MetaData', 0x01 => 'Title', 0x03 => { Name => 'ProductionDate', Groups => { 2 => 'Time' }, + Shift => 'Time', + Writable => 1, + Permanent => 1, + DelValue => '0000/00/00 00:00:00', # translate from format "YYYY/mm/dd HH:MM:SS" ValueConv => '$val=~tr{/}{:}; $val', + ValueConvInv => '$val=~s[^(\d{4}):(\d{2}):][$1/$2/]; $val', PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, 0x04 => 'Software', 0x05 => 'Product', @@ -1980,15 +2181,31 @@ my %eeBox = ( 0x0b => { Name => 'TimeZone', Groups => { 2 => 'Time' }, + Writable => 1, + Permanent => 1, + DelValue => 0, RawConv => 'Get16s(\$val,0)', + RawConvInv => 'Set16s($val)', PrintConv => 'TimeZoneString($val)', + PrintConvInv => q{ + return undef unless $val =~ /^([-+])(\d{1,2}):?(\d{2})$/' + my $tzmin = $2 * 60 + $3; + $tzmin = -$tzmin if $1 eq '-'; + return $tzmin; + } }, 0x0c => { Name => 'ModifyDate', Groups => { 2 => 'Time' }, + Shift => 'Time', + Writable => 1, + Permanent => 1, + DelValue => '0000/00/00 00:00:00', # translate from format "YYYY/mm/dd HH:MM:SS" ValueConv => '$val=~tr{/}{:}; $val', + ValueConvInv => '$val=~s[^(\d{4}):(\d{2}):][$1/$2/]; $val', PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, ); @@ -1997,7 +2214,7 @@ my %eeBox = ( PROCESS_PROC => \&ProcessMOV, GROUPS => { 2 => 'Video' }, dcom => 'Compression', - # cmvd - compressed movie data + # cmvd - compressed moov atom data ); # Profile atoms (ref 11) @@ -2140,7 +2357,8 @@ my %eeBox = ( # meta atoms %Image::ExifTool::QuickTime::Meta = ( PROCESS_PROC => \&ProcessMOV, - GROUPS => { 2 => 'Video' }, + WRITE_PROC => \&WriteQuickTime, + GROUPS => { 1 => 'Meta', 2 => 'Video' }, ilst => { Name => 'ItemList', SubDirectory => { @@ -2154,8 +2372,8 @@ my %eeBox = ( SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Handler' }, }, dinf => { - Name => 'DataInformation', - Flags => ['Binary','Unknown'], + Name => 'DataInfo', # (don't change this name -- used to recognize directory when writing) + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::DataInfo' }, }, ipmc => { Name => 'IPMPControl', @@ -2164,6 +2382,7 @@ my %eeBox = ( iloc => { Name => 'ItemLocation', RawConv => \&ParseItemLocation, + WriteHook => \&ParseItemLocation, Notes => 'parsed, but not extracted as a tag', }, ipro => { @@ -2172,7 +2391,7 @@ my %eeBox = ( }, iinf => [{ Name => 'ItemInformation', - Condition => '$$valPt =~ /^\0/', # (version 0?) + Condition => '$$valPt =~ /^\0/', # (check for version 0) SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ItemInfo', Start => 6, # (4-byte version/flags + 2-byte count) @@ -2186,7 +2405,7 @@ my %eeBox = ( }], 'xml ' => { Name => 'XML', - Flags => [ 'Binary', 'Protected', 'BlockExtract' ], + Flags => [ 'Binary', 'Protected' ], SubDirectory => { TagTable => 'Image::ExifTool::XMP::XML', IgnoreProp => { NonRealTimeMeta => 1 }, # ignore container for Sony 'nrtm' @@ -2204,9 +2423,11 @@ my %eeBox = ( Name => 'PrimaryItemReference', Condition => '$$valPt =~ /^\0/', # (version 0?) RawConv => '$$self{PrimaryItem} = unpack("x4n",$val)', + WriteHook => sub { my ($val,$et) = @_; $$et{PrimaryItem} = unpack("x4n",$val); }, },{ Name => 'PrimaryItemReference', RawConv => '$$self{PrimaryItem} = unpack("x4N",$val)', + WriteHook => sub { my ($val,$et) = @_; $$et{PrimaryItem} = unpack("x4N",$val); }, }], free => { #PH Name => 'Free', @@ -2228,8 +2449,35 @@ my %eeBox = ( # idat ); +# additional metadata container (ref ISO14496-12:2015) +%Image::ExifTool::QuickTime::OtherMeta = ( + PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, + GROUPS => { 2 => 'Video' }, + mere => { + Name => 'MetaRelation', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MetaRelation' }, + }, + meta => { + Name => 'Meta', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Meta' }, + }, +); + +# metabox relation (ref ISO14496-12:2015) +%Image::ExifTool::QuickTime::MetaRelation = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Video' }, + FORMAT => 'int32u', + # 0 => 'MetaRelationVersion', + # 1 => 'FirstMetaboxHandlerType', + # 2 => 'FirstMetaboxHandlerType', + # 3 => { Name => 'MetaboxRelation', Format => 'int8u' }, +); + %Image::ExifTool::QuickTime::ItemProp = ( PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, GROUPS => { 2 => 'Image' }, ipco => { Name => 'ItemPropertyContainer', @@ -2238,12 +2486,15 @@ my %eeBox = ( ipma => { Name => 'ItemPropertyAssociation', RawConv => \&ParseItemPropAssoc, + WriteHook => \&ParseItemPropAssoc, Notes => 'parsed, but not extracted as a tag', }, ); %Image::ExifTool::QuickTime::ItemPropCont = ( PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, + PERMANENT => 1, # (can't be deleted) GROUPS => { 2 => 'Image' }, VARS => { START_INDEX => 1 }, # show verbose indices starting at 1 colr => [{ @@ -2254,13 +2505,15 @@ my %eeBox = ( Start => 4, }, },{ - Name => 'Unknown_colr', - Flags => ['Binary','Unknown','Hidden'], + Name => 'ColorRepresentation', + ValueConv => 'join(" ", substr($val,0,4), unpack("x4n*",$val))', }], irot => { Name => 'Rotation', Format => 'int8u', + Writable => 'int8u', ValueConv => '$val * 90', + ValueConvInv => 'int($val / 90 + 0.5)', }, ispe => { Name => 'ImageSpatialExtent', @@ -2289,6 +2542,7 @@ my %eeBox = ( pasp => { Name => 'PixelAspectRatio', Format => 'int32u', + Writable => 'int32u', }, rloc => { Name => 'RelativeLocation', @@ -2302,12 +2556,204 @@ my %eeBox = ( }, hvcC => { Name => 'HEVCConfiguration', - Flags => ['Binary','Unknown'], + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HEVCConfig' }, + }, + av1C => { + Name => 'AV1Configuration', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::AV1Config' }, + }, +); + +# HEVC configuration (ref https://github.com/MPEGGroup/isobmff/blob/master/IsoLib/libisomediafile/src/HEVCConfigAtom.c) +%Image::ExifTool::QuickTime::HEVCConfig = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Video' }, + FIRST_ENTRY => 0, + 0 => 'HEVCConfigurationVersion', + 1 => { + Name => 'GeneralProfileSpace', + Mask => 0xc0, + PrintConv => { 0 => 'Conforming' }, + }, + 1.1 => { + Name => 'GeneralTierFlag', + Mask => 0x20, + PrintConv => { + 0 => 'Main Tier', + 1 => 'High Tier', + }, + }, + 1.2 => { + Name => 'GeneralProfileIDC', + Mask => 0x1f, + PrintConv => { + 0 => 'No Profile', + 1 => 'Main', + 2 => 'Main 10', + 3 => 'Main Still Picture', + 4 => 'Format Range Extensions', + 5 => 'High Throughput', + 6 => 'Multiview Main', + 7 => 'Scalable Main', + 8 => '3D Main', + 9 => 'Screen Content Coding Extensions', + 10 => 'Scalable Format Range Extensions', + 11 => 'High Throughput Screen Content Coding Extensions', + }, + }, + 2 => { + Name => 'GenProfileCompatibilityFlags', + Format => 'int32u', + PrintConv => { BITMASK => { + 31 => 'No Profile', # (bit 0 in stream) + 30 => 'Main', # (bit 1 in stream) + 29 => 'Main 10', # (bit 2 in stream) + 28 => 'Main Still Picture', # (bit 3 in stream) + 27 => 'Format Range Extensions',# (...) + 26 => 'High Throughput', + 25 => 'Multiview Main', + 24 => 'Scalable Main', + 23 => '3D Main', + 22 => 'Screen Content Coding Extensions', + 21 => 'Scalable Format Range Extensions', + 20 => 'High Throughput Screen Content Coding Extensions', + }}, + }, + 6 => { + Name => 'ConstraintIndicatorFlags', + Format => 'int8u[6]', + }, + 12 => { + Name => 'GeneralLevelIDC', + PrintConv => 'sprintf("%d (level %.1f)", $val, $val/30)', + }, + 13 => { + Name => 'MinSpatialSegmentationIDC', + Format => 'int16u', + Mask => 0x0fff, + }, + 15 => { + Name => 'ParallelismType', + Mask => 0x03, + }, + 16 => { + Name => 'ChromaFormat', + Mask => 0x03, + PrintConv => { + 0 => 'Monochrome', + 1 => '4:2:0', + 2 => '4:2:2', + 3 => '4:4:4', + }, + }, + 17 => { + Name => 'BitDepthLuma', + Mask => 0x07, + ValueConv => '$val + 8', + }, + 18 => { + Name => 'BitDepthChroma', + Mask => 0x07, + ValueConv => '$val + 8', + }, + 19 => { + Name => 'AverageFrameRate', + Format => 'int16u', + ValueConv => '$val / 256', + }, + 21 => { + Name => 'ConstantFrameRate', + Mask => 0xc0, + PrintConv => { + 0 => 'Unknown', + 1 => 'Constant Frame Rate', + 2 => 'Each Temporal Layer is Constant Frame Rate', + }, + }, + 21.1 => { + Name => 'NumTemporalLayers', + Mask => 0x38, + }, + 21.2 => { + Name => 'TemporalIDNested', + Mask => 0x04, + PrintConv => { 0 => 'No', 1 => 'Yes' }, + }, + #21.3 => { + # Name => 'NALUnitLengthSize', + # Mask => 0x03, + # ValueConv => '$val + 1', + # PrintConv => { 1 => '8-bit', 2 => '16-bit', 4 => '32-bit' }, + #}, + #22 => 'NumberOfNALUnitArrays', + # (don't decode the NAL unit arrays) +); + +# HEVC configuration (ref https://aomediacodec.github.io/av1-isobmff/#av1codecconfigurationbox) +%Image::ExifTool::QuickTime::AV1Config = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Video' }, + FIRST_ENTRY => 0, + 0 => { + Name => 'AV1ConfigurationVersion', + Mask => 0x7f, + }, + 1.0 => { + Name => 'SeqProfile', + Mask => 0xe0, + Unknown => 1, + }, + 1.1 => { + Name => 'SeqLevelIdx0', + Mask => 0x1f, + Unknown => 1, + }, + 2.0 => { + Name => 'SeqTier0', + Mask => 0x80, + Unknown => 1, + }, + 2.1 => { + Name => 'HighBitDepth', + Mask => 0x40, + Unknown => 1, + }, + 2.2 => { + Name => 'TwelveBit', + Mask => 0x20, + Unknown => 1, + }, + 2.3 => { + Name => 'ChromaFormat', # (Monochrome+SubSamplingX+SubSamplingY) + Notes => 'bits: 0x04 = Monochrome, 0x02 = SubSamplingX, 0x01 = SubSamplingY', + Mask => 0x1c, + PrintConv => { + 0x00 => 'YUV 4:4:4', + 0x02 => 'YUV 4:2:2', + 0x03 => 'YUV 4:2:0', + 0x07 => 'Monochrome 4:0:0', + }, + }, + 2.4 => { + Name => 'ChromaSamplePosition', + Mask => 0x03, + PrintConv => { + 0 => 'Unknown', + 1 => 'Vertical', + 2 => 'Colocated', + 3 => '(reserved)', + }, + }, + 3 => { + Name => 'InitialDelaySamples', + RawConv => '$val & 0x10 ? undef : ($val & 0x0f) + 1', + Unknown => 1, }, ); %Image::ExifTool::QuickTime::ItemRef = ( PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, GROUPS => { 2 => 'Image' }, # (Note: ExifTool's ItemRefVersion may be used to test the iref version number) # dimg - DerivedImage @@ -2316,26 +2762,14 @@ my %eeBox = ( cdsc => { Name => 'ContentDescribes', Notes => 'parsed, but not extracted as a tag', - RawConv => sub { - my ($val, $et) = @_; - my ($id, $count, @to); - if ($$et{ItemRefVersion}) { - return undef if length $val < 10; - ($id, $count, @to) = unpack('NnN*', $val); - } else { - return undef if length $val < 6; - ($id, $count, @to) = unpack('nnn*', $val); - } - # add all referenced item ID's to a "RefersTo" lookup - $$et{ItemInfo}{$id}{RefersTo}{$_} = 1 foreach @to; - $et->VPrint(1, "$$et{INDENT} Item $id describes: @to\n"); - return undef; - }, + RawConv => \&ParseContentDescribes, + WriteHook => \&ParseContentDescribes, }, ); %Image::ExifTool::QuickTime::ItemInfo = ( PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, GROUPS => { 2 => 'Image' }, # avc1 - AVC image # hvc1 - HEVC image @@ -2345,6 +2779,7 @@ my %eeBox = ( infe => { Name => 'ItemInfoEntry', RawConv => \&ParseItemInfoEntry, + WriteHook => \&ParseItemInfoEntry, Notes => 'parsed, but not extracted as a tag', }, ); @@ -2401,20 +2836,37 @@ my %eeBox = ( # -> these atoms are unique, and contain one or more 'data' atoms %Image::ExifTool::QuickTime::ItemList = ( PROCESS_PROC => \&ProcessMOV, - GROUPS => { 2 => 'Audio' }, + WRITE_PROC => \&WriteQuickTime, + CHECK_PROC => \&CheckQTValue, + WRITABLE => 1, + PREFERRED => 2, # (preferred over UserData and Keys tags when writing) + FORMAT => 'string', + GROUPS => { 1 => 'ItemList', 2 => 'Audio' }, + WRITE_GROUP => 'ItemList', + LANG_INFO => \&GetLangInfo, NOTES => q{ - As well as these tags, the "mdta" handler uses numerical tag ID's which are - added dynamically to this table after processing the Meta Keys information. + This is the preferred location for creating new QuickTime tags. Tags in + this table support alternate languages which are accessed by adding a + 3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2 + country code to the tag name (eg. "ItemList:Title-fra" or + "ItemList::Title-fra-FR"). When creating a new Meta box to contain the + ItemList directory, by default ExifTool does not specify a + L<Handler|Image::ExifTool::TagNames/QuickTime Handler Tags>, but the + API L<QuickTimeHandler|../ExifTool.html#QuickTimeHandler> option may be used to include an 'mdir' Handler box. }, # in this table, binary 1 and 2-byte "data"-type tags are interpreted as - # int8u and int16u. Multi-byte binary "data" tags are extracted as binary data + # int8u and int16u. Multi-byte binary "data" tags are extracted as binary data. + # (Note that the Preferred property is set to 0 for some tags to prevent them + # from being created when a same-named tag already exists in the table) "\xa9ART" => 'Artist', "\xa9alb" => 'Album', + "\xa9aut" => { Name => 'Author', Avoid => 1, Groups => { 2 => 'Author' } }, #forum10091 ('auth' is preferred) "\xa9cmt" => 'Comment', - "\xa9com" => 'Composer', + "\xa9com" => { Name => 'Composer', Avoid => 1, }, # ("\xa9wrt" is preferred in ItemList) "\xa9day" => { Name => 'ContentCreateDate', Groups => { 2 => 'Time' }, + Shift => 'Time', # handle values in the form "2010-02-12T13:27:14-0800" ValueConv => q{ require Image::ExifTool::XMP; @@ -2422,7 +2874,14 @@ my %eeBox = ( $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary return $val; }, + ValueConvInv => q{ + require Image::ExifTool::XMP; + $val = Image::ExifTool::XMP::FormatXMPDate($val); + $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon + return $val; + }, PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, "\xa9des" => 'Description', #4 "\xa9enc" => 'EncodedBy', #10 @@ -2442,15 +2901,18 @@ my %eeBox = ( covr => { Name => 'CoverArt', Groups => { 2 => 'Preview' } }, cpil => { #10 Name => 'Compilation', + Format => 'int8u', #23 PrintConv => { 0 => 'No', 1 => 'Yes' }, }, disk => { Name => 'DiskNumber', Format => 'undef', # (necessary to prevent decoding as string!) ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val', + ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef', }, pgap => { #10 Name => 'PlayGap', + Format => 'int8u', #23 PrintConv => { 0 => 'Insert Gap', 1 => 'No Gap', @@ -2464,6 +2926,7 @@ my %eeBox = ( Name => 'TrackNumber', Format => 'undef', # (necessary to prevent decoding as string!) ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val', + ValueConvInv => 'my @a = split / of /, $val; @a==2 ? pack("n3",0,@a) : undef', }, # # Note: it is possible that the tags below are not being decoded properly @@ -2471,12 +2934,13 @@ my %eeBox = ( # akID => { #10 Name => 'AppleStoreAccountType', + Format => 'int8u', #24 PrintConv => { 0 => 'iTunes', 1 => 'AOL', }, }, - albm => 'Album', #(ffmpeg source) + albm => { Name => 'Album', Avoid => 1 }, #(ffmpeg source) apID => 'AppleStoreAccount', atID => { #10 (or TV series) Name => 'AlbumTitleID', @@ -2489,22 +2953,31 @@ my %eeBox = ( Format => 'int32u', }, cprt => { Name => 'Copyright', Groups => { 2 => 'Author' } }, - dscp => 'Description', - desc => 'Description', #7 + dscp => { Name => 'Description', Avoid => 1 }, + desc => { Name => 'Description', Avoid => 1 }, #7 gnre => { #10 Name => 'Genre', + Avoid => 1, + # (Note: not written as int16u if numerical, although it should be) PrintConv => q{ return $val unless $val =~ /^\d+$/; require Image::ExifTool::ID3; Image::ExifTool::ID3::PrintGenre($val - 1); # note the "- 1" }, + PrintConvInv => q{ + require Image::ExifTool::ID3; + my $id = Image::ExifTool::ID3::GetGenreID($val); + return defined $id ? $id : $val; + }, }, egid => 'EpisodeGlobalUniqueID', #7 geID => { #10 Name => 'GenreID', Format => 'int32u', SeparateTable => 1, - PrintConv => { #21 (based on https://affiliate.itunes.apple.com/resources/documentation/genre-mapping/) + # the following lookup is based on http://itunes.apple.com/WebObjects/MZStoreServices.woa/ws/genres + # (see scripts/parse_genre to parse genre JSON file from above) + PrintConv => { #21/PH 2 => 'Music|Blues', 3 => 'Music|Comedy', 4 => "Music|Children's Music", @@ -2550,6 +3023,17 @@ my %eeBox = ( 53 => 'Music|Instrumental', 74 => 'Audiobooks|News', 75 => 'Audiobooks|Programs & Performances', + 500 => 'Fitness Music', + 501 => 'Fitness Music|Pop', + 502 => 'Fitness Music|Dance', + 503 => 'Fitness Music|Hip-Hop', + 504 => 'Fitness Music|Rock', + 505 => 'Fitness Music|Alt/Indie', + 506 => 'Fitness Music|Latino', + 507 => 'Fitness Music|Country', + 508 => 'Fitness Music|World', + 509 => 'Fitness Music|New Age', + 510 => 'Fitness Music|Classical', 1001 => 'Music|Alternative|College Rock', 1002 => 'Music|Alternative|Goth Rock', 1003 => 'Music|Alternative|Grunge', @@ -2665,12 +3149,12 @@ my %eeBox = ( 1116 => 'Music|Latino|Contemporary Latin', 1117 => 'Music|Latino|Pop Latino', 1118 => 'Music|Latino|Raices', # (Ra&iacute;ces) - 1119 => 'Music|Latino|Latin Urban', + 1119 => 'Music|Latino|Urbano latino', 1120 => 'Music|Latino|Baladas y Boleros', 1121 => 'Music|Latino|Rock y Alternativo', 1122 => 'Music|Brazilian', 1123 => 'Music|Latino|Musica Mexicana', # (M&uacute;sica Mexicana) - 1124 => 'Music|Latino|Salsa y Tropical', + 1124 => 'Music|Latino|Musica tropical', # (M&uacute;sica tropical) 1125 => 'Music|New Age|Environmental', 1126 => 'Music|New Age|Healing', 1127 => 'Music|New Age|Meditation', @@ -2721,8 +3205,8 @@ my %eeBox = ( 1174 => 'Music|Vocal|Traditional Pop', 1175 => 'Music|Jazz|Vocal Jazz', 1176 => 'Music|Vocal|Vocal Pop', - 1177 => 'Music|World|Afro-Beat', - 1178 => 'Music|World|Afro-Pop', + 1177 => 'Music|African|Afro-Beat', + 1178 => 'Music|African|Afro-Pop', 1179 => 'Music|World|Cajun', 1180 => 'Music|World|Celtic', 1181 => 'Music|World|Celtic Folk', @@ -2747,7 +3231,7 @@ my %eeBox = ( 1200 => 'Music|World|Australia', 1201 => 'Music|World|Japan', 1202 => 'Music|World|France', - 1203 => 'Music|World|Africa', + 1203 => 'Music|African', 1204 => 'Music|World|Asia', 1205 => 'Music|World|Europe', 1206 => 'Music|World|South Africa', @@ -2800,24 +3284,24 @@ my %eeBox = ( 1261 => 'Music|Vocal|Trot', 1262 => 'Music|Indian', 1263 => 'Music|Indian|Bollywood', - 1264 => 'Music|Indian|Tamil', - 1265 => 'Music|Indian|Telugu', + 1264 => 'Music|Indian|Regional Indian|Tamil', + 1265 => 'Music|Indian|Regional Indian|Telugu', 1266 => 'Music|Indian|Regional Indian', 1267 => 'Music|Indian|Devotional & Spiritual', 1268 => 'Music|Indian|Sufi', 1269 => 'Music|Indian|Indian Classical', - 1270 => 'Music|World|Russian Chanson', + 1270 => 'Music|Russian|Russian Chanson', 1271 => 'Music|World|Dini', - 1272 => 'Music|World|Halk', - 1273 => 'Music|World|Sanat', + 1272 => 'Music|Turkish|Halk', + 1273 => 'Music|Turkish|Sanat', 1274 => 'Music|World|Dangdut', 1275 => 'Music|World|Indonesian Religious', 1276 => 'Music|World|Calypso', 1277 => 'Music|World|Soca', 1278 => 'Music|Indian|Ghazals', 1279 => 'Music|Indian|Indian Folk', - 1280 => 'Music|World|Arabesque', - 1281 => 'Music|World|Afrikaans', + 1280 => 'Music|Turkish|Arabesque', + 1281 => 'Music|African|Afrikaans', 1282 => 'Music|World|Farsi', 1283 => 'Music|World|Israeli', 1284 => 'Music|Arabic|Khaleeji', @@ -2834,8 +3318,8 @@ my %eeBox = ( 1296 => 'Music|World|Tango', 1297 => 'Music|World|Fado', 1298 => 'Music|World|Iberia', - 1299 => 'Music|World|Russian', - 1300 => 'Music|World|Turkish', + 1299 => 'Music|Russian', + 1300 => 'Music|Turkish', 1301 => 'Podcasts|Arts', 1302 => 'Podcasts|Society & Culture|Personal Journals', 1303 => 'Podcasts|Comedy', @@ -2904,6 +3388,90 @@ my %eeBox = ( 1479 => 'Podcasts|Science & Medicine|Social Sciences', 1480 => 'Podcasts|Technology|Software How-To', 1481 => 'Podcasts|Health|Alternative Health', + 1482 => 'Podcasts|Arts|Books', + 1483 => 'Podcasts|Fiction', + 1484 => 'Podcasts|Fiction|Drama', + 1485 => 'Podcasts|Fiction|Science Fiction', + 1486 => 'Podcasts|Fiction|Comedy Fiction', + 1487 => 'Podcasts|History', + 1488 => 'Podcasts|True Crime', + 1489 => 'Podcasts|News', + 1490 => 'Podcasts|News|Business News', + 1491 => 'Podcasts|Business|Management', + 1492 => 'Podcasts|Business|Marketing', + 1493 => 'Podcasts|Business|Entrepreneurship', + 1494 => 'Podcasts|Business|Non-Profit', + 1495 => 'Podcasts|Comedy|Improv', + 1496 => 'Podcasts|Comedy|Comedy Interviews', + 1497 => 'Podcasts|Comedy|Stand-Up', + 1498 => 'Podcasts|Education|Language Learning', + 1499 => 'Podcasts|Education|How To', + 1500 => 'Podcasts|Education|Self-Improvement', + 1501 => 'Podcasts|Education|Courses', + 1502 => 'Podcasts|Leisure', + 1503 => 'Podcasts|Leisure|Automotive', + 1504 => 'Podcasts|Leisure|Aviation', + 1505 => 'Podcasts|Leisure|Hobbies', + 1506 => 'Podcasts|Leisure|Crafts', + 1507 => 'Podcasts|Leisure|Games', + 1508 => 'Podcasts|Leisure|Home & Garden', + 1509 => 'Podcasts|Leisure|Video Games', + 1510 => 'Podcasts|Leisure|Animation & Manga', + 1511 => 'Podcasts|Government', + 1512 => 'Podcasts|Health & Fitness', + 1513 => 'Podcasts|Health & Fitness|Alternative Health', + 1514 => 'Podcasts|Health & Fitness|Fitness', + 1515 => 'Podcasts|Health & Fitness|Nutrition', + 1516 => 'Podcasts|Health & Fitness|Sexuality', + 1517 => 'Podcasts|Health & Fitness|Mental Health', + 1518 => 'Podcasts|Health & Fitness|Medicine', + 1519 => 'Podcasts|Kids & Family|Education for Kids', + 1520 => 'Podcasts|Kids & Family|Stories for Kids', + 1521 => 'Podcasts|Kids & Family|Parenting', + 1522 => 'Podcasts|Kids & Family|Pets & Animals', + 1523 => 'Podcasts|Music|Music Commentary', + 1524 => 'Podcasts|Music|Music History', + 1525 => 'Podcasts|Music|Music Interviews', + 1526 => 'Podcasts|News|Daily News', + 1527 => 'Podcasts|News|Politics', + 1528 => 'Podcasts|News|Tech News', + 1529 => 'Podcasts|News|Sports News', + 1530 => 'Podcasts|News|News Commentary', + 1531 => 'Podcasts|News|Entertainment News', + 1532 => 'Podcasts|Religion & Spirituality|Religion', + 1533 => 'Podcasts|Science', + 1534 => 'Podcasts|Science|Natural Sciences', + 1535 => 'Podcasts|Science|Social Sciences', + 1536 => 'Podcasts|Science|Mathematics', + 1537 => 'Podcasts|Science|Nature', + 1538 => 'Podcasts|Science|Astronomy', + 1539 => 'Podcasts|Science|Chemistry', + 1540 => 'Podcasts|Science|Earth Sciences', + 1541 => 'Podcasts|Science|Life Sciences', + 1542 => 'Podcasts|Science|Physics', + 1543 => 'Podcasts|Society & Culture|Documentary', + 1544 => 'Podcasts|Society & Culture|Relationships', + 1545 => 'Podcasts|Sports', + 1546 => 'Podcasts|Sports|Soccer', + 1547 => 'Podcasts|Sports|Football', + 1548 => 'Podcasts|Sports|Basketball', + 1549 => 'Podcasts|Sports|Baseball', + 1550 => 'Podcasts|Sports|Hockey', + 1551 => 'Podcasts|Sports|Running', + 1552 => 'Podcasts|Sports|Rugby', + 1553 => 'Podcasts|Sports|Golf', + 1554 => 'Podcasts|Sports|Cricket', + 1555 => 'Podcasts|Sports|Wrestling', + 1556 => 'Podcasts|Sports|Tennis', + 1557 => 'Podcasts|Sports|Volleyball', + 1558 => 'Podcasts|Sports|Swimming', + 1559 => 'Podcasts|Sports|Wilderness', + 1560 => 'Podcasts|Sports|Fantasy Sports', + 1561 => 'Podcasts|TV & Film|TV Reviews', + 1562 => 'Podcasts|TV & Film|After Shows', + 1563 => 'Podcasts|TV & Film|Film Reviews', + 1564 => 'Podcasts|TV & Film|Film History', + 1565 => 'Podcasts|TV & Film|Film Interviews', 1602 => 'Music Videos|Blues', 1603 => 'Music Videos|Comedy', 1604 => "Music Videos|Children's Music", @@ -2990,16 +3558,16 @@ my %eeBox = ( 1689 => 'Music Videos|Spoken Word', 1690 => 'Music Videos|Indian', 1691 => 'Music Videos|Indian|Bollywood', - 1692 => 'Music Videos|Indian|Tamil', - 1693 => 'Music Videos|Indian|Telugu', + 1692 => 'Music Videos|Indian|Regional Indian|Tamil', + 1693 => 'Music Videos|Indian|Regional Indian|Telugu', 1694 => 'Music Videos|Indian|Regional Indian', 1695 => 'Music Videos|Indian|Devotional & Spiritual', 1696 => 'Music Videos|Indian|Sufi', 1697 => 'Music Videos|Indian|Indian Classical', - 1698 => 'Music Videos|World|Russian Chanson', + 1698 => 'Music Videos|Russian|Russian Chanson', 1699 => 'Music Videos|World|Dini', - 1700 => 'Music Videos|World|Halk', - 1701 => 'Music Videos|World|Sanat', + 1700 => 'Music Videos|Turkish|Halk', + 1701 => 'Music Videos|Turkish|Sanat', 1702 => 'Music Videos|World|Dangdut', 1703 => 'Music Videos|World|Indonesian Religious', 1704 => 'Music Videos|Indian|Indian Pop', @@ -3007,8 +3575,8 @@ my %eeBox = ( 1706 => 'Music Videos|World|Soca', 1707 => 'Music Videos|Indian|Ghazals', 1708 => 'Music Videos|Indian|Indian Folk', - 1709 => 'Music Videos|World|Arabesque', - 1710 => 'Music Videos|World|Afrikaans', + 1709 => 'Music Videos|Turkish|Arabesque', + 1710 => 'Music Videos|African|Afrikaans', 1711 => 'Music Videos|World|Farsi', 1712 => 'Music Videos|World|Israeli', 1713 => 'Music Videos|Arabic', @@ -3026,8 +3594,8 @@ my %eeBox = ( 1726 => 'Music Videos|World|Tango', 1727 => 'Music Videos|World|Fado', 1728 => 'Music Videos|World|Iberia', - 1729 => 'Music Videos|World|Russian', - 1730 => 'Music Videos|World|Turkish', + 1729 => 'Music Videos|Russian', + 1730 => 'Music Videos|Turkish', 1731 => 'Music Videos|Alternative|College Rock', 1732 => 'Music Videos|Alternative|Goth Rock', 1733 => 'Music Videos|Alternative|Grunge', @@ -3200,9 +3768,9 @@ my %eeBox = ( 1901 => 'Music Videos|Vocal|Traditional Pop', 1902 => 'Music Videos|Jazz|Vocal Jazz', 1903 => 'Music Videos|Vocal|Vocal Pop', - 1904 => 'Music Videos|World|Africa', - 1905 => 'Music Videos|World|Afro-Beat', - 1906 => 'Music Videos|World|Afro-Pop', + 1904 => 'Music Videos|African', + 1905 => 'Music Videos|African|Afro-Beat', + 1906 => 'Music Videos|African|Afro-Pop', 1907 => 'Music Videos|World|Asia', 1908 => 'Music Videos|World|Australia', 1909 => 'Music Videos|World|Cajun', @@ -3245,12 +3813,94 @@ my %eeBox = ( 1948 => 'Music Videos|New Age|Yoga', 1949 => 'Music Videos|Pop|Tribute', 1950 => 'Music Videos|Pop|Shows', + 1951 => 'Music Videos|Cuban', + 1952 => 'Music Videos|Cuban|Mambo', + 1953 => 'Music Videos|Cuban|Chachacha', + 1954 => 'Music Videos|Cuban|Guajira', + 1955 => 'Music Videos|Cuban|Son', + 1956 => 'Music Videos|Cuban|Bolero', + 1957 => 'Music Videos|Cuban|Guaracha', + 1958 => 'Music Videos|Cuban|Timba', + 1959 => 'Music Videos|Soundtrack|Video Game', + 1960 => 'Music Videos|Indian|Regional Indian|Punjabi|Punjabi Pop', + 1961 => 'Music Videos|Indian|Regional Indian|Bengali|Rabindra Sangeet', + 1962 => 'Music Videos|Indian|Regional Indian|Malayalam', + 1963 => 'Music Videos|Indian|Regional Indian|Kannada', + 1964 => 'Music Videos|Indian|Regional Indian|Marathi', + 1965 => 'Music Videos|Indian|Regional Indian|Gujarati', + 1966 => 'Music Videos|Indian|Regional Indian|Assamese', + 1967 => 'Music Videos|Indian|Regional Indian|Bhojpuri', + 1968 => 'Music Videos|Indian|Regional Indian|Haryanvi', + 1969 => 'Music Videos|Indian|Regional Indian|Odia', + 1970 => 'Music Videos|Indian|Regional Indian|Rajasthani', + 1971 => 'Music Videos|Indian|Regional Indian|Urdu', + 1972 => 'Music Videos|Indian|Regional Indian|Punjabi', + 1973 => 'Music Videos|Indian|Regional Indian|Bengali', + 1974 => 'Music Videos|Indian|Indian Classical|Carnatic Classical', + 1975 => 'Music Videos|Indian|Indian Classical|Hindustani Classical', + 1976 => 'Music Videos|African|Afro House', + 1977 => 'Music Videos|African|Afro Soul', + 1978 => 'Music Videos|African|Afrobeats', + 1979 => 'Music Videos|African|Benga', + 1980 => 'Music Videos|African|Bongo-Flava', + 1981 => 'Music Videos|African|Coupe-Decale', + 1982 => 'Music Videos|African|Gqom', + 1983 => 'Music Videos|African|Highlife', + 1984 => 'Music Videos|African|Kuduro', + 1985 => 'Music Videos|African|Kizomba', + 1986 => 'Music Videos|African|Kwaito', + 1987 => 'Music Videos|African|Mbalax', + 1988 => 'Music Videos|African|Ndombolo', + 1989 => 'Music Videos|African|Shangaan Electro', + 1990 => 'Music Videos|African|Soukous', + 1991 => 'Music Videos|African|Taarab', + 1992 => 'Music Videos|African|Zouglou', + 1993 => 'Music Videos|Turkish|Ozgun', + 1994 => 'Music Videos|Turkish|Fantezi', + 1995 => 'Music Videos|Turkish|Religious', + 1996 => 'Music Videos|Pop|Turkish Pop', + 1997 => 'Music Videos|Rock|Turkish Rock', + 1998 => 'Music Videos|Alternative|Turkish Alternative', + 1999 => 'Music Videos|Hip-Hop/Rap|Turkish Hip-Hop/Rap', + 2000 => 'Music Videos|African|Maskandi', + 2001 => 'Music Videos|Russian|Russian Romance', + 2002 => 'Music Videos|Russian|Russian Bard', + 2003 => 'Music Videos|Russian|Russian Pop', + 2004 => 'Music Videos|Russian|Russian Rock', + 2005 => 'Music Videos|Russian|Russian Hip-Hop', + 2006 => 'Music Videos|Arabic|Levant', + 2007 => 'Music Videos|Arabic|Levant|Dabke', + 2008 => 'Music Videos|Arabic|Maghreb Rai', + 2009 => 'Music Videos|Arabic|Khaleeji|Khaleeji Jalsat', + 2010 => 'Music Videos|Arabic|Khaleeji|Khaleeji Shailat', + 2011 => 'Music Videos|Tarab', + 2012 => 'Music Videos|Tarab|Iraqi Tarab', + 2013 => 'Music Videos|Tarab|Egyptian Tarab', + 2014 => 'Music Videos|Tarab|Khaleeji Tarab', + 2015 => 'Music Videos|Pop|Levant Pop', + 2016 => 'Music Videos|Pop|Iraqi Pop', + 2017 => 'Music Videos|Pop|Egyptian Pop', + 2018 => 'Music Videos|Pop|Maghreb Pop', + 2019 => 'Music Videos|Pop|Khaleeji Pop', + 2020 => 'Music Videos|Hip-Hop/Rap|Levant Hip-Hop', + 2021 => 'Music Videos|Hip-Hop/Rap|Egyptian Hip-Hop', + 2022 => 'Music Videos|Hip-Hop/Rap|Maghreb Hip-Hop', + 2023 => 'Music Videos|Hip-Hop/Rap|Khaleeji Hip-Hop', + 2024 => 'Music Videos|Alternative|Indie Levant', + 2025 => 'Music Videos|Alternative|Indie Egyptian', + 2026 => 'Music Videos|Alternative|Indie Maghreb', + 2027 => 'Music Videos|Electronic|Levant Electronic', + 2028 => "Music Videos|Electronic|Electro-Cha'abi", + 2029 => 'Music Videos|Electronic|Maghreb Electronic', + 2030 => 'Music Videos|Folk|Iraqi Folk', + 2031 => 'Music Videos|Folk|Khaleeji Folk', + 2032 => 'Music Videos|Dance|Maghreb Dance', 4000 => 'TV Shows|Comedy', 4001 => 'TV Shows|Drama', 4002 => 'TV Shows|Animation', 4003 => 'TV Shows|Action & Adventure', - 4004 => 'TV Shows|Classic', - 4005 => 'TV Shows|Kids', + 4004 => 'TV Shows|Classics', + 4005 => 'TV Shows|Kids & Family', 4006 => 'TV Shows|Nonfiction', 4007 => 'TV Shows|Reality TV', 4008 => 'TV Shows|Sci-Fi & Fantasy', @@ -3316,9 +3966,11 @@ my %eeBox = ( 6023 => 'App Store|Food & Drink', 6024 => 'App Store|Shopping', 6025 => 'App Store|Stickers', + 6026 => 'App Store|Developer Tools', + 6027 => 'App Store|Graphics & Design', 7001 => 'App Store|Games|Action', 7002 => 'App Store|Games|Adventure', - 7003 => 'App Store|Games|Arcade', + 7003 => 'App Store|Games|Casual', 7004 => 'App Store|Games|Board', 7005 => 'App Store|Games|Card', 7006 => 'App Store|Games|Casino', @@ -3510,8 +4162,8 @@ my %eeBox = ( 8193 => 'Tones|Ringtones|Indian|Indian Pop', 8194 => 'Tones|Ringtones|Indian|Regional Indian', 8195 => 'Tones|Ringtones|Indian|Sufi', - 8196 => 'Tones|Ringtones|Indian|Tamil', - 8197 => 'Tones|Ringtones|Indian|Telugu', + 8196 => 'Tones|Ringtones|Indian|Regional Indian|Tamil', + 8197 => 'Tones|Ringtones|Indian|Regional Indian|Telugu', 8198 => 'Tones|Ringtones|Instrumental', 8199 => 'Tones|Ringtones|Jazz|Avant-Garde Jazz', 8201 => 'Tones|Ringtones|Jazz|Big Band', @@ -3617,11 +4269,11 @@ my %eeBox = ( 8301 => 'Tones|Ringtones|Vocal|Trot', 8302 => 'Tones|Ringtones|Jazz|Vocal Jazz', 8303 => 'Tones|Ringtones|Vocal|Vocal Pop', - 8304 => 'Tones|Ringtones|World|Africa', - 8305 => 'Tones|Ringtones|World|Afrikaans', - 8306 => 'Tones|Ringtones|World|Afro-Beat', - 8307 => 'Tones|Ringtones|World|Afro-Pop', - 8308 => 'Tones|Ringtones|World|Arabesque', + 8304 => 'Tones|Ringtones|African', + 8305 => 'Tones|Ringtones|African|Afrikaans', + 8306 => 'Tones|Ringtones|African|Afro-Beat', + 8307 => 'Tones|Ringtones|African|Afro-Pop', + 8308 => 'Tones|Ringtones|Turkish|Arabesque', 8309 => 'Tones|Ringtones|World|Asia', 8310 => 'Tones|Ringtones|World|Australia', 8311 => 'Tones|Ringtones|World|Cajun', @@ -3637,7 +4289,7 @@ my %eeBox = ( 8321 => 'Tones|Ringtones|World|Farsi', 8322 => 'Tones|Ringtones|World|Flamenco', 8323 => 'Tones|Ringtones|World|France', - 8324 => 'Tones|Ringtones|World|Halk', + 8324 => 'Tones|Ringtones|Turkish|Halk', 8325 => 'Tones|Ringtones|World|Hawaii', 8326 => 'Tones|Ringtones|World|Iberia', 8327 => 'Tones|Ringtones|World|Indonesian Religious', @@ -3646,15 +4298,15 @@ my %eeBox = ( 8330 => 'Tones|Ringtones|World|Klezmer', 8331 => 'Tones|Ringtones|World|North America', 8332 => 'Tones|Ringtones|World|Polka', - 8333 => 'Tones|Ringtones|World|Russian', - 8334 => 'Tones|Ringtones|World|Russian Chanson', - 8335 => 'Tones|Ringtones|World|Sanat', + 8333 => 'Tones|Ringtones|Russian', + 8334 => 'Tones|Ringtones|Russian|Russian Chanson', + 8335 => 'Tones|Ringtones|Turkish|Sanat', 8336 => 'Tones|Ringtones|World|Soca', 8337 => 'Tones|Ringtones|World|South Africa', 8338 => 'Tones|Ringtones|World|South America', 8339 => 'Tones|Ringtones|World|Tango', 8340 => 'Tones|Ringtones|World|Traditional Celtic', - 8341 => 'Tones|Ringtones|World|Turkish', + 8341 => 'Tones|Ringtones|Turkish', 8342 => 'Tones|Ringtones|World|Worldbeat', 8343 => 'Tones|Ringtones|World|Zydeco', 8345 => 'Tones|Ringtones|Classical|Art Song', @@ -3680,6 +4332,88 @@ my %eeBox = ( 8365 => 'Tones|Ringtones|New Age|Yoga', 8366 => 'Tones|Ringtones|Pop|Tribute', 8367 => 'Tones|Ringtones|Pop|Shows', + 8368 => 'Tones|Ringtones|Cuban', + 8369 => 'Tones|Ringtones|Cuban|Mambo', + 8370 => 'Tones|Ringtones|Cuban|Chachacha', + 8371 => 'Tones|Ringtones|Cuban|Guajira', + 8372 => 'Tones|Ringtones|Cuban|Son', + 8373 => 'Tones|Ringtones|Cuban|Bolero', + 8374 => 'Tones|Ringtones|Cuban|Guaracha', + 8375 => 'Tones|Ringtones|Cuban|Timba', + 8376 => 'Tones|Ringtones|Soundtrack|Video Game', + 8377 => 'Tones|Ringtones|Indian|Regional Indian|Punjabi|Punjabi Pop', + 8378 => 'Tones|Ringtones|Indian|Regional Indian|Bengali|Rabindra Sangeet', + 8379 => 'Tones|Ringtones|Indian|Regional Indian|Malayalam', + 8380 => 'Tones|Ringtones|Indian|Regional Indian|Kannada', + 8381 => 'Tones|Ringtones|Indian|Regional Indian|Marathi', + 8382 => 'Tones|Ringtones|Indian|Regional Indian|Gujarati', + 8383 => 'Tones|Ringtones|Indian|Regional Indian|Assamese', + 8384 => 'Tones|Ringtones|Indian|Regional Indian|Bhojpuri', + 8385 => 'Tones|Ringtones|Indian|Regional Indian|Haryanvi', + 8386 => 'Tones|Ringtones|Indian|Regional Indian|Odia', + 8387 => 'Tones|Ringtones|Indian|Regional Indian|Rajasthani', + 8388 => 'Tones|Ringtones|Indian|Regional Indian|Urdu', + 8389 => 'Tones|Ringtones|Indian|Regional Indian|Punjabi', + 8390 => 'Tones|Ringtones|Indian|Regional Indian|Bengali', + 8391 => 'Tones|Ringtones|Indian|Indian Classical|Carnatic Classical', + 8392 => 'Tones|Ringtones|Indian|Indian Classical|Hindustani Classical', + 8393 => 'Tones|Ringtones|African|Afro House', + 8394 => 'Tones|Ringtones|African|Afro Soul', + 8395 => 'Tones|Ringtones|African|Afrobeats', + 8396 => 'Tones|Ringtones|African|Benga', + 8397 => 'Tones|Ringtones|African|Bongo-Flava', + 8398 => 'Tones|Ringtones|African|Coupe-Decale', + 8399 => 'Tones|Ringtones|African|Gqom', + 8400 => 'Tones|Ringtones|African|Highlife', + 8401 => 'Tones|Ringtones|African|Kuduro', + 8402 => 'Tones|Ringtones|African|Kizomba', + 8403 => 'Tones|Ringtones|African|Kwaito', + 8404 => 'Tones|Ringtones|African|Mbalax', + 8405 => 'Tones|Ringtones|African|Ndombolo', + 8406 => 'Tones|Ringtones|African|Shangaan Electro', + 8407 => 'Tones|Ringtones|African|Soukous', + 8408 => 'Tones|Ringtones|African|Taarab', + 8409 => 'Tones|Ringtones|African|Zouglou', + 8410 => 'Tones|Ringtones|Turkish|Ozgun', + 8411 => 'Tones|Ringtones|Turkish|Fantezi', + 8412 => 'Tones|Ringtones|Turkish|Religious', + 8413 => 'Tones|Ringtones|Pop|Turkish Pop', + 8414 => 'Tones|Ringtones|Rock|Turkish Rock', + 8415 => 'Tones|Ringtones|Alternative|Turkish Alternative', + 8416 => 'Tones|Ringtones|Hip-Hop/Rap|Turkish Hip-Hop/Rap', + 8417 => 'Tones|Ringtones|African|Maskandi', + 8418 => 'Tones|Ringtones|Russian|Russian Romance', + 8419 => 'Tones|Ringtones|Russian|Russian Bard', + 8420 => 'Tones|Ringtones|Russian|Russian Pop', + 8421 => 'Tones|Ringtones|Russian|Russian Rock', + 8422 => 'Tones|Ringtones|Russian|Russian Hip-Hop', + 8423 => 'Tones|Ringtones|Arabic|Levant', + 8424 => 'Tones|Ringtones|Arabic|Levant|Dabke', + 8425 => 'Tones|Ringtones|Arabic|Maghreb Rai', + 8426 => 'Tones|Ringtones|Arabic|Khaleeji|Khaleeji Jalsat', + 8427 => 'Tones|Ringtones|Arabic|Khaleeji|Khaleeji Shailat', + 8428 => 'Tones|Ringtones|Tarab', + 8429 => 'Tones|Ringtones|Tarab|Iraqi Tarab', + 8430 => 'Tones|Ringtones|Tarab|Egyptian Tarab', + 8431 => 'Tones|Ringtones|Tarab|Khaleeji Tarab', + 8432 => 'Tones|Ringtones|Pop|Levant Pop', + 8433 => 'Tones|Ringtones|Pop|Iraqi Pop', + 8434 => 'Tones|Ringtones|Pop|Egyptian Pop', + 8435 => 'Tones|Ringtones|Pop|Maghreb Pop', + 8436 => 'Tones|Ringtones|Pop|Khaleeji Pop', + 8437 => 'Tones|Ringtones|Hip-Hop/Rap|Levant Hip-Hop', + 8438 => 'Tones|Ringtones|Hip-Hop/Rap|Egyptian Hip-Hop', + 8439 => 'Tones|Ringtones|Hip-Hop/Rap|Maghreb Hip-Hop', + 8440 => 'Tones|Ringtones|Hip-Hop/Rap|Khaleeji Hip-Hop', + 8441 => 'Tones|Ringtones|Alternative|Indie Levant', + 8442 => 'Tones|Ringtones|Alternative|Indie Egyptian', + 8443 => 'Tones|Ringtones|Alternative|Indie Maghreb', + 8444 => 'Tones|Ringtones|Electronic|Levant Electronic', + 8445 => "Tones|Ringtones|Electronic|Electro-Cha'abi", + 8446 => 'Tones|Ringtones|Electronic|Maghreb Electronic', + 8447 => 'Tones|Ringtones|Folk|Iraqi Folk', + 8448 => 'Tones|Ringtones|Folk|Khaleeji Folk', + 8449 => 'Tones|Ringtones|Dance|Maghreb Dance', 9002 => 'Books|Nonfiction', 9003 => 'Books|Romance', 9004 => 'Books|Travel & Adventure', @@ -3693,7 +4427,7 @@ my %eeBox = ( 9019 => 'Books|Science & Nature', 9020 => 'Books|Sci-Fi & Fantasy', 9024 => 'Books|Lifestyle & Home', - 9025 => 'Books|Health, Mind & Body', + 9025 => 'Books|Self-Development', 9026 => 'Books|Comics & Graphic Novels', 9027 => 'Books|Computers & Internet', 9028 => 'Books|Cookbooks, Food & Wine', @@ -3707,7 +4441,7 @@ my %eeBox = ( 10001 => 'Books|Lifestyle & Home|Antiques & Collectibles', 10002 => 'Books|Arts & Entertainment|Art & Architecture', 10003 => 'Books|Religion & Spirituality|Bibles', - 10004 => 'Books|Health, Mind & Body|Spirituality', + 10004 => 'Books|Self-Development|Spirituality', 10005 => 'Books|Business & Personal Finance|Industries & Professions', 10006 => 'Books|Business & Personal Finance|Marketing & Sales', 10007 => 'Books|Business & Personal Finance|Small Business & Entrepreneurship', @@ -3772,7 +4506,7 @@ my %eeBox = ( 10066 => 'Books|Reference|Foreign Languages', 10067 => 'Books|Arts & Entertainment|Games', 10068 => 'Books|Lifestyle & Home|Gardening', - 10069 => 'Books|Health, Mind & Body|Health & Fitness', + 10069 => 'Books|Self-Development|Health & Fitness', 10070 => 'Books|History|Africa', 10071 => 'Books|History|Americas', 10072 => 'Books|History|Ancient', @@ -3797,7 +4531,7 @@ my %eeBox = ( 10091 => 'Books|Nonfiction|Philosophy', 10092 => 'Books|Arts & Entertainment|Photography', 10093 => 'Books|Fiction & Literature|Poetry', - 10094 => 'Books|Health, Mind & Body|Psychology', + 10094 => 'Books|Self-Development|Psychology', 10095 => 'Books|Reference|Almanacs & Yearbooks', 10096 => 'Books|Reference|Atlases & Maps', 10097 => 'Books|Reference|Catalogs & Directories', @@ -3822,7 +4556,7 @@ my %eeBox = ( 10116 => 'Books|Science & Nature|Life Sciences', 10117 => 'Books|Science & Nature|Physics', 10118 => 'Books|Science & Nature|Reference', - 10119 => 'Books|Health, Mind & Body|Self-Improvement', + 10119 => 'Books|Self-Development|Self-Improvement', 10120 => 'Books|Nonfiction|Social Science', 10121 => 'Books|Sports & Outdoors|Baseball', 10122 => 'Books|Sports & Outdoors|Basketball', @@ -3912,7 +4646,7 @@ my %eeBox = ( 11059 => 'Books|Sports & Outdoors|Motor Sports', 11060 => 'Books|Sports & Outdoors|Rugby', 11061 => 'Books|Sports & Outdoors|Running', - 11062 => 'Books|Health, Mind & Body|Diet & Nutrition', + 11062 => 'Books|Self-Development|Diet & Nutrition', 11063 => 'Books|Science & Nature|Agriculture', 11064 => 'Books|Science & Nature|Atmosphere', 11065 => 'Books|Science & Nature|Biology', @@ -4156,6 +4890,8 @@ my %eeBox = ( 11339 => 'Books|Comics & Graphic Novels|Manga|Girls', 11340 => 'Books|Comics & Graphic Novels|Manga|Women', 11341 => 'Books|Comics & Graphic Novels|Manga|Other', + 11342 => 'Books|Comics & Graphic Novels|Manga|Yaoi', + 11343 => 'Books|Comics & Graphic Novels|Manga|Comic Essays', 12001 => 'Mac App Store|Business', 12002 => 'Mac App Store|Developer Tools', 12003 => 'Mac App Store|Education', @@ -4179,7 +4915,7 @@ my %eeBox = ( 12022 => 'Mac App Store|Graphics & Design', 12201 => 'Mac App Store|Games|Action', 12202 => 'Mac App Store|Games|Adventure', - 12203 => 'Mac App Store|Games|Arcade', + 12203 => 'Mac App Store|Games|Casual', 12204 => 'Mac App Store|Games|Board', 12205 => 'Mac App Store|Games|Card', 12206 => 'Mac App Store|Games|Casino', @@ -4576,15 +5312,97 @@ my %eeBox = ( 100021 => 'Music|New Age|Yoga', 100022 => 'Music|Pop|Tribute', 100023 => 'Music|Pop|Shows', + 100024 => 'Music|Cuban', + 100025 => 'Music|Cuban|Mambo', + 100026 => 'Music|Cuban|Chachacha', + 100027 => 'Music|Cuban|Guajira', + 100028 => 'Music|Cuban|Son', + 100029 => 'Music|Cuban|Bolero', + 100030 => 'Music|Cuban|Guaracha', + 100031 => 'Music|Cuban|Timba', + 100032 => 'Music|Soundtrack|Video Game', + 100033 => 'Music|Indian|Regional Indian|Punjabi|Punjabi Pop', + 100034 => 'Music|Indian|Regional Indian|Bengali|Rabindra Sangeet', + 100035 => 'Music|Indian|Regional Indian|Malayalam', + 100036 => 'Music|Indian|Regional Indian|Kannada', + 100037 => 'Music|Indian|Regional Indian|Marathi', + 100038 => 'Music|Indian|Regional Indian|Gujarati', + 100039 => 'Music|Indian|Regional Indian|Assamese', + 100040 => 'Music|Indian|Regional Indian|Bhojpuri', + 100041 => 'Music|Indian|Regional Indian|Haryanvi', + 100042 => 'Music|Indian|Regional Indian|Odia', + 100043 => 'Music|Indian|Regional Indian|Rajasthani', + 100044 => 'Music|Indian|Regional Indian|Urdu', + 100045 => 'Music|Indian|Regional Indian|Punjabi', + 100046 => 'Music|Indian|Regional Indian|Bengali', + 100047 => 'Music|Indian|Indian Classical|Carnatic Classical', + 100048 => 'Music|Indian|Indian Classical|Hindustani Classical', + 100049 => 'Music|African|Afro House', + 100050 => 'Music|African|Afro Soul', + 100051 => 'Music|African|Afrobeats', + 100052 => 'Music|African|Benga', + 100053 => 'Music|African|Bongo-Flava', + 100054 => 'Music|African|Coupe-Decale', + 100055 => 'Music|African|Gqom', + 100056 => 'Music|African|Highlife', + 100057 => 'Music|African|Kuduro', + 100058 => 'Music|African|Kizomba', + 100059 => 'Music|African|Kwaito', + 100060 => 'Music|African|Mbalax', + 100061 => 'Music|African|Ndombolo', + 100062 => 'Music|African|Shangaan Electro', + 100063 => 'Music|African|Soukous', + 100064 => 'Music|African|Taarab', + 100065 => 'Music|African|Zouglou', + 100066 => 'Music|Turkish|Ozgun', + 100067 => 'Music|Turkish|Fantezi', + 100068 => 'Music|Turkish|Religious', + 100069 => 'Music|Pop|Turkish Pop', + 100070 => 'Music|Rock|Turkish Rock', + 100071 => 'Music|Alternative|Turkish Alternative', + 100072 => 'Music|Hip-Hop/Rap|Turkish Hip-Hop/Rap', + 100073 => 'Music|African|Maskandi', + 100074 => 'Music|Russian|Russian Romance', + 100075 => 'Music|Russian|Russian Bard', + 100076 => 'Music|Russian|Russian Pop', + 100077 => 'Music|Russian|Russian Rock', + 100078 => 'Music|Russian|Russian Hip-Hop', + 100079 => 'Music|Arabic|Levant', + 100080 => 'Music|Arabic|Levant|Dabke', + 100081 => 'Music|Arabic|Maghreb Rai', + 100082 => 'Music|Arabic|Khaleeji|Khaleeji Jalsat', + 100083 => 'Music|Arabic|Khaleeji|Khaleeji Shailat', + 100084 => 'Music|Tarab', + 100085 => 'Music|Tarab|Iraqi Tarab', + 100086 => 'Music|Tarab|Egyptian Tarab', + 100087 => 'Music|Tarab|Khaleeji Tarab', + 100088 => 'Music|Pop|Levant Pop', + 100089 => 'Music|Pop|Iraqi Pop', + 100090 => 'Music|Pop|Egyptian Pop', + 100091 => 'Music|Pop|Maghreb Pop', + 100092 => 'Music|Pop|Khaleeji Pop', + 100093 => 'Music|Hip-Hop/Rap|Levant Hip-Hop', + 100094 => 'Music|Hip-Hop/Rap|Egyptian Hip-Hop', + 100095 => 'Music|Hip-Hop/Rap|Maghreb Hip-Hop', + 100096 => 'Music|Hip-Hop/Rap|Khaleeji Hip-Hop', + 100097 => 'Music|Alternative|Indie Levant', + 100098 => 'Music|Alternative|Indie Egyptian', + 100099 => 'Music|Alternative|Indie Maghreb', + 100100 => 'Music|Electronic|Levant Electronic', + 100101 => "Music|Electronic|Electro-Cha'abi", + 100102 => 'Music|Electronic|Maghreb Electronic', + 100103 => 'Music|Folk|Iraqi Folk', + 100104 => 'Music|Folk|Khaleeji Folk', + 100105 => 'Music|Dance|Maghreb Dance', 40000000 => 'iTunes U', - 40000001 => 'iTunes U|Business', - 40000002 => 'iTunes U|Business|Economics', - 40000003 => 'iTunes U|Business|Finance', - 40000004 => 'iTunes U|Business|Hospitality', - 40000005 => 'iTunes U|Business|Management', - 40000006 => 'iTunes U|Business|Marketing', - 40000007 => 'iTunes U|Business|Personal Finance', - 40000008 => 'iTunes U|Business|Real Estate', + 40000001 => 'iTunes U|Business & Economics', + 40000002 => 'iTunes U|Business & Economics|Economics', + 40000003 => 'iTunes U|Business & Economics|Finance', + 40000004 => 'iTunes U|Business & Economics|Hospitality', + 40000005 => 'iTunes U|Business & Economics|Management', + 40000006 => 'iTunes U|Business & Economics|Marketing', + 40000007 => 'iTunes U|Business & Economics|Personal Finance', + 40000008 => 'iTunes U|Business & Economics|Real Estate', 40000009 => 'iTunes U|Engineering', 40000010 => 'iTunes U|Engineering|Chemical & Petroleum Engineering', 40000011 => 'iTunes U|Engineering|Civil Engineering', @@ -4592,15 +5410,15 @@ my %eeBox = ( 40000013 => 'iTunes U|Engineering|Electrical Engineering', 40000014 => 'iTunes U|Engineering|Environmental Engineering', 40000015 => 'iTunes U|Engineering|Mechanical Engineering', - 40000016 => 'iTunes U|Art & Architecture', - 40000017 => 'iTunes U|Art & Architecture|Architecture', - 40000019 => 'iTunes U|Art & Architecture|Art History', - 40000020 => 'iTunes U|Art & Architecture|Dance', - 40000021 => 'iTunes U|Art & Architecture|Film', - 40000022 => 'iTunes U|Art & Architecture|Design', - 40000023 => 'iTunes U|Art & Architecture|Interior Design', - 40000024 => 'iTunes U|Art & Architecture|Music', - 40000025 => 'iTunes U|Art & Architecture|Theater', + 40000016 => 'iTunes U|Music, Art, & Design', + 40000017 => 'iTunes U|Music, Art, & Design|Architecture', + 40000019 => 'iTunes U|Music, Art, & Design|Art History', + 40000020 => 'iTunes U|Music, Art, & Design|Dance', + 40000021 => 'iTunes U|Music, Art, & Design|Film', + 40000022 => 'iTunes U|Music, Art, & Design|Design', + 40000023 => 'iTunes U|Music, Art, & Design|Interior Design', + 40000024 => 'iTunes U|Music, Art, & Design|Music', + 40000025 => 'iTunes U|Music, Art, & Design|Theater', 40000026 => 'iTunes U|Health & Medicine', 40000027 => 'iTunes U|Health & Medicine|Anatomy & Physiology', 40000028 => 'iTunes U|Health & Medicine|Behavioral Science', @@ -4627,26 +5445,26 @@ my %eeBox = ( 40000049 => 'iTunes U|History|Middle Eastern History', 40000050 => 'iTunes U|History|North American History', 40000051 => 'iTunes U|History|South American History', - 40000053 => 'iTunes U|Communications & Media', + 40000053 => 'iTunes U|Communications & Journalism', 40000054 => 'iTunes U|Philosophy', 40000055 => 'iTunes U|Religion & Spirituality', - 40000056 => 'iTunes U|Language', - 40000057 => 'iTunes U|Language|African Languages', - 40000058 => 'iTunes U|Language|Ancient Languages', - 40000061 => 'iTunes U|Language|English', - 40000063 => 'iTunes U|Language|French', - 40000064 => 'iTunes U|Language|German', - 40000065 => 'iTunes U|Language|Italian', - 40000066 => 'iTunes U|Language|Linguistics', - 40000068 => 'iTunes U|Language|Spanish', - 40000069 => 'iTunes U|Language|Speech Pathology', - 40000070 => 'iTunes U|Literature', - 40000071 => 'iTunes U|Literature|Anthologies', - 40000072 => 'iTunes U|Literature|Biography', - 40000073 => 'iTunes U|Literature|Classics', - 40000074 => 'iTunes U|Literature|Literary Criticism', - 40000075 => 'iTunes U|Literature|Fiction', - 40000076 => 'iTunes U|Literature|Poetry', + 40000056 => 'iTunes U|Languages', + 40000057 => 'iTunes U|Languages|African Languages', + 40000058 => 'iTunes U|Languages|Ancient Languages', + 40000061 => 'iTunes U|Languages|English', + 40000063 => 'iTunes U|Languages|French', + 40000064 => 'iTunes U|Languages|German', + 40000065 => 'iTunes U|Languages|Italian', + 40000066 => 'iTunes U|Languages|Linguistics', + 40000068 => 'iTunes U|Languages|Spanish', + 40000069 => 'iTunes U|Languages|Speech Pathology', + 40000070 => 'iTunes U|Writing & Literature', + 40000071 => 'iTunes U|Writing & Literature|Anthologies', + 40000072 => 'iTunes U|Writing & Literature|Biography', + 40000073 => 'iTunes U|Writing & Literature|Classics', + 40000074 => 'iTunes U|Writing & Literature|Literary Criticism', + 40000075 => 'iTunes U|Writing & Literature|Fiction', + 40000076 => 'iTunes U|Writing & Literature|Poetry', 40000077 => 'iTunes U|Mathematics', 40000078 => 'iTunes U|Mathematics|Advanced Mathematics', 40000079 => 'iTunes U|Mathematics|Algebra', @@ -4664,13 +5482,13 @@ my %eeBox = ( 40000091 => 'iTunes U|Science|Geography', 40000092 => 'iTunes U|Science|Geology', 40000093 => 'iTunes U|Science|Physics', - 40000094 => 'iTunes U|Psychology & Social Science', + 40000094 => 'iTunes U|Social Science', 40000095 => 'iTunes U|Law & Politics|Law', 40000096 => 'iTunes U|Law & Politics|Political Science', 40000097 => 'iTunes U|Law & Politics|Public Administration', - 40000098 => 'iTunes U|Psychology & Social Science|Psychology', - 40000099 => 'iTunes U|Psychology & Social Science|Social Welfare', - 40000100 => 'iTunes U|Psychology & Social Science|Sociology', + 40000098 => 'iTunes U|Social Science|Psychology', + 40000099 => 'iTunes U|Social Science|Social Welfare', + 40000100 => 'iTunes U|Social Science|Sociology', 40000101 => 'iTunes U|Society', 40000103 => 'iTunes U|Society|Asia Pacific Studies', 40000104 => 'iTunes U|Society|European Studies', @@ -4685,36 +5503,36 @@ my %eeBox = ( 40000113 => 'iTunes U|Teaching & Learning|Learning Resources', 40000114 => 'iTunes U|Teaching & Learning|Psychology & Research', 40000115 => 'iTunes U|Teaching & Learning|Special Education', - 40000116 => 'iTunes U|Art & Architecture|Culinary Arts', - 40000117 => 'iTunes U|Art & Architecture|Fashion', - 40000118 => 'iTunes U|Art & Architecture|Media Arts', - 40000119 => 'iTunes U|Art & Architecture|Photography', - 40000120 => 'iTunes U|Art & Architecture|Visual Art', - 40000121 => 'iTunes U|Business|Entrepreneurship', - 40000122 => 'iTunes U|Communications & Media|Broadcasting', - 40000123 => 'iTunes U|Communications & Media|Digital Media', - 40000124 => 'iTunes U|Communications & Media|Journalism', - 40000125 => 'iTunes U|Communications & Media|Photojournalism', - 40000126 => 'iTunes U|Communications & Media|Print', - 40000127 => 'iTunes U|Communications & Media|Speech', - 40000128 => 'iTunes U|Communications & Media|Writing', + 40000116 => 'iTunes U|Music, Art, & Design|Culinary Arts', + 40000117 => 'iTunes U|Music, Art, & Design|Fashion', + 40000118 => 'iTunes U|Music, Art, & Design|Media Arts', + 40000119 => 'iTunes U|Music, Art, & Design|Photography', + 40000120 => 'iTunes U|Music, Art, & Design|Visual Art', + 40000121 => 'iTunes U|Business & Economics|Entrepreneurship', + 40000122 => 'iTunes U|Communications & Journalism|Broadcasting', + 40000123 => 'iTunes U|Communications & Journalism|Digital Media', + 40000124 => 'iTunes U|Communications & Journalism|Journalism', + 40000125 => 'iTunes U|Communications & Journalism|Photojournalism', + 40000126 => 'iTunes U|Communications & Journalism|Print', + 40000127 => 'iTunes U|Communications & Journalism|Speech', + 40000128 => 'iTunes U|Communications & Journalism|Writing', 40000129 => 'iTunes U|Health & Medicine|Nursing', - 40000130 => 'iTunes U|Language|Arabic', - 40000131 => 'iTunes U|Language|Chinese', - 40000132 => 'iTunes U|Language|Hebrew', - 40000133 => 'iTunes U|Language|Hindi', - 40000134 => 'iTunes U|Language|Indigenous Languages', - 40000135 => 'iTunes U|Language|Japanese', - 40000136 => 'iTunes U|Language|Korean', - 40000137 => 'iTunes U|Language|Other Languages', - 40000138 => 'iTunes U|Language|Portuguese', - 40000139 => 'iTunes U|Language|Russian', + 40000130 => 'iTunes U|Languages|Arabic', + 40000131 => 'iTunes U|Languages|Chinese', + 40000132 => 'iTunes U|Languages|Hebrew', + 40000133 => 'iTunes U|Languages|Hindi', + 40000134 => 'iTunes U|Languages|Indigenous Languages', + 40000135 => 'iTunes U|Languages|Japanese', + 40000136 => 'iTunes U|Languages|Korean', + 40000137 => 'iTunes U|Languages|Other Languages', + 40000138 => 'iTunes U|Languages|Portuguese', + 40000139 => 'iTunes U|Languages|Russian', 40000140 => 'iTunes U|Law & Politics', 40000141 => 'iTunes U|Law & Politics|Foreign Policy & International Relations', 40000142 => 'iTunes U|Law & Politics|Local Governments', 40000143 => 'iTunes U|Law & Politics|National Governments', 40000144 => 'iTunes U|Law & Politics|World Affairs', - 40000145 => 'iTunes U|Literature|Comparative Literature', + 40000145 => 'iTunes U|Writing & Literature|Comparative Literature', 40000146 => 'iTunes U|Philosophy|Aesthetics', 40000147 => 'iTunes U|Philosophy|Epistemology', 40000148 => 'iTunes U|Philosophy|Ethics', @@ -4723,8 +5541,8 @@ my %eeBox = ( 40000151 => 'iTunes U|Philosophy|Logic', 40000152 => 'iTunes U|Philosophy|Philosophy of Language', 40000153 => 'iTunes U|Philosophy|Philosophy of Religion', - 40000154 => 'iTunes U|Psychology & Social Science|Archaeology', - 40000155 => 'iTunes U|Psychology & Social Science|Anthropology', + 40000154 => 'iTunes U|Social Science|Archaeology', + 40000155 => 'iTunes U|Social Science|Anthropology', 40000156 => 'iTunes U|Religion & Spirituality|Buddhism', 40000157 => 'iTunes U|Religion & Spirituality|Christianity', 40000158 => 'iTunes U|Religion & Spirituality|Comparative Religion', @@ -4742,20 +5560,20 @@ my %eeBox = ( 40000170 => 'iTunes U|Society|Sexuality Studies', 40000171 => 'iTunes U|Teaching & Learning|Educational Technology', 40000172 => 'iTunes U|Teaching & Learning|Information/Library Science', - 40000173 => 'iTunes U|Language|Dutch', - 40000174 => 'iTunes U|Language|Luxembourgish', - 40000175 => 'iTunes U|Language|Swedish', - 40000176 => 'iTunes U|Language|Norwegian', - 40000177 => 'iTunes U|Language|Finnish', - 40000178 => 'iTunes U|Language|Danish', - 40000179 => 'iTunes U|Language|Polish', - 40000180 => 'iTunes U|Language|Turkish', - 40000181 => 'iTunes U|Language|Flemish', + 40000173 => 'iTunes U|Languages|Dutch', + 40000174 => 'iTunes U|Languages|Luxembourgish', + 40000175 => 'iTunes U|Languages|Swedish', + 40000176 => 'iTunes U|Languages|Norwegian', + 40000177 => 'iTunes U|Languages|Finnish', + 40000178 => 'iTunes U|Languages|Danish', + 40000179 => 'iTunes U|Languages|Polish', + 40000180 => 'iTunes U|Languages|Turkish', + 40000181 => 'iTunes U|Languages|Flemish', 50000024 => 'Audiobooks', 50000040 => 'Audiobooks|Fiction', 50000041 => 'Audiobooks|Arts & Entertainment', - 50000042 => 'Audiobooks|Biography & Memoir', - 50000043 => 'Audiobooks|Business', + 50000042 => 'Audiobooks|Biographies & Memoirs', + 50000043 => 'Audiobooks|Business & Personal Finance', 50000044 => 'Audiobooks|Kids & Young Adults', 50000045 => 'Audiobooks|Classics', 50000046 => 'Audiobooks|Comedy', @@ -4763,13 +5581,13 @@ my %eeBox = ( 50000048 => 'Audiobooks|Speakers & Storytellers', 50000049 => 'Audiobooks|History', 50000050 => 'Audiobooks|Languages', - 50000051 => 'Audiobooks|Mystery', + 50000051 => 'Audiobooks|Mysteries & Thrillers', 50000052 => 'Audiobooks|Nonfiction', 50000053 => 'Audiobooks|Religion & Spirituality', - 50000054 => 'Audiobooks|Science', + 50000054 => 'Audiobooks|Science & Nature', 50000055 => 'Audiobooks|Sci Fi & Fantasy', - 50000056 => 'Audiobooks|Self Development', - 50000057 => 'Audiobooks|Sports', + 50000056 => 'Audiobooks|Self-Development', + 50000057 => 'Audiobooks|Sports & Outdoors', 50000058 => 'Audiobooks|Technology', 50000059 => 'Audiobooks|Travel & Adventure', 50000061 => 'Music|Spoken Word', @@ -4800,17 +5618,21 @@ my %eeBox = ( 50000089 => 'Books|Comics & Graphic Novels|Manga|Horror', 50000090 => 'Books|Comics & Graphic Novels|Comics', 50000091 => 'Books|Romance|Multicultural', + 50000092 => 'Audiobooks|Erotica', + 50000093 => 'Audiobooks|Light Novels', }, }, - grup => 'Grouping', #10 + grup => { Name => 'Grouping', Avoid => 1 }, #10 hdvd => { #10 Name => 'HDVideo', + Format => 'int8u', #24 PrintConv => { 0 => 'No', 1 => 'Yes' }, }, keyw => 'Keyword', #7 ldes => 'LongDescription', #10 pcst => { #7 Name => 'Podcast', + Format => 'int8u', #23 PrintConv => { 0 => 'No', 1 => 'Yes' }, }, perf => 'Performer', @@ -4822,6 +5644,7 @@ my %eeBox = ( purl => 'PodcastURL', #7 rtng => { #10 Name => 'Rating', + Format => 'int8u', #23 PrintConv => { 0 => 'none', 1 => 'Explicit', @@ -4999,6 +5822,7 @@ my %eeBox = ( sosn => 'SortShow', #10 stik => { #10 Name => 'MediaType', + Format => 'int8u', #23 PrintConvColumns => 2, PrintConv => { #(http://weblog.xanga.com/gryphondwb/615474010/iphone-ringtones---what-did-itunes-741-really-do.html) 0 => 'Movie (old)', #forum9059 (was Movie) @@ -5015,7 +5839,7 @@ my %eeBox = ( }, }, rate => 'RatingPercent', #PH - titl => 'Title', + titl => { Name => 'Title', Avoid => 1 }, tven => 'TVEpisodeID', #7 tves => { #7/10 Name => 'TVEpisode', @@ -5030,6 +5854,7 @@ my %eeBox = ( yrrc => 'Year', #(ffmpeg source) itnu => { #PH (iTunes 10.5) Name => 'iTunesU', + Format => 'int8s', Description => 'iTunes U', PrintConv => { 0 => 'No', 1 => 'Yes' }, }, @@ -5039,10 +5864,24 @@ my %eeBox = ( gspu => { Name => 'GooglePingURL', Format => 'string' }, gssd => { Name => 'GoogleSourceData', Format => 'string' }, gsst => { Name => 'GoogleStartTime', Format => 'string' }, - gstd => { Name => 'GoogleTrackDuration',Format => 'string', ValueConv => '$val / 1000', PrintConv => 'ConvertDuration($val)' }, + gstd => { + Name => 'GoogleTrackDuration', + Format => 'string', + ValueConv => '$val / 1000', + ValueConvInv => '$val * 1000', + PrintConv => 'ConvertDuration($val)', + PrintConvInv => q{ + $val =~ s/ s$//; + my @a = split /(:| days )/, $val; + my $sign = ($val =~ s/^-//) ? -1 : 1; + $a[0] += shift(@a) * 24 if @a == 4; + $a[0] += shift(@a) * 60 while @a > 1; + return $a[0] * $sign; + }, + }, # atoms observed in AAX audiobooks (ref PH) - "\xa9cpy" => { Name => 'Copyright', Groups => { 2 => 'Author' } }, + "\xa9cpy" => { Name => 'Copyright', Avoid => 1, Groups => { 2 => 'Author' } }, "\xa9pub" => 'Publisher', "\xa9nrt" => 'Narrator', '@pti' => 'ParentTitle', # (guess -- same as "\xa9nam") @@ -5086,12 +5925,30 @@ my %eeBox = ( # item list keys (ref PH) %Image::ExifTool::QuickTime::Keys = ( - PROCESS_PROC => \&Image::ExifTool::QuickTime::ProcessKeys, + PROCESS_PROC => \&ProcessKeys, + WRITE_PROC => \&WriteKeys, + CHECK_PROC => \&CheckQTValue, VARS => { LONG_TAGS => 3 }, + WRITABLE => 1, + # (not PREFERRED when writing) + GROUPS => { 1 => 'Keys' }, + WRITE_GROUP => 'Keys', + LANG_INFO => \&GetLangInfo, + FORMAT => 'string', NOTES => q{ - This directory contains a list of key names which are used to decode - ItemList tags written by the "mdta" handler. The prefix of - "com.apple.quicktime." has been removed from all TagID's below. + This directory contains a list of key names which are used to decode tags + written by the "mdta" handler. Also in this table are a few tags found in + timed metadata that are not yet writable by ExifTool. The prefix of + "com.apple.quicktime." has been removed from the TagID's below. These tags + support alternate languages in the same way as the + L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> tags. Note + that by default, + L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> and + L<UserData|Image::ExifTool::TagNames/QuickTime UserData Tags> tags are + preferred when writing, so to create a tag when a same-named tag exists in + either of these tables, either the "Keys" location must be specified (eg. + C<-Keys:Author=Phil> on the command line), or the PREFERRED level must be + changed via L<the config file|../config.html#PREF>. }, version => 'Version', album => 'Album', @@ -5103,16 +5960,25 @@ my %eeBox = ( creationdate=> { Name => 'CreationDate', Groups => { 2 => 'Time' }, + Shift => 'Time', ValueConv => q{ require Image::ExifTool::XMP; $val = Image::ExifTool::XMP::ConvertXMPDate($val,1); $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary return $val; }, + ValueConvInv => q{ + require Image::ExifTool::XMP; + $val = Image::ExifTool::XMP::FormatXMPDate($val); + $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon + return $val; + }, PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, description => { }, director => { }, + displayname => { Name => 'DisplayName' }, title => { }, #22 genre => { }, information => { }, @@ -5127,13 +5993,17 @@ my %eeBox = ( 'camera.framereadouttimeinmicroseconds' => { # (iPhone 4) Name => 'FrameReadoutTime', ValueConv => '$val * 1e-6', + ValueConvInv => 'int($val * 1e6 + 0.5)', PrintConv => '$val * 1e6 . " microseconds"', + PrintConvInv => '$val =~ s/ .*//; $val * 1e-6', }, 'location.ISO6709' => { Name => 'GPSCoordinates', Groups => { 2 => 'Location' }, ValueConv => \&ConvertISO6709, + ValueConvInv => \&ConvInvISO6709, PrintConv => \&PrintGPSCoordinates, + PrintConvInv => \&PrintInvGPSCoordinates, }, 'location.name' => { Name => 'LocationName', Groups => { 2 => 'Location' } }, 'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } }, @@ -5150,17 +6020,25 @@ my %eeBox = ( 'location.date' => { Name => 'LocationDate', Groups => { 2 => 'Time' }, + Shift => 'Time', ValueConv => q{ require Image::ExifTool::XMP; $val = Image::ExifTool::XMP::ConvertXMPDate($val); $val =~ s/([-+]\d{2})(\d{2})$/$1:$2/; # add colon to timezone if necessary return $val; }, + ValueConvInv => q{ + require Image::ExifTool::XMP; + $val = Image::ExifTool::XMP::FormatXMPDate($val); + $val =~ s/([-+]\d{2}):(\d{2})$/$1$2/; # remove time zone colon + return $val; + }, PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', }, 'direction.facing' => { Name => 'CameraDirection', Groups => { 2 => 'Location' } }, - 'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } }, - 'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } }, + 'direction.motion' => { Name => 'CameraMotion', Groups => { 2 => 'Location' } }, + 'location.body' => { Name => 'LocationBody', Groups => { 2 => 'Location' } }, 'player.version' => 'PlayerVersion', 'player.movie.visual.brightness'=> 'Brightness', 'player.movie.visual.color' => 'Color', @@ -5180,29 +6058,63 @@ my %eeBox = ( 'collection.user' => 'UserCollection', #22 'Encoded_With' => 'EncodedWith', # -# seen in timed metadata (mebx), and added dynamically via SaveMetaKeys() (ref PH): +# the following tags aren't in the com.apple.quicktime namespace: +# + 'com.apple.photos.captureMode' => 'CaptureMode', + 'com.android.version' => 'AndroidVersion', +# +# also seen +# + # com.divergentmedia.clipwrap.model ('NEX-FS700EK') + # com.divergentmedia.clipwrap.model1 ('49') + # com.divergentmedia.clipwrap.model2 ('0') + # com.divergentmedia.clipwrap.manufacturer ('Sony') + # com.divergentmedia.clipwrap.originalDateTime ('2013/2/6 10:30:40+0200') +# +# seen in timed metadata (mebx), and added dynamically to the table +# via SaveMetaKeys(). NOTE: these tags are not writable! # # (mdta)com.apple.quicktime.video-orientation (dtyp=66, int16s) - 'video-orientation' => 'VideoOrientation', + 'video-orientation' => { Name => 'VideoOrientation', Writable => 0 }, + # (mdta)com.apple.quicktime.live-photo-info (dtyp=com.apple.quicktime.com.apple.quicktime.live-photo-info) + 'live-photo-info' => { + Name => 'LivePhotoInfo', + Writable => 0, + # not sure what these values mean, but unpack them anyway - PH + # (ignore the fact that the "f" and "l" unpacks won't work on a big-endian machine) + ValueConv => 'join " ",unpack "VfVVf6c4lCCcclf4Vvv", $val', + }, + # (mdta)com.apple.quicktime.still-image-time (dtyp=65, int8s) + 'still-image-time' => { # (found in live photo) + Name => 'StillImageTime', + Writable => 0, + Notes => q{ + this tag always has a value of -1; the time of the still image is obtained + from the associated SampleTime + }, + }, # (mdta)com.apple.quicktime.detected-face (dtyp='com.apple.quicktime.detected-face') 'detected-face' => { Name => 'FaceInfo', + Writable => 0, SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::FaceInfo' }, }, - # ---- detected-face fields ---- + # ---- detected-face fields ( ---- # --> back here after a round trip through FaceInfo -> FaceRec -> FaceItem # (fiel)com.apple.quicktime.detected-face.bounds (dtyp=80, float[8]) 'detected-face.bounds' => { Name => 'DetectedFaceBounds', + Writable => 0, # round to a reasonable number of decimal places PrintConv => 'my @a=split " ",$val;$_=int($_*1e6+.5)/1e6 foreach @a;join " ",@a', + PrintConvInv => '$val', }, # (fiel)com.apple.quicktime.detected-face.face-id (dtyp=77, int32u) - 'detected-face.face-id' => 'DetectedFaceID', + 'detected-face.face-id' => { Name => 'DetectedFaceID', Writable => 0 }, # (fiel)com.apple.quicktime.detected-face.roll-angle (dtyp=23, float) - 'detected-face.roll-angle' => 'DetectedFaceRollAngle', + 'detected-face.roll-angle' => { Name => 'DetectedFaceRollAngle', Writable => 0 }, # (fiel)com.apple.quicktime.detected-face.yaw-angle (dtyp=23, float) - 'detected-face.yaw-angle' => 'DetectedFaceYawAngle', + 'detected-face.yaw-angle' => { Name => 'DetectedFaceYawAngle', Writable => 0 }, ); # iTunes info ('----') atoms @@ -5489,7 +6401,7 @@ my %eeBox = ( Format => 'int16u', RawConv => '$val ? $val : undef', # allow both Macintosh (for MOV files) and ISO (for MP4 files) language codes - ValueConv => '$val < 0x400 ? $val : pack "C*", map { (($val>>$_)&0x1f)+0x60 } 10, 5, 0', + ValueConv => '($val < 0x400 or $val == 0x7fff) ? $val : pack "C*", map { (($val>>$_)&0x1f)+0x60 } 10, 5, 0', PrintConv => q{ return $val unless $val =~ /^\d+$/; require Image::ExifTool::Font; @@ -5521,7 +6433,7 @@ my %eeBox = ( Flags => ['Binary','Unknown'], }, dinf => { - Name => 'DataInfo', + Name => 'DataInfo', # (don't change this name -- used to recognize directory when writing) SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::DataInfo' }, }, gmhd => { @@ -5683,6 +6595,12 @@ my %eeBox = ( sgpd => { Name => 'SampleGroupDescription', Flags => ['Binary','Unknown'], + # bytes 4-7 give grouping type (ref ISO/IEC 14496-15:2014) + # tsas - temporal sublayer sample + # stsa - step-wise temporal layer access + # avss - AVC sample + # tscl - temporal layer scalability + # sync - sync sample }, subs => { Name => 'Sub-sampleInformation', @@ -5718,6 +6636,8 @@ my %eeBox = ( $self->OverrideFileType('M4P') if $val eq 'drms' and $$self{VALUE}{FileType} eq 'M4A'; return $val; }, + # see this link for print conversions (not complete): + # https://github.com/yannickcr/brooser/blob/master/php/librairies/getid3/module.audio-video.quicktime.php }, 20 => { #PH Name => 'AudioVendorID', @@ -5735,7 +6655,7 @@ my %eeBox = ( # # AudioFormat Offset Child atoms # ----------- ------ ---------------- -# mp4a 52 * wave, chan, esds +# mp4a 52 * wave, chan, esds, SA3D(Insta360 spherical video params?) # in24 52 wave, chan # "ms\0\x11" 52 wave # sowt 52 chan @@ -6242,11 +7162,13 @@ my %eeBox = ( # data - - # ftab => { Name => 'FontTable', Format => 'undef', ValueConv => 'substr($val, 5)' }, + name => { Name => 'OtherName', Format => 'undef', ValueConv => 'substr($val, 4)' }, ); # MP4 data information box (ref 5) %Image::ExifTool::QuickTime::DataInfo = ( PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, # (necessary to parse dref even though we don't change it) NOTES => 'MP4 data information box.', dref => { Name => 'DataRef', @@ -6347,6 +7269,7 @@ my %eeBox = ( # MP4 data reference box (ref 5) %Image::ExifTool::QuickTime::DataRef = ( PROCESS_PROC => \&ProcessMOV, + WRITE_PROC => \&WriteQuickTime, # (necessary to parse dref even though we don't change it) NOTES => 'MP4 data reference box.', 'url ' => { Name => 'URL', @@ -6418,6 +7341,8 @@ my %eeBox = ( pict => 'Picture', # (HEIC images) camm => 'Camera Metadata', # (Insta360 MP4) psmd => 'Panasonic Static Metadata', #PH (Leica C-Lux CAM-DC25) + data => 'Data', #PH (GPS and G-sensor data from DataKam) + sbtl => 'Subtitle', #PH (TomTom Bandit Action Cam) }, }, 12 => { #PH @@ -6461,6 +7386,66 @@ my %eeBox = ( }, ); +# atoms in Pittasoft "free" atom +%Image::ExifTool::QuickTime::Pittasoft = ( + PROCESS_PROC => \&ProcessMOV, + NOTES => 'Tags found in Pittasoft Blackvue dashcam "free" data.', + cprt => 'Copyright', + thum => { + Name => 'PreviewImage', + Groups => { 2 => 'Preview' }, + Binary => 1, + RawConv => q{ + return undef unless length $val > 4; + my $len = unpack('N', $val); + return undef unless length $val >= 4 + $len; + return substr($val, 4, $len); + }, + }, + ptnm => { + Name => 'OriginalFileName', + ValueConv => 'substr($val, 4, -1)', + }, + ptrh => { + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Pittasoft' }, + # contains these atoms: + # ptvi - 27 bytes: '..avc1...' + # ptso - 16 bytes: '..mp4a...' + }, + 'gps ' => { + Name => 'GPSLog', + Binary => 1, # (ASCII NMEA track log with leading timestamps) + Notes => 'parsed to extract GPS separately when ExtractEmbedded is used', + RawConv => q{ + $val =~ s/\0+$//; # remove trailing nulls + if (length $val and $$self{OPTIONS}{ExtractEmbedded}) { + my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); + Image::ExifTool::QuickTime::ProcessNMEA($self, { DataPt => \$val }, $tagTbl); + } + return $val; + }, + }, + '3gf ' => { + Name => 'AccelData', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Stream', + ProcessProc => \&Process_3gf, + }, + }, + sttm => { + Name => 'StartTime', + Format => 'int64u', + Groups => { 2 => 'Time' }, + RawConv => '$$self{StartTime} = $val', + # (ms since Jan 1, 1970, in local time zone - PH) + ValueConv => q{ + my $secs = int($val / 1000); + return ConvertUnixTime($secs) . sprintf(".%03d",$val - $secs * 1000); + }, + PrintConv => '$self->ConvertDateTime($val)', + }, +); + # QuickTime composite tags %Image::ExifTool::QuickTime::Composite = ( GROUPS => { 2 => 'Video' }, @@ -6483,13 +7468,13 @@ my %eeBox = ( AvgBitrate => { Priority => 0, # let QuickTime::AvgBitrate take priority Require => { - 0 => 'QuickTime::MovieDataSize', + 0 => 'QuickTime::MediaDataSize', 1 => 'QuickTime::Duration', }, RawConv => q{ return undef unless $val[1]; $val[1] /= $$self{TimeScale} if $$self{TimeScale}; - my $key = 'MovieDataSize'; + my $key = 'MediaDataSize'; my $size = $val[0]; for (;;) { $key = $self->NextTagKey($key) or last; @@ -6582,6 +7567,7 @@ Image::ExifTool::AddCompositeTags('Image::ExifTool::QuickTime'); # sub AUTOLOAD { + # (Note: no need to autoload routines in QuickTimeStream that use Stream table) if ($AUTOLOAD eq 'Image::ExifTool::QuickTime::Process_mebx') { require 'Image/ExifTool/QuickTimeStream.pl'; no strict 'refs'; @@ -6709,7 +7695,7 @@ sub FixWrongFormat($) #------------------------------------------------------------------------------ # Convert ISO 6709 string to standard lag/lon format # Inputs: 0) ISO 6709 string (lat, lon, and optional alt) -# Returns: position in decimal degress with altitude if available +# Returns: position in decimal degrees with altitude if available # Notes: Wikipedia indicates altitude may be in feet -- how is this specified? sub ConvertISO6709($) { @@ -6802,18 +7788,18 @@ sub PrintGPSCoordinates($) #------------------------------------------------------------------------------ # Unpack packed ISO 639/T language code -# Inputs: 0) packed language code (or undef) -# Returns: language code, or undef for default language, or 'err' for format error -sub UnpackLang($) +# Inputs: 0) packed language code (or undef/0), 1) true to not treat 'und' and 'eng' as default +# Returns: language code, or undef/0 for default language, or 'err' for format error +sub UnpackLang($;$) { - my $lang = shift; + my ($lang, $noDef) = @_; if ($lang) { # language code is packed in 5-bit characters - $lang = pack "C*", map { (($lang>>$_)&0x1f)+0x60 } 10, 5, 0; + $lang = pack 'C*', map { (($lang>>$_)&0x1f)+0x60 } 10, 5, 0; # validate language code if ($lang =~ /^[a-z]+$/) { # treat 'eng' or 'und' as the default language - undef $lang if $lang eq 'und' or $lang eq 'eng'; + undef $lang if ($lang eq 'und' or $lang eq 'eng') and not $noDef; } else { $lang = 'err'; # invalid language code } @@ -6821,6 +7807,30 @@ sub UnpackLang($) return $lang; } +#------------------------------------------------------------------------------ +# Get language code string given QuickTime language and country codes +# Inputs: 0) numerical language code, 1) numerical country code, 2) no defaults +# Returns: language code string (ie. "fra-FR") or undef for default language +sub GetLangCode($;$$) +{ + my ($lang, $ctry, $noDef) = @_; + # ignore country ('ctry') and language lists ('lang') for now + undef $ctry if $ctry and $ctry <= 255; + undef $lang if $lang and $lang <= 255; + $lang = UnpackLang($lang, $noDef); + # add country code if specified + if ($ctry) { + $ctry = unpack('a2',pack('n',$ctry)); # unpack as ISO 3166-1 + # treat 'ZZ' like a default country (see ref 12) + undef $ctry if $ctry eq 'ZZ'; + if ($ctry and $ctry =~ /^[A-Z]{2}$/) { + $lang or $lang = 'und'; + $lang .= "-$ctry"; + } + } + return $lang; +} + #------------------------------------------------------------------------------ # Get langInfo hash and save details about alt-lang tags # Inputs: 0) ExifTool ref, 1) tagInfo hash ref, 2) locale code @@ -6878,15 +7888,20 @@ sub GetString($$) #------------------------------------------------------------------------------ # Get a printable version of the tag ID -# Inputs: 0) tag ID, 1) Flag: 1=print as 4- or 8-digit hex value if necessary +# Inputs: 0) tag ID, 1) Flag: 0x01 - print as 4- or 8-digit hex value if necessary +# 0x02 - put leading backslash before escaped character # Returns: Printable tag ID sub PrintableTagID($;$) { my $tag = $_[0]; my $n = ($tag =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg); - if ($n > 2 and $_[1]) { - $tag = '0x' . unpack('H8', $_[0]); - $tag =~ s/^0x0000/0x/; + if ($n and $_[1]) { + if ($n > 2 and $_[1] & 0x01) { + $tag = '0x' . unpack('H8', $_[0]); + $tag =~ s/^0x0000/0x/; + } elsif ($_[1] & 0x02) { + ($tag = $_[0]) =~ s/([\x00-\x1f\x7f-\xff])/'\\x'.unpack('H*',$1)/eg; + } } return $tag; } @@ -6899,7 +7914,12 @@ sub PrintableTagID($;$) # ConstructionMethod - offset type: 0=file, 1=idat, 2=item # DataReferenceIndex - 0 for "this file", otherwise index in dref box # BaseOffset - base for file offsets -# Extents - list of index,offset,length details for data in file +# Extents - list of details for data in file: +# 0) index (extent_index) +# 1) offset (extent_offset) +# 2) length (extent_length) +# 3) nlen (length_size) +# 4) lenPt (pointer to length word) # infe: # ProtectionIndex - index if item is protected (0 for unprotected) # Name - item name @@ -6918,12 +7938,14 @@ sub PrintableTagID($;$) # Parse item location (iloc) box (ref ISO 14496-12:2015 pg.79) # Inputs: 0) iloc data, 1) ExifTool ref # Returns: undef, and fills in ExifTool ItemInfo hash +# Notes: see also Handle_iloc() in WriteQuickTime.pl sub ParseItemLocation($$) { my ($val, $et) = @_; my ($i, $j, $num, $pos, $id); my ($extent_index, $extent_offset, $extent_length); + my $verbose = $$et{IsWriting} ? 0 : $et->Options('Verbose'); my $items = $$et{ItemInfo} || ($$et{ItemInfo} = { }); my $len = length $val; return undef if $len < 8; @@ -6971,7 +7993,11 @@ sub ParseItemLocation($$) $extent_offset = GetVarInt(\$val, $pos, $noff); $extent_length = GetVarInt(\$val, $pos, $nlen); return undef unless defined $extent_length; - push @extents, [ $extent_index, $extent_offset, $extent_length ]; + $et->VPrint(1, "$$et{INDENT} Item $id: const_meth=", + defined $$items{$id}{ConstructionMethod} ? $$items{$id}{ConstructionMethod} : '', + sprintf(" base=0x%x offset=0x%x len=0x%x\n", $$items{$id}{BaseOffset}, + $extent_offset, $extent_length)) if $verbose; + push @extents, [ $extent_index, $extent_offset, $extent_length, $nlen, $pos-$nlen ]; } # save item location information keyed on 1-based item ID: $$items{$id}{Extents} = \@extents; @@ -6979,6 +8005,33 @@ sub ParseItemLocation($$) return undef; } +#------------------------------------------------------------------------------ +# Parse content describes entry (cdsc) box +# Inputs: 0) cdsc data, 1) ExifTool ref +# Returns: undef, and fills in ExifTool ItemInfo hash +sub ParseContentDescribes($$) +{ + my ($val, $et) = @_; + my ($id, $count, @to); + if ($$et{ItemRefVersion}) { + return undef if length $val < 10; + ($id, $count, @to) = unpack('NnN*', $val); + } else { + return undef if length $val < 6; + ($id, $count, @to) = unpack('nnn*', $val); + } + if ($count > @to) { + my $str = 'Missing values in ContentDescribes box'; + $$et{IsWriting} ? $et->Error($str) : $et->Warn($str); + } elsif ($count < @to) { + $et->Warn('Ignored extra values in ContentDescribes box', 1); + @to = $count; + } + # add all referenced item ID's to a "RefersTo" lookup + $$et{ItemInfo}{$id}{RefersTo}{$_} = 1 foreach @to; + return undef; +} + #------------------------------------------------------------------------------ # Parse item information entry (infe) box (ref ISO 14496-12:2015 pg.82) # Inputs: 0) infe data, 1) ExifTool ref @@ -6988,7 +8041,7 @@ sub ParseItemInfoEntry($$) my ($val, $et) = @_; my $id; - my $verbose = $et->Options('Verbose'); + my $verbose = $$et{IsWriting} ? 0 : $et->Options('Verbose'); my $items = $$et{ItemInfo} || ($$et{ItemInfo} = { }); my $len = length $val; return undef if $len < 4; @@ -7032,15 +8085,14 @@ sub ParseItemInfoEntry($$) #------------------------------------------------------------------------------ # Parse item property association (ipma) box (ref https://github.com/gpac/gpac/blob/master/src/isomedia/iff.c) -# Inputs: 0) infe data, 1) ExifTool ref +# Inputs: 0) ipma data, 1) ExifTool ref # Returns: undef, and fills in ExifTool ItemInfo hash -# Note: this information is currently not used by ExifTool (must figure out how to do this) sub ParseItemPropAssoc($$) { my ($val, $et) = @_; my ($i, $j, $id); - my $verbose = $et->Options('Verbose'); + my $verbose = $$et{IsWriting} ? 0 : $et->Options('Verbose'); my $items = $$et{ItemInfo} || ($$et{ItemInfo} = { }); my $len = length $val; return undef if $len < 8; @@ -7086,40 +8138,76 @@ sub ParseItemPropAssoc($$) #------------------------------------------------------------------------------ # Process item information now -# Inputs: 0) ExifTool ref, 1) RAF ref -sub HandleItemInfo($$) +# Inputs: 0) ExifTool ref +sub HandleItemInfo($) { - my ($et, $raf) = @_; + my $et = shift; + my $raf = $$et{RAF}; my $items = $$et{ItemInfo}; + my $verbose = $et->Options('Verbose'); my $buff; # extract information from EXIF/XMP metadata items if ($items and $raf) { + push @{$$et{PATH}}, 'ItemInformation'; my $curPos = $raf->Tell(); my $primary = $$et{PrimaryItem}; my $id; + $et->VerboseDir('Processing items from ItemInformation', scalar(keys %$items)); foreach $id (sort { $a <=> $b } keys %$items) { my $item = $$items{$id}; my $type = $$item{ContentType} || $$item{Type} || next; - unless ($type eq 'Exif') { - next unless $type eq 'application/rdf+xml'; - $type = 'XMP'; - } - if ($$item{ContentEncoding}) { - $et->WarnOnce("Can't currently decode encoded $type metadata"); - next; + if ($verbose) { + # add up total length of this item for the verbose output + my $len = 0; + if ($$item{Extents} and @{$$item{Extents}}) { + $len += $$_[2] foreach @{$$item{Extents}}; + } + $et->VPrint(0, "$$et{INDENT}Item $id) '${type}' ($len bytes)\n"); } - if ($$item{ProtectionIndex}) { - $et->WarnOnce("Can't currently decode protected $type metadata"); - next; + # get ExifTool name for this item + my $name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP' }->{$type} || ''; + my ($warn, $extent); + $warn = "Can't currently decode encoded $type metadata" if $$item{ContentEncoding}; + $warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex}; + $warn = "Can't currently extract $type with construction method $$item{ConstructionMethod}" if $$item{ConstructionMethod}; + $et->WarnOnce($warn) if $warn and $name; + $warn = 'Not this file' if $$item{DataReferenceIndex}; # (can only extract from "this file") + unless (($$item{Extents} and @{$$item{Extents}}) or $warn) { + $warn = "No Extents for $type item"; + $et->WarnOnce($warn) if $name; } - if ($$item{ConstructionMethod}) { - $et->WarnOnce("Can't currently extract $type with construction method $$item{ConstructionMethod}"); + if ($warn) { + $et->VPrint(0, "$$et{INDENT} [not extracted] ($warn)\n") if $verbose > 2; next; } - next if $$item{DataReferenceIndex}; # (can only extract information from "this file") - my ($extent, $proc); my $base = $$item{BaseOffset} || 0; + if ($verbose > 2) { + # do verbose hex dump + my $len = 0; + undef $buff; + my $val = ''; + my $maxLen = $verbose > 3 ? 2048 : 96; + foreach $extent (@{$$item{Extents}}) { + my $n = $$extent[2]; + my $more = $maxLen - $len; + if ($more > 0 and $n) { + $more = $n if $more > $n; + $val .= $buff if defined $buff; + $raf->Seek($$extent[1] + $base, 0) or last; + $raf->Read($buff, $more) or last; + } + $len += $n; + } + if (defined $buff) { + $buff = $val . $buff if length $val; + $et->VerboseDump(\$buff, DataPos => $$item{Extents}[0][1] + $base); + my $snip = $len - length $buff; + $et->VPrint(0, "$$et{INDENT} [snip $snip bytes]\n") if $snip; + } + } + next unless $name; + # assemble the data for this item undef $buff; my $val = ''; foreach $extent (@{$$item{Extents}}) { @@ -7129,15 +8217,29 @@ sub HandleItemInfo($$) } next unless defined $buff; $buff = $val . $buff if length $val; - my $start = $type eq 'Exif' ? 10 : 0; # skip count and "Exif\0\0" header + next unless length $buff; # ignore empty directories + my ($start, $subTable, $proc); my $pos = $$item{Extents}[0][1] + $base; + if ($name eq 'EXIF' and length $buff >= 4) { + my $n = unpack('N', $buff); + $start = 4 + $n; # skip "Exif\0\0" header if it exists + $subTable = GetTagTable('Image::ExifTool::Exif::Main'); + if ($$et{HTML_DUMP}) { + $et->HDump($pos, 4, 'Exif header length', "Value: $n"); + $et->HDump($pos+4, $start-4, 'Exif header') if $n; + } + $proc = \&Image::ExifTool::ProcessTIFF; + } else { + $start = 0; + $subTable = GetTagTable('Image::ExifTool::XMP::Main'); + } my %dirInfo = ( DataPt => \$buff, DataLen => length $buff, DirStart => $start, DirLen => length($buff) - $start, DataPos => $pos, - Base => $pos, # (needed for IsOffset tags in binary data) + Base => $pos + $start, # (needed for HtmlDump and IsOffset tags in binary data) ); # handle processing of metadata for sub-documents if (defined $primary and $$item{RefersTo} and not $$item{RefersTo}{$primary}) { @@ -7147,12 +8249,11 @@ sub HandleItemInfo($$) my ($lowest) = sort { $a <=> $b } keys %{$$item{RefersTo}}; $$items{$lowest}{DocNum} = $$et{DOC_NUM}; } - my $subTable = GetTagTable('Image::ExifTool::' . $type . '::Main'); - $proc = \&Image::ExifTool::ProcessTIFF if $type eq 'Exif'; $et->ProcessDirectory(\%dirInfo, $subTable, $proc); delete $$et{DOC_NUM}; } $raf->Seek($curPos, 0); # seek back to original position + pop @{$$et{PATH}}; } # process the item properties now that we should know their associations and document numbers if ($$et{ItemPropertyContainer}) { @@ -7166,6 +8267,36 @@ sub HandleItemInfo($$) delete $$et{ItemInfo}; } +#------------------------------------------------------------------------------ +# Warn if ExtractEmbedded option isn't used +# Inputs: 0) ExifTool ref +sub EEWarn($) +{ + my $et = shift; + $et->WarnOnce('The ExtractEmbedded option may find more tags in the media data',3); +} + +#------------------------------------------------------------------------------ +# Get quicktime format from flags word +# Inputs: 0) quicktime atom flags, 1) data length +# Returns: Exiftool format string +sub QuickTimeFormat($$) +{ + my ($flags, $len) = @_; + my $format; + if ($flags == 0x15 or $flags == 0x16) { + $format = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len}; + $format .= $flags == 0x15 ? 's' : 'u' if $format; + } elsif ($flags == 0x17) { + $format = 'float'; + } elsif ($flags == 0x18) { + $format = 'double'; + } elsif ($flags == 0x00) { + $format = { 1=>'int8u', 2=>'int16u' }->{$len}; + } + return $format; +} + #------------------------------------------------------------------------------ # Process MPEG-4 MTDT atom (ref 11) # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref @@ -7349,7 +8480,7 @@ sub ProcessEncodingParams($$$) } #------------------------------------------------------------------------------ -# Process Meta keys and add tags to the ItemList table ('mdta' handler) (ref PH) +# Read Meta Keys and add tags to ItemList table ('mdta' handler) (ref PH) # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref # Returns: 1 on success sub ProcessKeys($$$) @@ -7365,9 +8496,9 @@ sub ProcessKeys($$$) } my $pos = 8; my $index = 1; - ++$$et{KeyCount}; # increment key count for this directory - my $infoTable = GetTagTable('Image::ExifTool::QuickTime::ItemList'); - my $userTable = GetTagTable('Image::ExifTool::QuickTime::UserData'); + ++$$et{KeysCount}; # increment key count for this directory + my $itemList = GetTagTable('Image::ExifTool::QuickTime::ItemList'); + my $userData = GetTagTable('Image::ExifTool::QuickTime::UserData'); while ($pos < $dirLen - 4) { my $len = unpack("x${pos}N", $$dataPt); last if $len < 8 or $pos + $len > $dirLen; @@ -7375,53 +8506,61 @@ sub ProcessKeys($$$) my $ns = substr($$dataPt, $pos + 4, 4); my $tag = substr($$dataPt, $pos + 8, $len - 8); $tag =~ s/\0.*//s; # truncate at null - if ($ns eq 'mdta') { - $tag =~ s/^com\.apple\.quicktime\.//; # remove common apple quicktime domain - } + $tag =~ s/^com\.apple\.quicktime\.// if $ns eq 'mdta'; # remove apple quicktime domain $tag = "Tag_$ns" unless $tag; # (I have some samples where the tag is a reversed ItemList or UserData tag ID) my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); unless ($tagInfo) { - $tagInfo = $et->GetTagInfo($infoTable, $tag); + $tagInfo = $et->GetTagInfo($itemList, $tag); unless ($tagInfo) { - $tagInfo = $et->GetTagInfo($userTable, $tag); + $tagInfo = $et->GetTagInfo($userData, $tag); if (not $tagInfo and $tag =~ /^\w{3}\xa9$/) { $tag = pack('N', unpack('V', $tag)); - $tagInfo = $et->GetTagInfo($infoTable, $tag); - $tagInfo or $tagInfo = $et->GetTagInfo($userTable, $tag); + $tagInfo = $et->GetTagInfo($itemList, $tag); + $tagInfo or $tagInfo = $et->GetTagInfo($userData, $tag); } } } my ($newInfo, $msg); if ($tagInfo) { + # copy tag information into new Keys tag $newInfo = { Name => $$tagInfo{Name}, Format => $$tagInfo{Format}, ValueConv => $$tagInfo{ValueConv}, + ValueConvInv => $$tagInfo{ValueConvInv}, PrintConv => $$tagInfo{PrintConv}, + PrintConvInv => $$tagInfo{PrintConvInv}, + Writable => defined $$tagInfo{Writable} ? $$tagInfo{Writable} : 1, + SubDirectory => $$tagInfo{SubDirectory}, }; my $groups = $$tagInfo{Groups}; - $$newInfo{Groups} = { %$groups } if $groups; - } elsif ($tag =~ /^[-\w.]+$/) { + $$newInfo{Groups} = $groups ? { %$groups } : { }; + $$newInfo{Groups}{$_} or $$newInfo{Groups}{$_} = $$tagTablePtr{GROUPS}{$_} foreach 0..2; + $$newInfo{Groups}{1} = 'Keys'; + } elsif ($tag =~ /^[-\w. ]+$/) { # create info for tags with reasonable id's - my $name = $tag; - $name =~ s/\.(.)/\U$1/g; - $newInfo = { Name => ucfirst($name) }; + my $name = ucfirst $tag; + $name =~ s/[. ]+(.?)/\U$1/g; + $name =~ s/_([a-z])/_\U$1/g; + $name =~ s/([a-z])_([A-Z])/$1$2/g; + $name = "Tag_$name" if length $name < 2; + $newInfo = { Name => $name, Groups => { 1 => 'Keys' } }; $msg = ' (Unknown)'; } # substitute this tag in the ItemList table with the given index - my $id = $$et{KeyCount} . '.' . $index; - if (ref $$infoTable{$id} eq 'HASH') { + my $id = $$et{KeysCount} . '.' . $index; + if (ref $$itemList{$id} eq 'HASH') { # delete other languages too if they exist - my $oldInfo = $$infoTable{$id}; + my $oldInfo = $$itemList{$id}; if ($$oldInfo{OtherLang}) { - delete $$infoTable{$_} foreach @{$$oldInfo{OtherLang}}; + delete $$itemList{$_} foreach @{$$oldInfo{OtherLang}}; } - delete $$infoTable{$id}; + delete $$itemList{$id}; } if ($newInfo) { + AddTagToTable($itemList, $id, $newInfo); $msg or $msg = ''; - AddTagToTable($infoTable, $id, $newInfo); $out and print $out "$$et{INDENT}Added ItemList Tag $id = $tag$msg\n"; } $pos += $len; @@ -7453,17 +8592,19 @@ sub ProcessMOV($$;$) my $raf = $$dirInfo{RAF}; my $dataPt = $$dirInfo{DataPt}; my $verbose = $et->Options('Verbose'); + my $validate = $$et{OPTIONS}{Validate}; my $dataPos = $$dirInfo{Base} || 0; + my $dirID = $$dirInfo{DirID} || ''; my $charsetQuickTime = $et->Options('CharsetQuickTime'); my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index); - my ($dirEnd, $ee, $unkOpt, %saveOptions); + my ($dirEnd, $ee, $unkOpt, %saveOptions, $atomCount); my $topLevel = not $$et{InQuickTime}; $$et{InQuickTime} = 1; $$et{HandlerType} = $$et{MetaFormat} = '' unless defined $$et{HandlerType}; - unless (defined $$et{KeyCount}) { - $$et{KeyCount} = 0; # initialize ItemList key directory count + unless (defined $$et{KeysCount}) { + $$et{KeysCount} = 0; # initialize ItemList key directory count $doDefaultLang = 1; # flag to generate default language tags } # more convenient to package data as a RandomAccess file @@ -7525,9 +8666,13 @@ sub ProcessMOV($$;$) $unkOpt = $$et{OPTIONS}{Unknown}; require 'Image/ExifTool/QuickTimeStream.pl'; } - $index = $$tagTablePtr{VARS}{START_INDEX} if $$tagTablePtr{VARS}; + if ($$tagTablePtr{VARS}) { + $index = $$tagTablePtr{VARS}{START_INDEX}; + $atomCount = $$tagTablePtr{VARS}{ATOM_COUNT}; + } for (;;) { my ($eeTag, $ignore); + last if defined $atomCount and --$atomCount < 0; if ($size < 8) { if ($size == 0) { if ($dataPt) { @@ -7538,14 +8683,14 @@ sub ProcessMOV($$;$) my $str = $$dirInfo{DirName} . ' with ' . ($raf->Tell() - $pos) . ' bytes'; $et->VPrint(0,"$$et{INDENT}\[Terminator found in $str remaining]"); } else { - $tag = PrintableTagID($tag); - $et->VPrint(0,"$$et{INDENT}Tag '${tag}' extends to end of file"); + my $t = PrintableTagID($tag,2); + $et->VPrint(0,"$$et{INDENT}Tag '${t}' extends to end of file"); } last; } $size == 1 or $et->Warn('Invalid atom size'), last; # read extended atom size - $raf->Read($buff, 8) == 8 or last; + $raf->Read($buff, 8) == 8 or $et->Warn('Truncated atom header'), last; $dataPos += 8; my ($hi, $lo) = unpack('NN', $buff); if ($hi or $lo > 0x7fffffff) { @@ -7562,6 +8707,18 @@ sub ProcessMOV($$;$) } else { $size -= 8; } + if ($validate) { + $$et{ValidatePath} or $$et{ValidatePath} = { }; + my $path = join('-', @{$$et{PATH}}, $tag); + $path =~ s/-Track-/-$$et{SET_GROUP1}-/ if $$et{SET_GROUP1}; + if ($$et{ValidatePath}{$path} and not $dupTagOK{$tag} and not $dupDirOK{$dirID}) { + my $i = Get32u(\$tag,0); + my $str = $i < 255 ? "index $i" : "tag '" . PrintableTagID($tag,2) . "'"; + $et->WarnOnce("Duplicate $str at " . join('-', @{$$et{PATH}})); + $$et{ValidatePath} = { } if $path eq 'MOV-moov'; # avoid warnings for all contained dups + } + $$et{ValidatePath}{$path} = 1; + } if ($isUserData and $$et{SET_GROUP1}) { my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); # add track name to UserData tags inside tracks @@ -7580,10 +8737,13 @@ sub ProcessMOV($$;$) my $handlerType = $$et{HandlerType}; if ($eeBox{$handlerType} and $eeBox{$handlerType}{$tag}) { if ($ee) { - $eeTag = 1; - $$et{OPTIONS}{Unknown} = 1; # temporarily enable "Unknown" option + # (there is another 'gps ' box with a track log that doesn't contain offsets) + if ($tag ne 'gps ' or $eeBox{$handlerType}{$tag} eq $dirID) { + $eeTag = 1; + $$et{OPTIONS}{Unknown} = 1; # temporarily enable "Unknown" option + } } elsif ($handlerType ne 'vide' and not $$et{OPTIONS}{Validate}) { - $et->WarnOnce('The ExtractEmbedded option may find more tags in the movie data',3); + EEWarn($et); } } my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); @@ -7592,7 +8752,7 @@ sub ProcessMOV($$;$) # allow numerical tag ID's unless ($tagInfo) { - my $id = $$et{KeyCount} . '.' . unpack('N', $tag); + my $id = $$et{KeysCount} . '.' . unpack('N', $tag); if ($$tagTablePtr{$id}) { $tagInfo = $et->GetTagInfo($tagTablePtr, $id); $tag = $id; @@ -7624,9 +8784,21 @@ sub ProcessMOV($$;$) } # load values only if associated with a tag (or verbose) and not too big if ($size > 0x2000000) { # start to get worried above 32 MB + # check for RIFF trailer (written by Auto-Vox dashcam) + if ($buff =~ /^(gpsa|gps0|gsen|gsea)...\0/s) { # (yet seen only gpsa as first record) + $et->VPrint(0, "Found RIFF trailer"); + if ($et->Options('ExtractEmbedded')) { + $raf->Seek(-8, 1) or last; # seek back to start of trailer + my $tbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); + ProcessRIFFTrailer($et, { RAF => $raf }, $tbl); + } else { + EEWarn($et); + } + last; + } $ignore = 1; if ($tagInfo and not $$tagInfo{Unknown} and not $eeTag) { - my $t = PrintableTagID($tag); + my $t = PrintableTagID($tag,2); if ($size > 0x8000000) { $et->Warn("Skipping '${t}' atom > 128 MB", 1); } else { @@ -7638,7 +8810,7 @@ sub ProcessMOV($$;$) # set document number for this item property if necessary if ($$et{IsItemProperty}) { my $items = $$et{ItemInfo}; - my ($id, $prop, $mainItem, $docNum, $lowest); + my ($id, $prop, $docNum, $lowest); my $primary = $$et{PrimaryItem} || 0; ItemID: foreach $id (keys %$items) { next unless $$items{$id}{Association}; @@ -7655,7 +8827,7 @@ ItemID: foreach $id (keys %$items) { last ItemID; } elsif ($$item{DocNum}) { # this property is already associated with an item that has - # an ExifTool document number, so use the lowest assocated DocNum + # an ExifTool document number, so use the lowest associated DocNum $docNum = $$item{DocNum} if not defined $docNum or $docNum > $$item{DocNum}; } elsif (not defined $lowest or $lowest > $id) { # keep track of the lowest associated item ID @@ -7674,7 +8846,8 @@ ItemID: foreach $id (keys %$items) { my $val; my $missing = $size - $raf->Read($val, $size); if ($missing) { - $et->Warn("Truncated '${tag}' data (missing $missing bytes)"); + my $t = PrintableTagID($tag,2); + $et->Warn("Truncated '${t}' data (missing $missing bytes)"); last; } # use value to get tag info if necessary @@ -7693,6 +8866,24 @@ ItemID: foreach $id (keys %$items) { Format => $tagInfo ? $$tagInfo{Format} : undef, Index => $index, ); + # print iref item ID numbers + if ($dirID eq 'iref') { + my ($id, $count, @to, $i); + if ($$et{ItemRefVersion}) { + ($id, $count, @to) = unpack('NnN*', $val) if length $val >= 10; + } else { + ($id, $count, @to) = unpack('nnn*', $val) if length $val >= 6; + } + defined $id or $id = '<err>', $count = 0; + $id .= " (wrong count: $count)" if $count != @to; + # convert sequential numbers to a range + for ($i=1; $i<@to; ) { + $to[$i-1] =~ /(\d+)$/ and $to[$i] == $1 + 1 or ++$i, next; + $to[$i-1] =~ s/(-.*)?$/-$to[$i]/; + splice @to, $i, 1; + } + $et->VPrint(1, "$$et{INDENT} Item $id refers to: ",join(',',@to),"\n"); + } } # extract metadata from stream if ExtractEmbedded option is enabled if ($eeTag) { @@ -7750,6 +8941,7 @@ ItemID: foreach $id (keys %$items) { DirStart => $start, DirLen => $size - $start, DirName => $$subdir{DirName} || $$tagInfo{Name}, + DirID => $tag, HasData => $$subdir{HasData}, Multi => $$subdir{Multi}, IgnoreProp => $$subdir{IgnoreProp}, # (XML hack) @@ -7786,10 +8978,6 @@ ItemID: foreach $id (keys %$items) { } $$et{SET_GROUP1} = $oldGroup1; SetByteOrder('MM'); - if ($tag eq 'meta') { - # handle metadata now if we just processed the 'meta' box - HandleItemInfo($et, $raf) if $tag eq 'meta'; - } } elsif ($hasData) { # handle atoms containing 'data' tags # (currently ignore contained atoms: 'itif', 'name', etc.) @@ -7798,7 +8986,7 @@ ItemID: foreach $id (keys %$items) { last if $pos + 16 > $size; my ($len, $type, $flags, $ctry, $lang) = unpack("x${pos}Na4Nnn", $val); last if $pos + $len > $size; - my $value; + my ($value, $langInfo, $oldDir); my $format = $$tagInfo{Format}; if ($type eq 'data' and $len >= 16) { $pos += 16; @@ -7815,23 +9003,7 @@ ItemID: foreach $id (keys %$items) { # (shouldn't be null terminated, but some software writes it anyway) $value =~ s/\0$// unless $$tagInfo{Binary}; } else { - if (not $format) { - if ($flags == 0x15 or $flags == 0x16) { - $format = { 1=>'int8', 2=>'int16', 4=>'int32' }->{$len}; - $format .= $flags == 0x15 ? 's' : 'u' if $format; - } elsif ($flags == 0x17) { - $format = 'float'; - } elsif ($flags == 0x18) { - $format = 'double'; - } elsif ($flags == 0x00) { - # read 1 and 2-byte binary as integers - if ($len == 1) { - $format = 'int8u', - } elsif ($len == 2) { - $format = 'int16u', - } - } - } + $format = QuickTimeFormat($flags, $len) unless $format; if ($format) { $value = ReadValue(\$value, 0, $format, $$tagInfo{Count}, $len); } elsif (not $$tagInfo{ValueConv}) { @@ -7841,22 +9013,8 @@ ItemID: foreach $id (keys %$items) { } } } - my $langInfo; if ($ctry or $lang) { - # ignore country ('ctry') and language lists ('lang') for now - undef $ctry if $ctry and $ctry <= 255; - undef $lang if $lang and $lang <= 255; - $lang = UnpackLang($lang); - # add country code if specified - if ($ctry) { - $ctry = unpack('a2',pack('n',$ctry)); # unpack as ISO 3166-1 - # treat 'ZZ' like a default country (see ref 12) - undef $ctry if $ctry eq 'ZZ'; - if ($ctry and $ctry =~ /^[A-Z]{2}$/) { - $lang or $lang = 'und'; - $lang .= "-$ctry"; - } - } + $lang = GetLangCode($lang, $ctry); if ($lang) { # get tagInfo for other language $langInfo = GetLangInfoQT($et, $tagInfo, $lang); @@ -7876,9 +9034,16 @@ ItemID: foreach $id (keys %$items) { Size => $len, Format => $format, Index => $index, - Extra => sprintf(", Type='${type}', Flags=0x%x",$flags) + Extra => sprintf(", Type='${type}', Flags=0x%x%s",$flags,($lang ? ", Lang=$lang" : '')), ) if $verbose; + # use "Keys" in path instead of ItemList if this was defined by a Keys tag + my $isKey = $$tagInfo{Groups} && $$tagInfo{Groups}{1} && $$tagInfo{Groups}{1} eq 'Keys'; + if ($isKey) { + $oldDir = $$et{PATH}[-1]; + $$et{PATH}[-1] = 'Keys'; + } $et->FoundTag($langInfo, $value) if defined $value; + $$et{PATH}[-1] = $oldDir if $isKey; $pos += $len; } } elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) { @@ -7889,28 +9054,43 @@ ItemID: foreach $id (keys %$items) { $pos = $size; } for (;;) { - last if $pos + 4 > $size; - my ($len, $lang) = unpack("x${pos}nn", $val); - $pos += 4; - # according to the QuickTime spec (ref 12), $len should include - # 4 bytes for length and type words, but nobody (including - # Apple, Pentax and Kodak) seems to add these in, so try - # to allow for either - if ($pos + $len > $size) { - $len -= 4; - last if $pos + $len > $size or $len < 0; + my ($len, $lang); + if ($$tagInfo{IText} and $$tagInfo{IText} == 6) { + last if $pos + 6 > $size; + $pos += 4; + $lang = unpack("x${pos}n", $val); + $pos += 2; + $len = $size - $pos; + } else { + last if $pos + 4 > $size; + ($len, $lang) = unpack("x${pos}nn", $val); + $pos += 4; + # according to the QuickTime spec (ref 12), $len should include + # 4 bytes for length and type words, but nobody (including + # Apple, Pentax and Kodak) seems to add these in, so try + # to allow for either + if ($pos + $len > $size) { + $len -= 4; + last if $pos + $len > $size or $len < 0; + } } # ignore any empty entries (or null padding) after the first next if not $len and $pos; my $str = substr($val, $pos, $len); my $langInfo; - if ($lang < 0x400) { + if (($lang < 0x400 or $lang == 0x7fff) and $str !~ /^\xfe\xff/) { # this is a Macintosh language code # a language code of 0 is Macintosh english, so treat as default if ($lang) { - # use Font.pm to look up language string - require Image::ExifTool::Font; - $lang = $Image::ExifTool::Font::ttLang{Macintosh}{$lang}; + if ($lang == 0x7fff) { + # technically, ISO 639-2 doesn't have a 2-character + # equivalent for 'und', but use 'un' anyway + $lang = 'un'; + } else { + # use Font.pm to look up language string + require Image::ExifTool::Font; + $lang = $Image::ExifTool::Font::ttLang{Macintosh}{$lang}; + } } # the spec says only "Macintosh text encoding", but # allow this to be configured by the user @@ -7922,6 +9102,7 @@ ItemID: foreach $id (keys %$items) { my $enc = $str=~s/^\xfe\xff// ? 'UTF16' : 'UTF8'; $str = $et->Decode($str, $enc); } + $str =~ s/\0+$//; # remove any trailing nulls (eg. 3gp tags) $langInfo = GetLangInfoQT($et, $tagInfo, $lang) if $lang; $et->FoundTag($langInfo || $tagInfo, $str); $pos += $len; @@ -7959,7 +9140,11 @@ ItemID: foreach $id (keys %$items) { Size => $size, Extra => sprintf(' at offset 0x%.4x', $raf->Tell()), ) if $verbose; - $raf->Seek($size, 1) or $et->Warn("Truncated '${tag}' data"), last; + if ($size and (not $raf->Seek($size-1, 1) or $raf->Read($buff, 1) != 1)) { + my $t = PrintableTagID($tag,2); + $et->Warn("Truncated '${t}' data"); + last; + } } $dataPos += $size + 8; # point to start of next atom data last if $dirEnd and $dataPos >= $dirEnd; # (note: ignores last value if 0 bytes) @@ -7986,10 +9171,11 @@ QTLang: foreach $tag (@{$$et{QTLang}}) { } delete $$et{QTLang}; } - if ($topLevel) { - HandleItemInfo($et, $raf); # process our item information - ScanMovieData($et) if $ee; # brute force scan for metadata embedded in movie data - } + # process item information now that we are done processing its 'meta' container + HandleItemInfo($et) if $topLevel or $dirID eq 'meta'; + + ScanMediaData($et) if $ee and $topLevel; # brute force scan for metadata embedded in media data + # restore any changed options $et->Options($_ => $saveOptions{$_}) foreach keys %saveOptions; return 1; @@ -8025,7 +9211,7 @@ information from QuickTime and MP4 video, M4A audio, and HEIC image files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/QuickTimeStream.pl b/src/Image-ExifTool/lib/Image/ExifTool/QuickTimeStream.pl new file mode 100644 index 00000000..1f2546b4 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/QuickTimeStream.pl @@ -0,0 +1,2266 @@ +#------------------------------------------------------------------------------ +# File: QuickTimeStream.pl +# +# Description: Extract embedded information from QuickTime media data +# +# Revisions: 2018-01-03 - P. Harvey Created +# +# References: 1) https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-SW130 +# 2) http://sergei.nz/files/nvtk_mp42gpx.py +# 3) https://forum.flitsservice.nl/dashcam-info/dod-ls460w-gps-data-uit-mov-bestand-lezen-t87926.html +# 4) https://developers.google.com/streetview/publish/camm-spec +# 5) https://sergei.nz/extracting-gps-data-from-viofo-a119-and-other-novatek-powered-cameras/ +#------------------------------------------------------------------------------ +package Image::ExifTool::QuickTime; + +use strict; + +use Image::ExifTool qw(:DataAccess :Utils); +use Image::ExifTool::QuickTime; + +sub Process_tx3g($$$); +sub Process_mebx($$$); +sub ProcessFreeGPS($$$); +sub ProcessFreeGPS2($$$); + +# QuickTime data types that have ExifTool equivalents +# (ref https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35) +my %qtFmt = ( + 0 => 'undef', + 1 => 'string', # (UTF-8) + # 2 - UTF-16 + # 3 - shift-JIS + # 4 - UTF-8 sort + # 5 - UTF-16 sort + # 13 - JPEG image + # 14 - PNG image + # 21 - signed integer (1,2,3 or 4 bytes) + # 22 - unsigned integer (1,2,3 or 4 bytes) + 23 => 'float', + 24 => 'double', + # 27 - BMP image + # 28 - QuickTime atom + 65 => 'int8s', + 66 => 'int16s', + 67 => 'int32s', + 70 => 'float', # float[2] x,y + 71 => 'float', # float[2] width,height + 72 => 'float', # float[4] x,y,width,height + 74 => 'int64s', + 75 => 'int8u', + 76 => 'int16u', + 77 => 'int32u', + 78 => 'int64u', + 79 => 'float', # float[9] transform matrix + 80 => 'float', # float[8] face coordinates +); + +# maximums for validating H,M,S,d,m,Y from "freeGPS " metadata +my @dateMax = ( 24, 59, 59, 2200, 12, 31 ); + +# typical (minimum?) size of freeGPS block +my $gpsBlockSize = 0x8000; + +# conversion factors +my $knotsToKph = 1.852; # knots --> km/h +my $mpsToKph = 3.6; # m/s --> km/h + +# handler types to process based on MetaFormat/OtherFormat +my %processByMetaFormat = ( + meta => 1, # ('CTMD' in CR3 images, 'priv' unknown in DJI video) + data => 1, # ('RVMI') + sbtl => 1, # (subtitle; 'tx3g' in Yuneec drone videos) +); + +# data lengths for each INSV record type +my %insvDataLen = ( + 0x300 => 56, # accelerometer + 0x400 => 16, # unknown + 0x700 => 53, # GPS +); + +# limit the default amount of data we read for some record types +# (to avoid running out of memory) +my %insvLimit = ( + 0x300 => [ 'accelerometer', 20000 ], # maximum of 20000 accelerometer records +); + +# tags extracted from various QuickTime data streams +%Image::ExifTool::QuickTime::Stream = ( + GROUPS => { 2 => 'Location' }, + NOTES => q{ + Timed metadata extracted from QuickTime media data and some AVI videos when + the ExtractEmbedded option is used. Although most of these tags are + combined into the single table below, ExifTool currently reads 37 different + formats of timed GPS metadata from video files. + }, + VARS => { NO_ID => 1 }, + GPSLatitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', RawConv => '$$self{FoundGPSLatitude} = 1; $val' }, + GPSLongitude => { PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' }, + GPSAltitude => { PrintConv => '(sprintf("%.4f", $val) + 0) . " m"' }, # round to 4 decimals + GPSSpeed => { PrintConv => 'sprintf("%.4f", $val) + 0' }, # round to 4 decimals + GPSSpeedRef => { PrintConv => { K => 'km/h', M => 'mph', N => 'knots' } }, + GPSTrack => { PrintConv => 'sprintf("%.4f", $val) + 0' }, # round to 4 decimals + GPSTrackRef => { PrintConv => { M => 'Magnetic North', T => 'True North' } }, + GPSDateTime => { + Groups => { 2 => 'Time' }, + Description => 'GPS Date/Time', + RawConv => '$$self{FoundGPSDateTime} = 1; $val', + PrintConv => '$self->ConvertDateTime($val)', + }, + GPSTimeStamp => { PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)', Groups => { 2 => 'Time' } }, + GPSSatellites=> { }, + GPSDOP => { Description => 'GPS Dilution Of Precision' }, + Distance => { PrintConv => '"$val m"' }, + VerticalSpeed=> { PrintConv => '"$val m/s"' }, + FNumber => { PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)', Groups => { 2 => 'Camera' } }, + ExposureTime => { PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', Groups => { 2 => 'Camera' } }, + ExposureCompensation => { PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)', Groups => { 2 => 'Camera' } }, + ISO => { Groups => { 2 => 'Camera' } }, + CameraDateTime=>{ PrintConv => '$self->ConvertDateTime($val)', Groups => { 2 => 'Time' } }, + Accelerometer=> { Notes => '3-axis acceleration in units of g' }, + AccelerometerData => { }, + AngularVelocity => { }, + GSensor => { }, + Car => { }, + RawGSensor => { + # (same as GSensor, but offset by some unknown value) + ValueConv => 'my @a=split " ",$val; $_/=1000 foreach @a; "@a"', + }, + Text => { Groups => { 2 => 'Other' } }, + TimeCode => { Groups => { 2 => 'Video' } }, + FrameNumber => { Groups => { 2 => 'Video' } }, + SampleTime => { Groups => { 2 => 'Video' }, PrintConv => 'ConvertDuration($val)', Notes => 'sample decoding time' }, + SampleDuration=>{ Groups => { 2 => 'Video' }, PrintConv => 'ConvertDuration($val)' }, + UserLabel => { Groups => { 2 => 'Other' } }, +# +# timed metadata decoded based on MetaFormat (format of 'meta' or 'data' sample description) +# [or HandlerType, or specific 'vide' type if specified] +# + mebx => { + Name => 'mebx', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Keys', + ProcessProc => \&Process_mebx, + }, + }, + gpmd => { + Name => 'gpmd', + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' }, + }, + fdsc => { + Name => 'fdsc', + Condition => '$$valPt =~ /^GPRO/', + # (other types of "fdsc" samples aren't yet parsed: /^GP\x00/ and /^GP\x04/) + SubDirectory => { TagTable => 'Image::ExifTool::GoPro::fdsc' }, + }, + rtmd => { + Name => 'rtmd', + SubDirectory => { TagTable => 'Image::ExifTool::Sony::rtmd' }, + }, + CTMD => { # (Canon Timed MetaData) + Name => 'CTMD', + SubDirectory => { TagTable => 'Image::ExifTool::Canon::CTMD' }, + }, + tx3g => { + Name => 'tx3g', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::tx3g' }, + }, + RVMI => [{ # data "OtherFormat" written by unknown software + Name => 'RVMI_gReV', + Condition => '$$valPt =~ /^gReV/', # GPS data + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::RVMI_gReV', + ByteOrder => 'Little-endian', + }, + },{ + Name => 'RVMI_sReV', + Condition => '$$valPt =~ /^sReV/', # sensor data + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::RVMI_sReV', + ByteOrder => 'Little-endian', + }, + # (there is also "tReV" data that hasn't been decoded yet) + }], + camm => [{ + Name => 'camm0', + # (according to the spec. the first 2 bytes are reserved and should be zero, + # but I have a sample where these bytes are non-zero, so allow anything here) + Condition => '$$valPt =~ /^..\0\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm0', + ByteOrder => 'Little-Endian', + }, + },{ + Name => 'camm1', + Condition => '$$valPt =~ /^..\x01\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm1', + ByteOrder => 'Little-Endian', + }, + },{ # (written by Insta360) - [HandlerType, not MetaFormat] + Name => 'camm2', + Condition => '$$valPt =~ /^..\x02\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm2', + ByteOrder => 'Little-Endian', + }, + },{ + Name => 'camm3', + Condition => '$$valPt =~ /^..\x03\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm3', + ByteOrder => 'Little-Endian', + }, + },{ + Name => 'camm4', + Condition => '$$valPt =~ /^..\x04\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm4', + ByteOrder => 'Little-Endian', + }, + },{ + Name => 'camm5', + Condition => '$$valPt =~ /^..\x05\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm5', + ByteOrder => 'Little-Endian', + }, + },{ + Name => 'camm6', + Condition => '$$valPt =~ /^..\x06\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm6', + ByteOrder => 'Little-Endian', + }, + },{ + Name => 'camm7', + Condition => '$$valPt =~ /^..\x07\0/s', + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::camm7', + ByteOrder => 'Little-Endian', + }, + }], + mett => { # Parrot drones + Name => 'mett', + SubDirectory => { TagTable => 'Image::ExifTool::Parrot::mett' }, + }, + JPEG => { # (in CR3 images) - [vide HandlerType with JPEG in SampleDescription, not MetaFormat] + Name => 'JpgFromRaw', + Groups => { 2 => 'Preview' }, + RawConv => '$self->ValidateImage(\$val,$tag)', + }, + text => { # (TomTom Bandit MP4) - [sbtl HandlerType with 'text' in SampleDescription] + Name => 'PreviewInfo', + Condition => 'length $$valPt > 12 and Get32u($valPt,4) == length($$valPt) and $$valPt =~ /^.{8}\xff\xd8\xff/s', + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::PreviewInfo' }, + }, + INSV => { + Groups => { 0 => 'Trailer', 1 => 'Insta360' }, # (so these groups will appear in the -listg options) + SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::INSV_MakerNotes' }, + }, + Unknown00 => { Unknown => 1 }, + Unknown01 => { Unknown => 1 }, + Unknown02 => { Unknown => 1 }, + Unknown03 => { Unknown => 1 }, +); + +# tags found in 'camm' type 0 timed metadata (ref 4) +%Image::ExifTool::QuickTime::camm0 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + NOTES => q{ + The camm0 through camm7 tables define tags extracted from the Google Street + View Camera Motion Metadata of MP4 videos. See + L<https://developers.google.com/streetview/publish/camm-spec> for the + specification. + }, + 4 => { + Name => 'AngleAxis', + Notes => 'angle axis orientation in radians in local coordinate system', + Format => 'float[3]', + }, +); + +# tags found in 'camm' type 1 timed metadata (ref 4) +%Image::ExifTool::QuickTime::camm1 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Camera' }, + FIRST_ENTRY => 0, + 4 => { + Name => 'PixelExposureTime', + Format => 'int32s', + ValueConv => '$val * 1e-9', + PrintConv => 'sprintf("%.4g ms", $val * 1000)', + }, + 8 => { + Name => 'RollingShutterSkewTime', + Format => 'int32s', + ValueConv => '$val * 1e-9', + PrintConv => 'sprintf("%.4g ms", $val * 1000)', + }, +); + +# tags found in 'camm' type 2 timed metadata (ref PH, Insta360Pro) +%Image::ExifTool::QuickTime::camm2 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + 4 => { + Name => 'AngularVelocity', + Notes => 'gyro angular velocity about X, Y and Z axes in rad/s', + Format => 'float[3]', + }, +); + +# tags found in 'camm' type 3 timed metadata (ref PH, Insta360Pro) +%Image::ExifTool::QuickTime::camm3 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + 4 => { + Name => 'Acceleration', + Notes => 'acceleration in the X, Y and Z directions in m/s^2', + Format => 'float[3]', + }, +); + +# tags found in 'camm' type 4 timed metadata (ref 4) +%Image::ExifTool::QuickTime::camm4 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + 4 => { + Name => 'Position', + Notes => 'X, Y, Z position in local coordinate system', + Format => 'float[3]', + }, +); + +# tags found in 'camm' type 5 timed metadata (ref 4) +%Image::ExifTool::QuickTime::camm5 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + 4 => { + Name => 'GPSLatitude', + Format => 'double', + RawConv => '$$self{FoundGPSLatitude} = 1; $val', + ValueConv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 12 => { + Name => 'GPSLongitude', + Format => 'double', + ValueConv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 20 => { + Name => 'GPSAltitude', + Format => 'double', + PrintConv => '$_ = sprintf("%.6f", $val); s/\.?0+$//; "$_ m"', + }, +); + +# tags found in 'camm' type 6 timed metadata (ref PH/4, Insta360) +%Image::ExifTool::QuickTime::camm6 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + 0x04 => { + Name => 'GPSDateTime', + Description => 'GPS Date/Time', + Groups => { 2 => 'Time' }, + Format => 'double', + RawConv => '$$self{FoundGPSDateTime} = 1; $val', + ValueConv => q{ + my $str = ConvertUnixTime($val); + my $frac = $val - int($val); + if ($frac != 0) { + $frac = sprintf('%.6f', $frac); + $frac =~ s/^0//; + $frac =~ s/0+$//; + $str .= $frac; + } + return $str . 'Z'; + }, + PrintConv => '$self->ConvertDateTime($val)', + }, + 0x0c => { + Name => 'GPSMeasureMode', + Format => 'int32u', + PrintConv => { + 0 => 'No Measurement', + 2 => '2-Dimensional Measurement', + 3 => '3-Dimensional Measurement', + }, + }, + 0x10 => { + Name => 'GPSLatitude', + Format => 'double', + RawConv => '$$self{FoundGPSLatitude} = 1; $val', + ValueConv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 0x18 => { + Name => 'GPSLongitude', + Format => 'double', + ValueConv => 'Image::ExifTool::GPS::ToDegrees($val, 1)', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + 0x20 => { + Name => 'GPSAltitude', + Format => 'float', + PrintConv => '$_ = sprintf("%.3f", $val); s/\.?0+$//; "$_ m"', + }, + 0x24 => { Name => 'GPSHorizontalAccuracy', Format => 'float', Notes => 'metres' }, + 0x28 => { Name => 'GPSVerticalAccuracy', Format => 'float' }, + 0x2c => { Name => 'GPSVelocityEast', Format => 'float', Notes => 'm/s' }, + 0x30 => { Name => 'GPSVelocityNorth', Format => 'float' }, + 0x34 => { Name => 'GPSVelocityUp', Format => 'float' }, + 0x38 => { Name => 'GPSSpeedAccuracy', Format => 'float' }, +); + +# tags found in 'camm' type 7 timed metadata (ref 4) +%Image::ExifTool::QuickTime::camm7 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + 4 => { + Name => 'MagneticField', + Format => 'float[3]', + Notes => 'microtesla', + }, +); + +# preview image stored by TomTom Bandit ActionCam +%Image::ExifTool::QuickTime::PreviewInfo = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + FIRST_ENTRY => 0, + NOTES => 'Preview stored by TomTom Bandit ActionCam.', + 8 => { + Name => 'PreviewImage', + Groups => { 2 => 'Preview' }, + Binary => 1, + Format => 'undef[$size-8]', + }, +); + +# tags found in 'RVMI' 'gReV' timed metadata (ref PH) +%Image::ExifTool::QuickTime::RVMI_gReV = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + NOTES => 'GPS information extracted from the RVMI box of MOV videos.', + 4 => { + Name => 'GPSLatitude', + Format => 'int32s', + RawConv => '$$self{FoundGPSLatitude} = 1; $val', + ValueConv => 'Image::ExifTool::GPS::ToDegrees($val/1e6, 1)', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + 8 => { + Name => 'GPSLongitude', + Format => 'int32s', + ValueConv => 'Image::ExifTool::GPS::ToDegrees($val/1e6, 1)', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + # 12 - int32s: space for altitude? (always zero in my sample) + 16 => { + Name => 'GPSSpeed', # km/h + Format => 'int16s', + ValueConv => '$val / 10', + }, + 18 => { + Name => 'GPSTrack', + Format => 'int16u', + ValueConv => '$val * 2', + }, +); + +# tags found in 'RVMI' 'sReV' timed metadata (ref PH) +%Image::ExifTool::QuickTime::RVMI_sReV = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + NOTES => q{ + G-sensor information extracted from the RVMI box of MOV videos. + }, + 4 => { + Name => 'GSensor', + Format => 'int16s[3]', # X Y Z + ValueConv => 'my @a=split " ",$val; $_/=1000 foreach @a; "@a"', + }, +); + +# tags found in 'tx3g' sbtl timed metadata (ref PH) +%Image::ExifTool::QuickTime::tx3g = ( + PROCESS_PROC => \&Process_tx3g, + GROUPS => { 2 => 'Location' }, + FIRST_ENTRY => 0, + NOTES => 'Tags extracted from the tx3g sbtl timed metadata of Yuneec drones.', + Lat => { + Name => 'GPSLatitude', + RawConv => '$$self{FoundGPSLatitude} = 1; $val', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")', + }, + Lon => { + Name => 'GPSLongitude', + PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")', + }, + Alt => { + Name => 'GPSAltitude', + ValueConv => '$val =~ s/\s*m$//; $val', # remove " m" + PrintConv => '"$val m"', # add it back again + }, + Yaw => 'Yaw', + Pitch => 'Pitch', + Roll => 'Roll', + GimYaw => 'GimbalYaw', + GimPitch => 'GimbalPitch', + GimRoll => 'GimbalRoll', +); + +%Image::ExifTool::QuickTime::INSV_MakerNotes = ( + GROUPS => { 1 => 'MakerNotes', 2 => 'Camera' }, + 0x0a => 'SerialNumber', + 0x12 => 'Model', + 0x1a => 'Firmware', + 0x2a => { + Name => 'Parameters', + ValueConv => '$val =~ tr/_/ /; $val', + }, +); + +#------------------------------------------------------------------------------ +# Save information from keys in OtherSampleDesc directory for processing timed metadata +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +# (ref "Timed Metadata Media" here: +# https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html) +sub SaveMetaKeys($$$) +{ + local $_; + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = length $$dataPt; + return 0 unless $dirLen > 8; + my $pos = 0; + my $verbose = $$et{OPTIONS}{Verbose}; + my $oldIndent = $$et{INDENT}; + my $ee = $$et{ee}; + $ee or $ee = $$et{ee} = { }; + + $verbose and $et->VerboseDir($$dirInfo{DirName}, undef, $dirLen); + + # loop through metadata key table + while ($pos + 8 < $dirLen) { + my $size = Get32u($dataPt, $pos); + my $id = substr($$dataPt, $pos+4, 4); + my $end = $pos + $size; + $end = $dirLen if $end > $dirLen; + $pos += 8; + my ($tagID, $format, $pid); + if ($verbose) { + $pid = PrintableTagID($id,1); + $et->VPrint(0, "$oldIndent+ [Metadata Key entry, Local ID=$pid, $size bytes]\n"); + $$et{INDENT} .= '| '; + } + + while ($pos + 4 < $end) { + my $len = unpack("x${pos}N", $$dataPt); + last if $len < 8 or $pos + $len > $end; + my $tag = substr($$dataPt, $pos + 4, 4); + $pos += 8; $len -= 8; + my $val = substr($$dataPt, $pos, $len); + $pos += $len; + my $str; + if ($tag eq 'keyd') { + ($tagID = $val) =~ s/^(mdta|fiel)com\.apple\.quicktime\.//; + $tagID = "Tag_$val" unless $tagID; + ($str = $val) =~ s/(.{4})/$1 / if $verbose; + } elsif ($tag eq 'dtyp') { + next if length $val < 4; + if (length $val >= 4) { + my $ns = unpack('N', $val); + if ($ns == 0) { + length $val >= 8 or $et->Warn('Short dtyp data'), next; + $str = unpack('x4N',$val); + $format = $qtFmt{$str} || 'undef'; + } elsif ($ns == 1) { + $str = substr($val, 4); + $format = 'undef'; + } else { + $format = 'undef'; + } + $str .= " ($format)" if $verbose and defined $str; + } + } + if ($verbose > 1) { + if (defined $str) { + $str =~ tr/\x00-\x1f\x7f-\xff/./; + $str = " = $str"; + } else { + $str = ''; + } + $et->VPrint(1, $$et{INDENT}."- Tag '".PrintableTagID($tag,2)."' ($len bytes)$str\n"); + $et->VerboseDump(\$val); + } + } + if (defined $tagID and defined $format) { + if ($verbose) { + my $t2 = PrintableTagID($tagID); + $et->VPrint(0, "$$et{INDENT}Added Local ID $pid = $t2 ($format)\n"); + } + $$ee{'keys'}{$id} = { TagID => $tagID, Format => $format }; + } + $$et{INDENT} = $oldIndent; + } + return 1; +} + +#------------------------------------------------------------------------------ +# We found some tags for this sample, so set document number and save timing information +# Inputs: 0) ExifTool ref, 1) tag table ref, 2) sample time, 3) sample duration +sub FoundSomething($$;$$) +{ + my ($et, $tagTbl, $time, $dur) = @_; + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + $et->HandleTag($tagTbl, SampleTime => $time) if defined $time; + $et->HandleTag($tagTbl, SampleDuration => $dur) if defined $dur; +} + +#------------------------------------------------------------------------------ +# Approximate GPSDateTime value from sample time and CreateDate +# Inputs: 0) ExifTool ref, 1) tag table ptr, 2) sample time (ms) +# 3) true if CreateDate is at end of video +# Notes: Uses ExifTool CreateDateAtEnd as flag to subtract video duration +sub SetGPSDateTime($$$) +{ + my ($et, $tagTbl, $sampleTime) = @_; + my $value = $$et{VALUE}; + if (defined $sampleTime and $$value{CreateDate}) { + $sampleTime += $$value{CreateDate}; # adjust sample time to seconds since the epoch + if ($$et{CreateDateAtEnd}) { # adjust if CreateDate is at end of video + return unless $$value{TimeScale} and $$value{Duration}; + $sampleTime -= $$value{Duration} / $$value{TimeScale}; + $et->WarnOnce('Approximating GPSDateTime as CreateDate - Duration + SampleTime', 1); + } else { + $et->WarnOnce('Approximating GPSDateTime as CreateDate + SampleTime', 1); + } + unless ($et->Options('QuickTimeUTC')) { + my $tzOff = $$et{tzOff}; # use previously calculated offset + unless (defined $tzOff) { + # adjust to UTC, assuming time is local + my @tm = localtime $$value{CreateDate}; + my @gm = gmtime $$value{CreateDate}; + $tzOff = $$et{tzOff} = Image::ExifTool::GetTimeZone(\@tm, \@gm) * 60; + } + $sampleTime -= $tzOff; # shift from local time to UTC + } + $et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($sampleTime,0,3) . 'Z'); + } +} + +#------------------------------------------------------------------------------ +# Process subtitle 'text' +# Inputs: 0) ExifTool ref, 1) tag table ref, 2) data ref, 3) optional sample time +sub Process_text($$$) +{ + my ($et, $tagTbl, $buffPt) = @_; + my ($found, $val, %tags, $tag); + + return if $$et{NoMoreTextDecoding}; + + while ($$buffPt =~ /\$(\w+)([^\$]*)/g) { + my ($tag, $dat) = ($1, $2); + if ($tag =~ /^[A-Z]{2}RMC$/ and $dat =~ /^,(\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+)/) { + my $year = $15 + ($15 >= 70 ? 1900 : 2000); + my $str = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d%sZ', $year, $14, $13, $1, $2, $3, $4 || ''); + $et->HandleTag($tagTbl, GPSDateTime => $str); + $et->HandleTag($tagTbl, GPSLatitude => (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1)); + $et->HandleTag($tagTbl, GPSLongitude => (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1)); + if (length $11) { + $et->HandleTag($tagTbl, GPSSpeed => $11 * $knotsToKph); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + } + if (length $12) { + $et->HandleTag($tagTbl, GPSTrack => $12); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + } + $found = 1; + } elsif ($tag eq 'BEGINGSENSOR' and $dat =~ /^:([-+]\d+\.\d+):([-+]\d+\.\d+):([-+]\d+\.\d+)/) { + $et->HandleTag($tagTbl, Accelerometer => "$1 $2 $3"); + $found = 1; + } elsif ($tag eq 'TIME' and $dat =~ /^:(\d+)/) { + $et->HandleTag($tagTbl, TimeCode => $1 / ($$et{MediaTS} || 1)); + $found = 1; + } elsif ($tag eq 'BEGIN') { + $et->HandleTag($tagTbl, Text => $dat) if length $dat; + $found = 1; + } elsif ($tag ne 'END') { + $et->HandleTag($tagTbl, Text => "\$$tag$dat"); + $found = 1; + } + } + return if $found; + + # check for enciphered binary GPS data + # BlueSkySea: + # 0000: 00 00 aa aa aa aa 54 54 98 9a 9b 93 9a 92 98 9a [......TT........] + # 0010: 9a 9d 9f 9b 9f 9d aa aa aa aa aa aa aa aa aa aa [................] + # 0020: aa aa aa aa aa a9 e4 9e 92 9f 9b 9f 92 9d 99 ef [................] + # 0030: 9a 9a 98 9b 93 9d 9d 9c 93 aa aa aa aa aa 9a 99 [................] + # 0040: 9b aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa [................] + # [...] + # decrypted: + # 0000: aa aa 00 00 00 00 fe fe 32 30 31 39 30 38 32 30 [........20190820] + # 0010: 30 37 35 31 35 37 00 00 00 00 00 00 00 00 00 00 [075157..........] + # 0020: 00 00 00 00 00 03 4e 34 38 35 31 35 38 37 33 45 [......N48515873E] + # 0030: 30 30 32 31 39 37 37 36 39 00 00 00 00 00 30 33 [002197769.....03] + # 0040: 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [1...............] + # [...] + # Ambarella A12: + # 0000: 00 00 f2 e1 f0 ee 54 54 98 9a 9b 93 9b 9b 9b 9c [......TT........] + # 0010: 9b 9a 9a 93 9a 9b a6 9a 9b 9b 93 9b 9a 9b 9c 9a [................] + # 0020: 9d 9a 92 9f 93 a9 e4 9f 9f 9e 9f 9b 9b 9c 9d ef [................] + # 0030: 9a 99 9d 9e 99 9a 9a 9e 9b 81 9a 9b 9f 9d 9a 9a [................] + # 0040: 9a 87 9a 9a 9a 87 9a 98 99 87 9a 9a 99 87 9a 9a [................] + # [...] + # decrypted: + # 0000: aa aa 58 4b 5a 44 fe fe 32 30 31 39 31 31 31 36 [..XKZD..20191116] + # 0010: 31 30 30 39 30 31 0c 30 31 31 39 31 30 31 36 30 [100901.011910160] + # 0020: 37 30 38 35 39 03 4e 35 35 34 35 31 31 36 37 45 [70859.N55451167E] + # 0030: 30 33 37 34 33 30 30 34 31 2b 30 31 35 37 30 30 [037430041+015700] + # 0040: 30 2d 30 30 30 2d 30 32 33 2d 30 30 33 2d 30 30 [0-000-023-003-00] + # [...] + # 0100: aa 55 57 ed ed 45 58 54 44 00 01 30 30 30 30 31 [.UW..EXTD..00001] + # 0110: 31 30 38 30 30 30 58 00 58 00 58 00 58 00 58 00 [108000X.X.X.X.X.] + # 0120: 58 00 58 00 58 00 58 00 00 00 00 00 00 00 00 00 [X.X.X.X.........] + # 0130: 00 00 00 00 00 00 00 [.......] + if ($$buffPt =~ /^\0\0(..\xaa\xaa|\xf2\xe1\xf0\xee)/s and length $$buffPt >= 282) { + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 8, 14))); + if ($val =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/) { + $tags{GPSDateTime} = "$1:$2:$3 $4:$5:$6"; + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 38, 9))); + if ($val =~ /^([NS])(\d{2})(\d+$)$/) { + $tags{GPSLatitude} = ($2 + $3 / 600000) * ($1 eq 'S' ? -1 : 1); + } + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 47, 10))); + if ($val =~ /^([EW])(\d{3})(\d+$)$/) { + $tags{GPSLongitude} = ($2 + $3 / 600000) * ($1 eq 'W' ? -1 : 1); + } + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0x39, 5))); + $tags{GPSAltitude} = $val + 0 if $val =~ /^[-+]\d+$/; + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0x3e, 3))); + if ($val =~ /^\d+$/) { + $tags{GPSSpeed} = $val + 0; + $tags{GPSSpeedRef} = 'K'; + } + if ($$buffPt =~ /^\0\0..\xaa\xaa/s) { # (BlueSkySea) + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0xad, 12))); + # the first X,Y,Z accelerometer readings from the AccelerometerData + if ($val =~ /^([-+]\d{3})([-+]\d{3})([-+]\d{3})$/) { + $tags{Accelerometer} = "$1 $2 $3"; + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0xba, 96))); + my $order = GetByteOrder(); + SetByteOrder('II'); + $val = ReadValue(\$val, 0, 'float'); + SetByteOrder($order); + $tags{AccelerometerData} = $val; + } + } else { # (Ambarella) + my @acc; + $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$buffPt, 0x41, 195))); + push @acc, $1, $2, $3 while $val =~ /\G([-+]\d{3})([-+]\d{3})([-+]\d{3})/g; + $tags{Accelerometer} = "@acc" if @acc; + } + } + } + + # check for DJI telemetry data, eg: + # "F/3.5, SS 1000, ISO 100, EV 0, GPS (8.6499, 53.1665, 18), D 24.26m, + # H 6.00m, H.S 2.10m/s, V.S 0.00m/s \n" + if (not %tags and $$buffPt =~ /GPS \(([-+]?\d*\.\d+),\s*([-+]?\d*\.\d+)/) { + $$et{CreateDateAtEnd} = 1; # set flag indicating the file creation date is at the end + $tags{GPSLatitude} = $2; + $tags{GPSLongitude} = $1; + $tags{GPSAltitude} = $1 if $$buffPt =~ /,\s*H\s+([-+]?\d+\.?\d*)m/; + if ($$buffPt =~ /,\s*H.S\s+([-+]?\d+\.?\d*)/) { + $tags{GPSSpeed} = $1 * $mpsToKph; + $tags{GPSSpeedRef} = 'K'; + } + $tags{Distance} = $1 * $mpsToKph if $$buffPt =~ /,\s*D\s+(\d+\.?\d*)m/; + $tags{VerticalSpeed} = $1 if $$buffPt =~ /,\s*V.S\s+([-+]?\d+\.?\d*)/; + $tags{FNumber} = $1 if $$buffPt =~ /\bF\/(\d+\.?\d*)/; + $tags{ExposureTime} = 1 / $1 if $$buffPt =~ /\bSS\s+(\d+\.?\d*)/; + $tags{ExposureCompensation} = ($1 / ($2 || 1)) if $$buffPt =~ /\bEV\s+([-+]?\d+\.?\d*)(\/\d+)?/; + $tags{ISO} = $1 if $$buffPt =~ /\bISO\s+(\d+\.?\d*)/; + } + + # check for Mini 0806 dashcam GPS, eg: + # "A,270519,201555.000,3356.8925,N,08420.2071,W,000.0,331.0M,+01.84,-09.80,-00.61;\n" + if (not %tags and $$buffPt =~ /^A,(\d{2})(\d{2})(\d{2}),(\d{2})(\d{2})(\d{2}(\.\d+)?)/) { + $tags{GPSDateTime} = "20$3:$2:$1 $4:$5:$6Z"; + if ($$buffPt =~ /^A,.*?,.*?,(\d{2})(\d+\.\d+),([NS])/) { + $tags{GPSLatitude} = ($1 + $2/60) * ($3 eq 'S' ? -1 : 1); + } + if ($$buffPt =~ /^A,.*?,.*?,.*?,.*?,(\d{3})(\d+\.\d+),([EW])/) { + $tags{GPSLongitude} = ($1 + $2/60) * ($3 eq 'W' ? -1 : 1); + } + my @a = split ',', $$buffPt; + $tags{GPSAltitude} = $a[8] if $a[8] and $a[8] =~ s/M$//; + $tags{GPSSpeed} = $a[7] if $a[7] and $a[7] =~ /^\d+\.\d+$/; # (NC) + $tags{Accelerometer} = "$a[9] $a[10] $a[11]" if $a[11] and $a[11] =~ s/;\s*$//; + } + + # check for Thinkware format, eg: + # "gsensori,4,512,-67,-12,100;GNRMC,161313.00,A,4529.87489,N,07337.01215,W,6.225,35.34,310819,,,A*52..; + # CAR,0,0,0,0.0,0,0,0,0,0,0,0,0" + unless (%tags) { + if ($$buffPt =~ /[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+)/ and + # do some basic sanity checks on the date + $13 <= 31 and $14 <= 12 and $15 <= 99) + { + my $year = $15 + ($15 >= 70 ? 1900 : 2000); + $tags{GPSDateTime} = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', $year, $14, $13, $1, $2, $3); + $tags{GPSLatitude} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1); + $tags{GPSLongitude} = (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1); + if (length $11) { + $tags{GPSSpeed} = $11 * $knotsToKph; + $tags{GPSSpeedRef} = 'K'; + } + if (length $12) { + $tags{GPSTrack} = $12; + $tags{GPSTrackRef} = 'T'; + } + } + $tags{GSensor} = $1 if $$buffPt =~ /\bgsensori,(.*?)(;|$)/; + $tags{Car} = $1 if $$buffPt =~ /\bCAR,(.*?)(;|$)/; + } + if (%tags) { + foreach $tag (sort keys %tags) { + $et->HandleTag($tagTbl, $tag => $tags{$tag}); + } + $$et{UnknownTextCount} = 0; + } else { + $$et{UnknownTextCount} = ($$et{UnknownTextCount} || 0) + 1; + # give up trying to decode useful information if we haven't found anything for a while + $$et{NoMoreTextDecoding} = 1 if $$et{UnknownTextCount} > 100; + } +} + +#------------------------------------------------------------------------------ +# Extract embedded metadata from media samples +# Inputs: 0) ExifTool ref +# Notes: Also accesses ExifTool RAF*, SET_GROUP1, HandlerType, MetaFormat, +# ee*, and avcC elements (* = must exist) +sub ProcessSamples($) +{ + my $et = shift; + my ($raf, $ee) = @$et{qw(RAF ee)}; + my ($i, $buff, $pos, $hdrLen, $hdrFmt, @time, @dur, $oldIndent); + + return unless $ee; + delete $$et{ee}; # use only once + + # only process specific types of video streams + my $type = $$et{HandlerType} || ''; + if ($type eq 'vide') { + if ($$ee{avcC}) { $type = 'avcC' } + elsif ($$ee{JPEG}) { $type = 'JPEG' } + else { return } + } + + my ($start, $size) = @$ee{qw(start size)}; +# +# determine sample start offsets from chunk offsets (stco) and sample-to-chunk table (stsc), +# and sample time/duration from time-to-sample (stts) +# + unless ($start and $size) { + return unless $size; + my ($stco, $stsc, $stts) = @$ee{qw(stco stsc stts)}; + return unless $stco and $stsc and @$stsc; + $start = [ ]; + my ($nextChunk, $iChunk) = (0, 1); + my ($chunkStart, $startChunk, $samplesPerChunk, $descIdx, $timeCount, $timeDelta, $time); + if ($stts and @$stts > 1) { + $time = 0; + $timeCount = shift @$stts; + $timeDelta = shift @$stts; + } + my $ts = $$et{MediaTS} || 1; + foreach $chunkStart (@$stco) { + if ($iChunk >= $nextChunk and @$stsc) { + ($startChunk, $samplesPerChunk, $descIdx) = @{shift @$stsc}; + $nextChunk = $$stsc[0][0] if @$stsc; + } + @$size < @$start + $samplesPerChunk and $et->WarnOnce('Sample size error'), return; + my $sampleStart = $chunkStart; + for ($i=0; ; ) { + push @$start, $sampleStart; + if (defined $time) { + until ($timeCount) { + if (@$stts < 2) { + undef $time; + last; + } + $timeCount = shift @$stts; + $timeDelta = shift @$stts; + } + push @time, $time / $ts; + push @dur, $timeDelta / $ts; + $time += $timeDelta; + --$timeCount; + } + # (eventually should use the description indices: $descIdx) + last if ++$i >= $samplesPerChunk; + $sampleStart += $$size[$#$start]; + } + ++$iChunk; + } + @$start == @$size or $et->WarnOnce('Incorrect sample start/size count'), return; + } +# +# extract and parse the sample data +# + my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); + my $verbose = $et->Options('Verbose'); + my $metaFormat = $$et{MetaFormat} || ''; + my $tell = $raf->Tell(); + + if ($verbose) { + $et->VPrint(0, "---- Extract Embedded ----\n"); + $oldIndent = $$et{INDENT}; + $$et{INDENT} = ''; + } + # get required information from avcC box if parsing video data + if ($type eq 'avcC') { + $hdrLen = (Get8u(\$$ee{avcC}, 4) & 0x03) + 1; + $hdrFmt = ($hdrLen == 4 ? 'N' : $hdrLen == 2 ? 'n' : 'C'); + require Image::ExifTool::H264; + } + # loop through all samples + for ($i=0; $i<@$start and $i<@$size; ++$i) { + + # initialize our flags for setting GPSDateTime + delete $$et{FoundGPSLatitude}; + delete $$et{FoundGPSDateTime}; + + # read the sample data + my $size = $$size[$i]; + next unless $raf->Seek($$start[$i], 0) and $raf->Read($buff, $size) == $size; + + if ($type eq 'avcC') { + next if length($buff) <= $hdrLen; + # scan through all NAL units and send them to ParseH264Video() + for ($pos=0; ; ) { + my $len = unpack("x$pos$hdrFmt", $buff); + last if $pos + $hdrLen + $len > length($buff); + my $tmp = "\0\0\0\x01" . substr($buff, $pos+$hdrLen, $len); + Image::ExifTool::H264::ParseH264Video($et, \$tmp); + $pos += $hdrLen + $len; + last if $pos + $hdrLen >= length($buff); + } + next; + } + if ($verbose > 1) { + my $hdr = $$et{SET_GROUP1} ? "$$et{SET_GROUP1} Type='${type}' Format='${metaFormat}'" : "Type='${type}'"; + $et->VPrint(1, "${hdr}, Sample ".($i+1).' of '.scalar(@$start)." ($size bytes)\n"); + $et->VerboseDump(\$buff, Addr => $$start[$i]); + } + if ($type eq 'text') { + + FoundSomething($et, $tagTbl, $time[$i], $dur[$i]); + unless ($buff =~ /^\$BEGIN/) { + # remove ending "encd" box if it exists + $buff =~ s/\0\0\0\x0cencd\0\0\x01\0$// and $size -= 12; + # cameras such as the CanonPowerShotN100 store ASCII time codes with a + # leading 2-byte integer giving the length of the string + # (and chapter names start with a 2-byte integer too) + if ($size >= 2 and unpack('n',$buff) == $size - 2) { + next if $size == 2; + $buff = substr($buff,2); + } + my $val; + # check for encrypted GPS text as written by E-PRANCE B47FS camera + if ($buff =~ /^\0/ and $buff =~ /\x0a$/ and length($buff) > 5) { + # decode simple ASCII difference cipher, + # based on known value of 4th-last char = '*' + my $dif = ord('*') - ord(substr($buff, -4, 1)); + my $tmp = pack 'C*',map { $_=($_+$dif)&0xff } unpack 'C*',substr $buff,1,-1; + if ($verbose > 2) { + $et->VPrint(0, "[decrypted text]\n"); + $et->VerboseDump(\$tmp); + } + if ($tmp =~ /^(.*?)(\$[A-Z]{2}RMC.*)/s) { + ($val, $buff) = ($1, $2); + $val =~ tr/\t/ /; + $et->HandleTag($tagTbl, RawGSensor => $val) if length $val; + } + } elsif ($buff =~ /^PNDM/ and length $buff >= 20) { + # Garmin Dashcam format (actually binary, not text) + $et->HandleTag($tagTbl, GPSLatitude => Get32s(\$buff, 12) * 180/0x80000000); + $et->HandleTag($tagTbl, GPSLongitude => Get32s(\$buff, 16) * 180/0x80000000); + $et->HandleTag($tagTbl, GPSSpeed => Get16u(\$buff, 8)); + $et->HandleTag($tagTbl, GPSSpeedRef => 'M'); + SetGPSDateTime($et, $tagTbl, $time[$i]); + next; # all done (don't store/process as text) + } + unless (defined $val) { + $et->HandleTag($tagTbl, Text => $buff); # just store any other text + } + } + Process_text($et, $tagTbl, \$buff); + + } elsif ($processByMetaFormat{$type}) { + + if ($$tagTbl{$metaFormat}) { + my $tagInfo = $et->GetTagInfo($tagTbl, $metaFormat, \$buff); + if ($tagInfo) { + FoundSomething($et, $tagTbl, $time[$i], $dur[$i]); + $$et{ee} = $ee; # need ee information for 'keys' + $et->HandleTag($tagTbl, $metaFormat, undef, + DataPt => \$buff, + DataPos => $$start[$i], + Base => $$start[$i], + TagInfo => $tagInfo, + ); + delete $$et{ee}; + } elsif ($metaFormat eq 'camm' and $buff =~ /^X/) { + # seen 'camm' metadata in this format (X/Y/Z acceleration and G force? + GPRMC + ?) + # "X0000.0000Y0000.0000Z0000.0000G0000.0000$GPRMC,000125,V,,,,,000.0,,280908,002.1,N*71~, 794021 \x0a" + FoundSomething($et, $tagTbl, $time[$i], $dur[$i]); + $et->HandleTag($tagTbl, Accelerometer => "$1 $2 $3 $4") if $buff =~ /X(.*?)Y(.*?)Z(.*?)G(.*?)\$/; + Process_text($et, $tagTbl, \$buff); + } + } elsif ($verbose) { + $et->VPrint(0, "Unknown meta format ($metaFormat)"); + } + + } elsif ($type eq 'gps ') { # (ie. GPSDataList tag) + + if ($buff =~ /^....freeGPS /s) { + # decode "freeGPS " data (Novatek) + ProcessFreeGPS($et, { + DataPt => \$buff, + DataPos => $$start[$i], + SampleTime => $time[$i], + SampleDuration => $dur[$i], + }, $tagTbl) ; + } + + } elsif ($$tagTbl{$type}) { + + my $tagInfo = $et->GetTagInfo($tagTbl, $type, \$buff); + if ($tagInfo) { + FoundSomething($et, $tagTbl, $time[$i], $dur[$i]); + $et->HandleTag($tagTbl, $type, undef, + DataPt => \$buff, + DataPos => $$start[$i], + Base => $$start[$i], + TagInfo => $tagInfo, + ); + } + } + # generate approximate GPSDateTime if necessary + SetGPSDateTime($et, $tagTbl, $time[$i]) if $$et{FoundGPSLatitude} and not $$et{FoundGPSDateTime}; + } + if ($verbose) { + $$et{INDENT} = $oldIndent; + $et->VPrint(0, "--------------------------\n"); + } + # clean up + $raf->Seek($tell, 0); # restore original file position + $$et{DOC_NUM} = 0; + $$et{HandlerType} = $$et{HanderDesc} = ''; +} + +#------------------------------------------------------------------------------ +# Process "freeGPS " data blocks referenced by a 'gps ' (GPSDataList) atom +# Inputs: 0) ExifTool ref, 1) dirInfo ref {DataPt,SampleTime,SampleDuration}, 2) tagTable ref +# Returns: 1 on success (or 0 on unrecognized or "measurement-void" GPS data) +# Notes: +# - also see ProcessFreeGPS2() below for processing of other types of freeGPS blocks +sub ProcessFreeGPS($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = length $$dataPt; + my ($yr, $mon, $day, $hr, $min, $sec, $stat, $lbl); + my ($lat, $latRef, $lon, $lonRef, $spd, $trk, $alt, @acc, @xtra); + + return 0 if $dirLen < 92; + + if (substr($$dataPt,12,1) eq "\x05") { + + # decode encrypted ASCII-based GPS (DashCam Azdome GS63H, ref 5) + # header looks like this in my sample: + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 05 01 00 00 [....freeGPS ....] + # 0010: 01 03 aa aa f2 e1 f0 ee 54 54 98 9a 9b 92 9a 93 [........TT......] + # 0020: 98 9e 98 98 9e 93 98 92 a6 9f 9f 9c 9d ed fa 8a [................] + my $n = $dirLen - 18; + $n = 0x101 if $n > 0x101; + my $buf2 = pack 'C*', map { $_ ^ 0xaa } unpack 'C*', substr($$dataPt,18,$n); + if ($et->Options('Verbose') > 1) { + $et->VPrint(1, '[decrypted freeGPS data]'); + $et->VerboseDump(\$buf2); + } + # (extract longitude as 9 digits, not 8, ref PH) + return 0 unless $buf2 =~ /^.{8}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2}).(.{15})([NS])(\d{8})([EW])(\d{9})(\d{8})/s; + ($yr,$mon,$day,$hr,$min,$sec,$lbl,$latRef,$lat,$lonRef,$lon,$spd) = ($1,$2,$3,$4,$5,$6,$7,$8,$9/1e4,$10,$11/1e4,$12); + $spd += 0; # remove leading 0's + $lbl =~ s/\0.*//s; $lbl =~ s/\s+$//; # truncate at null and remove trailing spaces + push @xtra, UserLabel => $lbl if length $lbl; + # extract accelerometer data (ref PH) + @acc = ($1/100,$2/100,$3/100) if $buf2 =~ /^.{173}([-+]\d{3})([-+]\d{3})([-+]\d{3})/s; + + } elsif ($$dataPt =~ /^.{52}(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/s) { + + # decode NMEA-format GPS data (NextBase 512GW dashcam, ref PH) + # header looks like this in my sample: + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 40 01 00 00 [....freeGPS @...] + # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................] + # 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................] + push @xtra, CameraDateTime => "$1:$2:$3 $4:$5:$6"; + if ($$dataPt =~ /\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d+\.\d+),([NS]),(\d+\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/s) { + ($lat,$latRef,$lon,$lonRef) = ($5,$6,$7,$8); + $yr = $13 + ($13 >= 70 ? 1900 : 2000); + ($mon,$day,$hr,$min,$sec) = ($12,$11,$1,$2,$3); + $spd = $9 * $knotsToKph if length $9; + $trk = $10 if length $10; + } + if ($$dataPt =~ /\$[A-Z]{2}GGA,(\d{2})(\d{2})(\d+(\.\d*)?),(\d+\.\d+),([NS]),(\d+\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/s) { + ($hr,$min,$sec,$lat,$latRef,$lon,$lonRef) = ($1,$2,$3,$5,$6,$7,$8) unless defined $yr; + $alt = $11; + unshift @xtra, GPSSatellites => $9; + unshift @xtra, GPSDOP => $10; + } + if (defined $lat) { + # extract accelerometer readings if GPS was valid + @acc = unpack('x68V3', $$dataPt); + # change to signed integer and divide by 256 + map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc; + } + + } elsif ($$dataPt =~ /^.{40}A([NS])([EW])/s) { + + # decode freeGPS from ViofoA119v3 dashcam (similar to Novatek GPS format) + # 0000: 00 00 40 00 66 72 65 65 47 50 53 20 f0 03 00 00 [..@.freeGPS ....] + # 0010: 05 00 00 00 2f 00 00 00 03 00 00 00 13 00 00 00 [..../...........] + # 0020: 09 00 00 00 1b 00 00 00 41 4e 57 00 25 d1 99 45 [........ANW.%..E] + # 0030: f1 47 40 46 66 66 d2 41 85 eb 83 41 00 00 00 00 [.G@Fff.A...A....] + ($latRef, $lonRef) = ($1, $2); + ($hr,$min,$sec,$yr,$mon,$day) = unpack('x16V6', $$dataPt); + $yr += 2000; + SetByteOrder('II'); + $lat = GetFloat($dataPt, 0x2c); + $lon = GetFloat($dataPt, 0x30); + $spd = GetFloat($dataPt, 0x34) * $knotsToKph; # (convert knots to km/h) + $trk = GetFloat($dataPt, 0x38); + SetByteOrder('MM'); + + } elsif ($$dataPt =~ /^.{60}A\0{3}.{4}([NS])\0{3}.{4}([EW])\0{3}/s) { + + # decode freeGPS from Akaso dashcam + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 60 00 00 00 [....freeGPS `...] + # 0000: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............] + # 0000: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........] + # 0000: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A...] + # 0000: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE...] + # 0000: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B........] + # 0000: 0c 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 [................] + ($latRef, $lonRef) = ($1, $2); + ($hr, $min, $sec, $yr, $mon, $day) = unpack('x48V3x28V3', $$dataPt); + SetByteOrder('II'); + $lat = GetFloat($dataPt, 0x40); + $lon = GetFloat($dataPt, 0x48); + $spd = GetFloat($dataPt, 0x50); + $trk = GetFloat($dataPt, 0x54) + 180; # (why is this off by 180?) + $trk -= 360 if $trk >= 360; + SetByteOrder('MM'); + + } else { + + # decode binary GPS format (Viofo A119S, ref 2) + # header looks like this in my sample: + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...] + # 0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................] + # 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................] + # (records are same structure as Type 3 Novatek GPS in ProcessFreeGPS2() below) + ($hr,$min,$sec,$yr,$mon,$day,$stat,$latRef,$lonRef,$lat,$lon,$spd,$trk) = + unpack('x48V6a1a1a1x1V4', $$dataPt); + # ignore invalid fixes + return 0 unless $stat eq 'A' and ($latRef eq 'N' or $latRef eq 'S') and + ($lonRef eq 'E' or $lonRef eq 'W'); + ($lat,$lon,$spd,$trk) = unpack 'f*', pack 'L*', $lat, $lon, $spd, $trk; + $yr += 2000 if $yr < 2000; + $spd *= $knotsToKph; # convert speed to km/h + # ($trk is not confirmed; may be GPSImageDirection, ref PH) + } +# +# save tag values extracted by above code +# + FoundSomething($et, $tagTbl, $$dirInfo{SampleTime}, $$dirInfo{SampleDuration}); + # lat/long are in DDDMM.MMMM format + my $deg = int($lat / 100); + $lat = $deg + ($lat - $deg * 100) / 60; + $deg = int($lon / 100); + $lon = $deg + ($lon - $deg * 100) / 60; + $sec = '0' . $sec unless $sec =~ /^\d{2}/; # pad integer part of seconds to 2 digits + if (defined $yr) { + my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%sZ',$yr,$mon,$day,$hr,$min,$sec); + $et->HandleTag($tagTbl, GPSDateTime => $time); + } elsif (defined $hr) { + my $time = sprintf('%.2d:%.2d:%sZ',$hr,$min,$sec); + $et->HandleTag($tagTbl, GPSTimeStamp => $time); + } + $et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1)); + $et->HandleTag($tagTbl, GPSLongitude => $lon * ($lonRef eq 'W' ? -1 : 1)); + $et->HandleTag($tagTbl, GPSAltitude => $alt) if defined $alt; + if (defined $spd) { + $et->HandleTag($tagTbl, GPSSpeed => $spd); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + } + if (defined $trk) { + $et->HandleTag($tagTbl, GPSTrack => $trk); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + } + while (@xtra) { + my $tag = shift @xtra; + $et->HandleTag($tagTbl, $tag => shift @xtra); + } + $et->HandleTag($tagTbl, Accelerometer => \@acc) if @acc; + return 1; +} + +#------------------------------------------------------------------------------ +# Process "freeGPS " data blocks _not_ referenced by a 'gps ' atom +# Inputs: 0) ExifTool ref, 1) dirInfo ref {DataPt,DataPos,DirLen}, 2) tagTable ref +# Returns: 1 on success +# Notes: +# - also see ProcessFreeGPS() above +sub ProcessFreeGPS2($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = $$dirInfo{DirLen}; + my ($yr, $mon, $day, $hr, $min, $sec, $pos, @acc); + my ($lat, $latRef, $lon, $lonRef, $spd, $trk, $alt, $ddd, $unk); + + return 0 if $dirLen < 82; # minimum size of block with a single GPS record + + if (substr($$dataPt,0x45,3) eq 'ATC') { + + # header looks like this: (sample 1) + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 38 06 00 00 [....freeGPS 8...] + # 0010: 49 51 53 32 30 31 33 30 33 30 36 42 00 00 00 00 [IQS20130306B....] + # 0020: 4d 61 79 20 31 35 20 32 30 31 35 2c 20 31 39 3a [May 15 2015, 19:] + # (sample 2) + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 06 00 00 [....freeGPS L...] + # 0010: 32 30 31 33 30 33 31 38 2e 30 31 00 00 00 00 00 [20130318.01.....] + # 0020: 4d 61 72 20 31 38 20 32 30 31 33 2c 20 31 34 3a [Mar 18 2013, 14:] + + my ($recPos, $lastRecPos, $foundNew); + my $verbose = $et->Options('Verbose'); + my $dataPos = $$dirInfo{DataPos}; + my $then = $$et{FreeGPS2}{Then}; + $then or $then = $$et{FreeGPS2}{Then} = [ (0) x 6 ]; + # Loop through records in the ATC-type GPS block until we find the most recent. + # If we have already found one, then we only need to check the first record + # (in case the buffer wrapped around), and the record after the position of + # the last record we found, because the others will be old. Odd, but this + # is the way it is done... I have only seen one new 52-byte record in the + # entire 32 kB block, but the entire device ring buffer (containing 30 + # entries in my samples) is stored every time. The code below allows for + # the possibility of missing blocks and multiple new records in a single + # block, but I have never seen this. Note that there may be some earlier + # GPS records at the end of the first block that we will miss decoding, but + # these should (I believe) be before the start of the video +ATCRec: for ($recPos = 0x30; $recPos + 52 < $dirLen; $recPos += 52) { + + my $a = substr($$dataPt, $recPos, 52); # isolate a single record + # decrypt record + my @a = unpack('C*', $a); + my ($key1, $key2) = @a[0x14, 0x1c]; + $a[$_] ^= $key1 foreach 0x00..0x14, 0x18..0x1b; + $a[$_] ^= $key2 foreach 0x1c, 0x20..0x32; + my $b = pack 'C*', @a; + # unpack and validate date/time + my @now = unpack 'x13C3x28vC2', $b; # (H-1,M,S,Y,m,d) + $now[0] = ($now[0] + 1) & 0xff; # increment hour + my $i; + for ($i=0; $i<@dateMax; ++$i) { + next if $now[$i] <= $dateMax[$i]; + $et->WarnOnce('Invalid GPS date/time'); + next ATCRec; # ignore this record + } + # look for next ATC record in temporal sequence + foreach $i (3..5, 0..2) { + if ($now[$i] < $$then[$i]) { + last ATCRec if $foundNew; + last; + } + next if $now[$i] == $$then[$i]; + # we found a more recent record -- extract it and remember its location + if ($verbose) { + $et->VPrint(2, " + [encrypted GPS record]\n"); + $et->VerboseDump(\$a, DataPos => $dataPos + $recPos); + $et->VPrint(2, " + [decrypted GPS record]\n"); + $et->VerboseDump(\$b); + #my @v = unpack 'H8VVC4V!CA3V!CA3VvvV!vCCCCH4', $b; + #$et->VPrint(2, " + [unpacked: @v]\n"); + # values unpacked above (ref PH): + # 0) 0x00 4 bytes - byte 0=1, 1=counts to 255, 2=record index, 3=0 (ref 3) + # 1) 0x04 4 bytes - int32u: bits 0-4=day, 5-8=mon, 9-19=year (ref 3) + # 2) 0x08 4 bytes - int32u: bits 0-5=sec, 6-11=min, 12-16=hour (ref 3) + # 3) 0x0c 1 byte - seen values of 0,1,2 - GPS status maybe? + # 4) 0x0d 1 byte - hour minus 1 + # 5) 0x0e 1 byte - minute + # 6) 0x0f 1 byte - second + # 7) 0x10 4 bytes - int32s latitude * 1e7 + # 8) 0x14 1 byte - always 0 (used for decryption) + # 9) 0x15 3 bytes - always "ATC" + # 10) 0x18 4 bytes - int32s longitude * 1e7 + # 11) 0x1c 1 byte - always 0 (used for decryption) + # 12) 0x1d 3 bytes - always "001" + # 13) 0x20 4 bytes - int32s speed * 100 (m/s) + # 14) 0x24 2 bytes - int16u heading * 100 (-180 to 180 deg) + # 15) 0x26 2 bytes - always zero + # 16) 0x28 4 bytes - int32s altitude * 1000 (ref 3) + # 17) 0x2c 2 bytes - int16u year + # 18) 0x2e 1 byte - month + # 19) 0x2f 1 byte - day + # 20) 0x30 1 byte - unknown + # 21) 0x31 1 byte - always zero + # 22) 0x32 2 bytes - checksum ? + } + @$then = @now; + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + $trk = Get16s(\$b, 0x24) / 100; + $trk += 360 if $trk < 0; + my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', @now[3..5, 0..2]); + $et->HandleTag($tagTbl, GPSDateTime => $time); + $et->HandleTag($tagTbl, GPSLatitude => Get32s(\$b, 0x10) / 1e7); + $et->HandleTag($tagTbl, GPSLongitude => Get32s(\$b, 0x18) / 1e7); + $et->HandleTag($tagTbl, GPSSpeed => Get32s(\$b, 0x20) / 100 * $mpsToKph); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + $et->HandleTag($tagTbl, GPSTrack => $trk); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + $et->HandleTag($tagTbl, GPSAltitude => Get32s(\$b, 0x28) / 1000); + $lastRecPos = $recPos; + $foundNew = 1; + # don't skip to location of previous recent record in ring buffer + # since we found a more recent record here + delete $$et{FreeGPS2}{RecentRecPos}; + last; + } + # skip older records + my $recentRecPos = $$et{FreeGPS2}{RecentRecPos}; + $recPos = $recentRecPos if $recentRecPos and $recPos < $recentRecPos; + } + # save position of most recent record (needed when parsing the next freeGPS block) + $$et{FreeGPS2}{RecentRecPos} = $lastRecPos; + return 1; + + } elsif ($$dataPt =~ /^.{60}A\0.{10}([NS])\0.{14}([EW])\0/s) { + + # header looks like this in my sample: + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 08 01 00 00 [....freeGPS ....] + # 0010: 32 30 31 33 30 38 31 35 2e 30 31 00 00 00 00 00 [20130815.01.....] + # 0020: 4a 75 6e 20 31 30 20 32 30 31 37 2c 20 31 34 3a [Jun 10 2017, 14:] + + # Type 2 (ref PH): + # 0x30 - int32u hour + # 0x34 - int32u minute + # 0x38 - int32u second + # 0x3c - int32u GPS status ('A' or 'V') + # 0x40 - double latitude (DDMM.MMMMMM) + # 0x48 - int32u latitude ref ('N' or 'S') + # 0x50 - double longitude (DDMM.MMMMMM) + # 0x58 - int32u longitude ref ('E' or 'W') + # 0x60 - double speed (knots) + # 0x68 - double heading (deg) + # 0x70 - int32u year - 2000 + # 0x74 - int32u month + # 0x78 - int32u day + # 0x7c - int32s[3] accelerometer * 1000 + ($latRef, $lonRef) = ($1, $2); + ($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x52V6', $$dataPt); + map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; + $lat = GetDouble($dataPt, 0x40); + $lon = GetDouble($dataPt, 0x50); + $spd = GetDouble($dataPt, 0x60) * $knotsToKph; + $trk = GetDouble($dataPt, 0x68); + + } elsif ($$dataPt =~ /^.{72}A([NS])([EW])/s) { + + # Type 3 (Novatek GPS, ref 2): (in case it wasn't decoded via 'gps ' atom) + # 0x30 - int32u hour + # 0x34 - int32u minute + # 0x38 - int32u second + # 0x3c - int32u year - 2000 + # 0x40 - int32u month + # 0x44 - int32u day + # 0x48 - int8u GPS status ('A' or 'V') + # 0x49 - int8u latitude ref ('N' or 'S') + # 0x4a - int8u longitude ref ('E' or 'W') + # 0x4b - 0 + # 0x4c - float latitude (DDMM.MMMMMM) + # 0x50 - float longitude (DDMM.MMMMMM) + # 0x54 - float speed (knots) + # 0x58 - float heading (deg) + # Type 3b, same as above for 0x30-0x4a (ref PH) + # 0x4c - int32s latitude (decimal degrees * 1e7) + # 0x50 - int32s longitude (decimal degrees * 1e7) + # 0x54 - int32s speed (m/s * 100) + # 0x58 - float altitude (m * 1000, NC) + ($latRef, $lonRef) = ($1, $2); + ($hr,$min,$sec,$yr,$mon,$day) = unpack('x48V6', $$dataPt); + if (substr($$dataPt, 16, 3) eq 'IQS') { + # Type 3b (ref PH) + # header looks like this in my sample: + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 4c 00 00 00 [....freeGPS L...] + # 0010: 49 51 53 5f 41 37 5f 32 30 31 35 30 34 31 37 00 [IQS_A7_20150417.] + # 0020: 4d 61 72 20 32 39 20 32 30 31 37 2c 20 31 36 3a [Mar 29 2017, 16:] + $ddd = 1; + $lat = abs Get32s($dataPt, 0x4c) / 1e7; + $lon = abs Get32s($dataPt, 0x50) / 1e7; + $spd = Get32s($dataPt, 0x54) / 100 * $mpsToKph; + $alt = GetFloat($dataPt, 0x58) / 1000; # (NC) + } else { + # Type 3 (ref 2) + # (no sample with this format) + $lat = GetFloat($dataPt, 0x4c); + $lon = GetFloat($dataPt, 0x50); + $spd = GetFloat($dataPt, 0x54) * $knotsToKph; + $trk = GetFloat($dataPt, 0x58); + } + + } else { + + # (look for binary GPS as stored by NextBase 512G, ref PH) + # header looks like this in my sample: + # 0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 01 00 00 [....freeGPS x...] + # 0010: 78 2e 78 78 00 00 00 00 00 00 00 00 00 00 00 00 [x.xx............] + # 0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........] + + # followed by a number of 32-byte records in this format (big endian!): + # 0x30 - int16u unknown (seen: 0x24 0x53 = "$S") + # 0x32 - int16u speed (m/s * 100) + # 0x34 - int16s heading (deg * 100) (or GPSImgDirection?) + # 0x36 - int16u year + # 0x38 - int8u month + # 0x39 - int8u day + # 0x3a - int8u hour + # 0x3b - int8u min + # 0x3c - int16u sec * 10 + # 0x3e - int8u unknown (seen: 2) + # 0x3f - int32s latitude (decimal degrees * 1e7) + # 0x43 - int32s longitude (decimal degrees * 1e7) + # 0x47 - int8u unknown (seen: 16) + # 0x48-0x4f - all zero + for ($pos=0x32; ; ) { + ($spd,$trk,$yr,$mon,$day,$hr,$min,$sec,$unk,$lat,$lon) = unpack "x${pos}nnnCCCCnCNN", $$dataPt; + # validate record using date/time + last if $yr < 2000 or $yr > 2200 or + $mon < 1 or $mon > 12 or + $day < 1 or $day > 31 or + $hr > 59 or $min > 59 or $sec > 600; + # change lat/lon to signed integer and divide by 1e7 + map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1e7 } $lat, $lon; + $trk -= 0x10000 if $trk >= 0x8000; # make it signed + $trk /= 100; + $trk += 360 if $trk < 0; + my $time = sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%04.1fZ", $yr, $mon, $day, $hr, $min, $sec/10); + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + $et->HandleTag($tagTbl, GPSDateTime => $time); + $et->HandleTag($tagTbl, GPSLatitude => $lat); + $et->HandleTag($tagTbl, GPSLongitude => $lon); + $et->HandleTag($tagTbl, GPSSpeed => $spd / 100 * $mpsToKph); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + $et->HandleTag($tagTbl, GPSTrack => $trk); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + last if $pos += 0x20 > length($$dataPt) - 0x1e; + } + return $$et{DOC_NUM} ? 1 : 0; # return 0 if nothing extracted + } +# +# save tag values extracted by above code +# + return 0 if $mon < 1 or $mon > 12; # quick sanity check + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + $yr += 2000 if $yr < 2000; + my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', $yr, $mon, $day, $hr, $min, $sec); + # convert from DDMM.MMMMMM to DD.DDDDDD format if necessary + unless ($ddd) { + my $deg = int($lat / 100); + $lat = $deg + ($lat - $deg * 100) / 60; + $deg = int($lon / 100); + $lon = $deg + ($lon - $deg * 100) / 60; + } + $et->HandleTag($tagTbl, GPSDateTime => $time); + $et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1)); + $et->HandleTag($tagTbl, GPSLongitude => $lon * ($lonRef eq 'W' ? -1 : 1)); + $et->HandleTag($tagTbl, GPSSpeed => $spd); # (now in km/h) + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + if (defined $trk) { + $et->HandleTag($tagTbl, GPSTrack => $trk); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + } + if (defined $alt) { + $et->HandleTag($tagTbl, GPSAltitude => $alt); + } + $et->HandleTag($tagTbl, Accelerometer => "@acc") if @acc; + return 1; +} + +#------------------------------------------------------------------------------ +# Extract embedded information referenced from a track +# Inputs: 0) ExifTool ref, 1) tag name, 2) data ref +sub ParseTag($$$) +{ + local $_; + my ($et, $tag, $dataPt) = @_; + my $dataLen = length $$dataPt; + + if ($tag eq 'stsz' or $tag eq 'stz2' and $dataLen > 12) { + # read the sample sizes + my ($sz, $num) = unpack('x4N2', $$dataPt); + my $size = $$et{ee}{size} = [ ]; + if ($tag eq 'stsz') { + if ($sz == 0) { + @$size = ReadValue($dataPt, 12, 'int32u', $num, $dataLen-12); + } else { + @$size = ($sz) x $num; + } + } else { + $sz &= 0xff; + if ($sz == 4) { + my @tmp = ReadValue($dataPt, 12, 'int8u', int(($num+1)/2), $dataLen-12); + foreach (@tmp) { + push @$size, $_ >> 4; + push @$size, $_ & 0xff; + } + } elsif ($sz == 8 || $sz == 16) { + @$size = ReadValue($dataPt, 12, "int${sz}u", $num, $dataLen-12); + } + } + } elsif ($tag eq 'stco' or $tag eq 'co64' and $dataLen > 8) { + # read the chunk offsets + my $num = unpack('x4N', $$dataPt); + my $stco = $$et{ee}{stco} = [ ]; + @$stco = ReadValue($dataPt, 8, $tag eq 'stco' ? 'int32u' : 'int64u', $num, $dataLen-8); + } elsif ($tag eq 'stsc' and $dataLen > 8) { + # read the sample-to-chunk box + my $num = unpack('x4N', $$dataPt); + if ($dataLen >= 8 + $num * 12) { + my ($i, @stsc); + for ($i=0; $i<$num; ++$i) { + # list of (first-chunk, samples-per-chunk, sample-description-index) + push @stsc, [ unpack('x'.(8+$i*12).'N3', $$dataPt) ]; + } + $$et{ee}{stsc} = \@stsc; + } + } elsif ($tag eq 'stts' and $dataLen > 8) { + # read the time-to-sample box + my $num = unpack('x4N', $$dataPt); + if ($dataLen >= 8 + $num * 8) { + $$et{ee}{stts} = [ unpack('x8N'.($num*2), $$dataPt) ]; + } + } elsif ($tag eq 'avcC') { + # read the AVC compressor configuration + $$et{ee}{avcC} = $$dataPt if $dataLen >= 7; # (minimum length is 7) + } elsif ($tag eq 'JPEG') { + $$et{ee}{JPEG} = $$dataPt; + } elsif ($tag eq 'gps ' and $dataLen > 8) { + # decode Novatek 'gps ' box (ref 2) + my $num = Get32u($dataPt, 4); + $num = int(($dataLen - 8) / 8) if $num * 8 + 8 > $dataLen; + my $start = $$et{ee}{start} = [ ]; + my $size = $$et{ee}{size} = [ ]; + my $i; + for ($i=0; $i<$num; ++$i) { + push @$start, Get32u($dataPt, 8 + $i * 8); + push @$size, Get32u($dataPt, 12 + $i * 8); + } + $$et{HandlerType} = $tag; # fake handler type + ProcessSamples($et); # we have all we need to process sample data now + } +} + +#------------------------------------------------------------------------------ +# Process Yuneec 'tx3g' sbtl metadata (ref PH) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub Process_tx3g($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dataPt = $$dirInfo{DataPt}; + return 0 if length $$dataPt < 2; + pos($$dataPt) = 2; # skip 2-byte length word + $et->HandleTag($tagTablePtr, $1, $2) while $$dataPt =~ /(\w+):([^:]*[^:\s])(\s|$)/sg; + return 1; +} + +#------------------------------------------------------------------------------ +# Process QuickTime 'mebx' timed metadata +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +# - uses tag ID keys stored in the ExifTool ee data member by a previous call to SaveMetaKeys +sub Process_mebx($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $ee = $$et{ee} or return 0; + return 0 unless $$ee{'keys'}; + my $dataPt = $$dirInfo{DataPt}; + + # parse using information from 'keys' table (eg. Apple iPhone7+ hevc 'Core Media Data Handler') + $et->VerboseDir('mebx', undef, length $$dataPt); + my $pos = 0; + while ($pos + 8 < length $$dataPt) { + my $len = Get32u($dataPt, $pos); + last if $len < 8 or $pos + $len > length $$dataPt; + my $id = substr($$dataPt, $pos+4, 4); + my $info = $$ee{'keys'}{$id}; + if ($info) { + my $tag = $$info{TagID}; + unless ($$tagTbl{$tag}) { + next unless $tag =~ /^[-\w.]+$/; + # create info for tags with reasonable id's + my $name = $tag; + $name =~ s/[-.](.)/\U$1/g; + AddTagToTable($tagTbl, $tag, { Name => ucfirst($name) }); + } + my $val = ReadValue($dataPt, $pos+8, $$info{Format}, undef, $len-8); + $et->HandleTag($tagTbl, $tag, $val, + DataPt => $dataPt, + Base => $$dirInfo{Base}, + Start => $pos + 8, + Size => $len - 8, + ); + } else { + $et->WarnOnce('No key information for mebx ID ' . PrintableTagID($id,1)); + } + $pos += $len; + } + return 1; +} + +#------------------------------------------------------------------------------ +# Process QuickTime '3gf' timed metadata (ref PH, Pittasoft Blackvue dashcam) +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub Process_3gf($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = $$dirInfo{DirLen}; + my $recLen = 10; # 10-byte record length + $et->VerboseDir('3gf', undef, $dirLen); + if ($dirLen > $recLen and not $et->Options('ExtractEmbedded')) { + $dirLen = $recLen; + EEWarn($et); + } + my $pos; + for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) { + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + my $tc = Get32u($dataPt, $pos); + last if $tc == 0xffffffff; + my ($x, $y, $z) = (Get16s($dataPt, $pos+4)/10, Get16s($dataPt, $pos+6)/10, Get16s($dataPt, $pos+8)/10); + $et->HandleTag($tagTbl, TimeCode => $tc / 1000); + $et->HandleTag($tagTbl, Accelerometer => "$x $y $z"); + } + delete $$et{DOC_NUM}; + return 1; +} + +#------------------------------------------------------------------------------ +# Process DuDuBell M1 dashcam / VSYS M6L 'gps0' atom (ref PH) +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub Process_gps0($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = $$dirInfo{DirLen}; + my $recLen = 32; # 32-byte record length + $et->VerboseDir('gps0', undef, $dirLen); + SetByteOrder('II'); + if ($dirLen > $recLen and not $et->Options('ExtractEmbedded')) { + $dirLen = $recLen; + EEWarn($et); + } + my $pos; + for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) { + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + # lat/long are in DDDMM.MMMM format + my $lat = GetDouble($dataPt, $pos); + my $lon = GetDouble($dataPt, $pos+8); + next if abs($lat) > 9000 or abs($lon) > 18000; + # (note: this method works fine for negative coordinates) + my $deg = int($lat / 100); + $lat = $deg + ($lat - $deg * 100) / 60; + $deg = int($lon / 100); + $lon = $deg + ($lon - $deg * 100) / 60; + my @a = unpack('C*', substr($$dataPt, $pos+22, 6)); # unpack date/time + $a[0] += 2000; + $et->HandleTag($tagTbl, GPSDateTime => sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ", @a)); + $et->HandleTag($tagTbl, GPSLatitude => $lat); + $et->HandleTag($tagTbl, GPSLongitude => $lon); + $et->HandleTag($tagTbl, GPSSpeed => Get16u($dataPt, $pos+0x14)); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + $et->HandleTag($tagTbl, GPSTrack => Get8u($dataPt, $pos+0x1c) * 2); # (NC) + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + $et->HandleTag($tagTbl, GPSAltitude => Get32s($dataPt, $pos + 0x10)); + # yet to be decoded: + # 0x1d - int8u[3] seen: "1 1 0" + } + delete $$et{DOC_NUM}; + SetByteOrder('MM'); + return 1; +} + +#------------------------------------------------------------------------------ +# Process DuDuBell M1 dashcam / VSYS M6L 'gsen' atom (ref PH) +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub Process_gsen($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = $$dirInfo{DirLen}; + my $recLen = 3; # 3-byte record length + $et->VerboseDir('gsen', undef, $dirLen); + if ($dirLen > $recLen and not $et->Options('ExtractEmbedded')) { + $dirLen = $recLen; + EEWarn($et); + } + my $pos; + for ($pos=0; $pos+$recLen<=$dirLen; $pos+=$recLen) { + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + my @acc = map { $_ /= 16 } unpack "x${pos}c3", $$dataPt; + $et->HandleTag($tagTbl, Accelerometer => "@acc"); + # (there are no associated timestamps, but these are sampled at 5 Hz in my test video) + } + delete $$et{DOC_NUM}; + return 1; +} + +#------------------------------------------------------------------------------ +# Process RIFF-format trailer written by Auto-Vox dashcam (ref PH) +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +# Note: This trailer is basically RIFF chunks added to a QuickTime-format file (augh!), +# but there are differences in the record formats so we can't just call +# ProcessRIFF to process the gps0 and gsen atoms using the routines above +sub ProcessRIFFTrailer($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $raf = $$dirInfo{RAF}; + my $verbose = $et->Options('Verbose'); + my ($buff, $pos); + SetByteOrder('II'); + for (;;) { + last unless $raf->Read($buff, 8) == 8; + my ($tag, $len) = unpack('a4V', $buff); + last if $tag eq "\0\0\0\0"; + unless ($tag =~ /^[\w ]{4}/ and $len < 0x2000000) { + $et->Warn('Bad RIFF trailer'); + last; + } + $raf->Read($buff, $len) == $len or $et->Warn("Truncated $tag record in RIFF trailer"), last; + if ($verbose) { + $et->VPrint(0, " - RIFF trailer '${tag}' ($len bytes)\n"); + $et->VerboseDump(\$buff, Addr => $raf->Tell() - $len) if $verbose > 2; + $$et{INDENT} .= '| '; + $et->VerboseDir($tag, undef, $len) if $tag =~ /^(gps0|gsen)$/; + } + if ($tag eq 'gps0') { + # (similar to record decoded in Process_gps0, but with some differences) + # 0000: 41 49 54 47 74 46 94 f6 c6 c5 b4 40 34 a2 b4 37 [AITGtF.....@4..7] + # 0010: f8 7b 8a 40 ff ff 00 00 38 00 77 0a 1a 0c 12 28 [.{.@....8.w....(] + # 0020: 8d 01 02 40 29 07 00 00 [...@)...] + # 0x00 - undef[4] 'AITG' + # 0x04 - double latitude (always positive) + # 0x0c - double longitude (always positive) + # 0x14 - ? seen hex "ff ff 00 00" (altitude in Process_gps0 record below) + # 0x18 - int16u speed in knots (different than km/hr in Process_gps0) + # 0x1a - int8u[6] yr-1900,mon,day,hr,min,sec (different than -2000 in Process_gps0) + # 0x20 - int8u direction in degrees / 2 + # 0x21 - int8u guessing that this is 1=N, 2=S - PH + # 0x22 - int8u guessing that this is 1=E, 2=W - PH + # 0x23 - ? seen hex "40" + # 0x24 - in32u time since start of video (ms) + my $recLen = 0x28; + for ($pos=0; $pos+$recLen<$len; $pos+=$recLen) { + substr($buff, $pos, 4) eq 'AITG' or $et->Warn('Unrecognized gps0 record'), last; + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + # lat/long are in DDDMM.MMMM format + my $lat = GetDouble(\$buff, $pos+4); + my $lon = GetDouble(\$buff, $pos+12); + $et->Warn('Bad gps0 record') and last if abs($lat) > 9000 or abs($lon) > 18000; + my $deg = int($lat / 100); + $lat = $deg + ($lat - $deg * 100) / 60; + $deg = int($lon / 100); + $lon = $deg + ($lon - $deg * 100) / 60; + $lat = -$lat if Get8u(\$buff, $pos+0x21) == 2; # wild guess + $lon = -$lon if Get8u(\$buff, $pos+0x22) == 2; # wild guess + my @a = unpack('C*', substr($buff, $pos+26, 6)); # unpack date/time + $a[0] += 1900; # (different than Proces_gps0) + $et->HandleTag($tagTbl, SampleTime => Get32u(\$buff, $pos + 0x24) / 1000); + $et->HandleTag($tagTbl, GPSDateTime => sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ", @a)); + $et->HandleTag($tagTbl, GPSLatitude => $lat); + $et->HandleTag($tagTbl, GPSLongitude => $lon); + $et->HandleTag($tagTbl, GPSSpeed => Get16u(\$buff, $pos+0x18) * $knotsToKph); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + $et->HandleTag($tagTbl, GPSTrack => Get8u(\$buff, $pos+0x20) * 2); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + } + } elsif ($tag eq 'gsen') { + # (similar to record decoded in Process_gsen) + # 0000: 41 49 54 53 1a 0d 05 ff c8 00 00 00 [AITS........] + # 0x00 - undef[4] 'AITS' + # 0x04 - int8s[3] accelerometer readings + # 0x07 - ? seen hex "ff" + # 0x08 - in32u time since start of video (ms) + my $recLen = 0x0c; + for ($pos=0; $pos+$recLen<$len; $pos+=$recLen) { + substr($buff, $pos, 4) eq 'AITS' or $et->Warn('Unrecognized gsen record'), last; + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + my @acc = map { $_ /= 24 } unpack('x'.($pos+4).'c3', $buff); + $et->HandleTag($tagTbl, SampleTime => Get32u(\$buff, $pos + 8) / 1000); + # 0=+Up, 1=+Right, 3=+Forward (calibration of 24 counts/g is a wild guess - PH) + $et->HandleTag($tagTbl, Accelerometer => "@acc"); + } + } + # also seen, but not decoded: + # gpsa (8 bytes): hex "01 20 00 00 08 03 02 08 " + # gsea (20 bytes): all zeros + $$et{INDENT} = substr($$et{INDENT}, 0, -2) if $verbose; + } + delete $$et{DOC_NUM}; + SetByteOrder('MM'); + return 1; +} + +#------------------------------------------------------------------------------ +# Process 'gps ' atom containing NMEA from Pittasoft Blackvue dashcam (ref PH) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +sub ProcessNMEA($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + # parse only RMC sentence (with leading timestamp) for now + while ($$dataPt =~ /(?:\[(\d+)\])?\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d+\.\d+),([NS]),(\d+\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/g) { + my $tc = $1; # milliseconds since 1970 (local time) + my ($lat,$latRef,$lon,$lonRef) = ($6,$7,$8,$9); + my $yr = $14 + ($14 >= 70 ? 1900 : 2000); + my ($mon,$day,$hr,$min,$sec) = ($13,$12,$2,$3,$4); + my ($spd, $trk); + $spd = $10 * $knotsToKph if length $10; + $trk = $11 if length $11; + # lat/long are in DDDMM.MMMM format + my $deg = int($lat / 100); + $lat = $deg + ($lat - $deg * 100) / 60; + $deg = int($lon / 100); + $lon = $deg + ($lon - $deg * 100) / 60; + $sec = '0' . $sec unless $sec =~ /^\d{2}/; # pad integer part of seconds to 2 digits + my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%sZ',$yr,$mon,$day,$hr,$min,$sec); + my $sampleTime; + $sampleTime = ($tc - $$et{StartTime}) / 1000 if $tc and $$et{StartTime}; + FoundSomething($et, $tagTbl, $sampleTime); + $et->HandleTag($tagTbl, GPSDateTime => $time); + $et->HandleTag($tagTbl, GPSLatitude => $lat * ($latRef eq 'S' ? -1 : 1)); + $et->HandleTag($tagTbl, GPSLongitude => $lon * ($lonRef eq 'W' ? -1 : 1)); + if (defined $spd) { + $et->HandleTag($tagTbl, GPSSpeed => $spd); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + } + if (defined $trk) { + $et->HandleTag($tagTbl, GPSTrack => $trk); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + } + } + delete $$et{DOC_NUM}; + return 1; +} + +#------------------------------------------------------------------------------ +# Process TomTom Bandit Action Cam TTAD atom (ref PH) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: 1 on success +my %ttLen = ( # lengths of known TomTom records + 0 => 12, # angular velocity (NC) + 1 => 4, # ? + 2 => 12, # ? + 3 => 12, # accelerometer (NC) + # (haven't seen a record 4 yet) + 5 => 92, # GPS + 0xff => 4, # timecode +); +sub ProcessTTAD($$$) +{ + my ($et, $dirInfo, $tagTbl) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = $$dirInfo{DirLen}; + my $pos = 76; + + return 0 if $dirLen < $pos; + + $et->VerboseDir('TTAD', undef, $dirLen); + SetByteOrder('II'); + + my $eeOpt = $et->Options('ExtractEmbedded'); + my $unknown = $et->Options('Unknown'); + my $found = 0; + my $sampleTime = 0; + my $resync = 1; + my $skipped = 0; + my $warned; + + while ($pos < $dirLen) { + # get next record type + my $type = Get8u($dataPt, $pos++); + # resync if necessary by skipping data until next timecode record + if ($resync and $type != 0xff) { + ++$skipped > 0x100 and $et->Warn('Unrecognized or bad TTAD data', 1), last; + next; + } + unless ($ttLen{$type}) { + # skip unknown records + $et->Warn("Unknown TTAD record type $type",1) unless $warned; + $resync = $warned = 1; + ++$skipped; + next; + } + last if $pos + $ttLen{$type} > $dirLen; + if ($type == 0xff) { # timecode? + my $tm = Get32u($dataPt, $pos); + # validate timecode if skipping unknown data + if ($resync) { + if ($tm < $sampleTime or $tm > $sampleTime + 250) { + ++$skipped; + next; + } + undef $resync; + $skipped = 0; + } + $pos += $ttLen{$type}; + $sampleTime = $tm; + next; + } + unless ($eeOpt) { + # only extract one of each type without -ee option + $found & (1 << $type) and $pos += $ttLen{$type}, next; + $found |= (1 << $type); + } + if ($type == 0 or $type == 3) { + # (these are both just educated guesses - PH) + FoundSomething($et, $tagTbl, $sampleTime / 1000); + my @a = map { Get32s($dataPt,$pos+4*$_) / 1000 } 0..2; + $et->HandleTag($tagTbl, ($type ? 'Accelerometer' : 'AngularVelocity') => "@a"); + } elsif ($type == 5) { + # example records unpacked with 'dVddddVddddv*' + # datetime ? spd ele lat lon ? trk ? ? ? ? ? ? ? ? ? + # 2019:03:05 07:52:58.999Z 3 0.02 242 48.0254203 7.8497567 0 45.69 13.34 17.218 17.218 0 0 0 32760 5 0 + # 2019:03:05 07:52:59.999Z 3 0.14 242 48.0254203 7.8497567 0 45.7 12.96 15.662 15.662 0 0 0 32760 5 0 + # 2019:03:05 07:53:00.999Z 3 0.67 243.78 48.0254584 7.8497907 0 50.93 9.16 10.84 10.84 0 0 0 32760 5 0 + # (I think "5" may be the number of satellites. seen: 5,6,7 - PH) + FoundSomething($et, $tagTbl, $sampleTime / 1000); + my $t = GetDouble($dataPt, $pos); + $et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($t,undef,3).'Z'); + $et->HandleTag($tagTbl, GPSLatitude => GetDouble($dataPt, $pos+0x1c)); + $et->HandleTag($tagTbl, GPSLongitude => GetDouble($dataPt, $pos+0x24)); + $et->HandleTag($tagTbl, GPSAltitude => GetDouble($dataPt, $pos+0x14)); + $et->HandleTag($tagTbl, GPSSpeed => GetDouble($dataPt, $pos+0x0c) * $mpsToKph); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + $et->HandleTag($tagTbl, GPSTrack => GetDouble($dataPt, $pos+0x30)); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + if ($unknown) { + my @a = map { GetDouble($dataPt, $pos+0x38+8*$_) } 0..2; + $et->HandleTag($tagTbl, Unknown03 => "@a"); + } + } elsif ($type < 3) { + # as yet unknown: + # 1 - int32s[1]? (values around 98k) + # 2 - int32s[3] (values like "806 8124 4323" -- probably something * 1000 again) + if ($unknown) { + FoundSomething($et, $tagTbl, $sampleTime / 1000); + my $n = $type == 1 ? 0 : 2; + my @a = map { Get32s($dataPt,$pos+4*$_) } 0..$n; + $et->HandleTag($tagTbl, "Unknown0$type" => "@a"); + } + } else { + $et->WarnOnce("Unknown TTAD record type $type",1); + } + # without -ee, stop after we find types 0,3,5 (ie. bitmask 0x29) + $eeOpt or ($found & 0x29) != 0x29 or EEWarn($et), last; + $pos += $ttLen{$type}; + } + SetByteOrder('MM'); + delete $$et{DOC_NUM}; + return 1; +} + +#------------------------------------------------------------------------------ +# Extract information from Insta360 trailer (INSV and INSP files) (ref PH) +# Inputs: 0) ExifTool ref, 1) Optional dirInfo ref for returning trailer info +# Returns: true on success +sub ProcessInsta360($;$) +{ + local $_; + my ($et, $dirInfo) = @_; + my $raf = $$et{RAF}; + my $offset = $dirInfo ? $$dirInfo{Offset} || 0 : 0; + my $buff; + + return 0 unless $raf->Seek(-78-$offset, 2) and $raf->Read($buff, 78) == 78 and + substr($buff,-32) eq "8db42d694ccc418790edff439fe026bf"; # check magic number + + my $verbose = $et->Options('Verbose'); + my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); + my $fileEnd = $raf->Tell(); + my $trailerLen = unpack('x38V', $buff); + $trailerLen > $fileEnd and $et->Warn('Bad Insta360 trailer size'), return 0; + if ($dirInfo) { + $$dirInfo{DirLen} = $trailerLen if $dirInfo; + $$dirInfo{DataPos} = $fileEnd - $trailerLen; + if ($$dirInfo{OutFile}) { + if ($$et{DEL_GROUP}{Insta360}) { + ++$$et{CHANGED}; + # just copy the trailer when writing + } elsif ($trailerLen > $fileEnd or not $raf->Seek($$dirInfo{DataPos}, 0) or + $raf->Read(${$$dirInfo{OutFile}}, $trailerLen) != $trailerLen) + { + return 0; + } else { + return 1; + } + } + $et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP}; + } + unless ($et->Options('ExtractEmbedded')) { + # can arrive here when reading Insta360 trailer on JPEG image (INSP file) + $et->WarnOnce('Use ExtractEmbedded option to extract timed metadata from Insta360 trailer',3); + return 1; + } + + my $unknown = $et->Options('Unknown'); + # position relative to end of trailer (avoids using large offsets for files > 2 GB) + my $epos = -78-$offset; + my ($i, $p); + $$et{SET_GROUP0} = 'Trailer'; + $$et{SET_GROUP1} = 'Insta360'; + SetByteOrder('II'); + # loop through all records in the trailer, from last to first + for (;;) { + my ($id, $len) = unpack('vV', $buff); + ($epos -= $len) + $trailerLen < 0 and last; + $raf->Seek($epos, 2) or last; + my $dlen = $insvDataLen{$id}; + if ($verbose) { + $et->VPrint(0, sprintf("Insta360 Record 0x%x (offset 0x%x, %d bytes):\n", $id, $fileEnd + $epos, $len)); + } + # limit the number of records we read if necessary + if ($insvLimit{$id} and $len > $insvLimit{$id}[1] * $dlen and + $et->Warn("Insta360 $insvLimit{$id}[0] data is huge. Processing only the first $insvLimit{$id}[1] records",2)) + { + $len = $insvLimit{$id}[1] * $dlen; + } + $raf->Read($buff, $len) == $len or last; + $et->VerboseDump(\$buff) if $verbose > 2; + if ($dlen) { + $len % $dlen and $et->Warn(sprintf('Unexpected Insta360 record 0x%x length',$id)), last; + if ($id == 0x300) { + for ($p=0; $p<$len; $p+=$dlen) { + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + my @a = map { GetDouble(\$buff, $p + 8 * $_) } 1..6; + $et->HandleTag($tagTbl, TimeCode => sprintf('%.3f', Get64u(\$buff, $p) / 1000)); + $et->HandleTag($tagTbl, Accelerometer => "@a[0..2]"); # (NC) + $et->HandleTag($tagTbl, AngularVelocity => "@a[3..5]"); # (NC) + } + } elsif ($id == 0x400 and $unknown) { + for ($p=0; $p<$len; $p+=$dlen) { + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + $et->HandleTag($tagTbl, TimeCode => sprintf('%.3f', Get64u(\$buff, $p) / 1000)); + $et->HandleTag($tagTbl, Unknown01 => GetDouble(\$buff, $p + 8)); + } + } elsif ($id == 0x700) { + for ($p=0; $p<$len; $p+=$dlen) { + my $tmp = substr($buff, $p, $dlen); + my @a = unpack('VVvaa8aa8aa8a8a8', $tmp); + next unless $a[3] eq 'A'; # (ignore void fixes) + last unless ($a[5] eq 'N' or $a[5] eq 'S') and # (quick validation) + ($a[7] eq 'E' or $a[7] eq 'W'); + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; + $a[$_] = GetDouble(\$a[$_], 0) foreach 4,6,8,9,10; + $a[4] = -abs($a[4]) if $a[5] eq 'S'; # (abs just in case it was already signed) + $a[6] = -abs($a[6]) if $a[7] eq 'W'; + $et->HandleTag($tagTbl, GPSDateTime => Image::ExifTool::ConvertUnixTime($a[0]) . 'Z'); + $et->HandleTag($tagTbl, GPSLatitude => $a[4]); + $et->HandleTag($tagTbl, GPSLongitude => $a[6]); + $et->HandleTag($tagTbl, GPSSpeed => $a[8] * $mpsToKph); + $et->HandleTag($tagTbl, GPSSpeedRef => 'K'); + $et->HandleTag($tagTbl, GPSTrack => $a[9]); + $et->HandleTag($tagTbl, GPSTrackRef => 'T'); + $et->HandleTag($tagTbl, GPSAltitude => $a[10]); + $et->HandleTag($tagTbl, Unknown02 => "@a[1,2]") if $unknown; + } + } + } elsif ($id == 0x101) { + my $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::INSV_MakerNotes'); + for ($i=0, $p=0; $i<4; ++$i) { + last if $p + 2 > $len; + my ($t, $n) = unpack("x${p}CC", $buff); + last if $p + 2 + $n > $len; + my $val = substr($buff, $p+2, $n); + $et->HandleTag($tagTablePtr, $t, $val); + $p += 2 + $n; + } + } + ($epos -= 6) + $trailerLen < 0 and last; # step back to previous record + $raf->Seek($epos, 2) or last; + $raf->Read($buff, 6) == 6 or last; + } + $$et{DOC_NUM} = 0; + SetByteOrder('MM'); + delete $$et{SET_GROUP0}; + delete $$et{SET_GROUP1}; + return 1; +} + +#------------------------------------------------------------------------------ +# Scan media data for "freeGPS" metadata if not found already (ref PH) +# Inputs: 0) ExifTool ref +sub ScanMediaData($) +{ + my $et = shift; + my $raf = $$et{RAF} or return; + my ($tagTbl, $oldByteOrder, $verbose, $buff, $dataLen); + my ($pos, $buf2) = (0, ''); + + # don't rescan for freeGPS if we already found embedded metadata + my $dataPos = $$et{VALUE}{MediaDataOffset}; + if ($dataPos and not $$et{DOC_COUNT}) { + $dataLen = $$et{VALUE}{MediaDataSize}; + if ($dataLen) { + if ($raf->Seek($dataPos, 0)) { + $$et{FreeGPS2} = { }; # initialize variable space for FreeGPS2() + } else { + undef $dataLen; + } + } + } + + # loop through 'mdat' media data looking for GPS information + while ($dataLen) { + last if $pos + $gpsBlockSize > $dataLen; + last unless $raf->Read($buff, $gpsBlockSize); + $buff = $buf2 . $buff if length $buf2; + last if length $buff < $gpsBlockSize; + # look for "freeGPS " block + # (found on an absolute 0x8000-byte boundary in all of my samples, + # but allow for any alignment when searching) + if ($buff !~ /\0..\0freeGPS /sg) { # (seen ".." = "\0\x80","\x01\0") + $buf2 = substr($buff,-12); + $pos += length($buff)-12; + # in all of my samples the first freeGPS block is within 2 MB of the start + # of the mdat, so limit the scan to the first 20 MB to be fast and safe + next if $tagTbl or $pos < 20e6; + last; + } elsif (not $tagTbl) { + # initialize variables for extracting metadata from this block + $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream'); + $verbose = $$et{OPTIONS}{Verbose}; + $oldByteOrder = GetByteOrder(); + SetByteOrder('II'); + $et->VPrint(0, "---- Extract Embedded ----\n"); + $$et{INDENT} .= '| '; + } + if (pos($buff) > 12) { + $pos += pos($buff) - 12; + $buff = substr($buff, pos($buff) - 12); + } + # make sure we have the full freeGPS record + my $len = unpack('N', $buff); + if ($len < 12) { + $len = 12; + } else { + my $more = $len - length($buff); + if ($more > 0) { + last unless $raf->Read($buf2, $more) == $more; + $buff .= $buf2; + } + if ($verbose) { + $et->VerboseDir('GPS', undef, $len); + $et->VerboseDump(\$buff, DataPos => $pos + $dataPos); + } + my $dirInfo = { DataPt => \$buff, DataPos => $pos + $dataPos, DirLen => $len }; + ProcessFreeGPS2($et, $dirInfo, $tagTbl); + } + $pos += $len; + $buf2 = substr($buff, $len); + } + if ($tagTbl) { + $$et{DOC_NUM} = 0; + $et->VPrint(0, "--------------------------\n"); + SetByteOrder($oldByteOrder); + $$et{INDENT} = substr $$et{INDENT}, 0, -2; + } + # process Insta360 trailer if it exists + ProcessInsta360($et); +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::QuickTime - Extract embedded information from media data + +=head1 SYNOPSIS + +These routines are autoloaded by Image::ExifTool::QuickTime. + +=head1 DESCRIPTION + +This file contains routines used by Image::ExifTool to extract embedded +information like GPS tracks from MOV, MP4 and INSV media data. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item Lhttps://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-SW130> + +=item L<http://sergei.nz/files/nvtk_mp42gpx.py> + +=item L<https://forum.flitsservice.nl/dashcam-info/dod-ls460w-gps-data-uit-mov-bestand-lezen-t87926.html> + +=item L<https://developers.google.com/streetview/publish/camm-spec> + +=item L<https://sergei.nz/extracting-gps-data-from-viofo-a119-and-other-novatek-powered-cameras/> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::QuickTime(3pm)|Image::ExifTool::QuickTime>, +L<Image::ExifTool::TagNames/QuickTime Stream Tags>, +L<Image::ExifTool::TagNames/GoPro GPMF Tags>, +L<Image::ExifTool::TagNames/Sony rtmd Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/README b/src/Image-ExifTool/lib/Image/ExifTool/README index 8f9b4441..6703982b 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/README +++ b/src/Image-ExifTool/lib/Image/ExifTool/README @@ -14,13 +14,14 @@ the binary data block (floating point IDs allow multiple tags for the same offset, with the integer part being used for the offset). The corresponding hash value provides information about the tag (explained later). -Twenty-six special keys (TABLE_NAME, SHORT_NAME, PROCESS_PROC, WRITE_PROC, -CHECK_PROC, GROUPS, FORMAT, FIRST_ENTRY, TAG_PREFIX, PRINT_CONV, WRITABLE, -TABLE_DESC, NOTES, IS_OFFSET, IS_SUBDIR, EXTRACT_UNKNOWN, NAMESPACE, PREFERRED, -SRC_TABLE, PRIORITY, AVOID, WRITE_GROUP, LANG_INFO, VARS, DATAMEMBER and -SET_GROUP1) are used to provide additional information about a table. The -special keys have names that are all capitalized to avoid possible conflicts -with tag keys. Below is an explanation of the meaning of each special key: +Twenty-eight special keys (TABLE_NAME, SHORT_NAME, PROCESS_PROC, WRITE_PROC, +CHECK_PROC, INIT_TABLE, GROUPS, FORMAT, FIRST_ENTRY, TAG_PREFIX, PRINT_CONV, +WRITABLE, TABLE_DESC, NOTES, IS_OFFSET, IS_SUBDIR, EXTRACT_UNKNOWN, NAMESPACE, +PREFERRED, PERMANENT, SRC_TABLE, PRIORITY, AVOID, WRITE_GROUP, LANG_INFO, VARS, +DATAMEMBER and SET_GROUP1) are used to provide additional information about a +table. The special keys have names that are all capitalized to avoid possible +conflicts with tag keys. Below is an explanation of the meaning of each special +key: TABLE_NAME : Name of this table (set automatically by GetTagTable()). @@ -52,10 +53,11 @@ with tag keys. Below is an explanation of the meaning of each special key: FixOffsets - Evaluated for each value pointer to patch maker note offsets LastIFD - Used by WriteExif() to return offset of last IFD written ImageData - Used by WriteExif() to avoid buffering large image data blocks + NoRefTest - Flag to bypass "referenced by previous directory" test - WRITE_PROC : Reference to a function to write all new tags for this directory. - The write proc returns the new directory data or undefined on error. It takes - the same arguments as the process proc above except that the second argument + WRITE_PROC : Function reference or name for writing this directory. The + function returns the new directory data or undefined on error. It takes the + same arguments as the process proc above except that the second argument (reference to directory information hash) is optional, and if specified gives information about the source directory for tags to be copied to the output. @@ -65,6 +67,9 @@ with tag keys. Below is an explanation of the meaning of each special key: the input value) if successful, or an error message if there was a format problem. May set ExifTool CHECK_WARN datamember for success with a warning. + INIT_TABLE : Routine called to do any necessary initialization before the + first time the table is loaded. Argument is a reference to the table. + GROUPS : A hash lookup for the default group names for all entries in this table. If not specified, the default Group 0 and 1 names will be set automatically according to the name of the module, and the default Group 2 @@ -169,10 +174,13 @@ with tag keys. Below is an explanation of the meaning of each special key: PREFERRED : Set to true if the tags in this table should always be added when writing information. Overrides the order specified by SetNewGroups(). When - this feature is used, it may also be desireable to specify a preferred group + this feature is used, it may also be desirable to specify a preferred group when calling InitWriteDirs() to write these tags; this avoids creating other directories for tags which are already being creating in the preferred group. + PERMANENT : Tags in this table are Permanent, and can't be deleted. Maker + notes tags are Permanent by default, without the need to set this property. + SRC_TABLE : Used internally to store the source table name of a user-defined tag table so the appropriate module can be loaded as required. @@ -194,13 +202,16 @@ with tag keys. Below is an explanation of the meaning of each special key: ID_LABEL Label to use instead of "Tag ID" for column heading in tag name documentation. When this is set, numerical TagID's are - not converted to hexadecimal notation. Unless otherwise set, + not converted to hexadecimal notation. Unless otherwise set, an ID_LABEL of "Index" is assumed for tables which use ProcessBinaryData. NO_ID Avoid printing "Tag ID" column in tag name documentation. - HEX_ID Print tag ID in hexadecimal (with 4 hex digits or more). + HEX_ID Print tag ID in hexadecimal (with 4 hex digits or more). Set + to 0 for string ID's that look like hex numbers to prevent + them from being converted when importing an XML file for + language translations in BuildLangModules(). NO_LOOKUP Do not add tags to TagLookup.pm lookup tables. @@ -230,6 +241,10 @@ with tag keys. Below is an explanation of the meaning of each special key: START_INDEX [QuickTime tables only] Initial index for indices shown in Verbose output. Indices are not show otherwise. + ATOM_COUNT [QuickTime tables only] Maximum number of atoms contained in + within this atom. Currently used only for Canon CNTH atom, + which contains garbage after the first contained atom. + DATAMEMBER : BinaryData tables only. A reference to a list of sorted tag ID's which must be extracted as data members when writing. Must also list "var_" format tags and tags with Hook so offsets are properly calculated if the table @@ -245,7 +260,7 @@ describing this tag, or 3) a reference to a list of hashes which contain Condition expressions allowing the appropriate hash to be selected to suit the conditions. The following is a description of possible hash entries. All entries are optional, except for the tag Name which is required if the tag ID is -numerical. +numerical, and generated automatically otherwise. Name : The tag name. Tag names need not be unique. If they aren't unique, then duplicate tags will hide the values of previous @@ -349,6 +364,9 @@ numerical. 'DataTag' - associated tag name containing data for offset or byte count tags. + 'DelGroup' - set if deleting this tag is the same as deleting + the group of the same name. + 'Drop' - [IFD-format and PhaseOne makernote tags only] set to 1 for tags that should be excluded when rebuilding maker notes when copying all tags. Set to a number larger than 1 to drop @@ -456,8 +474,8 @@ numerical. 'PutFirst' - [EXIF only] flag to place this value before IFD0 when writing (ie. immediately after TIFF header). Only used - for main IFD's (IFD0, IFD1, etc) and IFD's where SubIFD flag - is set to 2 (currently only ExifIFD). + for values in main IFD's (IFD0, IFD1, etc) and IFD's where + SubIFD flag is set to 2 (currently only ExifIFD). 'RawJoin' - [List tags only] Joins raw List-type tag values into a single string with a space separator, allowing @@ -543,6 +561,10 @@ numerical. if a Warning may be issued) because ValueConv is more efficient since it is only executed if the tag value is requested, while RawConv is executed for all extracted tags. + Note that a tag is still writable if it has a RawConv without + a RawConvInv (with the exception of QuickTime ItemList and + UserData tags, which specifically require this), but this is + not true for ValueConv/PrintConv. ValueConv : Used to convert the Raw value to a useable form. May be a hash reference to act as a lookup table, a scalar which is @@ -551,53 +573,53 @@ numerical. split at whitespace into a list of items and each item is converted by the associated entry in the ValueConv list. A special value of 'REPEAT' may be used to repeat the previous - conversion for all remaning elements). If a hash reference is - used and the Raw value doesn't appear as one of the keys, then - the converted value is set to "Unknown (X)", where X is the - Raw value (unless either of the special keys exist: 'BITMASK', - a reference to a hash used to decode individual value bits; or - 'OTHER', a reference to a subroutine used to convert unknown - values. The OTHER subroutine takes 3 arguments: the value, a - flag which is set for the inverse conversion, and a reference - to the PrintConv hash, and returns the converted value or - undef on error -- it may call warn() to return an error - message. The lookup hash may also contain a 'Notes' entry - which is used for documentation if the SeparateTable flag is - set). In an expression, $self is a reference to the current - ExifTool object, $val is the Raw value, and $tag is the tag - key. The subroutine takes 2 arguments: the Raw value and a - reference to the current ExifTool object. The advanced - formatting expression (if any) may be accessed via the - ExifTool "FMT_EXPR" member variable. The expression or - subroutine is evaluated if and when the tag value is requested - (ie. only after all extraction is complete), so if necessary - at this time the values of all other tags are available via - calls to $self->GetValue("Tag","Raw"). (Note: In theory, - types other than "Raw" may be accessed, but they are slower - and may lead to cyclical dependencies so they should be - avoided). When evaluated, the expression or subroutine - returns a scalar for the converted value, a SCALAR reference - to a binary data value (see the 'Binary' flag), or an ARRAY - reference for a list of values. The return value should - always be defined -- use RawConv instead to return undef if it - is necessary to test the value for validity, otherwise an - undef tag may hide a previously defined value when the - Duplicates option is not enabled. If this isn't possible (as - with Composite tags where the converted values of the source - tags are needed), set the Priority to 0 to avoid taking - priority over a valid tag. If ValueConv is not specified, the - Raw value is not converted. Composite tags which Require or - Desire other tags may access the ValueConv, PrintConv and Raw - values of these tags through the elements of the @val, @prt - and @raw lists respectively (only if there was no RawConv or - it returned a hash reference). For these tags, $val may be - used in an expression to represent $val[0], and the first - argument passed for a code reference is a reference to @val. - Note: Warnings issued by these conversions are intercepted by - ExifTool and saved as Warning tags, but since ValueConv and - PrintConv conversions are done on demand, the warnings may be - generated after the list of extracted tags is returned, so may - easily be missed. + conversion for all remaining elements). If a hash reference + is used and the Raw value doesn't appear as one of the keys, + then the converted value is set to "Unknown (X)", where X is + the Raw value (unless either of the special keys exist: + 'BITMASK', a reference to a hash used to decode individual + value bits; or 'OTHER', a reference to a subroutine used to + convert unknown values. The OTHER subroutine takes 3 + arguments: the value, a flag which is set for the inverse + conversion, and a reference to the PrintConv hash, and returns + the converted value or undef on error -- it may call warn() to + return an error message. The lookup hash may also contain a + 'Notes' entry which is used for documentation if the + SeparateTable flag is set). In an expression, $self is a + reference to the current ExifTool object, $val is the Raw + value, and $tag is the tag key. The subroutine takes 2 + arguments: the Raw value and a reference to the current + ExifTool object. The advanced formatting expression (if any) + may be accessed via the ExifTool "FMT_EXPR" member variable. + The expression or subroutine is evaluated if and when the tag + value is requested (ie. only after all extraction is + complete), so if necessary at this time the values of all + other tags are available via calls to + $self->GetValue("Tag","Raw"). (Note: In theory, types other + than "Raw" may be accessed, but they are slower and may lead + to cyclical dependencies so they should be avoided). When + evaluated, the expression or subroutine returns a scalar for + the converted value, a SCALAR reference to a binary data value + (see the 'Binary' flag), or an ARRAY reference for a list of + values. The return value should always be defined -- use + RawConv instead to return undef if it is necessary to test the + value for validity, otherwise an undef tag may hide a + previously defined value when the Duplicates option is not + enabled. If this isn't possible (as with Composite tags where + the converted values of the source tags are needed), set the + Priority to 0 to avoid taking priority over a valid tag. If + ValueConv is not specified, the Raw value is not converted. + Composite tags which Require or Desire other tags may access + the ValueConv, PrintConv and Raw values of these tags through + the elements of the @val, @prt and @raw lists respectively + (only if there was no RawConv or it returned a hash + reference). For these tags, $val may be used in an expression + to represent $val[0], and the first argument passed for a code + reference is a reference to @val. Note: Warnings issued by + these conversions are intercepted by ExifTool and saved as + Warning tags, but since ValueConv and PrintConv conversions + are done on demand, the warnings may be generated after the + list of extracted tags is returned, so may easily be missed. PrintConv : This entry is similar to ValueConv above, except that it is used to further convert the tag value to a human readable @@ -674,8 +696,8 @@ numerical. BitShift : [Mask tags only] Bit shift for Mask-ed values. If not specified, set to the number of trailing bits in the Mask. - When reading, the value is shifted by this number of bits - after the Mask is applied. + When reading, the value is shifted right by this number of + bits after the Mask is applied. Condition : If given, specifies scalar which is evaluated as a Perl expression at extraction time to decide whether the tag is @@ -711,9 +733,10 @@ numerical. they are used as indices into the common @val, @prt and @raw lists), and together the keys must be sequential starting from 0. A special feature allows a scalar tag name to be used - instead of the hash reference when only the 0th tag is - defined. For example, the following two definitions are - equivalent: + instead of the hash reference, in which case the next + available index will be used (avoiding collisions with Desire + and Inhibit hash entries). For example, the following two + definitions are equivalent: Require => { 0 => 'XMP:Title' }, Require => 'XMP:Title', @@ -724,11 +747,15 @@ numerical. may be undefined for Desire'd tags. If no tags are Require'd, at least one of the Desire'd tags must exist for the Composite tag to be generated. If there are no Require'd or Desire'd - tags, then the Composite tag is always generated. + tags, then the Composite tag is always generated. A scalar + Desire tag name is given the next available index (after + scalar Require tags are allocated). Inhibit : [Composite tags only] Similar to the Require and Desire hashes, except that the Composite tag is NOT built if any of - the Inhibit tags exist. + the Inhibit tags exist. A scalar tag name is given the next + available index (after scalar Require and Desire tags are + allocated). Shift : [Writable tags only] Specifies type of shift to apply if this value may be shifted. Set to 'Time' for shifting date/time @@ -739,37 +766,41 @@ numerical. is set to zero), and for EXIF-type tables gives format for writing. Writable may be set to 1 for MakerNotes information because the existing format is always used, however providing - a format is desireable because it is used in validating the - value. For EXIF tables, the Writable flag may be different - than the Format flag, in which case Format is used for - converting the binary value and Writable specifies the format - code written to the EXIF IFD. For SubDirectories in EXIF - information, this flag is only defined if the SubDirectory is - writable as a block, or if the SubDirectory can not be edited - (in which case Writable is set to 0). If non-zero, the - SubDirectory is also extracted as a block, so the Binary and - Protected flags should usually set as well. There is - currently no way to specify a write format for a SubDirectory - that is not writable as a block (the default is 'int32u' for - IFD-type SubDirectories, and 'undef' for all others). + a format is desirable because it is used in validating the + value. Set to 2 for tag to show "yes" in the Writable column + of the tag name documentation even when there is no WRITE_PROC + defined (eg. if it is written via an Extra tag). For EXIF + tables, the Writable flag may be different than the Format + flag, in which case Format is used for converting the binary + value and Writable specifies the format code written to the + EXIF IFD. For SubDirectories in EXIF information, this flag + is only defined if the SubDirectory is writable as a block, or + if the SubDirectory can not be edited (in which case Writable + is set to 0). If non-zero, the SubDirectory is also extracted + as a block, so the Binary and Protected flags should usually + set as well. There is currently no way to specify a write + format for a SubDirectory that is not writable as a block (the + default is 'int32u' for IFD-type SubDirectories, and 'undef' + for all others). WriteAlso : Used for writable tag to specify other tags to write when this tag is written. The value is a hash reference. The hash keys are the names of the tags to write, and the values are evaluated to obtain the ValueConv values of each tag (or undef - to delete the tag). In the eval, $val is the Raw value of the - parent tag (which may be undef if the tag is being deleted, - and should not be modified because it will affect subsequent - WriteAlso tags), and the %opts hash may be accessed to modify - SetNewValue options for each tag. By default, Type is set to - "ValueConv" and the Protected option has bit 0x02 set to allow - writing of Protected tags that aren't directly writable. The - AddValue, DelValue, Shift and Replace options from the parent - tag are also defined, but no other options are set by default. - Previous new values of WriteAlso tags have already been - removed prior to the eval if the Replace option was used for - the parent tag. If an empty warning is issued ("\n"), the - target tag is not written and no error is reported. + to delete the tag). In the eval, $val is the new Raw value of + the parent tag (which may be undef if the tag is being + deleted, and should not be modified because it will affect + subsequent WriteAlso tags), and the %opts hash may be accessed + to modify SetNewValue options for each tag. By default, Type + is set to "ValueConv" and the Protected option has bit 0x02 + set to allow writing of Protected tags that aren't directly + writable. The AddValue, DelValue, Shift and Replace options + from the parent tag are also defined, but no other options are + set by default. Previous new values of WriteAlso tags have + already been removed prior to the eval if the Replace option + was used for the parent tag. If an empty warning is issued + ("\n"), the target tag is not written and no error is + reported. WriteCheck : If given, specifies a scalar which is evaluated as a Perl expression for a one-time validatation the Raw value being @@ -780,6 +811,9 @@ numerical. string is empty, the tag is not written and no warnings are issued, but WriteAlso is still evaluated if it exists. + WriteHook : [QuickTime only] Routine to call with these arguments when tag + is encountered during writing: 0) tag value, 1) ExifTool ref. + WriteOnly : Flag set if tag is write-only. Used for documentation only. DelCheck : Similar to WriteCheck, but called when the tag is deleted. The @@ -813,6 +847,8 @@ numerical. 0) ExifTool object ref, 1) new value hash ref, 2) old value, 3) new value reference. + Preferred : This tag is always preferred when writing. + Override : [User-defined Composite tags only] Flag to specify that the new tag definition should override the definition of existing Composite tags with the same name. Default is 1 unless @@ -874,13 +910,15 @@ numerical. Hook : [BinaryData tags only] Expression to be evaluated when extracting tag to allow dynamic Format, etc for BinaryData - tags. May access $self, and $size (the full size of the - binary data block), and assign a new value to $format to - dynamically set the tag format, and/or increment $varSize to - add a byte offset to subsequent tags. $varSize may be set to - a large number to effectively abort processing of the - directory after this tag. Must have corresponding DATAMEMBER - entry in writable tables. Must not have Unknown set. + tags. May access $self, $size (the full size of the binary + data record), $dataPt (reference to the data block), and $pos + (position of this tag in the data block), and assign a new + value to $format to dynamically set the tag format, and/or + increment $varSize to add a byte offset to subsequent tags. + $varSize may be set to a large number to effectively abort + processing of the directory after this tag. Must have + corresponding DATAMEMBER entry in writable tables. Must not + have Unknown set. LargeTag : [BinaryData tags only] Flag to indicate that the data for this tag is large, and that it shouldn't be stored in the %val @@ -978,7 +1016,7 @@ numerical. The following variables may be used in the expression: $val (value of the tag), $dirData (reference to directory data), $subdirStart (offset to subdirectory start) and $size (size of - subdirectory). Returns true if subirectory is valid. + subdirectory). Returns true if subdirectory is valid. ProcessProc: If given, specifies processing procedure used to decode this subdirectory data. This overrides the default procedure @@ -1057,7 +1095,7 @@ flattened tags are allowed, and are used when it is necessary to change the Name or Description of a flattened tag. The flattened tag information hash entries are copied from the corresponding structure field definitions, even for pre-defined flattened tags. The exception is that the List property is -generated automatically unless explicity set to 0 in a pre-defined flattened +generated automatically unless explicitly set to 0 in a pre-defined flattened tag. -------------------------------------------------------------------------------- diff --git a/src/Image-ExifTool/lib/Image/ExifTool/RIFF.pm b/src/Image-ExifTool/lib/Image/ExifTool/RIFF.pm index b37e0831..2ba6cf7a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/RIFF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/RIFF.pm @@ -29,7 +29,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.51'; +$VERSION = '1.54'; sub ConvertTimecode($); sub ProcessSGLT($$$); @@ -142,7 +142,7 @@ my %code2charset = ( 0x64 => 'APICOM G.726 ADPCM', 0x65 => 'APICOM G.722 ADPCM', 0x66 => 'Microsoft DSAT', #6 - 0x67 => 'Micorsoft DSAT DISPLAY', #6 + 0x67 => 'Microsoft DSAT DISPLAY', #6 0x69 => 'Voxware Byte Aligned', #7 0x70 => 'Voxware AC8', #7 0x71 => 'Voxware AC10', #7 @@ -339,7 +339,7 @@ my %code2charset = ( these files, information is extracted from subsequent RIFF chunks as sub-documents, but the Duration is calculated for the full video. }, - # (not 100% sure that the concatination technique mentioned above is valid - PH) + # (not 100% sure that the concatenation technique mentioned above is valid - PH) 'fmt ' => { Name => 'AudioFormat', SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AudioFormat' }, @@ -534,6 +534,38 @@ my %code2charset = ( ProcessProc => \&ProcessSLLT, }, }, + iXML => { #PH + SubDirectory => { TagTable => 'Image::ExifTool::XMP::XML' }, + }, + aXML => { #PH + SubDirectory => { TagTable => 'Image::ExifTool::XMP::XML' }, + }, +# +# tags found in an AlphaImagingTech AVI video - PH +# + LIST_INF0 => { # ('0' instead of 'O' -- odd) + Name => 'Info', + SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Info' }, + }, + gps0 => { + Name => 'GPSTrack', + SetGroups => 'RIFF', # (moves "QuickTime" tags to the "RIFF" group) + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Stream', + # (don't use code ref here or get "Prototype mismatch" warning with some Perl versions) + ProcessProc => 'Image::ExifTool::QuickTime::Process_gps0', + }, + }, + gsen => { + Name => 'GSensor', + SetGroups => 'RIFF', # (moves "QuickTime" tags to the "RIFF" group) + SubDirectory => { + TagTable => 'Image::ExifTool::QuickTime::Stream', + ProcessProc => 'Image::ExifTool::QuickTime::Process_gsen', + }, + }, + # gpsa - seen hex "01 20 00 00", same as QuickTime + # gsea - 16 bytes hex "04 08 02 00 20 02 00 00 1f 03 00 00 01 00 00 00" ); # the maker notes used by some digital cameras @@ -605,7 +637,11 @@ my %code2charset = ( Name => 'BWFVersion', Format => 'int16u', }, - # 348 - int8u[64] - SMPTE 330M UMID (Unique Material Identifier) + 348 => { + Name => 'BWF_UMID', + Format => 'undef[64]', + ValueConv => '$_=unpack("H*",$val); s/0{64}$//; uc $_', + }, # 412 - int8u[190] - reserved 602 => { Name => 'CodingHistory', @@ -878,7 +914,7 @@ my %code2charset = ( # RIFF character set chunk %Image::ExifTool::RIFF::CSET = ( - PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessBinaryData, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, GROUPS => { 2 => 'Other' }, FORMAT => 'int16u', 0 => { @@ -1248,7 +1284,7 @@ my %code2charset = ( # (can't calculate duration like this for compressed audio types) RawConv => q{ return undef if $$self{VALUE}{FileType} =~ /^(LA|OFR|PAC|WV)$/; - return ($val[0] and not ($val[2] or $val[3])) ? $val[1] / $val[0] : undef; + return(($val[0] and not ($val[2] or $val[3])) ? $val[1] / $val[0] : undef); }, PrintConv => 'ConvertDuration($val)', }, @@ -1320,7 +1356,8 @@ sub CalcDuration($@) # FujiFilm REAL 3D AVI's), but the video stream information isn't reliable for # some cameras (eg. Olympus FE models), so use the video stream information # only if the RIFF header duration is 2 to 3 times longer - my $dur1 = $val[1] / $val[0] if $val[0]; + my $dur1; + $dur1 = $val[1] / $val[0] if $val[0]; if ($val[2] and $val[3]) { my $dur2 = $val[3] / $val[2]; my $rat = $dur1 / $dur2; @@ -1431,8 +1468,7 @@ sub MakeTagInfo($$) #------------------------------------------------------------------------------ # Process RIFF chunks -# Inputs: 0) ExifTool object reference, 1) directory information reference -# 2) tag table reference +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref # Returns: 1 on success sub ProcessChunks($$$) { @@ -1660,9 +1696,14 @@ sub ProcessRIFF($$) } # RIFF chunks are padded to an even number of bytes my $len2 = $len + ($len & 0x01); - if ($$tagTbl{$tag} or (($verbose or $unknown) and $tag !~ /^(data|idx1|LIST_movi|RIFF)$/)) { + my $tagInfo = $$tagTbl{$tag}; + if ($tagInfo or (($verbose or $unknown) and $tag !~ /^(data|idx1|LIST_movi|RIFF)$/)) { $raf->Read($buff, $len2) == $len2 or $err=1, last; - MakeTagInfo($tagTbl, $tag) if not $$tagTbl{$tag} and ($verbose or $unknown); + my $setGroups; + if ($tagInfo and ref $tagInfo eq 'HASH' and $$tagInfo{SetGroups}) { + $setGroups = $$et{SET_GROUP0} = $$et{SET_GROUP1} = $$tagInfo{SetGroups}; + } + MakeTagInfo($tagTbl, $tag) if not $tagInfo and ($verbose or $unknown); $et->HandleTag($tagTbl, $tag, $buff, DataPt => \$buff, DataPos => 0, # (relative to Base) @@ -1670,6 +1711,10 @@ sub ProcessRIFF($$) Size => $len2, Base => $pos, ); + if ($setGroups) { + delete $$et{SET_GROUP0}; + delete $$et{SET_GROUP1}; + } } elsif ($tag eq 'RIFF') { # don't read into RIFF chunk (eg. concatenated video file) $raf->Read($buff, 4) == 4 or $err=1, last; @@ -1709,7 +1754,7 @@ including AVI videos, WAV audio files and WEBP images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/RSRC.pm b/src/Image-ExifTool/lib/Image/ExifTool/RSRC.pm index 61216997..95f431a8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/RSRC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/RSRC.pm @@ -23,7 +23,7 @@ $VERSION = '1.08'; Tags extracted from Mac OS resource files and DFONT files. These tags may also be extracted from the resource fork of any file in OS X, either by adding "/..namedfork/rsrc" to the filename to process the resource fork - alone, or by using the ExtractEmbedded (-ee) option to process the resource + alone, or by using the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> (-ee) option to process the resource fork as a sub-document of the main file. When writing, ExifTool preserves the Mac OS resource fork by default, but it may deleted with C<-rsrc:all=> on the command line. @@ -219,7 +219,7 @@ resource files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/RTF.pm b/src/Image-ExifTool/lib/Image/ExifTool/RTF.pm index 81f177bb..564d773c 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/RTF.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/RTF.pm @@ -153,7 +153,7 @@ sub UnescapeRTF($$$) $val =~ tr/\n\r//d; # ignore CR's and LF's return $val; } - # CR/LF is signficant if it terminates a control sequence (so change these to a space) + # CR/LF is significant if it terminates a control sequence (so change these to a space) # (was $val =~ s/(^|[^\\])((?:\\\\)*)(\\[a-zA-Z]+(?:-?\d+)?)[\n\r]/$1$2$3 /g;) $val =~ s/\\(?:([a-zA-Z]+(?:-?\d+)?)[\n\r]|(.))/'\\'.($1 ? "$1 " : $2)/sge; # protect the newline control sequence by converting to a \par command @@ -361,7 +361,7 @@ information from RTF (Rich Text Format) documents. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Radiance.pm b/src/Image-ExifTool/lib/Image/ExifTool/Radiance.pm index 6dd8611b..572b0e18 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Radiance.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Radiance.pm @@ -120,7 +120,7 @@ images are a type of high dynamic-range image. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Rawzor.pm b/src/Image-ExifTool/lib/Image/ExifTool/Rawzor.pm index cf537db2..6c19b1b2 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Rawzor.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Rawzor.pm @@ -168,7 +168,7 @@ information from Rawzor compressed images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Real.pm b/src/Image-ExifTool/lib/Image/ExifTool/Real.pm index 4b1c58f4..19a78097 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Real.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Real.pm @@ -715,7 +715,7 @@ little-endian, but the Real format is big-endian. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Reconyx.pm b/src/Image-ExifTool/lib/Image/ExifTool/Reconyx.pm index 2b7b62b7..8f0b1d97 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Reconyx.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Reconyx.pm @@ -7,6 +7,7 @@ # # References: 1) RCNX_MN10.pdf (courtesy of Reconyx Inc.) # 2) ultrafire_makernote.pdf (courtesy of Reconyx Inc.) +# 3) Reconyx private communication #------------------------------------------------------------------------------ package Image::ExifTool::Reconyx; @@ -14,7 +15,7 @@ package Image::ExifTool::Reconyx; use strict; use vars qw($VERSION); -$VERSION = '1.05'; +$VERSION = '1.06'; # info for Type2 version tags my %versionInfo = ( @@ -287,6 +288,132 @@ my %versionInfo = ( }, ); +# maker notes for Reconyx HF2 PRO cameras (ref 3) +%Image::ExifTool::Reconyx::Type3 = ( + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + WRITE_PROC => \&Image::ExifTool::WriteBinaryData, + CHECK_PROC => \&Image::ExifTool::CheckBinaryData, + TAG_PREFIX => 'Reconyx', + WRITABLE => 1, + FIRST_ENTRY => 0, + NOTES => 'Tags extracted from models such as the HF2 PRO.', + # 0x0a => { Name => 'StructureVersion', Format => 'int16u' }, + # 0x0c => { Name => 'ParentFileSize', Format => 'int32u' }, + 0x10 => { Name => 'FileNumber', Format => 'int16u' }, + 0x12 => { Name => 'DirectoryNumber', Format => 'int16u' }, + # 0x14 => { Name => 'DirCreateDate', Format => 'int16u' }, + # 0x16 => { Name => 'DirCreateTime', Format => 'int16u' }, + # 0x18 - int16[8] SDCardLabel + # 0x28 => { Name => 'MakerNoteVersion', Format => 'int16u' }, + 0x2a => { + Name => 'FirmwareVersion', + Format => 'int16u[3]', + ValueConv => 'my @a = split " ",$val; sprintf("%d.%d%c",@a)', + ValueConvInv => '$val=~/(\d+)\.(\d+)([a-zA-Z])/ ? "$1 $2 ".ord($3) : undef', + }, + 0x30 => { + Name => 'FirmwareDate', + Format => 'int16u[2]', + ValueConv => 'my ($y,$d) = split " ", $val; sprintf("%.4x:%.2x:%.2x",$y,$d>>8,$d&0xff)', + ValueConvInv => 'my @a=split ":", $val; hex($a[0])." ".hex($a[1].$a[2])', + }, + 0x34 => { + Name => 'TriggerMode', #PH (NC) (called EventType in the Reconyx code) + Format => 'string[2]', + PrintConv => { + M => 'Motion Detection', # (seen this one only) + T => 'Time Lapse', # (NC) + P => 'Point and Shoot', # (NC) + }, + }, + 0x36 => { + Name => 'Sequence', + Format => 'int16u[2]', + PrintConv => '$val =~ s/ / of /; $val', + PrintConvInv => 'join(" ", $val=~/\d+/g)', + }, + 0x3a => { + Name => 'EventNumber', + Format => 'int16u[2]', + ValueConv => 'my @a=split " ",$val;($a[0]<<16)+$a[1]', + ValueConvInv => '($val >> 16) . " " . ($val & 0xffff)', + }, + 0x3e => { + Name => 'DateTimeOriginal', + Description => 'Date/Time Original', + Format => 'int16u[6]', + Groups => { 2 => 'Time' }, + Priority => 0, # (not as reliable as EXIF) + Shift => 'Time', + ValueConv => q{ + my @a = split ' ', $val; + sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', reverse @a); + }, + ValueConvInv => q{ + my @a = ($val =~ /\d+/g); + return undef unless @a >= 6; + join ' ', @a[6,5,4,3,2,1,0]; + }, + PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val)', + }, + 0x4a => { #2 + Name => 'DayOfWeek', + Groups => { 2 => 'Time' }, + Format => 'int16u', + PrintConv => { + 0 => 'Sunday', + 1 => 'Monday', + 2 => 'Tuesday', + 3 => 'Wednesday', + 4 => 'Thursday', + 5 => 'Friday', + 6 => 'Saturday', + }, + }, + 0x4c => { + Name => 'MoonPhase', + Groups => { 2 => 'Time' }, + Format => 'int16u', + PrintConv => { + 0 => 'New', + 1 => 'New Crescent', + 2 => 'First Quarter', + 3 => 'Waxing Gibbous', + 4 => 'Full', + 5 => 'Waning Gibbous', + 6 => 'Last Quarter', + 7 => 'Old Crescent', + }, + }, + 0x4e => { + Name => 'AmbientTemperatureFahrenheit', + Format => 'int16s', + PrintConv => '"$val F"', + PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val', + }, + 0x50 => { + Name => 'AmbientTemperature', + Format => 'int16s', + PrintConv => '"$val C"', + PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val', + }, + 0x52 => { Name => 'Contrast', Format => 'int16u' }, + 0x54 => { Name => 'Brightness', Format => 'int16u' }, + 0x56 => { Name => 'Sharpness', Format => 'int16u' }, + 0x58 => { Name => 'Saturation', Format => 'int16u' }, + 0x5a => { Name => 'Flash', Format => 'int16u', PrintConv => { 0 => 'Off', 1 => 'On' } }, + 0x5c => { Name => 'AmbientInfrared', Format => 'int16u' }, + 0x5e => { Name => 'AmbientLight', Format => 'int16u' }, + 0x60 => { Name => 'MotionSensitivity', Format => 'int16u' }, + 0x62 => { Name => 'BatteryVoltage', Format => 'int16u' }, + 0x64 => { Name => 'BatteryVoltageAvg', Format => 'int16u' }, + 0x66 => { Name => 'BatteryType', Format => 'int16u' }, + 0x68 => { Name => 'UserLabel', Format => 'string[22]' }, + 0x7e => { Name => 'SerialNumber', Format => 'unicode[15]' }, +); + __END__ =head1 NAME @@ -304,7 +431,7 @@ maker notes in images from Reconyx cameras. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Red.pm b/src/Image-ExifTool/lib/Image/ExifTool/Red.pm new file mode 100644 index 00000000..a0cd9eb0 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Red.pm @@ -0,0 +1,325 @@ +#------------------------------------------------------------------------------ +# File: Red.pm +# +# Description: Read Redcode R3D video files +# +# Revisions: 2018-01-25 - P. Harvey Created +# +# References: 1) http://www.wikiwand.com/en/REDCODE +#------------------------------------------------------------------------------ + +package Image::ExifTool::Red; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.01'; + +sub ProcessR3D($$); + +# RED format codes (ref PH) +my %redFormat = ( + 0 => 'int8u', + 1 => 'string', + 2 => 'float', + 3 => 'int8u', # (how is this different than 0?) + 4 => 'int16u', + 5 => 'int8s', # (not sure about this) + 6 => 'int32s', + 7 => 'undef', # (mixed-format structure?) + 8 => 'int32u', # (NC) + 9 => 'undef', # ? (seen 256 bytes, all zero) +); + +# error strings +my $errTrunc = 'Truncated R3D file'; + +# RED directory tags (ref PH) +%Image::ExifTool::Red::Main = ( + GROUPS => { 2 => 'Camera' }, + NOTES => 'Tags extracted from Redcode R3D video files.', + VARS => { ALPHA_FIRST => 1 }, + + RED1 => { Name => 'Red1Header', SubDirectory => { TagTable => 'Image::ExifTool::Red::RED1' } }, + RED2 => { Name => 'Red2Header', SubDirectory => { TagTable => 'Image::ExifTool::Red::RED2' } }, + + # (upper 4 bits of tag ID are the format code) + # ---- format 1 ---- + 0x1000 => 'StartEdgeCode', #1 + 0x1001 => { Name => 'StartTimecode', Groups => { 2 => 'Time' } }, #1 + 0x1002 => { #1 + Name => 'OtherDate1', + Groups => { 2 => 'Time' }, + # format is "YYYY_MM_DD[_TZ?]" + ValueConv => '$val =~ s/(\d{4})_(\d{2})_/$1:$2:/; $val =~ tr/_/ /; $val', + }, + 0x1003 => { #1 + Name => 'OtherDate2', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{4})_(\d{2})_/$1:$2:/; $val =~ tr/_/ /; $val', + }, + 0x1004 => { #1 + Name => 'OtherDate3', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{4})_(\d{2})_/$1:$2:/; $val =~ tr/_/ /; $val', + }, + 0x1005 => { #1 + Name => 'DateTimeOriginal', + Description => 'Date/Time Original', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})/$1:$2:$3 $4:$5:/; $val', + PrintConv => '$self->ConvertDateTime($val)', + }, + 0x1006 => 'SerialNumber', #1 + 0x1019 => 'CameraType', #1 + 0x101a => { Name => 'ReelNumber', Groups => { 2 => 'Video' } }, #1 + 0x101b => { Name => 'Take', Groups => { 2 => 'Video' } }, + 0x1023 => { #1 + Name => 'DateCreated', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{4})(\d{2})/$1:$2:/; $val', + }, + 0x1024 => { #1 + Name => 'TimeCreated', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{2})(\d{2})/$1:$2:/; $val', + }, + 0x1025 => 'FirmwareVersion', #1 + 0x1029 => { Name => 'ReelTimecode', Groups => { 2 => 'Time' } }, #1 + 0x102a => 'StorageType', #1 + 0x1030 => { #1 + Name => 'StorageFormatDate', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{4})(\d{2})/$1:$2:/; $val', + }, + 0x1031 => { #1 + Name => 'StorageFormatTime', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ s/(\d{2})(\d{2})/$1:$2:/; $val', + }, + 0x1032 => 'StorageSerialNumber', #1 + 0x1033 => 'StorageModel', #1 + 0x1036 => 'AspectRatio', #1 + # 0x1041 - seen 'NA' + 0x1042 => 'Revision', # ? (seen "TODO, rev EPIC-1.0" and "MYSTERIUM X, rev EPIC-1.0") + # 0x1051 - seen 'C', 'L' + 0x1056 => 'OriginalFileName', + 0x106e => 'LensMake', + 0x106f => 'LensNumber', # (last 2 hex digits are LensType) + 0x1070 => 'LensModel', + 0x1071 => { + Name => 'Model', + Description => 'Camera Model Name', + }, + 0x107c => { Name => 'CameraOperator', Groups => { 2 => 'Author' } }, + 0x1086 => { + Name => 'VideoFormat', + Groups => { 2 => 'Video' }, + }, + 0x1096 => 'Filter', # optical low-pass filter + 0x10a0 => 'Brain', + 0x10a1 => 'Sensor', + # ---- format 2 ---- + 0x200d => 'ColorTemperature', + # 0x200e - (sometimes this is frame rate) + # 0x2015 - seen '1 1 1' (RGBGain or RGBGamma?) + 0x204b => 'RGBCurves', # (blackx/y,toex/y,midx/y,kneex/y,whitex/y) + 0x2066 => { + Name => 'OriginalFrameRate', + Groups => { 2 => 'Video' }, + PrintConv => 'int($val * 1000 + 0.5) / 1000', + }, + # ---- format 4 ---- + 0x4037 => { Name => 'CropArea' }, # (NC) + 0x403b => 'ISO', + # 0x404e - related to CropArea (or "0 0 0 0") + 0x406a => { Name => 'FNumber', ValueConv => '$val / 10' }, + 0x406b => 'FocalLength', + # 0x4084 - related to ISO? + # 0x4087 - related to ISO? + # ---- format 6 ---- + 0x606c => { Name => 'FocusDistance', ValueConv => '$val/1000', PrintConv => '"$val m"' }, +); + +# RED1 file header (ref PH) +%Image::ExifTool::Red::RED1 = ( + GROUPS => { 2 => 'Video' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + NOTES => 'Redcode version 1 header.', + # 0x00 - int32u: length of header + # 0x04 - string: "RED1" + # 0x0a - string: "R1" + 0x07 => { Name => 'RedcodeVersion', Format => 'string[1]' }, #1 + # 0x0e - looks funny; my sample has a value of 43392 here + # 0x0e => { Name => 'AudioSampleRate', Format => 'int16u' }, #1 + 0x36 => { Name => 'ImageWidth', Format => 'int16u' }, #1 + 0x3a => { Name => 'ImageHeight', Format => 'int16u' }, #PH (ref 1 gave 0x3c) + 0x3e => { #PH (ref 1 gave 0x42 for denom) + Name => 'FrameRate', + Format => 'rational32u', + PrintConv => 'int($val * 1000 + 0.5) / 1000', + }, + 0x43 => { Name => 'OriginalFileName', Format => 'string[32]' }, #1 +); + +# RED2 file header (ref PH) +%Image::ExifTool::Red::RED2 = ( + GROUPS => { 2 => 'Video' }, + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + NOTES => 'Redcode version 2 header.', + # 0x00 - int32u: length of header + # 0x04 - string: "RED2" + 0x07 => { Name => 'RedcodeVersion', Format => 'string[1]' }, + # 0x08 - seen 0x05 + # 0x09 - seen 0x0d,0x0f,0x10 + # 0x0a - string: "R2" + # 0x0c - seen 0x04,0x05,0x07,0x08,0x0b,0x0c + # 0x0d - seen 0x01,0x08 (and 0x09 in block 1) + # 0x0e - int16u: seen 3072 + # 0x10 - looks like some sort of 32-byte hash or something (same in other blocks) + # 0x30-0x3f - mostly 0x00's with a couple of 0x01's + # 0x40 - int8u: count of 0x18-byte "rdi" records + # 0x41-0x43 - seen "\0\0\x01" + # ---- rdi record: (0x18 bytes long) ---- + # 0x44 - string: "rdi#" (where number is index of "rdi" record, starting at \x01) + 0x4c => { Name => 'ImageWidth', Format => 'int32u' }, + 0x50 => { Name => 'ImageHeight', Format => 'int32u' }, + # 0x54 - seen 0x11,0x13,0x15 (and 0x03 in "rdi\x02" record) + # 0x55 - seen 0x02 + 0x56 => { + Name => 'FrameRate', + Format => 'int16u[3]', + ValueConv => 'my @a = split " ",$val; ($a[1] * 0x10000 + $a[2]) / $a[0]', + PrintConv => 'int($val * 1000 + 0.5) / 1000', + }, + # (immediately following last "rdi" record is a + # Red directory beginning with int16u size) +); + +#------------------------------------------------------------------------------ +# Process metadata from a Redcode R3D video (ref PH) +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid R3D file +sub ProcessR3D($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $buf2, $pos, $dirLen, $dirEnd); + my $verbose = $et->Options('Verbose'); + + # R3D file structure: + # - each block starts with int32u block size followed by 4-byte block type + # - first block type is either "RED1" (version 1) or "RED2" (version 2) + # - blocks begin on even 0x1000 byte boundaries for version 2 files + + # validate the file header + return 0 unless $raf->Read($buff, 8) == 8 and $buff =~ /^\0\0..RED(1|2)/s; + my $ver = $1; + my $size = unpack('N', $buff); + return 0 if $size < 8; + + $et->SetFileType(); + SetByteOrder('MM'); + my $tagTablePtr = GetTagTable('Image::ExifTool::Red::Main'); + my $dataPos = 0; + + # read the first block of the file + $raf->Read($buf2, $size - 8) == $size - 8 or return $et->Warn($errTrunc); + $buff .= $buf2; + + # extract tags from the header + $et->HandleTag($tagTablePtr, "RED$ver", undef, DataPt => \$buff); + + # read the second block from a version 1 file because + # the first block doesn't contain a Red directory + if ($ver eq '1') { + # (read more than we need) + $raf->Read($buff, 0x10000) or return $et->Warn($errTrunc); + $dataPos += $size; + $pos = 0x22; # directory starts at offset 0x22 + } else { + # calculate position of Red directory start + length($buff) < 0x41 and return $et->Warn($errTrunc); + my $n = Get8u(\$buff, 0x40); # number of "rdi" records + $pos = 0x44 + $n * 0x18; + } + if ($pos + 8 > length $buff) { + $dirLen = 0; # find directory the hard way + } else { + $dirLen = Get16u(\$buff, $pos); # get length of Red directory + $pos += 2; # skip length word + } + # do sanity check on the directory size (in case our assumptions were wrong) + if ($dirLen < 300 or $dirLen >= 2048 or $pos + $dirLen > length $buff) { + # tag 0x1000 with length 0x000f should be near the directory start + $buff =~ /\0\x0f\x10\0/g or return $et->Warn("Can't find Red directory"); + $pos = pos($buff) - 4; + $dirEnd = length $buff; + undef $dirLen; + $et->Warn('This R3D file is different. Please submit a sample for testing'); + } else { + $dirEnd = $pos + $dirLen; + } + $$et{INDENT} .= '| ', $et->VerboseDir('Red', undef, $dirLen) if $verbose; + + # process the first Red directory + while ($pos + 4 <= $dirEnd) { + my $len = Get16u(\$buff, $pos); + last if $len < 4 or $pos + $len > $dirEnd; + my $tag = Get16u(\$buff, $pos + 2); + my $fmt = $redFormat{$tag >> 12}; # format is top 4 bits of tag ID (ref PH) + $fmt or $dirLen && $et->Warn('Unknown format code'), last; + $et->HandleTag($tagTablePtr, $tag, undef, + DataPt => \$buff, + DataPos => $dataPos, + Start => $pos + 4, + Size => $len - 4, + Format => $fmt, + ); + $pos += $len; + } + $$et{INDENT} = substr($$et{INDENT}, 0, -2) if $verbose; + + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Red - Read Redcode R3D video files + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains routines required by Image::ExifTool to read metadata +from Redcode R3D version 1 and 2 video files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<http://www.wikiwand.com/en/REDCODE> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/Red Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Ricoh.pm b/src/Image-ExifTool/lib/Image/ExifTool/Ricoh.pm index 7807b25a..6c22ab01 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Ricoh.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Ricoh.pm @@ -19,7 +19,7 @@ use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.33'; +$VERSION = '1.34'; sub ProcessRicohText($$$); sub ProcessRicohRMETA($$$); @@ -330,9 +330,13 @@ my %ricohLensIDs = ( }, }, 0x1018 => { #3 - Name => 'CropMode35mm', + Name => 'CropMode', Writable => 'int16u', - PrintConv => { 0 => 'Off', 1 => 'On' }, + PrintConv => { + 0 => 'Off', + 1 => 'On (35mm)', + 2 => 'On (47mm)', #IB + }, }, 0x1019 => { #3 Name => 'NDFilter', @@ -1121,7 +1125,7 @@ interpret Ricoh maker notes EXIF meta information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Samsung.pm b/src/Image-ExifTool/lib/Image/ExifTool/Samsung.pm index caeb8521..d750c126 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Samsung.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Samsung.pm @@ -11,7 +11,7 @@ # 4) Jaroslav Stepanek via rt.cpan.org # 5) Nick Livchits private communication # 6) Sreerag Raghavan private communication (SM-C200) -# IB) Iliah Borg private communcation (LibRaw) +# IB) Iliah Borg private communication (LibRaw) # NJ) Niels Kristian Bech Jensen private communication #------------------------------------------------------------------------------ @@ -22,10 +22,11 @@ use vars qw($VERSION %samsungLensTypes); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; -$VERSION = '1.43'; +$VERSION = '1.48'; sub WriteSTMN($$$); sub ProcessINFO($$$); +sub ProcessSamsungMeta($$$); sub ProcessSamsungIFD($$$); # Samsung LensType lookup @@ -111,7 +112,7 @@ my %formatMinMax = ( This is a standard-format IFD found in the maker notes of some Samsung models, except that the entry count is a 4-byte integer and the offsets are relative to the end of the IFD. Currently, no tags in this IFD are known, - so the Unknown (-u) or Verbose (-v) option must be used to see this + so the L<Unknown|../ExifTool.html#Unknown> (-u) or L<Verbose|../ExifTool.html#Verbose> (-v) option must be used to see this information. }, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, @@ -234,6 +235,7 @@ my %formatMinMax = ( 0x500103c => 'WB600 / VLUU WB600 / WB610', 0x500133e => 'WB150 / WB150F / WB152 / WB152F / WB151', 0x5a0000f => 'WB5000 / HZ25W', + 0x5a0001e => 'WB5500 / VLUU WB5500 / HZ50W', 0x6001036 => 'EX1', 0x700131c => 'VLUU SH100, SH100', 0x27127002 => 'SMX-C20N', @@ -924,10 +926,20 @@ my %formatMinMax = ( 4 => { Name => 'ThumbnailOffset', IsOffset => 1 }, ); +# information extracted from "ssuniqueid\0" APP5 (ref PH) +%Image::ExifTool::Samsung::APP5 = ( + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + ssuniqueid => { + Name => 'UniqueID', + # 32 bytes - some sort of serial number? + ValueConv => 'unpack("H*",$val)', + }, +); + # information extracted from Samsung trailer (ie. Samsung SM-T805 "Sound & Shot" JPEG) (ref PH) %Image::ExifTool::Samsung::Trailer = ( GROUPS => { 0 => 'MakerNotes', 2 => 'Other' }, - VARS => { NO_ID => 1 }, + VARS => { NO_ID => 1, HEX_ID => 0 }, NOTES => q{ Tags extracted from the trailer of JPEG images written when using certain features (such as "Sound & Shot" or "Shot & More") from Samsung models such @@ -948,6 +960,8 @@ my %formatMinMax = ( # 0x08e0-name - seen 'Panorama_Shot_Info' # 0x08e0 - string, seen 'PanoramaShot' # 0x08e1-name - seen 'Motion_Panorama_Info' + # 0x0910-name - seen 'Front_Cam_Selfie_Info' + # 0x0910 - string, seen 'Front_Cam_Selfie_Info' # 0x09e0-name - seen 'Burst_Shot_Info' # 0x09e0 - string, seen '489489125' # 0x0a01-name - seen 'Image_UTC_Data' @@ -963,27 +977,95 @@ my %formatMinMax = ( '0x0a30' => { Name => 'EmbeddedVideoFile', Groups => { 2 => 'Video' }, Binary => 1 }, #forum7161 # 0x0aa1-name - seen 'MCC_Data' # 0x0aa1 - seen '234','222' + # 0x0ab0-name - seen 'DualShot_Meta_Info' '0x0ab1-name' => 'DepthMapName', # seen 'DualShot_DepthMap_1' (SM-N950U) '0x0ab1' => { Name => 'DepthMapData', Binary => 1 }, # 0x0ab3-name - seen 'DualShot_Extra_Info' (SM-N950U) '0x0ab3' => { # (SM-N950U) - Name => 'DualShotInfo', - SubDirectory => { TagTable => 'Image::ExifTool::Samsung::DualShotInfo' }, + Name => 'DualShotExtra', + SubDirectory => { TagTable => 'Image::ExifTool::Samsung::DualShotExtra' }, }, # 0x0ac0-name - seen 'ZoomInOut_Info' (SM-N950U) # 0x0ac0 - 2048 bytes of interesting stuff including firmware version? (SM-N950U) + '0x0b40' => { # (SM-N975X front camera) + Name => 'SingleShotMeta', + SubDirectory => { TagTable => 'Image::ExifTool::Samsung::SingleShotMeta' }, + }, + # 0x0b41-name - seen 'SingeShot_DepthMap_1' (Yes, "Singe") (SM-N975X front camera) + '0x0b41' => { Name => 'SingleShotDepthMap', Binary => 1 }, # 0xa050-name - seen 'Jpeg360_2D_Info' (Samsung Gear 360) # 0xa050 - seen 'Jpeg3602D' (Samsung Gear 360) ); # DualShot Extra Info (ref PH) -%Image::ExifTool::Samsung::DualShotInfo = ( +%Image::ExifTool::Samsung::DualShotExtra = ( PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, FIRST_ENTRY => 0, FORMAT => 'int32u', - 9 => 'DepthMapWidth', - 10 => 'DepthMapHeight', + # This is a pain, but the DepthMapWidth/Height move around in this record. + # In all of my samples so far, the bytes "01 00 ff ff" precede these tags. + # I have seen this byte sequence at offsets 32, 60, 64 and 68, so look for + # it in bytes 32-95, and use its location to adjust the tag positions + 8 => { + Name => 'DualShotDummy', + Format => 'undef[64]', + Hidden => 1, + Hook => q{ + if ($size >= 96) { + my $tmp = substr($$dataPt, $pos, 64); + if ($tmp =~ /\x01\0\xff\xff/g and not pos($tmp) % 4) { + $$self{DepthMapTagPos} = pos($tmp); + $varSize += $$self{DepthMapTagPos} - 32; + } + } + }, + RawConv => 'undef', # not a real tag + }, + 16 => { + Name => 'DepthMapWidth', + Condition => '$$self{DepthMapTagPos}', + Notes => 'index varies depending on model', + }, + 17 => { + Name => 'DepthMapHeight', + Condition => '$$self{DepthMapTagPos}', + Notes => 'index varies depending on model', + }, +); + +# SingleShot Meta Info (ref PH) (SM-N975X front camera) +%Image::ExifTool::Samsung::SingleShotMeta = ( + PROCESS_PROC => \&ProcessSamsungMeta, + GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + inputWidth => { }, + inputHeight => { }, + outputWidth => { }, + outputHeight => { }, + segWidth => { }, + segHeight => { }, + depthSWWidth => { }, + depthSWHeight => { }, + depthHWWidth => { }, + depthHWHeight => { }, + flipStatus => { }, + lensFacing => { }, + deviceOrientation => { }, + objectOrientation => { }, + isArtBokeh => { }, + beautyRetouchLevel => { }, + beautyColorLevel => { }, + effectType => { }, + effectStrength => { }, + blurStrength => { }, + spinStrength => { }, + zoomStrength => { }, + colorpopStrength => { }, + monoStrength => { }, + sidelightStrength => { }, + vintageStrength => { }, + bokehShape => { }, + perfMode => { }, ); # Samsung composite tags @@ -1012,7 +1094,19 @@ my %formatMinMax = ( my $tiff = MakeTiffHeader($val[1],$val[2],1,8) . ${$val[0]}; return \$tiff; }, - } + }, + SingleShotDepthMapTiff => { + Require => { + 0 => 'SingleShotDepthMap', + 1 => 'SegWidth', + 2 => 'SegHeight', + }, + ValueConv => q{ + return undef unless length ${$val[0]} == $val[1] * $val[2]; + my $tiff = MakeTiffHeader($val[1],$val[2],1,8) . ${$val[0]}; + return \$tiff; + }, + }, ); # add our composite tags @@ -1081,6 +1175,54 @@ sub ProcessINFO($$$) return 1; } +#------------------------------------------------------------------------------ +# Read Samsung Meta Info from trailer +# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref +# Returns: true on success +sub ProcessSamsungMeta($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dirName = $$dirInfo{DirName}; + my $dataPt = $$dirInfo{DataPt}; + my $pos = $$dirInfo{DirStart}; + my $end = $$dirInfo{DirLen} + $pos; + unless ($pos + 8 <= $end and substr($$dataPt, $pos, 4) eq 'DOFS') { + $et->Warn("Unrecognized $dirName data"); + return 0; + } + my $ver = Get32u($dataPt, $pos + 4); + if ($ver == 3) { + unless ($pos + 18 <= $end and Get32u($dataPt, $pos + 12) == $$dirInfo{DirLen}) { + $et->Warn("Unrecognized $dirName version $ver data"); + return 0; + } + my $num = Get16u($dataPt, $pos + 16); + $et->VerboseDir("$dirName version $ver", $num); + $pos += 18; + my ($i, $val); + for ($i=0; $i<$num; ++$i) { + last if $pos + 2 > $end; + my ($x, $n) = unpack("x${pos}CC", $$dataPt); + $pos += 2; + last if $pos + $n + 2 > $end; + my $tag = substr($$dataPt, $pos, $n); + my $len = Get16u($dataPt, $pos + $n); + $pos += $n + 2; + last if $pos + $len > $end; + if ($len == 4) { + $val = Get32u($dataPt, $pos); + } else { + my $tmp = substr($$dataPt, $pos, $len); + $val = \$pos; + } + $et->HandleTag($tagTablePtr, $tag, $val); + $pos += $len; + } + $et->Warn("Unexpected end of $dirName version $ver $i $num data") if $i < $num; + } + return 1; +} + #------------------------------------------------------------------------------ # Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref # Returns: true on success @@ -1305,7 +1447,7 @@ Samsung maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Sanyo.pm b/src/Image-ExifTool/lib/Image/ExifTool/Sanyo.pm index 68fad062..d594dcaa 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Sanyo.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Sanyo.pm @@ -419,7 +419,7 @@ Sanyo maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Scalado.pm b/src/Image-ExifTool/lib/Image/ExifTool/Scalado.pm index 43583278..27e34869 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Scalado.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Scalado.pm @@ -128,7 +128,7 @@ metadata from the JPEG APP4 SCALADO segment. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Shift.pl b/src/Image-ExifTool/lib/Image/ExifTool/Shift.pl index fc2ccf00..dbdbd511 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Shift.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/Shift.pl @@ -4,13 +4,14 @@ # Description: ExifTool time shifting routines # # Revisions: 10/28/2005 - P. Harvey Created +# 03/13/2019 - PH Added single-argument form of ShiftTime() #------------------------------------------------------------------------------ package Image::ExifTool; use strict; -sub ShiftTime($$;$$); +sub ShiftTime($;$$$); #------------------------------------------------------------------------------ # apply shift to value in new value hash @@ -280,12 +281,19 @@ ($$$;$) # Inputs: 0) date/time string, 1) shift string, 2) shift direction (+1 or -1), # or 0 or undef to take shift direction from sign of shift, # 3) reference to ShiftOffset hash (with Date, DateTime, Time, Timezone keys) +# or 0) shift string (and operates on $_) # Returns: error string or undef on success and date/time string is updated -sub ShiftTime($$;$$) +sub ShiftTime($;$$$) { - local $_; - my ($val, $shift, $dir, $shiftOffset) = @_; + my ($val, $shift, $dir, $shiftOffset); my (@time, @shift, @toTime, $mode, $needShiftOffset, $dec); + + if (@_ == 1) { # single argument form of ShiftTime()? + $val = $_; + $shift = $_[0]; + } else { + ($val, $shift, $dir, $shiftOffset) = @_; + } $dir or $dir = ($shift =~ s/^(\+|-)// and $1 eq '-') ? -1 : 1; # # figure out what we are dealing with (time, date or date/time) @@ -418,7 +426,7 @@ ($$;$$) # # insert shifted time components back into original string # - my ($i, $err); + my $i; for ($i=0; $i<@toTime; ++$i) { next unless defined $time[$i] and defined $toTime[$i]; my ($v, $d, $s); @@ -447,13 +455,15 @@ ($$;$$) my $sig = $len - length $s; my $dec = $d ? length($d) - 1 : 0; my $newNum = sprintf($dec ? "$s%0$sig.${dec}f" : "$s%0${sig}d", $nv); - length($newNum) != $len and $err = 1; substr($val, $pos - $len, $len) = $newNum; - pos($val) = $pos; + pos($val) = $pos + length($newNum) - $len; } - $err and return "Error packing shifted time ($val)"; - $_[0] = $val; # return shifted value - return undef; # success! + if (@_ == 1) { + $_ = $val; # set $_ to the returned value + } else { + $_[0] = $val; # return shifted value + } + return undef; # success! } @@ -494,6 +504,10 @@ =head2 ShiftTime B<ShiftTime>, and used in subsequent calls to shift date/time values by the same relative amount (see L</TRICKY> section below). +or + +0) Shift string (and $_ contains the input date/time string). + =item Return value: Error string, or undef on success and the input date/time string is shifted @@ -615,7 +629,7 @@ =head1 BUGS =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Shortcuts.pm b/src/Image-ExifTool/lib/Image/ExifTool/Shortcuts.pm index b251b864..28480a50 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Shortcuts.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Shortcuts.pm @@ -19,7 +19,7 @@ package Image::ExifTool::Shortcuts; use strict; use vars qw($VERSION); -$VERSION = '1.60'; +$VERSION = '1.65'; # this is a special table used to define command-line shortcuts # (documentation Notes may be added for these via %shortcutNotes in BuildTagLookup.pm) @@ -167,6 +167,7 @@ $VERSION = '1.60'; 'MakerNoteLeica7', 'MakerNoteLeica8', 'MakerNoteLeica9', + 'MakerNoteLeica10', 'MakerNotePanasonic', 'MakerNotePanasonic2', 'MakerNotePanasonic3', @@ -179,8 +180,10 @@ $VERSION = '1.60'; 'MakerNotePhaseOne', 'MakerNoteReconyx', 'MakerNoteReconyx2', + 'MakerNoteReconyx3', 'MakerNoteRicoh', 'MakerNoteRicoh2', + 'MakerNoteRicohPentax', 'MakerNoteRicohText', 'MakerNoteSamsung1a', 'MakerNoteSamsung1b', @@ -329,7 +332,7 @@ name prefix. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Sigma.pm b/src/Image-ExifTool/lib/Image/ExifTool/Sigma.pm index 68fb70ad..feb036eb 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Sigma.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Sigma.pm @@ -19,7 +19,7 @@ use strict; use vars qw($VERSION %sigmaLensTypes); use Image::ExifTool::Exif; -$VERSION = '1.24'; +$VERSION = '1.31'; # sigma LensType lookup (ref IB) %sigmaLensTypes = ( @@ -88,7 +88,9 @@ $VERSION = '1.24'; 0x256 => 'Sigma 105mm F2.8 EX Macro', 0x257 => 'Sigma 105mm F2.8 EX DG Macro', 0x258 => 'Sigma 105mm F2.8 EX DG OS HSM Macro', + 0x259 => 'Sigma 105mm F1.4 DG HSM | A', #IB (A018) 0x270 => 'Sigma 70mm F2.8 EX DG Macro', #NJ (SD1) + 0x271 => 'Sigma 70mm F2.8 DG Macro | A', #IB (A018) 0x300 => 'Sigma 30mm F1.4 EX DC HSM', 0x301 => 'Sigma 30mm F1.4 DC HSM | A', 0x302 => 'Sigma 30mm F1.4 DC DN | C', #JR (DN lenses are only for Sony E or MFT mount) @@ -116,6 +118,8 @@ $VERSION = '1.24'; 0x484 => 'Sigma 8mm F4 EX DG Circular Fisheye', 0x485 => 'Sigma 8mm F3.5 EX DG Circular Fisheye', 0x486 => 'Sigma 4.5mm F2.8 EX DC HSM Circular Fisheye', + 0x504 => 'Sigma 70-300mm F4-5.6 Macro Super', #IB + 0x505 => 'Sigma APO 70-300mm F4-5.6 Macro Super', #IB 0x506 => 'Sigma 70-300mm F4-5.6 APO Macro Super II', 0x507 => 'Sigma 70-300mm F4-5.6 DL Macro Super II', 0x508 => 'Sigma 70-300mm F4-5.6 DG APO Macro', @@ -128,6 +132,7 @@ $VERSION = '1.24'; 0x521 => 'Sigma 18-50mm F3.5-5.6 DC Macro', 0x527 => 'Sigma 100-300mm F4 EX IF HSM', 0x529 => 'Sigma 120-300mm F2.8 EX HSM IF APO', + 0x545 => 'Sigma 28-70mm F2.8 EX ASP DF', #IB 0x547 => 'Sigma 24-60mm F2.8 EX DG', 0x548 => 'Sigma 24-70mm F2.8 EX DG Macro', 0x549 => 'Sigma 28-70mm F2.8 EX DG', @@ -150,6 +155,7 @@ $VERSION = '1.24'; 0x597 => 'Sigma 200-500mm F2.8 APO EX DG', 0x5A8 => 'Sigma 70-300mm F4-5.6 APO DG Macro (Motorized)', 0x5A9 => 'Sigma 70-300mm F4-5.6 DG Macro (Motorized)', + 0x605 => 'Sigma 24-70mm F3.5-5.6 ASP HF', #IB 0x633 => 'Sigma 28-70mm F2.8-4 HS', 0x634 => 'Sigma 28-70mm F2.8-4 DG', 0x635 => 'Sigma 24-105mm F4 DG OS HSM | A', @@ -175,6 +181,7 @@ $VERSION = '1.24'; 0x727 => 'Sigma 135-400mm F4.5-5.6 DG ASP APO', 0x728 => 'Sigma 120-400mm F4.5-5.6 DG APO OS HSM', 0x729 => 'Sigma 100-400mm F5-6.3 DG OS HSM | C', #JR (017) + 0x730 => 'Sigma 60-600mm F4.5-6.3 DG OS HSM | S', #IB (S018) 0x733 => 'Sigma 170-500mm F5-6.3 ASP APO', 0x734 => 'Sigma 170-500mm F5-6.3 DG ASP APO', 0x735 => 'Sigma 50-500mm F4-6.3 EX RF HSM APO', @@ -185,8 +192,10 @@ $VERSION = '1.24'; 0x745 => 'Sigma 150-600mm F5-6.3 DG OS HSM | C', 0x777 => 'Sigma 18-200mm F3.5-6.3 DC', 0x77D => 'Sigma 18-200mm F3.5-6.3 DC (Motorized)', + 0x785 => 'Sigma 28-200mm F3.5-5.6 DL ASP IF HZM Macro', #IB 0x787 => 'Sigma 28-200mm F3.5-5.6 Compact ASP HZ Macro', 0x789 => 'Sigma 18-125mm F3.5-5.6 DC', + 0x790 => 'Sigma 28-300mm F3.5-6.3 DL ASP IF HZM', #IB 0x793 => 'Sigma 28-300mm F3.5-6.3 Macro', 0x794 => 'Sigma 28-200mm F3.5-5.6 DG Compact ASP HZ Macro', 0x795 => 'Sigma 28-300mm F3.5-6.3 DG Macro', @@ -216,6 +225,12 @@ $VERSION = '1.24'; 0x1007 => 'Sigma 30mm F2.8', #PH (DP2 Quattro kit) 0x1008 => 'Sigma 50mm F2.8 Macro', #NJ (DP3 Quattro kit) 0x1009 => 'Sigma 14mm F4', #NJ (DP0 Quattro kit) + # L-mount lenses?: + 0x6001 => 'Sigma 150-600mm F5-6.3 DG OS HSM | S', #PH (NC, fp) + 0x6003 => 'Sigma 45mm F2.8 DG DN | C', #PH (NC, fp) + 0x6006 => 'Sigma 50mm F1.4 DG HSM | A', #IB (014) + 0x8005 => 'Sigma 35mm F1.4 DG HSM | A', #PH (012) + 0x8009 => 'Sigma 18-35mm F1.8 DC HSM | A', #PH 0x8900 => 'Sigma 70-300mm F4-5.6 DG OS', #PH (SD15) 0xA100 => 'Sigma 24-70mm F2.8 DG Macro', #PH (SD15) # 'FFFF' - seen this for a 28-70mm F2.8 lens - PH @@ -420,13 +435,15 @@ $VERSION = '1.24'; 0x001c => [ #PH { Name => 'PreviewImageSize', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => q{ PreviewImageStart for the SD1 and Merrill/Quattro models, and PreviewImageSize for others }, Writable => 'int16u', Count => 2, + PrintConv => '$val =~ tr/ /x/; $val', + PrintConvInv => '$val =~ tr/x/ /; $val', },{ Name => 'PreviewImageStart', Condition => '$format eq "int32u"', @@ -441,7 +458,7 @@ $VERSION = '1.24'; 0x001d => [ #PH { Name => 'MakerNoteVersion', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => q{ PreviewImageLength for the SD1 and Merrill/Quattro models, and MakerNoteVersion for others @@ -460,15 +477,17 @@ $VERSION = '1.24'; # 0x001e - int16u: 0, 4, 13 - flash mode for other models? 0x001e => { #PH Name => 'PreviewImageSize', - Condition => '$$self{Model} =~ /^(SIGMA (DP\d (Merrill|Quattro))|sd Quattro)$/i', + Condition => '$$self{MakerNoteSigmaVer} >= 3', Notes => 'only valid for some models', Writable => 'int16u', Count => 2, + PrintConv => '$val =~ tr/ /x/; $val', + PrintConvInv => '$val =~ tr/x/ /; $val', }, 0x001f => [ #PH { Name => 'AFPoint', # (NC -- invalid for SD9,SD14?) - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => q{ MakerNoteVersion for the SD1 and Merrill/Quattro models, and AFPoint for others @@ -483,38 +502,47 @@ $VERSION = '1.24'; # 0x0021 - string: " " for most models, or int8u[2]: '3 3' for the DP3 Merrill 0x0022 => { #PH (NC) Name => 'FileFormat', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', # values: "JPG", "JPG-S", "JPG-P", "X3F", "X3F-S" }, # 0x0023 - string: "", 10, 83, 131, 145, 150, 152, 169 0x0024 => { # (invalid for SD9,SD14?) Name => 'Calibration', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', }, # 0x0025 - string: "", "0.70", "0.90" # 0x0026-2b - int32u: 0 0x0026 => { #PH (NC) Name => 'FileFormat', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', + # (also Sigma fp) }, - 0x0027 => { #PH + 0x0027 => [{ #PH Name => 'LensType', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3 and $format eq "string"', + Notes => 'some newer models only', ValueConv => '$val =~ /^[0-9a-f]+$/i ? hex($val) : $val', # (truncate decimal part and convert hex) ValueConvInv => '$val=~s/\.\d+$//;$val=~/^0x/ and $val=hex($val);IsInt($val) ? sprintf("%x",$val) : $val', SeparateTable => 'LensType', PrintHex => 1, PrintConv => \%sigmaLensTypes, - }, + },{ #PH + Name => 'LensType', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some other models like the fp', + Writable => 'int16u', + SeparateTable => 'LensType', + PrintHex => 1, + PrintConv => \%sigmaLensTypes, + }], 0x002a => { #PH Name => 'LensFocalRange', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Writable => 'rational64u', Count => 2, PrintConv => '$val=~s/ / to /; $val', @@ -524,13 +552,14 @@ $VERSION = '1.24'; Name => 'LensMaxApertureRange', # for most models this gives the max aperture at the long/short focal lengths, # but for some models this gives the min/max aperture - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Writable => 'rational64u', Count => 2, PrintConv => '$val=~s/ / to /; $val', PrintConvInv => '$val=~s/to /; $val', }, + # 0x002c is rational64u for some models, with a value that may be related to FNumber - PH 0x002c => { #PH Name => 'ColorMode', Condition => '$format eq "int32u"', @@ -555,7 +584,7 @@ $VERSION = '1.24'; 0x0030 => [ #PH { Name => 'LensApertureRange', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => q{ Calibration for the SD1 and Merrill/Quattro models, and LensApertureRange for others. Note that LensApertureRange changes with focal length, and some @@ -567,7 +596,7 @@ $VERSION = '1.24'; ], 0x0031 => { #PH Name => 'FNumber', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Writable => 'rational64u', PrintConv => 'sprintf("%.1f",$val)', @@ -576,7 +605,7 @@ $VERSION = '1.24'; }, 0x0032 => { #PH Name => 'ExposureTime', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Writable => 'rational64u', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', @@ -585,9 +614,8 @@ $VERSION = '1.24'; }, 0x0033 => { #PH Name => 'ExposureTime2', - Condition => '$$self{Model} !~ / (SD1|SD9|SD15|Merrill|Quattro)$/', + Condition => '$$self{Model} !~ / (SD1|SD9|SD15|Merrill|Quattro|fp)$/', Notes => 'models other than the SD1, SD9, SD15 and Merrill/Quattro models', - Writable => 'string', ValueConv => '$val * 1e-6', ValueConvInv => 'int($val * 1e6 + 0.5)', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', @@ -595,14 +623,14 @@ $VERSION = '1.24'; }, 0x0034 => { #PH Name => 'BurstShot', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Writable => 'int32u', }, # 0x0034 - int32u: 0,1,2,3 or 4 0x0035 => { #PH Name => 'ExposureCompensation', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Writable => 'rational64s', # add a '+' sign to positive values @@ -613,7 +641,7 @@ $VERSION = '1.24'; # 0x0037-38 - string: "" 0x0039 => { #PH (invalid for SD9, SD14?) Name => 'SensorTemperature', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', # (string format) PrintConv => 'IsInt($val) ? "$val C" : $val', @@ -621,19 +649,19 @@ $VERSION = '1.24'; }, 0x003a => { #PH Name => 'FlashExposureComp', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Writable => 'rational64s', }, 0x003b => { #PH (how is this different from other Firmware?) Name => 'Firmware', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Priority => 0, }, 0x003c => { #PH Name => 'WhiteBalance', - Condition => '$$self{Model} !~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', + Condition => '$$self{MakerNoteSigmaVer} < 3', Notes => 'models other than the SD1 and Merrill/Quattro models', Priority => 0, }, @@ -643,13 +671,13 @@ $VERSION = '1.24'; }, 0x0048 => { #PH Name => 'LensApertureRange', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', }, 0x0049 => { #PH Name => 'FNumber', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Writable => 'rational64u', PrintConv => 'sprintf("%.1f",$val)', PrintConvInv => '$val', @@ -657,8 +685,8 @@ $VERSION = '1.24'; }, 0x004a => { #PH Name => 'ExposureTime', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Writable => 'rational64u', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', PrintConvInv => '$val', @@ -667,15 +695,13 @@ $VERSION = '1.24'; 0x004b => [{ #PH Name => 'ExposureTime2', Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d Merrill)$/', - Notes => 'SD1 and Merrill/Quattro models only', - Writable => 'string', + Notes => 'SD1 and DP Merrill models only', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)', - },{ + },{ #PH Name => 'ExposureTime2', Condition => '$$self{Model} =~ /^SIGMA dp\d Quattro$/i', - Notes => 'SD1 and Merrill/Quattro models only', - Writable => 'string', + Notes => 'DP Quattro models only', ValueConv => '$val / 1000000', ValueConvInv => '$val * 1000000', PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)', @@ -683,8 +709,8 @@ $VERSION = '1.24'; }], 0x004d => { #PH Name => 'ExposureCompensation', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Writable => 'rational64s', # add a '+' sign to positive values PrintConv => '$val and $val =~ s/^(\d)/\+$1/; $val', @@ -693,45 +719,105 @@ $VERSION = '1.24'; # 0x0054 - string: "F20","F23" 0x0055 => { #PH Name => 'SensorTemperature', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', # (string format) PrintConv => 'IsInt($val) ? "$val C" : $val', PrintConvInv => '$val=~s/ ?C$//; $val', }, 0x0056 => { #PH (NC) Name => 'FlashExposureComp', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Writable => 'rational64s', }, 0x0057 => { #PH (how is this different from other Firmware?) - Name => 'Firmware', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Name => 'Firmware2', + Condition => '$format eq "string"', + Notes => 'some newer models only', Priority => 0, }, 0x0058 => { #PH Name => 'WhiteBalance', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', Priority => 0, }, 0x0059 => { #PH Name => 'DigitalFilter', - Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d (Merrill|Quattro))$/i', - Notes => 'SD1 and Merrill/Quattro models only', - # seen: Standard, Landscape,Monochrome,Neutral,Portrait,Sepia,Vivid + Condition => '$$self{MakerNoteSigmaVer} >= 3', + Notes => 'some newer models only', + # seen: Standard,Landscape,Monochrome,Neutral,Portrait,Sepia,Vivid }, # 0x005a/b/c - rational64s: 0/10 for the SD1 - 0x0084 => { #PH + 0x0084 => { #PH (Quattro models and fp) Name => 'Model', Description => 'Camera Model Name', - Writable => 'string', }, # 0x0085 + 0x0086 => { #PH (Quattro models) + Name => 'ISO', + Writable => 'int16u', + }, + 0x0087 => 'ResolutionMode', #PH (Quattro models) + 0x0088 => 'WhiteBalance', #PH (Quattro models) + 0x008c => 'Firmware', #PH (Quattro models) + 0x011f => { #IB (FP DNG images) + Name => 'CameraCalibration', + Writable => 'float', + Count => 9, + }, + 0x0120 => { #IB (FP DNG images) + Name => 'WBSettings', + SubDirectory => { TagTable => 'Image::ExifTool::Sigma::WBSettings' }, + }, + 0x0121 => { #IB (FP DNG images) + Name => 'WBSettings2', + SubDirectory => { TagTable => 'Image::ExifTool::Sigma::WBSettings2' }, + }, ); +# WB settings (ref IB) +%Image::ExifTool::Sigma::WBSettings = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + WRITE_PROC => \&Image::ExifTool::WriteBinaryData, + CHECK_PROC => \&Image::ExifTool::CheckBinaryData, + WRITABLE => 1, + FORMAT => 'float', + GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + 0 => { Name => 'WB_RGBLevelsAuto', Format => 'float[3]' }, + 3 => { Name => 'WB_RGBLevelsDaylight', Format => 'float[3]' }, + 6 => { Name => 'WB_RGBLevelsShade', Format => 'float[3]' }, + 9 => { Name => 'WB_RGBLevelsOvercast', Format => 'float[3]' }, + 12 => { Name => 'WB_RGBLevelsIncandescent', Format => 'float[3]' }, + 15 => { Name => 'WB_RGBLevelsFluorescent', Format => 'float[3]' }, + 18 => { Name => 'WB_RGBLevelsFlash', Format => 'float[3]' }, + 21 => { Name => 'WB_RGBLevelsCustom1', Format => 'float[3]' }, + 24 => { Name => 'WB_RGBLevelsCustom2', Format => 'float[3]' }, + 27 => { Name => 'WB_RGBLevelsCustom3', Format => 'float[3]' }, +); + +# WB settings (ref IB) +%Image::ExifTool::Sigma::WBSettings2 = ( + PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, + WRITE_PROC => \&Image::ExifTool::WriteBinaryData, + CHECK_PROC => \&Image::ExifTool::CheckBinaryData, + WRITABLE => 1, + FORMAT => 'float', + GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + 0 => { Name => 'WB_RGBLevelsUnknown0', Unknown => 1, Format => 'float[3]' }, + 3 => { Name => 'WB_RGBLevelsUnknown1', Unknown => 1, Format => 'float[3]' }, + 6 => { Name => 'WB_RGBLevelsUnknown2', Unknown => 1, Format => 'float[3]' }, + 9 => { Name => 'WB_RGBLevelsUnknown3', Unknown => 1, Format => 'float[3]' }, + 12 => { Name => 'WB_RGBLevelsUnknown4', Unknown => 1, Format => 'float[3]' }, + 15 => { Name => 'WB_RGBLevelsUnknown5', Unknown => 1, Format => 'float[3]' }, + 18 => { Name => 'WB_RGBLevelsUnknown6', Unknown => 1, Format => 'float[3]' }, + 21 => { Name => 'WB_RGBLevelsUnknown7', Unknown => 1, Format => 'float[3]' }, + 24 => { Name => 'WB_RGBLevelsUnknown8', Unknown => 1, Format => 'float[3]' }, + 27 => { Name => 'WB_RGBLevelsUnknown9', Unknown => 1, Format => 'float[3]' }, +); + + 1; # end __END__ @@ -751,7 +837,7 @@ Sigma and Foveon maker notes in EXIF information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/SigmaRaw.pm b/src/Image-ExifTool/lib/Image/ExifTool/SigmaRaw.pm index acecf892..f32f6923 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/SigmaRaw.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/SigmaRaw.pm @@ -643,7 +643,7 @@ Sigma and Foveon X3F images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Sony.pm b/src/Image-ExifTool/lib/Image/ExifTool/Sony.pm index b592e902..6930cf2b 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Sony.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Sony.pm @@ -22,17 +22,19 @@ # IB) Iliah Borg private communication (LibRaw) # JD) Jens Duttke private communication # JR) Jos Roost private communication +# +# NC = Not Confirmed #------------------------------------------------------------------------------ package Image::ExifTool::Sony; use strict; -use vars qw($VERSION %sonyLensTypes); +use vars qw($VERSION %sonyLensTypes %sonyLensTypes2); use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::Exif; use Image::ExifTool::Minolta; -$VERSION = '2.93'; +$VERSION = '3.22'; sub ProcessSRF($$$); sub ProcessSR2($$$); @@ -52,16 +54,29 @@ sub PrintInvLensSpec($;$$); # Sony E-mount lenses # (NOTE: these should be kept in sync with the 65535 entries in %minoltaLensTypes) -my %sonyLensTypes2 = ( - Notes => 'Lens type numbers for Sony E-mount lenses used by NEX models.', +%sonyLensTypes2 = ( + Notes => 'Lens type numbers for Sony E-mount lenses used by NEX/ILCE models.', 0 => 'Unknown E-mount lens or other lens', + 0.1 => 'Sigma 19mm F2.8 [EX] DN', + 0.2 => 'Sigma 30mm F2.8 [EX] DN', + 0.3 => 'Sigma 60mm F2.8 DN', + 0.4 => 'Sony E 18-200mm F3.5-6.3 OSS LE', # (firmware Ver.01) + 0.5 => 'Tamron 18-200mm F3.5-6.3 Di III VC', # (Model B011) + 0.6 => 'Tokina FiRIN 20mm F2 FE AF', # (firmware Ver.00) samples from Tokina, May 2018 + 0.7 => 'Tokina FiRIN 20mm F2 FE MF', # samples from Tokina, 16-12-2016, DC-watch 01-02-2017 + 0.8 => 'Zeiss Touit 12mm F2.8', # (firmware Ver.00) + 0.9 => 'Zeiss Touit 32mm F1.8', # (firmware Ver.00) + '0.10' => 'Zeiss Touit 50mm F2.8 Macro', # (firmware Ver.00) + '0.11' => 'Zeiss Loxia 50mm F2', # (firmware Ver.01) + '0.12' => 'Zeiss Loxia 35mm F2', # (firmware Ver.01) 1 => 'Sony LA-EA1 or Sigma MC-11 Adapter', # MC-11 with not-supported lenses 2 => 'Sony LA-EA2 Adapter', 3 => 'Sony LA-EA3 Adapter', #(NC) ILCE-7 image with A-mount lens, but also has 0x940e 2nd byte=2 6 => 'Sony LA-EA4 Adapter', #(NC) ILCE-7R image with A-mount lens and having phase-detect info blocks in 0x940e AFInfo - # 27 => Venus Optics Laowa 12mm f2.8 Zero-D or 105mm f2 (T3.2) Smooth Trans Focus (ref IB) + # 27 => Venus Optics Laowa 12mm f2.8 Zero-D or 105mm f2 (T3.2) Smooth Trans Focus (ref IB) 44 => 'Metabones Canon EF Smart Adapter', #JR 78 => 'Metabones Canon EF Smart Adapter Mark III or Other Adapter', #PH/JR (also Mark IV, Fotodiox and Viltrox) + 184 => 'Metabones Canon EF Speed Booster Ultra', #JR ('Green' mode, LensMount reported as A-mount) 234 => 'Metabones Canon EF Smart Adapter Mark IV', #JR (LensMount reported as A-mount) 239 => 'Metabones Canon EF Speed Booster', #JR # Sony VX product code: (http://www.mi-fo.de/forum/index.php?s=7df1c8d3b1cd675f2abf4f4442e19cf2&showtopic=35035&view=findpost&p=303746) @@ -70,18 +85,20 @@ my %sonyLensTypes2 = ( 32786 => 'Sony E 55-210mm F4.5-6.3 OSS', # VX9102 32787 => 'Sony E 18-200mm F3.5-6.3 OSS', # VX9103 32788 => 'Sony E 30mm F3.5 Macro', # VX9104 - 32789 => 'Sony E 24mm F1.8 ZA or Samyang AF 50mm F1.4 FE', # VX9105 - 32789.1 => 'Samyang AF 50mm F1.4 FE', - 32790 => 'Sony E 50mm F1.8 OSS or Samyang AF 14mm F2.8 FE', # VX9106 - 32790.1 => 'Samyang AF 14mm F2.8 FE', + 32789 => 'Sony E 24mm F1.8 ZA or Samyang AF 50mm F1.4', # VX9105 + 32789.1 => 'Samyang AF 50mm F1.4', + 32790 => 'Sony E 50mm F1.8 OSS or Samyang AF 14mm F2.8', # VX9106 + 32790.1 => 'Samyang AF 14mm F2.8', 32791 => 'Sony E 16-70mm F4 ZA OSS', # VX9107 32792 => 'Sony E 10-18mm F4 OSS', # VX9108 32793 => 'Sony E PZ 16-50mm F3.5-5.6 OSS', # VX9109 - 32794 => 'Sony FE 35mm F2.8 ZA or Samyang AF 24mm F2.8 FE', # VX9110 - 32794.1 => 'Samyang AF 24mm F2.8 FE', #JR + 32794 => 'Sony FE 35mm F2.8 ZA or Samyang Lens', # VX9110 + 32794.1 => 'Samyang AF 24mm F2.8', #JR + 32794.2 => 'Samyang AF 35mm F2.8', #IB (also 51505) 32795 => 'Sony FE 24-70mm F4 ZA OSS', # VX9111 - 32796 => 'Sony FE 85mm F1.8', #JR - 32797 => 'Sony E 18-200mm F3.5-6.3 OSS LE', # VX9113 + 32796 => 'Sony FE 85mm F1.8 or Viltrox PFU RBMH 85mm F1.8', #JR + 32796.1 => 'Viltrox PFU RBMH 85mm F1.8', #JR (MF) + 32797 => 'Sony E 18-200mm F3.5-6.3 OSS LE', # VX9113 (firmware Ver.02) 32798 => 'Sony E 20mm F2.8', # VX9114 32799 => 'Sony E 35mm F1.8 OSS', # VX9115 32800 => 'Sony E PZ 18-105mm F4 G OSS', #JR # VX9116 @@ -107,7 +124,8 @@ my %sonyLensTypes2 = ( 32820 => 'Sony E PZ 18-110mm F4 G OSS', #JR 32821 => 'Sony FE 24-70mm F2.8 GM', #JR/IB 32822 => 'Sony FE 50mm F1.4 ZA', #JR - 32823 => 'Sony FE 85mm F1.4 GM', #JR/IB + 32823 => 'Sony FE 85mm F1.4 GM or Samyang AF 85mm F1.4', #JR/IB + 32823.1 => 'Samyang AF 85mm F1.4', #IB 32824 => 'Sony FE 50mm F1.8', #JR (Sony code 'SEL50F18F' with trailing "F" as compared to 'SEL50F18' for 32790) 32826 => 'Sony FE 21mm F2.8 (SEL28F20 + SEL075UWC)', #JR # (+ Ultra-wide converter) @@ -118,8 +136,16 @@ my %sonyLensTypes2 = ( 32831 => 'Sony FE 16-35mm F2.8 GM', #JR 32848 => 'Sony FE 400mm F2.8 GM OSS', #IB 32849 => 'Sony E 18-135mm F3.5-5.6 OSS', #JR + 32850 => 'Sony FE 135mm F1.8 GM', #IB + 32851 => 'Sony FE 200-600mm F5.6-6.3 G OSS', #IB + 32852 => 'Sony FE 600mm F4 GM OSS', #IB + 32853 => 'Sony E 16-55mm F2.8 G', #IB/JR + 32854 => 'Sony E 70-350mm F4.5-6.3 G OSS', #IB/JR + 32858 => 'Sony FE 35mm F1.8', #JR/IB + 32859 => 'Sony FE 20mm F1.8 G', #IB/JR # (comment this out so LensID will report the LensModel, which is more useful) + # 32952 => 'Metabones Canon EF Speed Booster Ultra', #JR (corresponds to 184, but 'Advanced' mode, LensMount reported as E-mount) # 33002 => 'Metabones Canon EF Smart Adapter with Ver.5x', #PH/JR (corresponds to 234, but LensMount reported as E-mount) 33072 => 'Sony FE 70-200mm F2.8 GM OSS + 1.4X Teleconverter', #JR @@ -129,6 +155,10 @@ my %sonyLensTypes2 = ( 33078 => 'Sony FE 100-400mm F4.5-5.6 GM OSS + 2X Teleconverter', #JR 33079 => 'Sony FE 400mm F2.8 GM OSS + 1.4X Teleconverter', #IB 33080 => 'Sony FE 400mm F2.8 GM OSS + 2X Teleconverter', #JR + 33081 => 'Sony FE 200-600mm F5.6-6.3 G OSS + 1.4X Teleconverter', #JR + 33082 => 'Sony FE 200-600mm F5.6-6.3 G OSS + 2X Teleconverter', #JR + 33083 => 'Sony FE 600mm F4 GM OSS + 1.4X Teleconverter', #JR (NC) + 33084 => 'Sony FE 600mm F4 GM OSS + 2X Teleconverter', #JR 49201 => 'Zeiss Touit 12mm F2.8', #JR (lens firmware Ver.02) 49202 => 'Zeiss Touit 32mm F1.8', #JR (lens firmware Ver.02) @@ -145,15 +175,23 @@ my %sonyLensTypes2 = ( 49236 => 'Zeiss Loxia 25mm F2.4', #JR 49457 => 'Tamron 28-75mm F2.8 Di III RXD', #JR (Model A036) + 49458 => 'Tamron 17-28mm F2.8 Di III RXD', #JR (Model A046) + 49459 => 'Tamron 35mm F2.8 Di III OSD M1:2', #IB (Model F053) + 49460 => 'Tamron 24mm F2.8 Di III OSD M1:2', #JR (Model F051) + 49461 => 'Tamron 20mm F2.8 Di III OSD M1:2', #JR (Model F050) + + 49712 => 'Tokina FiRIN 20mm F2 FE AF', # (firmware Ver.01) + 49713 => 'Tokina FiRIN 100mm F2.8 FE MACRO', # (firmware Ver.01) 50480 => 'Sigma 30mm F1.4 DC DN | C', #IB/JR (016) - 50481 => 'Sigma 50mm F1.4 DG HSM | A + MC-11', #JR (014) + 50481 => 'Sigma 50mm F1.4 DG HSM | A', #JR (014 + MC-11 or 018) 50482 => 'Sigma 18-300mm F3.5-6.3 DC MACRO OS HSM | C + MC-11', #JR (014) 50483 => 'Sigma 18-35mm F1.8 DC HSM | A + MC-11', #JR (013) 50484 => 'Sigma 24-35mm F2 DG HSM | A + MC-11', #JR (015) + 50485 => 'Sigma 24mm F1.4 DG HSM | A + MC-11', #JR (015) 50486 => 'Sigma 150-600mm F5-6.3 DG OS HSM | C + MC-11', #JR (015) 50487 => 'Sigma 20mm F1.4 DG HSM | A + MC-11', #JR (015) - 50488 => 'Sigma 35mm F1.4 DG HSM | A + MC-11', #JR (012) + 50488 => 'Sigma 35mm F1.4 DG HSM | A', #JR (012 + MC-11 or 018) 50489 => 'Sigma 150-600mm F5-6.3 DG OS HSM | S + MC-11', #JR (014) 50490 => 'Sigma 120-300mm F2.8 DG OS HSM | S + MC-11', #JR (013) 50492 => 'Sigma 24-105mm F4 DG OS HSM | A + MC-11', #JR (013) @@ -162,7 +200,14 @@ my %sonyLensTypes2 = ( 50499 => 'Sigma 85mm F1.4 DG HSM | A', #JR (018) 50501 => 'Sigma 100-400mm F5-6.3 DG OS HSM | C + MC-11', #JR (017) 50503 => 'Sigma 16mm F1.4 DC DN | C', #JR (017) + 50507 => 'Sigma 105mm F1.4 DG HSM | A', #IB (018) + 50508 => 'Sigma 56mm F1.4 DC DN | C', #JR (018) + 50512 => 'Sigma 70-200mm F2.8 DG OS HSM | S + MC-11', #IB (018) (JR added "+ MC-11") 50513 => 'Sigma 70mm F2.8 DG MACRO | A', #JR (018) + 50514 => 'Sigma 45mm F2.8 DG DN | C', #IB/JR (019) + 50515 => 'Sigma 35mm F1.2 DG DN | A', #IB/JR (019) + 50516 => 'Sigma 14-24mm F2.8 DG DN | A', #IB/JR (019) + 50517 => 'Sigma 24-70mm F2.8 DG DN | A', #JR (019) 50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR 50993 => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB @@ -170,15 +215,23 @@ my %sonyLensTypes2 = ( 50995 => 'Voigtlander MACRO APO-LANTHAR 65mm F2 Aspherical', #JR 50996 => 'Voigtlander NOKTON 40mm F1.2 Aspherical', #JR 50997 => 'Voigtlander NOKTON classic 35mm F1.4', #JR + 50998 => 'Voigtlander MACRO APO-LANTHAR 110mm F2.5', #JR + 50999 => 'Voigtlander COLOR-SKOPAR 21mm F3.5 Aspherical', #IB + 51000 => 'Voigtlander NOKTON 50mm F1.2 Aspherical', #JR + 51001 => 'Voigtlander NOKTON 21mm F1.4 Aspherical', #JR + 51002 => 'Voigtlander APO-LANTHAR 50mm F2 Aspherical', #JR # lenses listed in the Sigma MC-11 list, but not yet seen: # 504xx => 'Sigma 18-200mm F3.5-6.3 DC MACRO OS HSM | C + MC-11', # (014) - # 504xx => 'Sigma 24mm F1.4 DG HSM | A + MC-11', # (015) # 504xx => 'Sigma 30mm F1.4 DC HSM | A + MC-11', # (013) - 51505 => 'Samyang AF 14mm F2.8 FE or Samyang AF 35mm F2.8 FE', #forum3833 - 51505.1 => 'Samyang AF 35mm F2.8 FE', #PH + 51504 => 'Samyang AF 50mm F1.4', #IB + 51505 => 'Samyang AF 14mm F2.8 or Samyang AF 35mm F2.8', #forum3833 + 51505.1 => 'Samyang AF 35mm F2.8', #PH (also 32794) 51507 => 'Samyang AF 35mm F1.4', #IB + 51508 => 'Samyang AF 45mm F1.8', + 51510 => 'Samyang AF 18mm F2.8', #JR + ); # ExposureProgram values (ref PH, mainly decoded from A200) @@ -897,8 +950,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # unknown offsets or values for DSC-TX20/TX55/WX30 # unknown offsets or values for DSC-HX60V/HX350/HX400V/QX10/QX30/QX100/RX10/RX100M2/RX100M3/WX220/WX350, # ILCA-68/77M2, ILCE-5000/5100/6000/7/7M2/7R/7S/QX1, Stellar2, Lusso - # unknown offsets or values for DSC-HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500, ILCE-6300/6500/7RM2/7SM2, ILCA-99M2 - # unknown offsets or values for ILCE-7M3/7RM3/9, DSC-RX10M4/RX100M6/RX100M5A + # unknown offsets or values for DSC-HX80/HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500, ILCE-6300/6500/7RM2/7SM2, ILCA-99M2 + # unknown offsets or values for ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M6/RX100M5A/RX100M7/HX99 { Name => 'Tag2010a', # ad Condition => '$$self{Model} =~ /^NEX-5N$/', @@ -935,11 +988,11 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010g' }, },{ Name => 'Tag2010h', # ? - Condition => '$$self{Model} =~ /^(DSC-(RX0|RX1RM2|RX10M2|RX10M3|RX100M4|RX100M5|HX90V?|WX500)|ILCE-(6300|6500|7RM2|7SM2)|ILCA-99M2)\b/', + Condition => '$$self{Model} =~ /^(DSC-(RX0|RX1RM2|RX10M2|RX10M3|RX100M4|RX100M5|HX80|HX90V?|WX500)|ILCE-(6300|6500|7RM2|7SM2)|ILCA-99M2)\b/', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010h' }, },{ Name => 'Tag2010i', # ? - Condition => '$$self{Model} =~ /^(ILCE-(7M3|7RM3|9)|DSC-(RX10M4|RX100M6|RX100M5A))\b/', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7|HX99|RX0M2))\b/', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010i' }, },{ Name => 'Tag_0x2010', @@ -997,6 +1050,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); 1 => 'Flash Fired', 2 => 'External Flash Fired', 3 => 'Wireless Controlled Flash Fired', # (NC) seen for ILCE-9 and ILCE-7M3 images + # 5 => 'External Flash ???', # seen for ILCE-7RM4 }, }, # 0x2018 - something with external flash: seen 1 only when 0x2017 = 2 @@ -1014,7 +1068,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # FocusMode for SLT/HV/ILCA and NEX/ILCE; doesn't seem to apply to DSC models (always 0) # from 2018: at least DSC-RX10M4 and RX100M6 also use this tag Name => 'FocusMode', - Condition => '($$self{Model} !~ /^DSC-/) or ($$self{Model} =~ /^DSC-(RX10M4|RX100M6|RX100M5A)/)', + Condition => '($$self{Model} !~ /^DSC-/) or ($$self{Model} =~ /^DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2)/)', Writable => 'int8u', Priority => 0, PrintConv => { @@ -1046,7 +1100,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); }, },{ Name => 'AFAreaModeSetting', - Condition => '$$self{Model} =~ /^(NEX-|ILCE-|DSC-(RX10M4|RX100M6|RX100M5A))/', + Condition => '$$self{Model} =~ /^(NEX-|ILCE-|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))/', Notes => 'NEX, ILCE and some DSC models', RawConv => '$$self{AFAreaILCE} = $val', DataMember => 'AFAreaILCE', @@ -1082,7 +1136,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # observed values in range (0 0) to (640 480), with center (320 240) often seen # for NEX-5R/6, positions appear to be in an 11x9 grid Name => 'FlexibleSpotPosition', - Condition => '$$self{Model} =~ /^(NEX-|ILCE-|DSC-(RX10M4|RX100M6|RX100M5A))/', + Condition => '$$self{Model} =~ /^(NEX-|ILCE-|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))/', Writable => 'int16u', Count => 2, Notes => q{ @@ -1242,7 +1296,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # from 2018: at least DSC-RX10M4 and RX100M6 also use this tag 0x2021 => { #JR Name => 'AFTracking', - Condition => '($$self{Model} !~ /^DSC-/) or ($$self{Model} =~ /^DSC-(RX10M4|RX100M6|RX100M5A)/)', + Condition => '($$self{Model} !~ /^DSC-/) or ($$self{Model} =~ /^DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2)/)', Writable => 'int8u', PrintConv => { 0 => 'Off', @@ -1393,8 +1447,9 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # first 4 bytes: GroupID, read as int32u # the ID displayed by Sony ImageDataConverter appears to be based on the lower 22 bits: # 5 bits, 5 bits, 6 bits, 6 bits - # last 2 bytes: ShotNumber: (1 4) to (4 4) are the 4 source images, - # (0 4) is combined "PixelShifted" image + # last 2 bytes: ShotNumber: (1 4) to (4 4) and (1 16) to (16 16) are the 4 or 16 source images, + # (0 4) is the combined image for 4-shot PixelShift mode + # (0 16) is the combined image for 16-shot PixelShift mode (ILCE-7RM4) RawConv => q{ my ($a,$b,$c) = (Get32u(\$val,0), Get8u(\$val,4), Get8u(\$val,5)); sprintf("%.2d%.2d%.2d%.2d %d %d 0x%x",($a>>17)&0x1f,($a>>12)&0x1f,($a>>6)&0x3f,$a&0x3f,$b,$c,$a>>22); @@ -1410,20 +1465,20 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); OTHER => sub { my ($val, $inv) = @_; if ($inv) { - $val =~ s{Composed}{Shot 0/4}i; + $val =~ s{Composed (\d+)-shot}{Shot 0/$1}i; $val =~ s{^(?:Group)?\s*(\d+)[, ]+(?:Shot\s*)?(\d+)[/ ](\d+)\s*\(?(\w+)\)?}{$1 $2 $3 $4}i or return undef; } else { $val =~ s{(\d+) (\d+) (\d+) (\w+)}{Group $1, Shot $2/$3 ($4)} or return undef; - $val =~ s{Shot\s*0+/0*4\b}{Composed}i; + $val =~ s{Shot 0+/0*(\d+)\b}{Composed $1-shot}i; } return $val; }, }, }, - 0x2031 => { #JR (new for ILCE-9 v2.00) + 0x2031 => { #JR (only for ILCE-9 v2.00; ILCE-9 v2.10 and higher have "option" to write into EXIF tag 0xa431 ) Name => 'SerialNumber', Writable => 'string', - ValueConv => '$val=~s/(\d{2})(\d{2})(\d{2})(\d{2})/$4$3$2$1/; $val=~s/^0//; $val', # (NC) + ValueConv => '$val=~s/(\d{2})(\d{2})(\d{2})(\d{2})/$4$3$2$1/; $val=~s/^0//; $val', ValueConvInv => '$val="0$val" if length($val)==7; $val=~s/(\d{2})(\d{2})(\d{2})(\d{2})/$4$3$2$1/; $val', PrintConv => 'sprintf("%.8d",$val)', PrintConvInv => '$val', @@ -1456,14 +1511,14 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # from mid-2015: ILCE-7RM2/7SM2/6300 and newer models use different offsets { Name => 'Tag9050a', - Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9)|ILCA-99M2)/', + Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(6100|6300|6400|6500|6600|7M3|7RM2|7RM3|7RM4|7SM2|9|9M2)|ILCA-99M2)/', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9050a', ByteOrder => 'LittleEndian', }, },{ Name => 'Tag9050b', - Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9)|ILCA-99M2)/', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6300|6400|6500|6600|7M3|7RM2|7RM3|7RM4|7SM2|9|9M2)|ILCA-99M2)/', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9050b', ByteOrder => 'LittleEndian', @@ -1480,9 +1535,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 0x0c (e) for ILCE-3000/3500, NEX-3N, SLT-A58, DSC-HX50V/HX300/RX100M2/TX30/WX60/WX80/WX200/WX300, DSC-QX10/QX100 # 0xd0 (e) H90, W650, W690: tag9400 decoding appears not valid/different # 0x23 (e) for DSC-RX10/HX60V/HX350/HX400V/WX220/WX350, ILCE-7/7R/5000/6000, ILCA-68/77M2 - # 0x24 (e) for ILCA-99M2,ILCE-5100/6300/6500/7M2/7RM2/7S/7SM2/QX1, DSC-HX90V/QX30/RX0/RX100M3/RX100M4/RX100M5/RX10M2/RX10M3/RX1RM2/WX500 - # 0x26 (e) for ILCE-7M3/7RM3/9, DSC-RX10M4/RX100M6 - # first byte decoded: 40, 204, 202, 27, 58, 62, 48, 215 respectively + # 0x24 (e) for ILCA-99M2,ILCE-5100/6300/6500/7M2/7RM2/7S/7SM2/QX1, DSC-HX80/HX90V/QX30/RX0/RX100M3/RX100M4/RX100M5/RX10M2/RX10M3/RX1RM2/WX500 + # 0x26 (e) for ILCE-6100/6400/6600/7M3/7RM3/9, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/HX99 + # 0x28 (e) for ILCE-7RM4/9M2, DSC-RX100M7 + # first byte decoded: 40, 204, 202, 27, 58, 62, 48, 215, 28 respectively { Name => 'Tag9400a', Condition => q{ @@ -1496,15 +1552,15 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400b' }, },{ Name => 'Tag9400c', - Condition => '$$valPt =~ /^[\x23\x24\x26]/', + Condition => '$$valPt =~ /^[\x23\x24\x26\x28]/', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400c' }, },{ Name => 'Sony_0x9400', %unknownCipherData, }], 0x9401 => { - Name => 'Sony_0x9401', - %unknownCipherData, + Name => 'Tag9401', + SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9401' }, # notes for data in this block (ref PH/JR): # 0x02-0x03 appear to have some relation to start-offset of data... # 0x00 - 0x03 Metering @@ -1527,7 +1583,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 33 41 0d 0e 0x09d7 (k) DSC-RX1, DSC-RX1R # 38 00 32 0e 0x09fc (l) SLT-A58, ILCE-3000/3500, NEX-3N, DSC-HX300/HX50V/WX200/WX300/WX60/WX80/TX30 # 3a 10 3a 0e 0x0a01 (m) DSC-QX10/QX100 - # 3a 20 47 0e 0x0a01 (m) DSC-RX100M2, + # 3a 20 47 0e 0x0a01 (m) DSC-RX100M2 # 43 00 66 0e 0x0a1b (n) ILCE-7/7R v0.xx/v1.00/v1.01, ILCE-5000, DSC-RX10 # 43 10 66 0e 0x0a1b (n) ILCE-7/7R v1.02/v1.10 # 43 30 6c 0e 0x0a1b (n) ILCE-7/7R v1.20-v3.20 @@ -1536,10 +1592,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 44 20 a2 0e 0x0a39 (o) ILCE-6000 v2.00-v3.20 # 49 00 b0 0e 0x0a3b (p) ILCA-68 v1.00, ILCA-77M2 V1.00/v1.01/v2.00 (also DSC-RX100M3 samples from sony.net) # 4a 00 b3 0e 0x0a3d (q) ILCE-7S v1.00, ILCE-5100 v1.00/v1.10, ILCE-QX1, DSC-QX30/RX100M3 - # 4a 20 b9 0e 0x0a3d (q) ILCE-7S v1.20-v3.10 + # 4a 20 b9 0e 0x0a3d (q) ILCE-7S v1.20-v3.20 # 4e 10 d0 0e 0x0a5a (r) ILCE-7M2 v1.00/v1.10 # 4e 30 d6 0e 0x0a5a (r) ILCE-7M2 v1.20-v4.00 - # 5a 00 14 0f 0x0a85 (s) DSC-HX90V/WX500 + # 5a 00 14 0f 0x0a85 (s) DSC-HX80/HX90V/WX500 # 5d 00 56 0f 0x0ac7 (t) DSC-RX10M2/RX100M4, ILCE-7RM2/7SM2 v1.00-v2.20 (also DSC-RX1RM2 samples from Sony) # 5d 1d 58 0f 0x0ac7 (t) ILCE-7RM2 v3.00-v4.00 # 5d 1e 57 0f 0x0ac7 (t) DSC-RX1RM2 v1.00 @@ -1547,10 +1603,17 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 5d 20 58 0f 0x0ac7 (t) ILCE-6300 v1.00/v1.10 # 5e 00 56 0f 0x0ac7 (t) DSC-RX10M3 v1.00 # 64 00 a8 0f 0x0b15 (u) DSC-RX100M5 v1.00 - # 67 00 f9 0f 0x0b66 (v) ILCA-99M2 v1.00, ILCE-6500 v1.00/v1.03, DSC-RX0 v1.00 - # 7c 00 fe 0f 0x0adb (w) ILCE-9 v0.01/v1.00/v1.01/v1.10/v2.00 + # 67 00 f9 0f 0x0b66 (v) ILCA-99M2 v1.00, ILCE-6500 v1.00-v1.05, DSC-RX0 v1.00 + # 7c 00 fe 0f 0x0adb (w) ILCE-9 v0.01-v2.00 + # 7d 00 fe 0f 0x0adb (w) ILCE-9 v2.10-v4.10 # 7f 00 fa 0f 0x0add (x) DSC-RX10M4 v1.00 - # 80 00 fa 0f 0x0add (x) ILCE-7M3 v1.00, ILCE-7RM3 v0.01/v1.00/v1.01 + # 80 00 fa 0f 0x0add (x) ILCE-7M3/7RM3 v1.00-v3.01 + # 82 00 fc 0f 0x0ad9 (y) DSC-RX100M5A v1.00, DSC-RX100M6 v1.00 + # 90 00 fe 0f 0x098f? (z) DSC-HX99 v1.00 + # 92 10 ff 0f 0x0990 (za) ILCE-6100/6400/6600 v1.00 + # 94 00 ce 0b 0x0879 (zb) ILCE-9 v5.00-v6.00, DSC-RX0M2 + # 98 00 db 0c 0x088a (zc) ILCE-7RM4 v1.00 + # 9a 00 e3 0c 0x088a (zc) DSC-RX100M7 v1.00, ILCE-9M2 v1.00 # # 0x0004 - (RX100: 0 or 1. subsequent data valid only if 1 - PH) # 0x0007 => { @@ -1583,11 +1646,13 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 0x15 0x01 for a few ILCE-7/7R ... # 0x14 0x01 ILCE-6000, DSC-HX60V/HX350/HX400V/WX220/WX350 # 0x17 0x01 ILCE-7S/7M2/5100/QX1, DSC-QX30/RX100M3 - # 0x19 0x01 DSC-HX90V/RX1RM2/RX10M2/RX100M4/WX500, ILCE-6300/7RM2/7SM2 + # 0x19 0x01 DSC-HX80/HX90V/RX1RM2/RX10M2/RX100M4/WX500, ILCE-6300/7RM2/7SM2 # 0x1a 0x01 DSC-RX0/RX10M3/RX100M5, ILCE-6500 # 0x1c 0x01 ILCE-9 # 0x1d 0x01 DSC-RX10M4 - # 0x1e 0x01 ILCE-7M3/7RM3, DSC-RX100M6 + # 0x1e 0x01 ILCE-7M3/7RM3, DSC-RX100M5A/RX100M6 + # 0x1f 0x01 DSC-HX99 + # 0x20 0x01 ILCE-6100/6400/6600/7RM4/9M2, ILCE-9 v5.00-v6.00, DSC-RX0M2/RX100M7 # var var SLT-A58/A99V, HV, ILCA-68/77M2/99M2 # only valid when first byte 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x17, 0x19, 0x1a, 0x1c (enciphered 0x8a, 0x70, 0xb6, 0x69, 0x88, 0x20, 0x30, 0xd7, 0xbb, 0x92, 0x28) # Condition => '$$self{DoubleCipher} ? $$valPt =~ /^[\x7e\x46\x1d\x18\x3a\x95\x24\x26\xd6]\x01/ : $$valPt =~ /^[\x8a\x70\xb6\x69\x88\x20\x30\xd7\xbb\x92\x28]\x01/', @@ -1610,8 +1675,8 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 12 0 8 2 2 SLT-A58, NEX-3N, ILCE-3000/3500, DSC-HX300/HX50V/WX60/WX80/WX300/TX30... # 13 0 9 2 2 DSC-QX10/QX100/RX100M2 # 15 0 35 2 2 ILCA-68/77M2, ILCE-5000/5100/6000/7/7R/7S/7M2/QX1, DSC-HX60V/HX350/HX400V/QX30/RX10/RX100M3/WX220/WX350 - # 16 0 85 2 2 DSC-HX90V/WX500 - # 17 0 232 1 2 DSC-RX0/RX1RM2/RX10M2/RX10M3/RX10M4/RX100M4/RX100M5/RX100M6, ILCE-6300/6500/7M3/7RM2/7RM3/7SM2/9, ILCA-99M2 + # 16 0 85 2 2 DSC-HX80/HX90V/WX500 + # 17 0 232 1 2 DSC-RX0/RX0M2/RX1RM2/RX10M2/RX10M3/RX10M4/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/HX99, ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, ILCA-99M2 # other values for Panorama images and several other models 0x9404 => [{ Name => 'Tag9404a', @@ -1642,10 +1707,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); # 137 var (0xb3 = 179 var enc.) ILCA-68/77M2, DSC-RX100M3 - appears to go with 136 # 138 var (0x7e = 126 var enc.) ILCE-7S/5100/QX1, DSC-QX30 - appears to go with 136 # 139 var (0x9a = 154 var enc.) ILCE-7M2 - # 142 var (0x25 = 37 var enc.) DSC-HX90V/RX1RM2/RX10M2/RX10M3/RX100M4/WX500, ILCE-6300/7RM2/7SM2 + # 142 var (0x25 = 37 var enc.) DSC-HX80/HX90V/RX1RM2/RX10M2/RX10M3/RX100M4/WX500, ILCE-6300/7RM2/7SM2 # 144 var (0xe1 = 225 var enc.) DSC-RX100M5 # 145 var (0x76 = 118 var enc.) ILCA-99M2, ILCE-6500, DSC-RX0 - # 163 var (0x8b = 139 var enc.) ILCE-7M3/7RM3/9, DSC-RX10M4/RX100M6 + # 163 var (0x8b = 139 var enc.) ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/RX100M7/HX99 0x9405 => [{ Name => 'Tag9405a', # first byte must be 0x1b or 0x40 or 0x7d @@ -1662,9 +1727,10 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); }], 0x9406 => [{ Name => 'Tag9406', - # - first byte must be 0x01 or 0x02 (enciphered 0x01 or 0x08), or 0x03 (enc. 0x1b) for ILCE-6300/7RM2/7SM2, and + # - first byte must be 0x01 or 0x02 (enciphered 0x01 or 0x08), + # or 0x03 (enc. 0x1b) for ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, and ILCA-99M2 # third byte must be 0x02 or 0x03 (enciphered 0x08 or 0x1b) - ref JR - # (applies to most SLT and NEX models, but no DSC models) + # (applies to most SLT/ILCA and NEX/ILCE models, but no DSC models) Condition => '$$valPt =~ /^[\x01\x08\x1b].[\x08\x1b]/s', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9406' }, },{ @@ -1752,6 +1818,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); '3 3 1 0' => 'ARW 2.3.1', #PH/JR (DSC-RX1R/RX100M2/Stellar2) '3 3 2 0' => 'ARW 2.3.2', #JR (DSC-RX1RM2,ILCE-7SM2 - support for uncompressed 14-bit RAW) '3 3 3 0' => 'ARW 2.3.3', #JR (ILCE-9) + '3 3 5 0' => 'ARW 2.3.5', #JR (DSC-HX99) # what about cRAW images? }, }, @@ -1761,7 +1828,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); Writable => 'int16u', PrintConvColumns => 2, PrintConv => { - 0 => 'DSC-HX80', #PH + #0 => 'DSC-HX80', #PH (and several other DSC models) 2 => 'DSC-R1', 256 => 'DSLR-A100', 257 => 'DSLR-A900', @@ -1769,13 +1836,13 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); 259 => 'DSLR-A200', 260 => 'DSLR-A350', 261 => 'DSLR-A300', - 262 => 'DSLR-A900 (APS-C mode)', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3994.0.html + 262 => 'DSLR-A900 (APS-C mode)', #https://exiftool.org/forum/index.php/topic,3994.0.html 263 => 'DSLR-A380/A390', #PH (A390) 264 => 'DSLR-A330', 265 => 'DSLR-A230', 266 => 'DSLR-A290', #PH 269 => 'DSLR-A850', - 270 => 'DSLR-A850 (APS-C mode)', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3994.0.html + 270 => 'DSLR-A850 (APS-C mode)', #https://exiftool.org/forum/index.php/topic,3994.0.html 273 => 'DSLR-A550', 274 => 'DSLR-A500', #PH 275 => 'DSLR-A450', #http://dev.exiv2.org/issues/show/0000611 @@ -1784,7 +1851,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); 280 => 'SLT-A33', #PH 281 => 'SLT-A55 / SLT-A55V', #PH (A55 NC) 282 => 'DSLR-A560', #PH - 283 => 'DSLR-A580', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2881.0.html + 283 => 'DSLR-A580', #https://exiftool.org/forum/index.php/topic,2881.0.html 284 => 'NEX-C3', #PH 285 => 'SLT-A35', #JR 286 => 'SLT-A65 / SLT-A65V', #PH @@ -1836,7 +1903,15 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); 364 => 'DSC-RX0', #PH 365 => 'DSC-RX10M4', #JR 366 => 'DSC-RX100M6', #IB + 367 => 'DSC-HX99', #IB 369 => 'DSC-RX100M5A', #JR + 371 => 'ILCE-6400', #IB + 372 => 'DSC-RX0M2', #JR + 374 => 'DSC-RX100M7', #IB + 375 => 'ILCE-7RM4', #IB + 376 => 'ILCE-9M2', #JR + 378 => 'ILCE-6600', #IB/JR + 379 => 'ILCE-6100', #IB/JR }, }, 0xb020 => { #2 @@ -2134,6 +2209,7 @@ my %hidUnk = ( Hidden => 1, Unknown => 1 ); 4 => '+4/3', #JR (NC) 5 => '+5/3', #JR (NC) 6 => '+6/3', #JR + 9 => '+9/3', #JR 128 => 'n/a', #JR (HX9V) 32767 => 'High', }, @@ -5420,7 +5496,7 @@ my %faceInfo = ( PrintConv => { 191 => 'On (191)', # seen a few times with moving subject, continuous drive, bracketing 207 => 'On (207)', # seen once with RemoteCommander - 210 => 'On (210)', # seen a few times with continous drive + 210 => 'On (210)', # seen a few times with continuous drive 213 => 'On', 246 => 'Off', }, @@ -5745,7 +5821,7 @@ my %releaseMode2 = ( #JR 15 => 'Continuous - High Resolution Sweep Panorama', #JR (HX50V) 16 => 'Continuous - 3D Image', # (HX9V) 17 => 'Continuous - Burst 2', # (WX7 - PH) (#JR 9400-SequenceLength=10 shots) - # 18 - seen for several ILCE-7S v2.00 iAuto+ single-shot images ... + 18 => 'Normal - iAuto+', # seen for several ILCE-3500/6000/6500/7S iAuto+ single-shot images ... 19 => 'Continuous - Speed/Advance Priority', #PH/JR (RX100) 20 => 'Continuous - Multi Frame NR', 23 => 'Single-frame - Exposure Bracketing', # (seen for ILCE-7 series) @@ -5786,6 +5862,7 @@ my %releaseMode2010 = ( 4 => 'Continuous - Burst', # seen for DSC-WX500 with burst of 10 shots 5 => 'Continuous - Speed/Advance Priority', 6 => 'Normal - Self-timer', # seen for ILCE-6300/6500/9, ILCA-99M2 + 9 => 'Single Burst Shooting', # first seen for DSC-RX100M7 }, ); my %selfTimer2010 = ( @@ -5940,6 +6017,45 @@ my %pictureProfile2010 = ( 33 => 'Gamma HLG2 (PP10)', #14 }, ); +my %isoSetting2010 = ( + 0 => 'Auto', + 5 => 25, + 8 => 50, + 9 => 64, + 10 => 80, + 11 => 100, + 12 => 125, + 13 => 160, + 14 => 200, + 15 => 250, + 16 => 320, + 17 => 400, + 18 => 500, + 19 => 640, + 20 => 800, + 21 => 1000, + 22 => 1250, + 23 => 1600, + 24 => 2000, + 25 => 2500, + 26 => 3200, + 27 => 4000, + 28 => 5000, + 29 => 6400, + 30 => 8000, + 31 => 10000, + 32 => 12800, + 33 => 16000, + 34 => 20000, + 35 => 25600, + 38 => 51200, + 39 => 64000, + 41 => 102400, + 42 => 128000, + 43 => 160000, + 44 => 204800, + 47 => 409600, +); %Image::ExifTool::Sony::Tag2010a = ( #JR PROCESS_PROC => \&ProcessEnciphered, @@ -5951,6 +6067,7 @@ my %pictureProfile2010 = ( FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + IS_SUBDIR => [ 0x04b0 ], 0x04b0 => { Name => 'MeterInfo', Format => 'int32u[486]', @@ -5987,6 +6104,7 @@ my %pictureProfile2010 = ( FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + IS_SUBDIR => [ 0x04b4 ], 0x0000 => { %sequenceImageNumber }, #PH 0x0004 => { %sequenceFileNumber }, #PH 0x0008 => { %releaseMode2, Format => 'int32u' }, @@ -6054,6 +6172,7 @@ my %pictureProfile2010 = ( FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + IS_SUBDIR => [ 0x0490 ], 0x0000 => { %sequenceImageNumber }, #PH 0x0004 => { %sequenceFileNumber }, #PH 0x0008 => { %releaseMode2, Format => 'int32u' }, @@ -6122,6 +6241,7 @@ my %pictureProfile2010 = ( FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + IS_SUBDIR => [ 0x050c ], 0x0000 => { %sequenceImageNumber }, #PH 0x0004 => { %sequenceFileNumber }, #PH 0x0008 => { %releaseMode2, Format => 'int32u' }, @@ -6176,14 +6296,16 @@ my %pictureProfile2010 = ( CHECK_PROC => \&Image::ExifTool::CheckBinaryData, FORMAT => 'int8u', NOTES => q{ - Valid for SLT-A58/A99, ILCE-3000/3500, NEX-3N/5R/5T/6/VG30E/VG900, DSC-RX100, - DSC-RX1/RX1R. Also valid for DSC-HX300/HX50V/TX30/WX60/WX200/WX300, but not - for panorama images. + Valid for SLT-A58/A99, ILCE-3000/3500, NEX-3N/5R/5T/6/VG30E/VG900, + DSC-RX100, DSC-RX1/RX1R. Also valid for DSC-HX300/HX50V/TX30/WX60/WX200/ + WX300, but not for panorama images. }, WRITABLE => 1, FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x1892 ], + IS_SUBDIR => [ 0x04b8 ], 0x0000 => { %sequenceImageNumber }, #PH 0x0004 => { %sequenceFileNumber }, #PH 0x0008 => { %releaseMode2, Format => 'int32u' }, @@ -6286,7 +6408,9 @@ my %pictureProfile2010 = ( Condition => '$$self{Model} !~ /^(DSC-|Stellar)/', Format => 'int16s[16]', }, - # 0x1890 - same as 0x1892, but has value 3 for 50mm F1.4 ZA, DT 18-135mm and for 70-400mm G II: meaning ?? + # 0x1890 - same as 0x1892, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 + # Presumably, these are the A-mount lenses "compatible with software updates" as referred to in the ILCA-99M2 manual. + # Indeed, SAL70400G2 on ILCA-77M2 gives Version: "Lens: Ver.01" 0x1891 => { Name => 'LensFormat', Condition => '$$self{Model} !~ /^(DSC-|Stellar)/', @@ -6348,6 +6472,7 @@ my %pictureProfile2010 = ( FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + IS_SUBDIR => [ 0x01e0 ], 0x0004 => { %releaseMode2, Format => 'int32u' }, # NOT at offset 0x08 ! #0x002e => { Name => 'SonyImageWidth3', Format => 'int16u' }, #0x0042 => { Name => 'SonyImageWidth3', Format => 'int16u' }, @@ -6427,6 +6552,8 @@ my %pictureProfile2010 = ( FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x18be ], + IS_SUBDIR => [ 0x0388 ], 0x0004 => { %releaseMode2, Format => 'int32u' }, # NOT at offset 0x08 ! 0x0050 => { %dynamicRangeOptimizer2010 }, 0x020c => { %releaseMode2010 }, @@ -6489,7 +6616,7 @@ my %pictureProfile2010 = ( Condition => '$$self{Model} !~ /^DSC-/', Format => 'int16s[16]', }, - # 0x18bc - same as 0x18be, but has value 3 for 50mm F1.4 ZA, DT 18-135mm and for 70-400mm G II: meaning ?? + # 0x18bc - same as 0x18be, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x18bd => { Name => 'LensFormat', Condition => '$$self{Model} !~ /^DSC-/', @@ -6547,13 +6674,15 @@ my %pictureProfile2010 = ( CHECK_PROC => \&Image::ExifTool::CheckBinaryData, FORMAT => 'int8u', NOTES => q{ - Valid for DSC-HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500, + Valid for DSC-HX80/HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500, ILCE-6300/6500/7RM2/7SM2, ILCA-99M2. }, WRITABLE => 1, FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x18ee ], + IS_SUBDIR => [ 0x0388, 0x0398 ], 0x0004 => { %releaseMode2, Format => 'int32u' }, 0x0050 => { %dynamicRangeOptimizer2010 }, 0x020c => { %releaseMode2010 }, @@ -6624,7 +6753,7 @@ my %pictureProfile2010 = ( Condition => '$$self{Model} !~ /^DSC-/', Format => 'int16s[16]', }, - # 0x18ec - same as 0x18ee, but has value 3 for LensType>=65, except SAL300F28G2 + # 0x18ec - same as 0x18ee, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x18ed => { Name => 'LensFormat', Condition => '$$self{Model} !~ /^DSC-/', @@ -6682,12 +6811,15 @@ my %pictureProfile2010 = ( CHECK_PROC => \&Image::ExifTool::CheckBinaryData, FORMAT => 'int8u', NOTES => q{ - Valid for ILCE-7M3/7RM3/9, DSC-RX10M4/RX100M6/RX100M5A. + Valid for ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M6/ + RX100M5A/RX100M7/HX99. }, WRITABLE => 1, FIRST_ENTRY => 0, PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x17f2 ], + IS_SUBDIR => [ 0x036d ], 0x0004 => { %releaseMode2, Format => 'int32u' }, 0x004e => { %dynamicRangeOptimizer2010 }, 0x0204 => { %releaseMode2010 }, @@ -6750,7 +6882,7 @@ my %pictureProfile2010 = ( Condition => '$$self{Model} !~ /^DSC-/', Format => 'int16s[16]', }, - # 0x17f0 - same as 0x17f2, but has value 3 for LensType>=65, except SAL300F28G2 + # 0x17f0 - same as 0x17f2, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x17f1 => { Name => 'LensFormat', Condition => '$$self{Model} !~ /^DSC-/', @@ -6982,8 +7114,8 @@ my %pictureProfile2010 = ( }, WRITABLE => 1, FIRST_ENTRY => 0, - DATAMEMBER => [ 0x0105 ], GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x0031, 0x0105 ], NOTES => q{ Data for tags 0x9050, 0x94xx and 0x2010 is encrypted by a simple substitution cipher, but the deciphered values are listed below. @@ -7010,6 +7142,17 @@ my %pictureProfile2010 = ( # appears to be difference between used FNumber and MaxAperture, 256 being +1 APEX or stop # however, not always valid e.g. bracketing, Shutter-prio e.a. # difference between 0x0002 and 0x0004 mostly 0.0, 0.1 or 0.2 stops. + 0x0020 => { + Name => 'Shutter', + Format => 'int16u[3]', + PrintConv => { + '0 0 0' => 'Silent / Electronic (0 0 0)', + OTHER => sub { + my ($val, $inv) = @_; + return $inv ? ($val=~/\((.*?)\)/ ? $1 : undef) : "Mechanical ($val)"; + }, + }, + }, 0x0031 => { #JR Name => 'FlashStatus', RawConv => '$$self{FlashFired} = $val', @@ -7024,7 +7167,7 @@ my %pictureProfile2010 = ( }, }, 0x0032 => { #13 - Name => 'ImageCount', + Name => 'ShutterCount', # this seems to be valid for the A7R,A37,A57,A65,A77,A99,A99V and possibly the # NEX-5N/7. For the A99V it is definitely more than 16 bits, but it wraps at # 65536 for the A7R. @@ -7059,9 +7202,9 @@ my %pictureProfile2010 = ( # e.g for SAL70400G2: 9 5 5 64 69 74 79 84 89 94 98 104 255 105 89 80 # where 9 means 9 focal lengths: 64 ... 104, # corresponding to 70-400mm via FocalLength = 4.375*2**($val/16) -# 0x004c, 0x0051: E-Mount: ImageCount and dateTime +# 0x004c, 0x0051: E-Mount: ShutterCount and dateTime 0x004c => { # only ILCE-7/7R/7S/7M2/5000/5100/6000/QX1 - but appears not valid when flash is used ... - Name => 'ImageCount2', + Name => 'ShutterCount2', Condition => '($$self{Model} =~ /^(ILCE-(7(R|S|M2)?|[56]000|5100|QX1))\b/) and (($$self{FlashFired} & 0x01) != 1)', Format => 'int32u', RawConv => '$val & 0x00ffffff', @@ -7104,7 +7247,7 @@ my %pictureProfile2010 = ( PrintConv => 'unpack "H*", pack "C*", split " ", $val', PrintConvInv => 'join " ", unpack "C*", pack "H*", $val', }, - # 0x0104 - same as 0x0105, but has value 3 for 50mm F1.4 ZA, DT 18-135mm and for 70-400mm G II: meaning ?? + # 0x0104 - same as 0x0105, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x0105 => { Name => 'LensMount', DataMember => 'LensMount', @@ -7145,6 +7288,14 @@ my %pictureProfile2010 = ( Name => 'DistortionCorrParamsPresent', PrintConv => { 0 => 'No', 1 => 'Yes'}, }, + 0x0114 => { + Name => 'APS-CSizeCapture', + Condition => '$$self{Model} =~ /^(SLT-A99|HV|ILCE-7)/', + PrintConv => { + 0 => 'Off', + 1 => 'On', + }, + }, # 0x0115 and 0x0116, or 0x0116 and 0x0117: # give the same info as the first and last bytes of LensSpec, # but also for older Sony and Minolta lenses where all LensSpec bytes are 0. @@ -7178,27 +7329,27 @@ my %pictureProfile2010 = ( # 0x012d => {Name=>'LensType',Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/'}, # 0x012e => {Name=>'LensType',Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(58|99V?)|HV|ILCA-(68|77M2)|NEX-(3N|5R|5T|6|VG30E|VG900)|ILCE-(3000|3500|5000|5100|6000|7|7R|7S|7M2|QX1))/'}, -# ImageCount3 = ImageCount for SLT-A58, ILCE, ILCA, NEX-3N -# ImageCount-1 for SLT-A37,A57,A65,A77,A99, NEX-F3,5N,5R,5T,6,7, sometimes 0 -# ImageCount-2 for NEX-VG, and often 0; "ImageCount-2" also seen on a few A99V images -# The offset for ImageCount3 changes with firmware version for the ILCE-7/7R/7S/7M2, so don't decode it for now: +# ShutterCount3 = ShutterCount for SLT-A58, ILCE, ILCA, NEX-3N +# ShutterCount-1 for SLT-A37,A57,A65,A77,A99, NEX-F3,5N,5R,5T,6,7, sometimes 0 +# ShutterCount-2 for NEX-VG, and often 0; "ShutterCount-2" also seen on a few A99V images +# The offset for ShutterCount3 changes with firmware version for the ILCE-7/7R/7S/7M2, so don't decode it for now: # ILCE-7M2/7S: 0x01a0 (firmware 1.0x, 1.1x), 0x01b6 (firmware 1.20, 1.21, 2.00) # ILCE-7/7R: 0x01aa (firmware 1.0x, 1.1x), 0x01c0 (firmware 1.20, 1.21, 2.00) # Similarly for ILCE-6000 v2.00: 0x01aa --> 0x01c0: removed from 0x01aa 0x01a0 => { - Name => 'ImageCount3', + Name => 'ShutterCount3', Format => 'int32u', RawConv => '$val == 0 ? undef : $val', Condition => '$$self{Model} =~ /^(ILCE-(5100|QX1)|ILCA-(68|77M2))/', }, 0x01aa => { - Name => 'ImageCount3', + Name => 'ShutterCount3', Format => 'int32u', RawConv => '$val == 0 ? undef : $val', Condition => '$$self{Model} =~ /^(SLT-A(58|99V?)|HV|NEX-(3N|5R|5T|6|VG900|VG30E)|ILCE-([35]000|3500))\b/', }, 0x01bd => { - Name => 'ImageCount3', + Name => 'ShutterCount3', Format => 'int32u', RawConv => '$val == 0 ? undef : $val', Condition => '$$self{Model} =~ /^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/', @@ -7240,11 +7391,14 @@ my %pictureProfile2010 = ( WRITE_PROC => \&WriteEnciphered, CHECK_PROC => \&Image::ExifTool::CheckBinaryData, FORMAT => 'int8u', - NOTES => 'Valid from July 2015 for ILCE-6300/6500/7M3/7RM2/7RM3/7SM2/9, ILCA-99M2.', + NOTES => q{ + Valid from July 2015 for ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/ + 7SM2/9/9M2, ILCA-99M2. + }, WRITABLE => 1, FIRST_ENTRY => 0, - DATAMEMBER => [ 0x0105 ], GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x0039, 0x0105 ], 0x0000 => { Condition => '$$self{Model} =~ /^(ILCA-)/', Name => 'SonyMaxAperture', # (at current focal length) @@ -7263,6 +7417,25 @@ my %pictureProfile2010 = ( PrintConv => 'sprintf("%.0f",$val)', PrintConvInv => '$val', }, + 0x0026 => { + Name => 'Shutter', + Format => 'int16u[3]', + PrintConv => { + '0 0 0' => 'Silent / Electronic (0 0 0)', + OTHER => sub { + my ($val, $inv) = @_; + return $inv ? ($val=~/\((.*?)\)/ ? $1 : undef) : "Mechanical ($val)"; + }, + }, + }, + #0x002c => { + # Name => 'Shutter', + # Condition => '$$self{Model} !~ /^(ILCE-6400)/ and $$self{Software} !~ /^ILCE-9 v5.0/', + # PrintConv => { + # 0 => 'Silent / Electronic', + # 56 => 'Mechanical', + # }, + #}, 0x0039 => { Name => 'FlashStatus', RawConv => '$$self{FlashFired} = $val', @@ -7274,10 +7447,11 @@ my %pictureProfile2010 = ( 66 => 'Built-in Flash Inhibited', # seen for panorama, HDR, burst mode 128 => 'External Flash present', # seen for NEX-5N/5T 129 => 'External Flash Fired', # seen for SLT-A99V, ILCE-7R, NEX-5N/5R +# 131 => 'External Flash ???', # seen for ILCE-7RM4 }, }, 0x003a => { - Name => 'ImageCount', + Name => 'ShutterCount', # or "ShutterCount"? : number of shutter actuations, does not increase during Silent Shooting, # at least for ILCE-7RM2 Format => 'int32u', @@ -7304,36 +7478,52 @@ my %pictureProfile2010 = ( Name => 'ReleaseMode2', %releaseMode2, }, +# March 2019: ILCE-9 with v5.0x firmware follows ILCE-6400 in many tags ... + 0x0050 => { + Name => 'ShutterCount2', + Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} =~ /^(ILCE-(6100|6400|6600|7RM4|9M2))/ or $$self{Software} =~ /^ILCE-9 (v5.0|v6.0)/)', + Format => 'int32u', + RawConv => '$val & 0x00ffffff', + }, 0x0052 => { - Name => 'ImageCount2', + Name => 'ShutterCount2', Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} =~ /^(ILCE-(7M3|7RM3))/)', Format => 'int32u', RawConv => '$val & 0x00ffffff', - PrintConv => 'sprintf("%6d",$val)', }, # 0x0058 - 0x0067: A-Mount: 16 values, only non-zero data for lenses giving "A-mount (3)" in 0x0104 below. # e.g for SAL70400G2: 9 5 5 64 69 74 79 84 89 94 98 104 255 105 89 80 # where 9 means 9 focal lengths: 64 ... 104, # corresponding to 70-400mm via FocalLength = 4.375*2**($val/16) -# 0x0058, 0x0061: E-Mount: ImageCount and dateTime +# 0x0058, 0x0061: E-Mount: ShutterCount and dateTime 0x0058 => { # appears not valid when flash is used ... not for ILCA-99M2 - Name => 'ImageCount2', - Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} !~ /^(ILCA-99M2|ILCE-(7M3|7RM3))/)', + Name => 'ShutterCount2', + Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} !~ /^(ILCA-99M2|ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9M2))/) and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/', Format => 'int32u', RawConv => '$val & 0x00ffffff', }, 0x0061 => { # only minutes-seconds, not for ILCA-99M2, ILCE-9 Name => 'SonyTimeMinSec', - Condition => '$$self{Model} !~ /^(ILCA-99M2|ILCE-(7M3|7RM3|9))/', + Condition => '$$self{Model} !~ /^(ILCA-99M2|ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2))/', Format => 'undef[2]', ValueConv => q{ my @v = unpack('C*', $val); return sprintf("%.2d:%.2d", @v) }, }, + 0x006b => { + Name => 'ReleaseMode2', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7RM4|9M2))/ or $$self{Software} =~ /^ILCE-9 (v5.0|v6.0)/', + %releaseMode2, + }, + 0x006d => { + Name => 'ReleaseMode2', + Condition => '$$self{Model} =~ /^(ILCE-(7M3|7RM3))/', + %releaseMode2, + }, 0x0073 => { Name => 'ReleaseMode2', - Condition => '$$self{Model} !~ /^(ILCE-(7M3|7RM3))/', + Condition => '$$self{Model} !~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9M2))/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/', %releaseMode2, }, 0x0088 => { @@ -7344,7 +7534,7 @@ my %pictureProfile2010 = ( ##### same offsets for lens info tags - # 0x0104 - same as 0x0105, but has value 3 for 50mm F1.4 ZA, DT 18-135mm and for 70-400mm G II: meaning ?? + # 0x0104 - same as 0x0105, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x0105 => { Name => 'LensMount', DataMember => 'LensMount', @@ -7385,6 +7575,14 @@ my %pictureProfile2010 = ( Name => 'DistortionCorrParamsPresent', PrintConv => { 0 => 'No', 1 => 'Yes'}, }, + 0x0114 => { + Name => 'APS-CSizeCapture', + Condition => '$$self{Model} =~ /^(ILCE-7|ILCE-9|ILCA-99)/', + PrintConv => { + 0 => 'Off', + 1 => 'On', + }, + }, # 0x0116 and 0x0117: # give the same info as the first and last bytes of LensSpec, # but also for older Sony and Minolta lenses where all LensSpec bytes are 0. @@ -7403,23 +7601,65 @@ my %pictureProfile2010 = ( # tags becoming model- and/or firmware-dependent from here. # 0x019f => { - Name => 'ImageCount3', - Condition => '$$self{Model} =~ /^(ILCE-(7M3|7RM3|9))/', + Name => 'ShutterCount3', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2))\b/', Format => 'int32u', RawConv => '$val == 0 ? undef : $val', }, 0x01cb => { - Name => 'ImageCount3', + Name => 'ShutterCount3', Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2))/', Format => 'int32u', RawConv => '$val == 0 ? undef : $val', }, 0x01cd => { - Name => 'ImageCount3', + Name => 'ShutterCount3', Condition => '$$self{Model} =~ /^(ILCE-(6300|6500)|ILCA-99M2)/', Format => 'int32u', RawConv => '$val == 0 ? undef : $val', }, + 0x01eb => { + Name => 'APS-CSizeCapture', + Condition => '$$self{Model} =~ /^ILCE-(7RM4|9M2)/ or $$self{Software} =~ /^ILCE-9 (v5.0|v6.0)/', + PrintConv => { + 0 => 'Off', + 1 => 'On', + }, + }, + 0x01ed => { + Name => 'LensSpecFeatures', + Condition => '$$self{Model} =~ /^ILCE-(7RM4|9M2)/ or $$self{Software} =~ /^ILCE-9 (v5.0|v6.0)/', + Priority => 0, + Format => 'undef[2]', + ValueConv => 'join " ", unpack "H2H2", $val', + ValueConvInv => sub { + my @a = split(" ", shift); + return @a == 2 ? pack 'CC', hex($a[0]), hex($a[1]) : undef; + }, + PrintConv => \&PrintLensSpec, + PrintConvInv => 'Image::ExifTool::Sony::PrintInvLensSpec($val, $self, 1)', + }, + 0x01ee => { + Name => 'APS-CSizeCapture', + Condition => '$$self{Model} =~ /^(ILCE-(7M3|7RM3|9))\b/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/', + PrintConv => { + 0 => 'Off', + 1 => 'On', + }, + }, + 0x01f0 => { + Name => 'LensSpecFeatures', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|9))\b/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/', + Priority => 0, + Format => 'undef[2]', + ValueConv => 'join " ", unpack "H2H2", $val', + ValueConvInv => sub { + my @a = split(" ", shift); + return @a == 2 ? pack 'CC', hex($a[0]), hex($a[1]) : undef; + }, + PrintConv => \&PrintLensSpec, + PrintConvInv => 'Image::ExifTool::Sony::PrintInvLensSpec($val, $self, 1)', + }, # the following tags are commented out because they can cause problems for the # Composite LensID of non-electronic lenses (even if Priority is set to 0) # 0x020d => { @@ -7441,7 +7681,15 @@ my %pictureProfile2010 = ( # Condition => '$$self{Model} =~ /^(ILCE-(6300|6500)|ILCA-99M2)/', # Format=>'int16u', # }, - 0x021c => { + 0x021a => { + Name => 'APS-CSizeCapture', + Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2))/', + PrintConv => { + 0 => 'Off', + 1 => 'On', + }, + }, + 0x021c => [{ Name => 'LensSpecFeatures', Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2))/', Priority => 0, @@ -7453,7 +7701,14 @@ my %pictureProfile2010 = ( }, PrintConv => \&PrintLensSpec, PrintConvInv => 'Image::ExifTool::Sony::PrintInvLensSpec($val, $self, 1)', - }, + },{ + Name => 'APS-CSizeCapture', + Condition => '$$self{Model} =~ /^(ILCA-99M2)/', + PrintConv => { + 0 => 'Off', + 1 => 'On', + }, + }], 0x021e => { Name => 'LensSpecFeatures', Condition => '$$self{Model} =~ /^(ILCE-(6300|6500)|ILCA-99M2)/', @@ -7636,15 +7891,16 @@ my %pictureProfile2010 = ( FORMAT => 'int8u', WRITABLE => 1, NOTES => q{ - Valid for DSC-HX60V/HX90V/HX350/HX400V/QX30/RX0/RX1RM2/RX10/RX10M2/RX10M3/ - RX10M4/RX100M3/RX100M4/RX100M5/RX100M6/WX220/WX350/WX500, ILCE-7/7R/7S/ - 7M2/7M3/7RM2/7RM3/7SM2/9/5000/5100/6000/6300/6500/QX1, ILCA-68/77M2/99M2. + Valid for DSC-HX60V/HX80/HX90V/HX99/HX350/HX400V/QX30/RX0/RX1RM2/RX10/ + RX10M2/RX10M3/RX10M4/RX100M3/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/WX220/ + WX350/WX500, ILCE-7/7R/7S/7M2/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2/5000/5100/6000/ + 6100/6300/6400/6500/6600/QX1, ILCA-68/77M2/99M2. }, FIRST_ENTRY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, 0x0009 => { %releaseMode2 }, 0x000a => [{ - Condition => '$$self{Model} =~ /^(ILCE-(7M3|7RM3|9)|DSC-(RX10M4|RX100M6|RX100M5A))\b/', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M7|RX100M5A|HX99|RX0M2))\b/', Name => 'ShotNumberSincePowerUp', Format => 'int8u', },{ @@ -7662,9 +7918,11 @@ my %pictureProfile2010 = ( 4 => '4 shots', 5 => '5 shots', 6 => '6 shots', + 7 => '7 shots', # DSC-RX100M7 Single Burst Shooting 9 => '9 shots', # ILCE-7RM2 9-shot bracketing 10 => '10 shots', 12 => '12 shots', # ILCA-77M2 12-shot MFNR-mode + 16 => '16 shots', # ILCE-7RM4 16-shot PixelShift 100 => 'Continuous - iSweep Panorama', 200 => 'Continuous - Sweep Panorama', }, @@ -7678,6 +7936,7 @@ my %pictureProfile2010 = ( 2 => '2 files', 3 => '3 files', 5 => '5 files', + 7 => '7 files', # DSC-RX100M7 Single Burst Shooting 9 => '9 files', # ILCE-7RM2 9-shot bracketing 10 => '10 files', # seen for DSC-WX500 with burst of 10 shots }, @@ -7712,6 +7971,40 @@ my %pictureProfile2010 = ( }, ); +%Image::ExifTool::Sony::Tag9401 = ( # JR + PROCESS_PROC => \&ProcessEnciphered, + WRITE_PROC => \&WriteEnciphered, + CHECK_PROC => \&Image::ExifTool::CheckBinaryData, + FORMAT => 'int8u', + WRITABLE => 1, + FIRST_ENTRY => 0, + GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0 ], + IS_SUBDIR => [ 0x0498, 0x04a2, 0x059d, 0x0634, 0x0636, 0x064c, 0x0653, 0x0678, 0x06b8, 0x06de, 0x06e7 ], + 0x0000 => { Name => 'Ver9401', Hidden => 1, RawConv => '$$self{Ver9401} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val' }, + + 0x0498 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 148', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x04a2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(152|154)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x059d => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(144|146)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x0634 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 68', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x0636 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(73|74)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x064c => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 78', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x0653 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} == 90', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x0678 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(93|94)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x06b8 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(100|103)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x06de => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(124|125)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, + 0x06e7 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(127|128|130)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } }, +); + +%Image::ExifTool::Sony::ISOInfo = ( # JR + FORMAT => 'int8u', + %binaryDataAttrs, + GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, + 0x0000 => { Name => 'ISOSetting', ValueConv => \%isoSetting2010 }, + 0x0002 => { Name => 'ISOAutoMin', ValueConv => \%isoSetting2010 }, + 0x0004 => { Name => 'ISOAutoMax', ValueConv => \%isoSetting2010 }, +); + # PH (RX100) %Image::ExifTool::Sony::Tag9402 = ( PROCESS_PROC => \&ProcessEnciphered, @@ -7761,6 +8054,7 @@ my %pictureProfile2010 = ( 12 => 'Expanded Flexible Spot', #JR (HX90V, ILCE-7 series) 14 => 'Tracking', 15 => 'Face Tracking', + 20 => 'Animal Eye Tracking', 255 => 'Manual', }, }, @@ -7911,8 +8205,8 @@ my %pictureProfile2010 = ( WRITABLE => 1, FIRST_ENTRY => 0, PRIORITY => 0, - DATAMEMBER => [ 0x0604 ], GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x0604 ], NOTES => 'Valid for SLT, NEX, ILCE-3000/3500 and several DSC models.', 0x0600 => { Name => 'DistortionCorrParamsPresent', @@ -7926,7 +8220,7 @@ my %pictureProfile2010 = ( 1 => 'Applied', }, }, - # 0x0602 - same as 0x0604, but has value 3 for 50mm F1.4 ZA, DT 18-135mm and for 70-400mm G II: meaning ?? + # 0x0602 - same as 0x0604, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x0603 => { Name => 'LensFormat', Condition => '$$self{Model} !~ /^(DSC-|Stellar)/', @@ -7989,12 +8283,13 @@ my %pictureProfile2010 = ( WRITABLE => 1, FIRST_ENTRY => 0, PRIORITY => 0, - DATAMEMBER => [ 0x005e ], GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, + DATAMEMBER => [ 0x005e ], NOTES => q{ - Valid for DSC-HX60V/HX350/HX400V/QX30/RX0/RX10/RX10M2/RX10M3/RX10M4/ - RX100M3/RX100M4/RX100M5/RX100M6/WX220/WX350, ILCE-7/7M2/7M3/7R/7RM2/ - 7S/7SM2/9/5000/5100/6000/6300/6500/QX1, ILCA-68/77M2/99M2. + Valid for DSC-HX60V/HX80/HX90V/HX99/HX350/HX400V/QX30/RX0/RX10/RX10M2/ + RX10M3/RX10M4/RX100M3/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/WX220/WX350, + ILCE-7/7M2/7M3/7R/7RM2/7RM3/7RM4/7S/7SM2/9/9M2/5000/5100/6000/6100/6300/ + 6400/6500/6600/QX1, ILCA-68/77M2/99M2. }, 0x0004 => { Name => 'SonyISO', @@ -8104,7 +8399,7 @@ my %pictureProfile2010 = ( 1 => 'Applied', }, }, - # 0x005c - same as 0x005e, but has value 3 for 50mm F1.4 ZA, DT 18-135mm and for 70-400mm G II: meaning ?? + # 0x005c - same as 0x005e, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2 0x005d => { Name => 'LensFormat', Condition => '$$self{Model} !~ /^DSC-/', @@ -8147,7 +8442,7 @@ my %pictureProfile2010 = ( }, 0x0342 => { Name => 'LensZoomPosition', - Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7SM2|6500|9)|DSC-(HX90V|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M6|WX500))/', + Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7RM4|7SM2|6100|6300|6400|6500|6600|9|9M2)|DSC-(HX80|HX90V|HX99|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M5A|RX100M6|RX100M7|WX500))/', Format => 'int16u', PrintConv => 'sprintf("%.0f%%",$val/10.24)', PrintConvInv => '$val=~s/ ?%$//; $val * 10.24', @@ -8157,6 +8452,13 @@ my %pictureProfile2010 = ( Condition => '$$self{Model} =~ /^(ILCA-(68|77M2)|ILCE-(5000|5100|6000|7|7R|7S|QX1)|Lusso)\b/', Format => 'int16s[16]', }, + 0x034e => { + Name => 'LensZoomPosition', + Condition => '$$self{Model} =~ /^(DSC-(RX100M5|RX100M5A|RX100M6|RX100M7|RX10M4|HX99)|ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9M2))/', + Format => 'int16u', + PrintConv => 'sprintf("%.0f%%",$val/10.24)', + PrintConvInv => '$val=~s/ ?%$//; $val * 10.24', + }, 0x0350 => { Name => 'VignettingCorrParams', Condition => '$$self{Model} =~ /^(ILCE-7M2)/', @@ -8164,12 +8466,12 @@ my %pictureProfile2010 = ( }, 0x035c => { Name => 'VignettingCorrParams', - Condition => '$$self{Model} =~ /^(ILCA-99M2|ILCE-(6500|7M3|7RM3|9))/', + Condition => '$$self{Model} =~ /^(ILCA-99M2|ILCE-(6100|6400|6500|6600|7M3|7RM3|7RM4|9|9M2))/', Format => 'int16s[16]', }, 0x035a => { Name => 'LensZoomPosition', - Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2)|DSC-(HX90V|RX10M2|RX10M3|RX100M4|WX500))/', + Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2)|DSC-(HX80|HX90V|RX10M2|RX10M3|RX100M4|WX500))/', Format => 'int16u', PrintConv => 'sprintf("%.0f%%",$val/10.24)', PrintConvInv => '$val=~s/ ?%$//; $val * 10.24', @@ -8201,7 +8503,7 @@ my %pictureProfile2010 = ( }, 0x03b8 => { Name => 'ChromaticAberrationCorrParams', - Condition => '$$self{Model} =~ /^(ILCE-(7M3|7RM3|9))/', + Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7M3|7RM3|7RM4|9|9M2))/', Format => 'int16s[32]', }, ); @@ -8217,7 +8519,7 @@ my %pictureProfile2010 = ( GROUPS => { 0 => 'MakerNotes', 2 => 'Image' }, # 0x0000: 1 for SLT-A37/A57/A65/A77, NEX-5N/7/F3/VG20 # 2 for SLT-A58/99V, NEX-3N/5R/5T/6/VG30/VG900, ILCA-68/77M2, ILCE-3000/3500/7/7M2/7R/7S/5000/6000 -# 3 for ILCA-99M2, ILCE-6300/6500/7M3/7RM2/7RM3/7SM2/9 +# 3 for ILCA-99M2, ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2 # 0x0001+0x0002: Int16u, seen 580 - 770: similar to "BatteryUnknown" ?? # 0x0005: int8u, seen 73 - 117: maybe Fahrenheit? Higher than "AmbientTemperature", but same trend. 0x0005 => { @@ -8230,7 +8532,7 @@ my %pictureProfile2010 = ( # 0x0006: usually 0, seen non-zero values only for SLT-A99V, ILCA-77M2/99M2 and ILCE-7/7R/7RM2/9: BatteryLevel Grip ? 0x0006 => { Name => 'BatteryLevelGrip1', - Condition => '$$valPt !~ /^\x00/', # only valid when not 0 + RawConv => '$val ? $val : undef', # only valid when not 0 PrintConv => '"$val%"', PrintConvInv => '$val=~s/\s*\%//; $val', }, @@ -8245,7 +8547,8 @@ my %pictureProfile2010 = ( # but ILCE-7/7R with grip can have max 2, and as all ILCE-7/7R samples give >100 values, exclude... 0x0008 => { Name => 'BatteryLevelGrip2', - Condition => '$$valPt !~ /^[\x00\xff]/ and $$self{Model} !~ /^(ILCE-(7|7R)|Lusso)$/', # only when not 0 or 255 and not for ILCE-7/7R + Condition => '$$self{Model} !~ /^(ILCE-(7|7R)|Lusso)$/', # not valid for ILCE-7/7R + RawConv => '($val and $val != 255) ? $val : undef', # not valid if 0 or 255 PrintConv => '"$val%"', PrintConvInv => '$val=~s/\s*\%//; $val', }, @@ -8273,12 +8576,13 @@ my %pictureProfile2010 = ( PrintConv => { # verified for A77 firmware 1.03 and 1.07 and A99 firmware 1.00, # but there were inconsistencies with my A77 firmware 1.04 samples - PH - 0 => '(none)', + 0 => '(none)', # ILCA-68/77M2/99M2 always give this 0x00007801 => 'Center Zone', 0x0001821c => 'Right Zone', 0x000605c0 => 'Left Zone', - 0x7fffffff => '(all)', - # 0xffffffff - 'n/a' - RX1 and NEX models always give this + 0x0003ffff => '(all LA-EA4)', # for LA-EA4: 18 bits + 0x7fffffff => '(all)', # also for LA-EA2 + 0xffffffff => 'n/a', # DSC and ILCE/NEX models always give this, except when using LA-EA2 or LA-EA4 # (on Wide AFAreaMode, outer focus points are dropped # at progressively higher digital zoom ratios, ref JR) BITMASK => { @@ -8359,10 +8663,11 @@ my %pictureProfile2010 = ( # 1.30: NEX-5T v1.00, NEX-6 v1.02/v1.03, NEX-7 v1.03 # 1.31: ILCE-7/7R v0.95/v1.00/v1.01, ILCE-5000 # 1.40: ILCE-7/7R v1.02/v1.10, ILCE-7S v1.00, ILCE-6000 v1.00/v1.10, ILCE-5100/QX1 - # 1.50: ILCE-7/7R/7S v1.20-v3.20, ILCE-7M2 v1.00-v4.00, ILCE-7RM2 v1.00-v3.00, ILCE-7SM2 v1.00-v2.10, + # 1.50: ILCE-7/7R/7S v1.20-v3.20, ILCE-7M2, ILCE-7RM2 v1.00-v3.00, ILCE-7SM2 v1.00-v2.20, # ILCE-6000 v1.20-v3.20 # 1.60: ILCE-6300/6500, ILCE-7RM2 v3.05-v4.00 - # 1.70: ILCE-7M3/7RM3/9 + # 1.70: ILCE-7M3/7RM3, ILCE-9 v1.00-v4.10 + # 1.80: ILCE-6100/6400/6600/7RM4/9M2, ILCE-9 v5.00-v6.00 }, 0x000d => { Name => 'LensE-mountVersion', @@ -8384,11 +8689,14 @@ my %pictureProfile2010 = ( # 1.40: SEL1635Z, SEL24240, SEL35F14Z, SELP28135G, Zeiss Loxia 35mm/50mm Ver.01, Zeiss Touit Ver.02 # 1.41: SELP18105G Ver.02 # 1.50: SEL28F20, SEL90M28G, Zeiss Batis 18mm/25mm/85mm/135mm, Zeiss Loxia 21mm, Zeiss Loxia 35mm/50mm Ver.02, - # Tokina Firin 20mm - # 1.60: SEL1224G, SEL1635GM, SELP18110G, SEL18135, SEL2470GM, SEL24105G, SEL50F14Z, SEL50F18F, SEL50M28, SEL70200GM, - # SEL70300G, SEL85F14GM, SEL85F18, SEL100F28GM, SEL100400GM, Sigma 30mm F1.4 DC DN, Sigma MC-11, - # Samyang AF 14mm/50mm, Voigtlander 15mm, Sigma 16mm F1.4 DC DN - # 1.70: LA-EA3 Ver.02, Samyang AF 35mm, Tamron 28-75mm, Voigtlander 10mm/12mm/40mm/65mm, Zeiss Loxia 25mm/85mm + # Tokina FiRIN 20mm + # 1.60: SEL1224G, SEL1635GM, SEL1655G, SELP18110G, SEL18135, SEL2470GM, SEL24105G, SEL35F18F, SEL50F14Z, SEL50F18F, + # SEL50M28, SEL70200GM, SEL70300G, SEL70350G, SEL85F14GM, SEL85F18, SEL100F28GM, SEL100400GM, SEL135F18GM, + # SEL200600G, SEL600F40GM, Sigma 16F14DCDN/30F14DCDN/35F12DGDN/45F28DGDN, Sigma MC-11, Samyang AF 14mm/50mm, + # Voigtlander 15mm, Viltrox 85mm MF + # 1.70: LA-EA3 Ver.02, Samyang AF 24mm/35mm/85mm, Tamron 17-28mm, 28-75mm, Tokina FiRIN 20mm AF Ver.01, Tokina FiRIN 100mm Macro, + # Voigtlander 10mm/12mm/40mm/65mm, Zeiss Loxia 25mm/85mm, Sigma 14-24mm + # 1.80: Voigtlander 21mm }, # 0x0014 and 0x0015: change together: LensFirmwareVersion # 0x0015 as 2-digit hex matches known firmware versions of Sony lenses and Metabones adapters, @@ -8409,7 +8717,7 @@ my %pictureProfile2010 = ( ); -# AFInfo (SLT models only) (ref PH, decoded mainly from A77) +# AFInfo 0x940e (SLT models only) (ref PH, decoded mainly from A77) %Image::ExifTool::Sony::AFInfo = ( PROCESS_PROC => \&ProcessEnciphered, WRITE_PROC => \&WriteEnciphered, @@ -8420,7 +8728,7 @@ my %pictureProfile2010 = ( PRIORITY => 0, GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' }, DATAMEMBER => [ 0x02 ], - IS_SUBDIR => [ 0x11 ], + IS_SUBDIR => [ 0x11, 0x7d ], NOTES => 'These tags are currently extracted for SLT models only.', # first 4 bytes (deciphered) (ref JR): # 0 1 1 0 for A37, A57, A58 @@ -8430,7 +8738,7 @@ my %pictureProfile2010 = ( # 1 1 3 0 for ILCA-68/77M2/99M2 # 0 0 0 0 for NEX and ILCE-3000/3500, also seen for SLT/ILCA with non-AF lens # 1 0 0 0 for ILCE-5000/5100/6000/7/7M2/7R/7S/QX1 - # 6 0 0 0 for ILCE-6300/6500/7M3/7RM2/7RM3/7SM2/9 + # 6 0 0 0 for ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2 # 0 2 0 0 for NEX/ILCE with LA-EA2/EA4 Phase-AF adapter # 2 0 0 0 seen for a few NEX-5N images # 2 2 0 0 seen for a few NEX-5N/7 images with LA-EA2 adapter @@ -8723,11 +9031,12 @@ my %pictureProfile2010 = ( # other NEX/ILCE: 74 blocks of 164 bytes # 0x1a06 onwards - first seen for ILCE-7RM2: appears to be some kind of metering image - 0x1a06 => { Name => 'TiffMeteringImageWidth', Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9))\b/' }, - 0x1a07 => { Name => 'TiffMeteringImageHeight', Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9))\b/' }, + # but not valid anymore for ILCE-6400, ILCE-9 v5.0x + 0x1a06 => { Name => 'TiffMeteringImageWidth', Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9))\b/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/' }, + 0x1a07 => { Name => 'TiffMeteringImageHeight', Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9))\b/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/' }, 0x1a08 => { # (2640 bytes: 1 set of 44x30 int16u values) Name => 'TiffMeteringImage', - Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9))\b/', + Condition => '$$self{Model} =~ /^(ILCE-(6300|6500|7M3|7RM2|7RM3|7SM2|9))\b/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/', Format => 'undef[2640]', Notes => q{ 13(?)-bit intensity data from 1320 (1200) metering segments, extracted as a @@ -9307,7 +9616,7 @@ my %pictureProfile2010 = ( ValueConv => 'length($val) > 12 ? substr($val,0,12) : $val', }, # 'EvA:' - exposure compensation * 10 (ref JR) - # for documentation only -- this IFD is handled manually + # IFD: for documentation only -- this IFD is handled manually IFD => { Name => 'PIC_IFD', SubDirectory => { TagTable => 'Image::ExifTool::Sony::Main' }, @@ -9417,7 +9726,7 @@ my %pictureProfile2010 = ( GROUPS => { 2 => 'Video' }, NOTES => q{ These tags are extracted from the 'rtmd' timed metadata of MP4 videos from - some models when the ExtractEmbedded option is used. + some models when the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option is used. }, # 0x060e - 16 bytes starting with 0x060e2b340253 (fake tag ID - comes before 0x8300 container) 0x060e => { Name => 'Sony_rtmd_0x060e', Format => 'int8u', %hidUnk }, @@ -9466,7 +9775,7 @@ my %pictureProfile2010 = ( # For DSLR-A550 and newer, NEX/ILCE/SLT/ILCA (only A65V/A77V are missing ...): # seen FocusPosition2 with values from 80 - 255 (and 21 for Touit 12mm...) # Formula from minolta.pm (WBInfoA100 - 0x49bb) gives mostly correct/acceptable distance indications. - # (http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3688.0.html) + # (https://exiftool.org/forum/index.php/topic,3688.0.html) # if this value is the 35mm equivalent magnification, then the formula could # be (1.5 * 2**($val/16-5)+1) * FocalLength, but this tends to underestimate # distance by about 18% (ref 20) (255=inf) @@ -9980,7 +10289,7 @@ sub Decrypt($$$$) } #------------------------------------------------------------------------------ -# Decipher/encipher Sony tag 0x94xx data (ref PH) +# Decipher/encipher Sony tag 0x2010, 0x900b, 0x9050 and 0x940x data (ref PH) # Inputs: 0) data reference, 1) true to encipher the data sub Decipher($;$) { @@ -10402,7 +10711,7 @@ Minolta. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/SonyIDC.pm b/src/Image-ExifTool/lib/Image/ExifTool/SonyIDC.pm index c512fb45..3b85413f 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/SonyIDC.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/SonyIDC.pm @@ -379,7 +379,7 @@ write Sony Image Data Converter version 3.0 metadata in ARW images. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Stim.pm b/src/Image-ExifTool/lib/Image/ExifTool/Stim.pm index 3c82e49d..0185526c 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Stim.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Stim.pm @@ -174,7 +174,7 @@ information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/TagInfoXML.pm b/src/Image-ExifTool/lib/Image/ExifTool/TagInfoXML.pm index 6a6c10d9..ad6287ec 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/TagInfoXML.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/TagInfoXML.pm @@ -15,7 +15,7 @@ use vars qw($VERSION @ISA $makeMissing); use Image::ExifTool qw(:Utils :Vars); use Image::ExifTool::XMP; -$VERSION = '1.30'; +$VERSION = '1.31'; @ISA = qw(Exporter); # set this to a language code to generate Lang module with 'MISSING' entries @@ -28,7 +28,7 @@ sub NumbersFirst; # names for acknowledgements in the POD documentation my %credits = ( cs => 'Jens Duttke and Petr MichE<aacute>lek', - de => 'Jens Duttke and Herbert Kauer', + de => 'Jens Duttke, Herbert Kauer and Jobi', es => 'Jens Duttke, Santiago del BrE<iacute>o GonzE<aacute>lez and Emilio Sancha', fi => 'Jens Duttke and Jarkko ME<auml>kineva', fr => 'Jens Duttke, Bernard Guillotin, Jean Glasser, Jean Piquemal, Harry Nizard and Alphonse Philippe', @@ -37,7 +37,7 @@ my %credits = ( ko => 'Jens Duttke and Jeong Beom Kim', nl => 'Jens Duttke, Peter Moonen, Herman Beld and Peter van der Laan', pl => 'Jens Duttke, Przemyslaw Sulek and Kacper Perschke', - ru => 'Jens Duttke, Sergey Shemetov, Dmitry Yerokhin and Anton Sukhinov', + ru => 'Jens Duttke, Sergey Shemetov, Dmitry Yerokhin, Anton Sukhinov and Alexander', sv => 'Jens Duttke and BjE<ouml>rn SE<ouml>derstrE<ouml>m', 'tr' => 'Jens Duttke, Hasan Yildirim and Cihan Ulusoy', zh_cn => 'Jens Duttke and Haibing Zhong', @@ -67,9 +67,9 @@ sub Write(;$$%) { local ($_, *PTIFILE); my ($file, $group, %opts) = @_; - my @groups = split ':', $group if $group; my $et = new Image::ExifTool; - my ($fp, $tableName, %langInfo, @langs, $defaultLang); + my ($fp, $tableName, %langInfo, @langs, $defaultLang, @groups); + @groups = split ':', $group if $group; Image::ExifTool::LoadAllTables(); # first load all our tables unless ($opts{NoDesc}) { @@ -366,7 +366,12 @@ sub BuildLangModules($;$) $id = Image::ExifTool::XMP::FullUnescapeXML($1); $name = $2; $index = $4; - $id = hex($id) if $id =~ /^0x[\da-fA-F]+$/; # convert hex ID's + # convert hex ID's unless HEX_ID is 0 (for string ID's that look like hex) + if ($id =~ /^0x[\da-fA-F]+$/ and (not defined $$table{VARS} or + not defined $$table{VARS}{HEX_ID} or $$table{VARS}{HEX_ID})) + { + $id = hex($id); + } next; } if ($tok eq 'values') { @@ -619,7 +624,6 @@ HEADER 1; # end - __END__ ~head1 NAME @@ -633,7 +637,7 @@ and values. ~head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -817,7 +821,7 @@ Number of modules updated, or negative on error. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/TagLookup.pm b/src/Image-ExifTool/lib/Image/ExifTool/TagLookup.pm index c29fcdf7..8c499898 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/TagLookup.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/TagLookup.pm @@ -17,7 +17,7 @@ require Exporter; use vars qw($VERSION @ISA @EXPORT_OK); use Image::ExifTool qw(:Utils); -$VERSION = '1.16'; +$VERSION = '1.18'; @ISA = qw(Exporter); @EXPORT_OK = qw(FindTagInfo TagExists); @@ -38,6 +38,7 @@ my @tableList = ( 'Image::ExifTool::Canon::AFMicroAdj', 'Image::ExifTool::Canon::Ambience', 'Image::ExifTool::Canon::AspectInfo', + 'Image::ExifTool::Canon::CNTH', 'Image::ExifTool::Canon::CameraInfo1000D', 'Image::ExifTool::Canon::CameraInfo1D', 'Image::ExifTool::Canon::CameraInfo1DX', @@ -103,11 +104,13 @@ my @tableList = ( 'Image::ExifTool::Canon::Panorama', 'Image::ExifTool::Canon::PreviewImageInfo', 'Image::ExifTool::Canon::Processing', + 'Image::ExifTool::Canon::RawBurstInfo', 'Image::ExifTool::Canon::SerialInfo', 'Image::ExifTool::Canon::ShotInfo', 'Image::ExifTool::Canon::TimeInfo', 'Image::ExifTool::Canon::VignettingCorr', 'Image::ExifTool::Canon::VignettingCorr2', + 'Image::ExifTool::Canon::WBInfo', 'Image::ExifTool::CanonCustom::Functions10D', 'Image::ExifTool::CanonCustom::Functions1D', 'Image::ExifTool::CanonCustom::Functions2', @@ -176,6 +179,8 @@ my @tableList = ( 'Image::ExifTool::Kodak::Type2', 'Image::ExifTool::Kodak::Type3', 'Image::ExifTool::Kodak::Type4', + 'Image::ExifTool::Kodak::Type5', + 'Image::ExifTool::Kodak::Type6', 'Image::ExifTool::Kodak::Type7', 'Image::ExifTool::Kodak::Type9', 'Image::ExifTool::MIE::Audio', @@ -242,11 +247,15 @@ my @tableList = ( 'Image::ExifTool::Nikon::LensData01', 'Image::ExifTool::Nikon::LensData0204', 'Image::ExifTool::Nikon::LensData0400', + 'Image::ExifTool::Nikon::LensData0402', + 'Image::ExifTool::Nikon::LensData0403', + 'Image::ExifTool::Nikon::LensData0800', 'Image::ExifTool::Nikon::LocationInfo', 'Image::ExifTool::Nikon::Main', 'Image::ExifTool::Nikon::MultiExposure', 'Image::ExifTool::Nikon::PictureControl', 'Image::ExifTool::Nikon::PictureControl2', + 'Image::ExifTool::Nikon::PictureControl3', 'Image::ExifTool::Nikon::PreviewIFD', 'Image::ExifTool::Nikon::ROC', 'Image::ExifTool::Nikon::RetouchInfo', @@ -381,12 +390,18 @@ my @tableList = ( 'Image::ExifTool::Photoshop::Main', 'Image::ExifTool::Photoshop::Resolution', 'Image::ExifTool::PostScript::Main', + 'Image::ExifTool::QuickTime::ItemList', + 'Image::ExifTool::QuickTime::ItemPropCont', + 'Image::ExifTool::QuickTime::Keys', + 'Image::ExifTool::QuickTime::Main', 'Image::ExifTool::QuickTime::MediaHeader', 'Image::ExifTool::QuickTime::MovieHeader', 'Image::ExifTool::QuickTime::Preview', 'Image::ExifTool::QuickTime::TrackHeader', + 'Image::ExifTool::QuickTime::UserData', 'Image::ExifTool::Reconyx::Main', 'Image::ExifTool::Reconyx::Type2', + 'Image::ExifTool::Reconyx::Type3', 'Image::ExifTool::Ricoh::FaceInfo', 'Image::ExifTool::Ricoh::FirmwareInfo', 'Image::ExifTool::Ricoh::ImageInfo', @@ -401,6 +416,8 @@ my @tableList = ( 'Image::ExifTool::Sanyo::FaceInfo', 'Image::ExifTool::Sanyo::Main', 'Image::ExifTool::Sigma::Main', + 'Image::ExifTool::Sigma::WBSettings', + 'Image::ExifTool::Sigma::WBSettings2', 'Image::ExifTool::Sony::AFInfo', 'Image::ExifTool::Sony::AFStatus15', 'Image::ExifTool::Sony::AFStatus19', @@ -420,6 +437,7 @@ my @tableList = ( 'Image::ExifTool::Sony::FaceInfo2', 'Image::ExifTool::Sony::FaceInfoA', 'Image::ExifTool::Sony::FocusInfo', + 'Image::ExifTool::Sony::ISOInfo', 'Image::ExifTool::Sony::Main', 'Image::ExifTool::Sony::MeterInfo', 'Image::ExifTool::Sony::MeterInfo9', @@ -456,8 +474,11 @@ my @tableList = ( 'Image::ExifTool::SonyIDC::Main', 'Image::ExifTool::XMP::Album', 'Image::ExifTool::XMP::DICOM', + 'Image::ExifTool::XMP::Device', 'Image::ExifTool::XMP::ExpressionMedia', 'Image::ExifTool::XMP::GAudio', + 'Image::ExifTool::XMP::GCamera', + 'Image::ExifTool::XMP::GCreations', 'Image::ExifTool::XMP::GDepth', 'Image::ExifTool::XMP::GFocus', 'Image::ExifTool::XMP::GImage', @@ -473,6 +494,7 @@ my @tableList = ( 'Image::ExifTool::XMP::aux', 'Image::ExifTool::XMP::cc', 'Image::ExifTool::XMP::cell', + 'Image::ExifTool::XMP::crd', 'Image::ExifTool::XMP::creatorAtom', 'Image::ExifTool::XMP::crs', 'Image::ExifTool::XMP::dc', @@ -508,5350 +530,5741 @@ my @tableList = ( # lookup for all writable tags my %tagLookup = ( - 'aberrationcorrectiondistance' => { 103 => 0x69 }, - 'about' => { 460 => 'about' }, - 'aboutcvterm' => { 452 => 'AboutCvTerm' }, - 'aboutcvtermcvid' => { 452 => [\'AboutCvTerm','AboutCvTermCvId'] }, - 'aboutcvtermid' => { 452 => [\'AboutCvTerm','AboutCvTermCvTermId'] }, - 'aboutcvtermname' => { 452 => [\'AboutCvTerm','AboutCvTermCvTermName'] }, - 'aboutcvtermrefinedabout' => { 452 => [\'AboutCvTerm','AboutCvTermCvTermRefinedAbout'] }, - 'absolutealtitude' => { 110 => 'AbsoluteAltitude' }, - 'abspeakaudiofilepath' => { 466 => 'absPeakAudioFilePath' }, - 'academicfield' => { 456 => 'academicField' }, - 'acceleration' => { 113 => 0x9404, 447 => 'Acceleration' }, - 'accelerationtracking' => { 78 => 0x518 }, + 'aberrationcorrectiondistance' => { 106 => 0x69 }, + 'about' => { 482 => 'about' }, + 'aboutcvterm' => { 474 => 'AboutCvTerm' }, + 'aboutcvtermcvid' => { 474 => [\'AboutCvTerm','AboutCvTermCvId'] }, + 'aboutcvtermid' => { 474 => [\'AboutCvTerm','AboutCvTermCvTermId'] }, + 'aboutcvtermname' => { 474 => [\'AboutCvTerm','AboutCvTermCvTermName'] }, + 'aboutcvtermrefinedabout' => { 474 => [\'AboutCvTerm','AboutCvTermCvTermRefinedAbout'] }, + 'absolutealtitude' => { 113 => 'AbsoluteAltitude' }, + 'abspeakaudiofilepath' => { 488 => 'absPeakAudioFilePath' }, + 'academicfield' => { 478 => 'academicField' }, + 'acceleration' => { 116 => 0x9404, 469 => 'Acceleration' }, + 'accelerationtracking' => { 81 => 0x518 }, 'accelerationvector' => { 1 => 0x8 }, - 'accelerometer' => { 361 => 0x3 }, - 'accelerometerx' => { 297 => 0x8d }, - 'accelerometery' => { 297 => 0x8e }, - 'accelerometerz' => { 297 => 0x8c }, - 'accessoryserialnumber' => { 297 => 0x54 }, - 'accessorytype' => { 297 => 0x53 }, - 'actionadvised' => { 125 => 0x2a }, - 'activearea' => { 113 => 0xc68d }, - 'actived-lighting' => { 211 => 0x22, 248 => 0x24 }, - 'actived-lightingmode' => { 248 => 0x25 }, - 'adaptervoltage' => { 131 => 0x407 }, - 'addaspectratioinfo' => { 78 => 0x80e }, - 'addiptcinformation' => { 78 => 0x815 }, - 'additionalmodelinformation' => { 452 => 'AddlModelInfo' }, - 'addoriginaldecisiondata' => { 78 => 0x80f, 79 => 0x11, 80 => 0x13, 83 => 0x14 }, - 'address' => { 152 => 'Address' }, - 'adjustmentmode' => { 368 => 0x15 }, - 'adlbracketingstep' => { 229 => 0x883 }, - 'adlbracketingtype' => { 229 => 0x884 }, - 'adobe' => { 114 => 'Adobe' }, - 'adultcontentwarning' => { 284 => 'AdultContentWarning', 459 => 'adultContentWarning' }, - 'advancedfilter' => { 121 => 0x1201 }, - 'advancedraw' => { 250 => 0x76a43203 }, - 'advancedscenetype' => { 297 => 0x3d }, - 'advisory' => { 464 => 'Advisory' }, - 'ae_iso' => { 305 => 0x2, 306 => 0x4, 307 => 0x12 }, - 'aeaperture' => { 305 => 0x1, 306 => 0x3, 307 => 0x11 }, - 'aeaperturesteps' => { 305 => 0x8, 306 => 0xb }, - 'aebautocancel' => { 78 => 0x104 }, - 'aebbracketvalue' => { 72 => 0x11 }, - 'aebracketingsteps' => { 228 => 0x174c, 229 => 0x87b, 237 => 0x1756 }, - 'aebsequence' => { 78 => 0x105 }, - 'aebsequenceautocancel' => { 76 => 0x9, 77 => 0x9, 79 => 0x8, 80 => 0x9, 83 => 0x9, 84 => 0x7 }, - 'aebshotcount' => { 78 => 0x106 }, - 'aebxv' => { 305 => 0x4, 306 => 0x6 }, - 'aeerror' => { 306 => 0x8 }, - 'aeexposuretime' => { 305 => 0x0, 306 => 0x2, 307 => 0x10 }, - 'aelbutton' => { 174 => 0x45 }, - 'aelexposureindicator' => { 174 => 0x51 }, - 'aelock' => { 174 => 0x5b, 259 => '4.2', 268 => '4.2', 274 => 0x201, 332 => 0x48, 376 => 0x40, 377 => 0x40, 378 => [0x86,0x286] }, - 'aelockbutton' => { 257 => '16.1', 259 => '4.1', 262 => '15.1', 263 => '16.1', 264 => '16.1', 266 => '30.1', 267 => '16.1', 268 => '4.1', 270 => '17.1', 272 => '17.1' }, - 'aelockbuttonplusdials' => { 257 => '16.2', 266 => '32.1', 270 => '44.1' }, - 'aelockformb-d80' => { 272 => '3.1' }, - 'aelockmetermodeafterfocus' => { 78 => 0x114 }, - 'aemaxaperture' => { 305 => 0x9, 306 => 0x10, 307 => 0x1c }, - 'aemaxaperture2' => { 305 => 0xa, 306 => 0x11, 307 => 0x1d }, - 'aemeteringmode' => { 305 => 0xc }, - 'aemeteringmode2' => { 305 => '13.1' }, - 'aemeteringsegments' => { 177 => 0x628, 332 => 0x209 }, - 'aemicroadjustment' => { 78 => 0x110 }, - 'aeminaperture' => { 305 => 0xb, 306 => 0x12, 307 => 0x1e }, - 'aeminexposuretime' => { 305 => 0x5, 306 => 0x13, 307 => 0x1f }, - 'aeprogrammode' => { 305 => 0x6 }, - 'aeprojectlink' => { 441 => 'aeProjectLink' }, - 'aeprojectlinkcompositionid' => { 441 => [\'aeProjectLink','aeProjectLinkCompositionID'] }, - 'aeprojectlinkfullpath' => { 441 => [\'aeProjectLink','aeProjectLinkFullPath'] }, - 'aeprojectlinkrenderoutputmoduleindex' => { 441 => [\'aeProjectLink','aeProjectLinkRenderOutputModuleIndex'] }, - 'aeprojectlinkrenderqueueitemid' => { 441 => [\'aeProjectLink','aeProjectLinkRenderQueueItemID'] }, - 'aeprojectlinkrendertimestamp' => { 441 => [\'aeProjectLink','aeProjectLinkRenderTimeStamp'] }, - 'aesetting' => { 33 => 0x21 }, - 'aewhitebalance' => { 305 => 0xd }, - 'aexv' => { 305 => 0x3, 306 => 0x5 }, - 'af-cpriority' => { 122 => '0.2' }, - 'af-cpriorityselection' => { 257 => '1.1', 258 => '1.1', 260 => '1.1', 261 => '1.1', 263 => '0.1', 264 => '0.1', 265 => '0.1', 266 => '1.1', 267 => '0.1', 270 => '1.1', 271 => '1.1' }, - 'af-csetting' => { 118 => 0x0 }, - 'af-cspeedtrackingsensitivity' => { 118 => '0.2' }, - 'af-ctrackingsensitivity' => { 118 => '0.1' }, - 'af-czoneareaswitching' => { 118 => '0.3' }, - 'af-onbutton' => { 260 => '70.1', 261 => '70.1', 271 => '70.1' }, - 'af-onformb-d10' => { 257 => '3.3', 266 => '3.2' }, - 'af-onformb-d11' => { 267 => '2.2' }, - 'af-onformb-d12' => { 270 => '50.1' }, - 'af-spriority' => { 122 => '0.1' }, - 'af-spriorityselection' => { 257 => '1.2', 258 => '1.2', 260 => '1.4', 261 => '1.4', 265 => '0.2', 266 => '1.2', 267 => '0.2', 270 => '1.2', 271 => '1.2' }, + 'accelerometer' => { 376 => 0x3 }, + 'accelerometerdata' => { 366 => 'vrot' }, + 'accelerometerx' => { 306 => 0x8d }, + 'accelerometery' => { 306 => 0x8e }, + 'accelerometerz' => { 306 => 0x8c }, + 'accessoryserialnumber' => { 306 => 0x54 }, + 'accessorytype' => { 306 => 0x53 }, + 'actionadvised' => { 128 => 0x2a }, + 'activearea' => { 116 => 0xc68d }, + 'actived-lighting' => { 219 => 0x22, 257 => 0x24 }, + 'actived-lightingmode' => { 257 => 0x25 }, + 'adaptervoltage' => { 134 => 0x407 }, + 'addaspectratioinfo' => { 81 => 0x80e }, + 'addiptcinformation' => { 81 => 0x815 }, + 'additionalmodelinformation' => { 474 => 'AddlModelInfo' }, + 'addoriginaldecisiondata' => { 81 => 0x80f, 82 => 0x11, 83 => 0x13, 86 => 0x14 }, + 'address' => { 157 => 'Address' }, + 'adjustmentmode' => { 383 => 0x15 }, + 'adlbracketingstep' => { 238 => 0x883 }, + 'adlbracketingtype' => { 238 => 0x884 }, + 'adobe' => { 117 => 'Adobe' }, + 'adultcontentwarning' => { 293 => 'AdultContentWarning', 481 => 'adultContentWarning' }, + 'advancedfilter' => { 124 => 0x1201 }, + 'advancedraw' => { 259 => 0x76a43203 }, + 'advancedscenetype' => { 306 => 0x3d }, + 'advisory' => { 486 => 'Advisory' }, + 'ae_iso' => { 314 => 0x2, 315 => 0x4, 316 => 0x12 }, + 'aeaperture' => { 314 => 0x1, 315 => 0x3, 316 => 0x11 }, + 'aeaperturesteps' => { 314 => 0x8, 315 => 0xb }, + 'aebautocancel' => { 81 => 0x104 }, + 'aebbracketvalue' => { 74 => 0x11 }, + 'aebracketingsteps' => { 237 => 0x174c, 238 => 0x87b, 246 => 0x1756 }, + 'aebsequence' => { 81 => 0x105 }, + 'aebsequenceautocancel' => { 79 => 0x9, 80 => 0x9, 82 => 0x8, 83 => 0x9, 86 => 0x9, 87 => 0x7 }, + 'aebshotcount' => { 81 => 0x106 }, + 'aebxv' => { 314 => 0x4, 315 => 0x6 }, + 'aeerror' => { 315 => 0x8 }, + 'aeexposuretime' => { 314 => 0x0, 315 => 0x2, 316 => 0x10 }, + 'aelbutton' => { 179 => 0x45 }, + 'aelexposureindicator' => { 179 => 0x51 }, + 'aelock' => { 179 => 0x5b, 268 => '4.2', 277 => '4.2', 283 => 0x201, 341 => 0x48, 393 => 0x40, 394 => 0x40, 395 => [0x86,0x286] }, + 'aelockbutton' => { 266 => '16.1', 268 => '4.1', 271 => '15.1', 272 => '16.1', 273 => '16.1', 275 => '30.1', 276 => '16.1', 277 => '4.1', 279 => '17.1', 281 => '17.1' }, + 'aelockbuttonplusdials' => { 266 => '16.2', 275 => '32.1', 279 => '44.1' }, + 'aelockformb-d80' => { 281 => '3.1' }, + 'aelockmetermodeafterfocus' => { 81 => 0x114 }, + 'aemaxaperture' => { 314 => 0x9, 315 => 0x10, 316 => 0x1c }, + 'aemaxaperture2' => { 314 => 0xa, 315 => 0x11, 316 => 0x1d }, + 'aemeteringmode' => { 314 => 0xc }, + 'aemeteringmode2' => { 314 => '13.1' }, + 'aemeteringsegments' => { 182 => 0x628, 341 => 0x209 }, + 'aemicroadjustment' => { 81 => 0x110 }, + 'aeminaperture' => { 314 => 0xb, 315 => 0x12, 316 => 0x1e }, + 'aeminexposuretime' => { 314 => 0x5, 315 => 0x13, 316 => 0x1f }, + 'aeprogrammode' => { 314 => 0x6 }, + 'aeprojectlink' => { 463 => 'aeProjectLink' }, + 'aeprojectlinkcompositionid' => { 463 => [\'aeProjectLink','aeProjectLinkCompositionID'] }, + 'aeprojectlinkfullpath' => { 463 => [\'aeProjectLink','aeProjectLinkFullPath'] }, + 'aeprojectlinkrenderoutputmoduleindex' => { 463 => [\'aeProjectLink','aeProjectLinkRenderOutputModuleIndex'] }, + 'aeprojectlinkrenderqueueitemid' => { 463 => [\'aeProjectLink','aeProjectLinkRenderQueueItemID'] }, + 'aeprojectlinkrendertimestamp' => { 463 => [\'aeProjectLink','aeProjectLinkRenderTimeStamp'] }, + 'aesetting' => { 34 => 0x21 }, + 'aewhitebalance' => { 314 => 0xd }, + 'aexv' => { 314 => 0x3, 315 => 0x5 }, + 'af-cpriority' => { 125 => '0.2' }, + 'af-cpriorityselection' => { 266 => '1.1', 267 => '1.1', 269 => '1.1', 270 => '1.1', 272 => '0.1', 273 => '0.1', 274 => '0.1', 275 => '1.1', 276 => '0.1', 279 => '1.1', 280 => '1.1' }, + 'af-csetting' => { 121 => 0x0 }, + 'af-cspeedtrackingsensitivity' => { 121 => '0.2' }, + 'af-ctrackingsensitivity' => { 121 => '0.1' }, + 'af-czoneareaswitching' => { 121 => '0.3' }, + 'af-onbutton' => { 269 => '70.1', 270 => '70.1', 280 => '70.1' }, + 'af-onformb-d10' => { 266 => '3.3', 275 => '3.2' }, + 'af-onformb-d11' => { 276 => '2.2' }, + 'af-onformb-d12' => { 279 => '50.1' }, + 'af-spriority' => { 125 => '0.1' }, + 'af-spriorityselection' => { 266 => '1.2', 267 => '1.2', 269 => '1.2', 270 => '1.2', 274 => '0.2', 275 => '1.2', 276 => '0.2', 279 => '1.2', 280 => '1.2' }, 'afacceldeceltracking' => { 2 => 0x3 }, - 'afactivation' => { 257 => '2.1', 258 => '2.1', 260 => '78.3', 261 => '78.3', 266 => '2.1', 270 => '2.1', 271 => '78.3' }, - 'afadjustment' => { 332 => 0x72, 341 => 0x267 }, - 'afandmeteringbuttons' => { 78 => 0x701 }, - 'afaperture' => { 207 => 0x5, 208 => 0x5 }, - 'afareaheight' => { 183 => [0x1a,0x50] }, - 'afareaillumination' => { 174 => 0x4b, 268 => '15.3' }, - 'afareamode' => { 120 => '0.2', 170 => 0x33, 174 => 0xe, 182 => 0x0, 183 => 0x5, 297 => 0xf, 358 => 0x1205, 369 => [0xa,0x3a], 376 => 0x11, 377 => 0x10, 378 => 0x24, 388 => 0xb043, 411 => 0x17 }, - 'afareamodesetting' => { 259 => '11.1', 262 => '0.1', 268 => '16.1', 272 => '2.1', 388 => 0x201c }, - 'afareapointsize' => { 120 => '0.3' }, - 'afareas' => { 274 => 0x304 }, + 'afactivation' => { 266 => '2.1', 267 => '2.1', 269 => '78.3', 270 => '78.3', 275 => '2.1', 279 => '2.1', 280 => '78.3' }, + 'afadjustment' => { 341 => 0x72, 350 => 0x267 }, + 'afandmeteringbuttons' => { 81 => 0x701 }, + 'afaperture' => { 212 => 0x5, 213 => 0x5, 217 => 0x5 }, + 'afareaheight' => { 188 => [0x1a,0x34,0x50] }, + 'afareaillumination' => { 179 => 0x4b, 277 => '15.3' }, + 'afareamode' => { 123 => '0.2', 175 => 0x33, 179 => 0xe, 187 => 0x0, 188 => 0x5, 306 => 0xf, 373 => 0x1205, 386 => [0xa,0x3a], 393 => 0x11, 394 => 0x10, 395 => 0x24, 406 => 0xb043, 429 => 0x17 }, + 'afareamodesetting' => { 268 => '11.1', 271 => '0.1', 277 => '16.1', 281 => '2.1', 406 => 0x201c }, + 'afareapointsize' => { 123 => '0.3' }, + 'afareas' => { 283 => 0x304 }, 'afareaselectionmethod' => { 2 => 0xd }, - 'afareaselectmethod' => { 78 => 0x51b }, - 'afareawidth' => { 183 => [0x18,0x4e] }, - 'afareaxposition' => { 183 => [0x14,0x4a], 358 => 0x1203 }, - 'afareaxposition1' => { 358 => 0x1201 }, - 'afareayposition' => { 183 => [0x16,0x4c], 358 => 0x1204 }, - 'afareayposition1' => { 358 => 0x1202 }, - 'afareazonesize' => { 120 => '0.4' }, - 'afassist' => { 76 => 0x5, 84 => 0x5, 174 => 0x48, 257 => '2.5', 259 => '0.2', 262 => '0.2', 263 => '1.1', 264 => '1.1', 265 => '1.3', 266 => '2.4', 267 => '1.3', 268 => '0.2', 270 => '2.4', 272 => '2.3' }, - 'afassistbeam' => { 2 => 0x8, 78 => 0x50e, 79 => 0x4, 80 => 0x5, 81 => 0x4, 82 => 0x4, 83 => 0x5 }, - 'afassistlamp' => { 297 => 0x31 }, - 'afbuttonpressed' => { 378 => [0x83,0x283] }, + 'afareaselectmethod' => { 81 => 0x51b }, + 'afareawidth' => { 188 => [0x18,0x32,0x4e] }, + 'afareaxposition' => { 188 => [0x14,0x2e,0x4a], 373 => 0x1203 }, + 'afareaxposition1' => { 373 => 0x1201 }, + 'afareayposition' => { 188 => [0x16,0x30,0x4c], 373 => 0x1204 }, + 'afareayposition1' => { 373 => 0x1202 }, + 'afareazonesize' => { 123 => '0.4' }, + 'afassist' => { 79 => 0x5, 87 => 0x5, 179 => 0x48, 266 => '2.5', 268 => '0.2', 271 => '0.2', 272 => '1.1', 273 => '1.1', 274 => '1.3', 275 => '2.4', 276 => '1.3', 277 => '0.2', 279 => '2.4', 281 => '2.3' }, + 'afassistbeam' => { 2 => 0x8, 81 => 0x50e, 82 => 0x4, 83 => 0x5, 84 => 0x4, 85 => 0x4, 86 => 0x5 }, + 'afassistlamp' => { 306 => 0x31 }, + 'afbuttonpressed' => { 395 => [0x83,0x283] }, 'afconfigtool' => { 2 => 0x1 }, - 'afdefocus' => { 308 => 0x6 }, - 'afduringliveview' => { 78 => 0x511 }, - 'affinea' => { 435 => 'AffineA' }, - 'affineb' => { 435 => 'AffineB' }, - 'affinec' => { 435 => 'AffineC' }, - 'affined' => { 435 => 'AffineD' }, - 'affinetune' => { 184 => 0x0, 274 => 0x306 }, - 'affinetuneadj' => { 184 => 0x2, 221 => 0x2d1, 222 => 0x2dc, 274 => 0x307 }, - 'affinetuneindex' => { 184 => 0x1 }, - 'affinex' => { 435 => 'AffineX' }, - 'affiney' => { 435 => 'AffineY' }, - 'afhold' => { 308 => 0x1fd }, - 'afilluminator' => { 376 => 0x29, 388 => 0xb044 }, - 'afimageheight' => { 183 => [0x12,0x48] }, - 'afimagewidth' => { 183 => [0x10,0x46] }, - 'afintegrationtime' => { 308 => 0x7 }, - 'afmicroadj' => { 369 => [0x17d,0x50] }, - 'afmicroadjmode' => { 3 => 0x1, 373 => 0x131 }, - 'afmicroadjregisteredlenses' => { 373 => '305.1' }, - 'afmicroadjustment' => { 78 => 0x507 }, - 'afmicroadjvalue' => { 3 => 0x2, 373 => 0x130 }, - 'afmode' => { 107 => 0x3009, 121 => 0x1022, 170 => 0x16, 368 => 0x5 }, - 'afmoderestrictions' => { 258 => '50.3', 260 => '48.3', 261 => '48.3', 270 => '48.3', 271 => '48.3' }, - 'afonaelockbuttonswitch' => { 78 => 0x702 }, - 'afonbutton' => { 257 => '3.1', 258 => '47.1' }, - 'afpoint' => { 33 => 0x13, 106 => 0x18, 170 => 0x15, 182 => 0x1, 277 => 0x308, 368 => 0x1f, 369 => [0x37,0x7], 373 => 0x19, 374 => 0x18, 375 => [0x18,0x20] }, - 'afpointactivationarea' => { 77 => 0x11, 83 => 0x11 }, - 'afpointareaexpansion' => { 78 => 0x508 }, - 'afpointatshutterrelease' => { 369 => [0x39,0x9] }, - 'afpointautoselection' => { 78 => 0x50b }, - 'afpointbrightness' => { 78 => 0x50d, 257 => '2.4', 258 => '46.5', 260 => '2.2', 261 => '2.2', 270 => '2.3', 271 => '2.2' }, - 'afpointdisplayduringfocus' => { 2 => 0x10, 78 => 0x50c }, - 'afpointillumination' => { 77 => 0xa, 257 => '2.3', 258 => '46.2', 260 => '47.2', 261 => '47.2', 265 => '1.2', 266 => '2.3', 267 => '1.2', 270 => '47.2', 271 => '47.2', 272 => '2.4' }, - 'afpointinfocus' => { 369 => [0x38,0x8] }, - 'afpointmode' => { 313 => 0x3 }, - 'afpointposition' => { 107 => 0x2021, 297 => 0x4d }, - 'afpointregistration' => { 76 => 0x7 }, - 'afpoints' => { 173 => 0x10 }, - 'afpointselected' => { 174 => 0xd, 274 => 0x305, 332 => 0xe, 373 => 0x15, 374 => 0x14, 375 => [0x14,0x1c], 388 => 0x201e }, - 'afpointselected2' => { 313 => 0x4 }, - 'afpointselection' => { 77 => 0xb, 257 => '1.3', 258 => '1.3', 266 => '1.3', 270 => '1.3', 271 => '1.3' }, - 'afpointselectionmethod' => { 78 => 0x50f, 79 => 0xc, 80 => 0xd, 83 => 0xd }, - 'afpointsetting' => { 376 => 0x12, 377 => 0x11 }, - 'afpointsinfocus' => { 72 => 0xe, 182 => 0x2, 308 => 0xb, 309 => 0x4, 332 => [0xf,0x3c] }, - 'afpointsinfocus5d' => { 18 => 0x38 }, - 'afpointspotmetering' => { 77 => 0xd }, - 'afpointsselected' => { 309 => '4.1', 419 => 0x4 }, - 'afpointsspecial' => { 309 => '4.2' }, - 'afpointsunknown1' => { 308 => 0x0 }, - 'afpointsunknown2' => { 308 => 0x2 }, - 'afpointsused' => { 183 => 0x8, 369 => [0x10,0x16e] }, + 'afdefocus' => { 317 => 0x6 }, + 'afduringliveview' => { 81 => 0x511 }, + 'affinea' => { 456 => 'AffineA' }, + 'affineb' => { 456 => 'AffineB' }, + 'affinec' => { 456 => 'AffineC' }, + 'affined' => { 456 => 'AffineD' }, + 'affinetune' => { 189 => 0x0, 283 => 0x306 }, + 'affinetuneadj' => { 189 => 0x2, 230 => 0x2d1, 231 => 0x2dc, 283 => 0x307 }, + 'affinetuneindex' => { 189 => 0x1 }, + 'affinex' => { 456 => 'AffineX' }, + 'affiney' => { 456 => 'AffineY' }, + 'afhold' => { 317 => 0x1fd }, + 'afilluminator' => { 393 => 0x29, 406 => 0xb044 }, + 'afimageheight' => { 188 => [0x12,0x2c,0x48] }, + 'afimagewidth' => { 188 => [0x10,0x2a,0x46] }, + 'afintegrationtime' => { 317 => 0x7 }, + 'afmicroadj' => { 386 => [0x17d,0x50] }, + 'afmicroadjmode' => { 3 => 0x1, 390 => 0x131 }, + 'afmicroadjregisteredlenses' => { 390 => '305.1' }, + 'afmicroadjustment' => { 81 => 0x507 }, + 'afmicroadjvalue' => { 3 => 0x2, 390 => 0x130 }, + 'afmode' => { 110 => 0x3009, 124 => 0x1022, 175 => 0x16, 383 => 0x5 }, + 'afmoderestrictions' => { 267 => '50.3', 269 => '48.3', 270 => '48.3', 279 => '48.3', 280 => '48.3' }, + 'afonaelockbuttonswitch' => { 81 => 0x702 }, + 'afonbutton' => { 266 => '3.1', 267 => '47.1' }, + 'afpoint' => { 34 => 0x13, 109 => 0x18, 175 => 0x15, 187 => 0x1, 286 => 0x308, 383 => 0x1f, 386 => [0x37,0x7], 390 => 0x19, 391 => 0x18, 392 => [0x18,0x20] }, + 'afpointactivationarea' => { 80 => 0x11, 86 => 0x11 }, + 'afpointareaexpansion' => { 81 => 0x508 }, + 'afpointatshutterrelease' => { 386 => [0x39,0x9] }, + 'afpointautoselection' => { 81 => 0x50b }, + 'afpointbrightness' => { 81 => 0x50d, 266 => '2.4', 267 => '46.5', 269 => '2.2', 270 => '2.2', 279 => '2.3', 280 => '2.2' }, + 'afpointdisplayduringfocus' => { 2 => 0x10, 81 => 0x50c }, + 'afpointillumination' => { 80 => 0xa, 266 => '2.3', 267 => '46.2', 269 => '47.2', 270 => '47.2', 274 => '1.2', 275 => '2.3', 276 => '1.2', 279 => '47.2', 280 => '47.2', 281 => '2.4' }, + 'afpointinfocus' => { 386 => [0x38,0x8] }, + 'afpointmode' => { 322 => 0x3 }, + 'afpointposition' => { 110 => 0x2021, 306 => 0x4d }, + 'afpointregistration' => { 79 => 0x7 }, + 'afpoints' => { 178 => 0x10 }, + 'afpointselected' => { 179 => 0xd, 283 => 0x305, 341 => 0xe, 390 => 0x15, 391 => 0x14, 392 => [0x14,0x1c], 406 => 0x201e }, + 'afpointselected2' => { 322 => 0x4 }, + 'afpointselection' => { 80 => 0xb, 266 => '1.3', 267 => '1.3', 275 => '1.3', 279 => '1.3', 280 => '1.3' }, + 'afpointselectionmethod' => { 81 => 0x50f, 82 => 0xc, 83 => 0xd, 86 => 0xd }, + 'afpointsetting' => { 393 => 0x12, 394 => 0x11 }, + 'afpointsinfocus' => { 74 => 0xe, 187 => 0x2, 317 => 0xb, 318 => 0x4, 341 => [0xf,0x3c] }, + 'afpointsinfocus5d' => { 19 => 0x38 }, + 'afpointspotmetering' => { 80 => 0xd }, + 'afpointsselected' => { 318 => '4.1', 437 => 0x4 }, + 'afpointsspecial' => { 318 => '4.2' }, + 'afpointsunknown1' => { 317 => 0x0 }, + 'afpointsunknown2' => { 317 => 0x2 }, + 'afpointsused' => { 188 => 0x8, 386 => [0x10,0x16e] }, 'afpointswitching' => { 2 => 0x4 }, - 'afpredictor' => { 308 => 0x4 }, - 'afresponse' => { 211 => 0xad }, - 'afresult' => { 279 => 0x1038 }, - 'afsearch' => { 274 => 0x303 }, - 'afsensoractive' => { 170 => 0x1 }, - 'afstatus' => { 358 => 0x1200 }, - 'afstatus_00_b4' => { 372 => 0x0 }, - 'afstatus_01_c4' => { 372 => 0x2 }, - 'afstatus_02_d4' => { 372 => 0x4 }, - 'afstatus_03_e4' => { 372 => 0x6 }, - 'afstatus_04_f4' => { 372 => 0x8 }, - 'afstatus_05_g4' => { 372 => 0xa }, - 'afstatus_06_h4' => { 372 => 0xc }, - 'afstatus_07_b3' => { 372 => 0xe }, - 'afstatus_08_c3' => { 372 => 0x10 }, - 'afstatus_09_d3' => { 372 => 0x12 }, - 'afstatus_10_e3' => { 372 => 0x14 }, - 'afstatus_11_f3' => { 372 => 0x16 }, - 'afstatus_12_g3' => { 372 => 0x18 }, - 'afstatus_13_h3' => { 372 => 0x1a }, - 'afstatus_14_b2' => { 372 => 0x1c }, - 'afstatus_15_c2' => { 372 => 0x1e }, - 'afstatus_16_d2' => { 372 => 0x20 }, - 'afstatus_17_e2' => { 372 => 0x22 }, - 'afstatus_18_f2' => { 372 => 0x24 }, - 'afstatus_19_g2' => { 372 => 0x26 }, - 'afstatus_20_h2' => { 372 => 0x28 }, - 'afstatus_21_c1' => { 372 => 0x2a }, - 'afstatus_22_d1' => { 372 => 0x2c }, - 'afstatus_23_e1' => { 372 => 0x2e }, - 'afstatus_24_f1' => { 372 => 0x30 }, - 'afstatus_25_g1' => { 372 => 0x32 }, - 'afstatus_26_a7_vertical' => { 372 => 0x34 }, - 'afstatus_27_a6_vertical' => { 372 => 0x36 }, - 'afstatus_28_a5_vertical' => { 372 => 0x38 }, - 'afstatus_29_c7_vertical' => { 372 => 0x3a }, - 'afstatus_30_c6_vertical' => { 372 => 0x3c }, - 'afstatus_31_c5_vertical' => { 372 => 0x3e }, - 'afstatus_32_e7_vertical' => { 372 => 0x40 }, - 'afstatus_33_e6_center_vertical' => { 372 => 0x42 }, - 'afstatus_34_e5_vertical' => { 372 => 0x44 }, - 'afstatus_35_g7_vertical' => { 372 => 0x46 }, - 'afstatus_36_g6_vertical' => { 372 => 0x48 }, - 'afstatus_37_g5_vertical' => { 372 => 0x4a }, - 'afstatus_38_i7_vertical' => { 372 => 0x4c }, - 'afstatus_39_i6_vertical' => { 372 => 0x4e }, - 'afstatus_40_i5_vertical' => { 372 => 0x50 }, - 'afstatus_41_a7' => { 372 => 0x52 }, - 'afstatus_42_b7' => { 372 => 0x54 }, - 'afstatus_43_c7' => { 372 => 0x56 }, - 'afstatus_44_d7' => { 372 => 0x58 }, - 'afstatus_45_e7' => { 372 => 0x5a }, - 'afstatus_46_f7' => { 372 => 0x5c }, - 'afstatus_47_g7' => { 372 => 0x5e }, - 'afstatus_48_h7' => { 372 => 0x60 }, - 'afstatus_49_i7' => { 372 => 0x62 }, - 'afstatus_50_a6' => { 372 => 0x64 }, - 'afstatus_51_b6' => { 372 => 0x66 }, - 'afstatus_52_c6' => { 372 => 0x68 }, - 'afstatus_53_d6' => { 372 => 0x6a }, - 'afstatus_54_e6_center' => { 372 => 0x6c }, - 'afstatus_55_f6' => { 372 => 0x6e }, - 'afstatus_56_g6' => { 372 => 0x70 }, - 'afstatus_57_h6' => { 372 => 0x72 }, - 'afstatus_58_i6' => { 372 => 0x74 }, - 'afstatus_59_a5' => { 372 => 0x76 }, - 'afstatus_60_b5' => { 372 => 0x78 }, - 'afstatus_61_c5' => { 372 => 0x7a }, - 'afstatus_62_d5' => { 372 => 0x7c }, - 'afstatus_63_e5' => { 372 => 0x7e }, - 'afstatus_64_f5' => { 372 => 0x80 }, - 'afstatus_65_g5' => { 372 => 0x82 }, - 'afstatus_66_h5' => { 372 => 0x84 }, - 'afstatus_67_i5' => { 372 => 0x86 }, - 'afstatus_68_c11' => { 372 => 0x88 }, - 'afstatus_69_d11' => { 372 => 0x8a }, - 'afstatus_70_e11' => { 372 => 0x8c }, - 'afstatus_71_f11' => { 372 => 0x8e }, - 'afstatus_72_g11' => { 372 => 0x90 }, - 'afstatus_73_b10' => { 372 => 0x92 }, - 'afstatus_74_c10' => { 372 => 0x94 }, - 'afstatus_75_d10' => { 372 => 0x96 }, - 'afstatus_76_e10' => { 372 => 0x98 }, - 'afstatus_77_f10' => { 372 => 0x9a }, - 'afstatus_78_g10' => { 372 => 0x9c }, - 'afstatus_79_h10' => { 372 => 0x9e }, - 'afstatus_80_b9' => { 372 => 0xa0 }, - 'afstatus_81_c9' => { 372 => 0xa2 }, - 'afstatus_82_d9' => { 372 => 0xa4 }, - 'afstatus_83_e9' => { 372 => 0xa6 }, - 'afstatus_84_f9' => { 372 => 0xa8 }, - 'afstatus_85_g9' => { 372 => 0xaa }, - 'afstatus_86_h9' => { 372 => 0xac }, - 'afstatus_87_b8' => { 372 => 0xae }, - 'afstatus_88_c8' => { 372 => 0xb0 }, - 'afstatus_89_d8' => { 372 => 0xb2 }, - 'afstatus_90_e8' => { 372 => 0xb4 }, - 'afstatus_91_f8' => { 372 => 0xb6 }, - 'afstatus_92_g8' => { 372 => 0xb8 }, - 'afstatus_93_h8' => { 372 => 0xba }, - 'afstatus_94_e6_center_f2-8' => { 372 => 0xbc }, - 'afstatusactivesensor' => { 170 => 0x2, 369 => [0x4,0x3b], 373 => 0x1e, 374 => 0x1b, 375 => [0x1b,0x21] }, - 'afstatusbottom' => { 170 => 0x8, 373 => 0x2a, 374 => 0x21, 375 => 0x21 }, - 'afstatusbottom-left' => { 170 => 0x12, 374 => 0x2b, 375 => 0x2b }, - 'afstatusbottom-right' => { 170 => 0x6, 374 => 0x1f, 375 => 0x1f }, - 'afstatusbottomassist-left' => { 373 => 0x28 }, - 'afstatusbottomassist-right' => { 373 => 0x2c }, - 'afstatusbottomhorizontal' => { 370 => 0x10, 371 => 0x1c }, - 'afstatusbottomvertical' => { 370 => 0x16, 371 => 0x26 }, - 'afstatuscenter-10' => { 373 => 0x34 }, - 'afstatuscenter-11' => { 373 => 0x36 }, - 'afstatuscenter-12' => { 373 => 0x38 }, - 'afstatuscenter-14' => { 373 => 0x3c }, - 'afstatuscenter-7' => { 373 => 0x2e }, - 'afstatuscenter-9' => { 373 => 0x32 }, - 'afstatuscenter-horizontal' => { 373 => 0x30 }, - 'afstatuscenter-vertical' => { 373 => 0x3a }, - 'afstatuscenterf2-8' => { 373 => 0x4c }, - 'afstatuscenterhorizontal' => { 170 => 0x2f, 370 => 0xc, 371 => 0x18, 374 => 0x2f, 375 => 0x2f }, - 'afstatuscentervertical' => { 170 => 0xc, 370 => 0x14, 371 => 0x22, 374 => 0x25, 375 => 0x25 }, - 'afstatusfarleft' => { 370 => 0x6, 373 => 0x26 }, - 'afstatusfarlefthorizontal' => { 371 => 0x4 }, - 'afstatusfarleftvertical' => { 371 => 0x12 }, - 'afstatusfarright' => { 370 => 0x18, 373 => 0x44 }, - 'afstatusfarrighthorizontal' => { 371 => 0x2c }, - 'afstatusfarrightvertical' => { 371 => 0x34 }, - 'afstatusleft' => { 170 => 0x2d, 370 => 0x2, 373 => 0x22, 374 => 0x2d, 375 => 0x2d }, - 'afstatuslefthorizontal' => { 371 => 0x6 }, - 'afstatusleftvertical' => { 371 => 0xe }, - 'afstatuslower-left' => { 370 => 0x4, 373 => 0x24 }, - 'afstatuslower-lefthorizontal' => { 371 => 0xa }, - 'afstatuslower-leftvertical' => { 371 => 0x10 }, - 'afstatuslower-middle' => { 370 => 0x22, 371 => 0x24 }, - 'afstatuslower-right' => { 370 => 0x1e, 373 => 0x4a }, - 'afstatuslower-righthorizontal' => { 371 => 0x32 }, - 'afstatuslower-rightvertical' => { 371 => 0x3a }, - 'afstatuslowerfarleft' => { 371 => 0x8 }, - 'afstatuslowerfarright' => { 371 => 0x30 }, - 'afstatusmiddlehorizontal' => { 170 => 0xa, 374 => 0x23, 375 => 0x23 }, - 'afstatusnearleft' => { 370 => 0xe, 371 => 0x1a }, - 'afstatusnearright' => { 370 => 0xa, 371 => 0x16 }, - 'afstatusright' => { 170 => 0x31, 370 => 0x1c, 373 => 0x48, 374 => 0x31, 375 => 0x31 }, - 'afstatusrighthorizontal' => { 371 => 0x2e }, - 'afstatusrightvertical' => { 371 => 0x38 }, - 'afstatustop' => { 170 => 0xe, 373 => 0x40, 374 => 0x27, 375 => 0x27 }, - 'afstatustop-left' => { 170 => 0x10, 374 => 0x29, 375 => 0x29 }, - 'afstatustop-right' => { 170 => 0x4, 374 => 0x1d, 375 => 0x1d }, - 'afstatustopassist-left' => { 373 => 0x3e }, - 'afstatustopassist-right' => { 373 => 0x42 }, - 'afstatustophorizontal' => { 370 => 0x8, 371 => 0x14 }, - 'afstatustopvertical' => { 370 => 0x12, 371 => 0x1e }, - 'afstatusupper-left' => { 370 => 0x0, 373 => 0x20 }, - 'afstatusupper-lefthorizontal' => { 371 => 0x2 }, - 'afstatusupper-leftvertical' => { 371 => 0xc }, - 'afstatusupper-middle' => { 370 => 0x20, 371 => 0x20 }, - 'afstatusupper-right' => { 370 => 0x1a, 373 => 0x46 }, - 'afstatusupper-righthorizontal' => { 371 => 0x2a }, - 'afstatusupper-rightvertical' => { 371 => 0x36 }, - 'afstatusupperfarleft' => { 371 => 0x0 }, - 'afstatusupperfarright' => { 371 => 0x28 }, + 'afpredictor' => { 317 => 0x4 }, + 'afresponse' => { 219 => 0xad }, + 'afresult' => { 288 => 0x1038 }, + 'afsearch' => { 283 => 0x303 }, + 'afsensoractive' => { 175 => 0x1 }, + 'afstatus' => { 373 => 0x1200 }, + 'afstatus_00_b4' => { 389 => 0x0 }, + 'afstatus_01_c4' => { 389 => 0x2 }, + 'afstatus_02_d4' => { 389 => 0x4 }, + 'afstatus_03_e4' => { 389 => 0x6 }, + 'afstatus_04_f4' => { 389 => 0x8 }, + 'afstatus_05_g4' => { 389 => 0xa }, + 'afstatus_06_h4' => { 389 => 0xc }, + 'afstatus_07_b3' => { 389 => 0xe }, + 'afstatus_08_c3' => { 389 => 0x10 }, + 'afstatus_09_d3' => { 389 => 0x12 }, + 'afstatus_10_e3' => { 389 => 0x14 }, + 'afstatus_11_f3' => { 389 => 0x16 }, + 'afstatus_12_g3' => { 389 => 0x18 }, + 'afstatus_13_h3' => { 389 => 0x1a }, + 'afstatus_14_b2' => { 389 => 0x1c }, + 'afstatus_15_c2' => { 389 => 0x1e }, + 'afstatus_16_d2' => { 389 => 0x20 }, + 'afstatus_17_e2' => { 389 => 0x22 }, + 'afstatus_18_f2' => { 389 => 0x24 }, + 'afstatus_19_g2' => { 389 => 0x26 }, + 'afstatus_20_h2' => { 389 => 0x28 }, + 'afstatus_21_c1' => { 389 => 0x2a }, + 'afstatus_22_d1' => { 389 => 0x2c }, + 'afstatus_23_e1' => { 389 => 0x2e }, + 'afstatus_24_f1' => { 389 => 0x30 }, + 'afstatus_25_g1' => { 389 => 0x32 }, + 'afstatus_26_a7_vertical' => { 389 => 0x34 }, + 'afstatus_27_a6_vertical' => { 389 => 0x36 }, + 'afstatus_28_a5_vertical' => { 389 => 0x38 }, + 'afstatus_29_c7_vertical' => { 389 => 0x3a }, + 'afstatus_30_c6_vertical' => { 389 => 0x3c }, + 'afstatus_31_c5_vertical' => { 389 => 0x3e }, + 'afstatus_32_e7_vertical' => { 389 => 0x40 }, + 'afstatus_33_e6_center_vertical' => { 389 => 0x42 }, + 'afstatus_34_e5_vertical' => { 389 => 0x44 }, + 'afstatus_35_g7_vertical' => { 389 => 0x46 }, + 'afstatus_36_g6_vertical' => { 389 => 0x48 }, + 'afstatus_37_g5_vertical' => { 389 => 0x4a }, + 'afstatus_38_i7_vertical' => { 389 => 0x4c }, + 'afstatus_39_i6_vertical' => { 389 => 0x4e }, + 'afstatus_40_i5_vertical' => { 389 => 0x50 }, + 'afstatus_41_a7' => { 389 => 0x52 }, + 'afstatus_42_b7' => { 389 => 0x54 }, + 'afstatus_43_c7' => { 389 => 0x56 }, + 'afstatus_44_d7' => { 389 => 0x58 }, + 'afstatus_45_e7' => { 389 => 0x5a }, + 'afstatus_46_f7' => { 389 => 0x5c }, + 'afstatus_47_g7' => { 389 => 0x5e }, + 'afstatus_48_h7' => { 389 => 0x60 }, + 'afstatus_49_i7' => { 389 => 0x62 }, + 'afstatus_50_a6' => { 389 => 0x64 }, + 'afstatus_51_b6' => { 389 => 0x66 }, + 'afstatus_52_c6' => { 389 => 0x68 }, + 'afstatus_53_d6' => { 389 => 0x6a }, + 'afstatus_54_e6_center' => { 389 => 0x6c }, + 'afstatus_55_f6' => { 389 => 0x6e }, + 'afstatus_56_g6' => { 389 => 0x70 }, + 'afstatus_57_h6' => { 389 => 0x72 }, + 'afstatus_58_i6' => { 389 => 0x74 }, + 'afstatus_59_a5' => { 389 => 0x76 }, + 'afstatus_60_b5' => { 389 => 0x78 }, + 'afstatus_61_c5' => { 389 => 0x7a }, + 'afstatus_62_d5' => { 389 => 0x7c }, + 'afstatus_63_e5' => { 389 => 0x7e }, + 'afstatus_64_f5' => { 389 => 0x80 }, + 'afstatus_65_g5' => { 389 => 0x82 }, + 'afstatus_66_h5' => { 389 => 0x84 }, + 'afstatus_67_i5' => { 389 => 0x86 }, + 'afstatus_68_c11' => { 389 => 0x88 }, + 'afstatus_69_d11' => { 389 => 0x8a }, + 'afstatus_70_e11' => { 389 => 0x8c }, + 'afstatus_71_f11' => { 389 => 0x8e }, + 'afstatus_72_g11' => { 389 => 0x90 }, + 'afstatus_73_b10' => { 389 => 0x92 }, + 'afstatus_74_c10' => { 389 => 0x94 }, + 'afstatus_75_d10' => { 389 => 0x96 }, + 'afstatus_76_e10' => { 389 => 0x98 }, + 'afstatus_77_f10' => { 389 => 0x9a }, + 'afstatus_78_g10' => { 389 => 0x9c }, + 'afstatus_79_h10' => { 389 => 0x9e }, + 'afstatus_80_b9' => { 389 => 0xa0 }, + 'afstatus_81_c9' => { 389 => 0xa2 }, + 'afstatus_82_d9' => { 389 => 0xa4 }, + 'afstatus_83_e9' => { 389 => 0xa6 }, + 'afstatus_84_f9' => { 389 => 0xa8 }, + 'afstatus_85_g9' => { 389 => 0xaa }, + 'afstatus_86_h9' => { 389 => 0xac }, + 'afstatus_87_b8' => { 389 => 0xae }, + 'afstatus_88_c8' => { 389 => 0xb0 }, + 'afstatus_89_d8' => { 389 => 0xb2 }, + 'afstatus_90_e8' => { 389 => 0xb4 }, + 'afstatus_91_f8' => { 389 => 0xb6 }, + 'afstatus_92_g8' => { 389 => 0xb8 }, + 'afstatus_93_h8' => { 389 => 0xba }, + 'afstatus_94_e6_center_f2-8' => { 389 => 0xbc }, + 'afstatusactivesensor' => { 175 => 0x2, 386 => [0x4,0x3b], 390 => 0x1e, 391 => 0x1b, 392 => [0x1b,0x21] }, + 'afstatusbottom' => { 175 => 0x8, 390 => 0x2a, 391 => 0x21, 392 => 0x21 }, + 'afstatusbottom-left' => { 175 => 0x12, 391 => 0x2b, 392 => 0x2b }, + 'afstatusbottom-right' => { 175 => 0x6, 391 => 0x1f, 392 => 0x1f }, + 'afstatusbottomassist-left' => { 390 => 0x28 }, + 'afstatusbottomassist-right' => { 390 => 0x2c }, + 'afstatusbottomhorizontal' => { 387 => 0x10, 388 => 0x1c }, + 'afstatusbottomvertical' => { 387 => 0x16, 388 => 0x26 }, + 'afstatuscenter-10' => { 390 => 0x34 }, + 'afstatuscenter-11' => { 390 => 0x36 }, + 'afstatuscenter-12' => { 390 => 0x38 }, + 'afstatuscenter-14' => { 390 => 0x3c }, + 'afstatuscenter-7' => { 390 => 0x2e }, + 'afstatuscenter-9' => { 390 => 0x32 }, + 'afstatuscenter-horizontal' => { 390 => 0x30 }, + 'afstatuscenter-vertical' => { 390 => 0x3a }, + 'afstatuscenterf2-8' => { 390 => 0x4c }, + 'afstatuscenterhorizontal' => { 175 => 0x2f, 387 => 0xc, 388 => 0x18, 391 => 0x2f, 392 => 0x2f }, + 'afstatuscentervertical' => { 175 => 0xc, 387 => 0x14, 388 => 0x22, 391 => 0x25, 392 => 0x25 }, + 'afstatusfarleft' => { 387 => 0x6, 390 => 0x26 }, + 'afstatusfarlefthorizontal' => { 388 => 0x4 }, + 'afstatusfarleftvertical' => { 388 => 0x12 }, + 'afstatusfarright' => { 387 => 0x18, 390 => 0x44 }, + 'afstatusfarrighthorizontal' => { 388 => 0x2c }, + 'afstatusfarrightvertical' => { 388 => 0x34 }, + 'afstatusleft' => { 175 => 0x2d, 387 => 0x2, 390 => 0x22, 391 => 0x2d, 392 => 0x2d }, + 'afstatuslefthorizontal' => { 388 => 0x6 }, + 'afstatusleftvertical' => { 388 => 0xe }, + 'afstatuslower-left' => { 387 => 0x4, 390 => 0x24 }, + 'afstatuslower-lefthorizontal' => { 388 => 0xa }, + 'afstatuslower-leftvertical' => { 388 => 0x10 }, + 'afstatuslower-middle' => { 387 => 0x22, 388 => 0x24 }, + 'afstatuslower-right' => { 387 => 0x1e, 390 => 0x4a }, + 'afstatuslower-righthorizontal' => { 388 => 0x32 }, + 'afstatuslower-rightvertical' => { 388 => 0x3a }, + 'afstatuslowerfarleft' => { 388 => 0x8 }, + 'afstatuslowerfarright' => { 388 => 0x30 }, + 'afstatusmiddlehorizontal' => { 175 => 0xa, 391 => 0x23, 392 => 0x23 }, + 'afstatusnearleft' => { 387 => 0xe, 388 => 0x1a }, + 'afstatusnearright' => { 387 => 0xa, 388 => 0x16 }, + 'afstatusright' => { 175 => 0x31, 387 => 0x1c, 390 => 0x48, 391 => 0x31, 392 => 0x31 }, + 'afstatusrighthorizontal' => { 388 => 0x2e }, + 'afstatusrightvertical' => { 388 => 0x38 }, + 'afstatustop' => { 175 => 0xe, 390 => 0x40, 391 => 0x27, 392 => 0x27 }, + 'afstatustop-left' => { 175 => 0x10, 391 => 0x29, 392 => 0x29 }, + 'afstatustop-right' => { 175 => 0x4, 391 => 0x1d, 392 => 0x1d }, + 'afstatustopassist-left' => { 390 => 0x3e }, + 'afstatustopassist-right' => { 390 => 0x42 }, + 'afstatustophorizontal' => { 387 => 0x8, 388 => 0x14 }, + 'afstatustopvertical' => { 387 => 0x12, 388 => 0x1e }, + 'afstatusupper-left' => { 387 => 0x0, 390 => 0x20 }, + 'afstatusupper-lefthorizontal' => { 388 => 0x2 }, + 'afstatusupper-leftvertical' => { 388 => 0xc }, + 'afstatusupper-middle' => { 387 => 0x20, 388 => 0x20 }, + 'afstatusupper-right' => { 387 => 0x1a, 390 => 0x46 }, + 'afstatusupper-righthorizontal' => { 388 => 0x2a }, + 'afstatusupper-rightvertical' => { 388 => 0x36 }, + 'afstatusupperfarleft' => { 388 => 0x0 }, + 'afstatusupperfarright' => { 388 => 0x28 }, 'afstatusviewfinder' => { 2 => 0x12 }, - 'aftracking' => { 388 => 0x2021 }, + 'aftracking' => { 406 => 0x2021 }, 'aftrackingsensitivity' => { 2 => 0x2 }, - 'aftype' => { 369 => 0x2 }, - 'afwithshutter' => { 376 => 0x2a }, - 'aggregateissuenumber' => { 456 => 'aggregateIssueNumber' }, - 'aggregationtype' => { 456 => 'aggregationType' }, - 'agreement' => { 459 => 'agreement' }, - 'ah2greeninterpolationthreshold' => { 131 => 0xe4e }, - 'aiservocontinuousshooting' => { 77 => 0x15 }, + 'aftype' => { 386 => 0x2 }, + 'afwithshutter' => { 393 => 0x2a }, + 'aggregateissuenumber' => { 478 => 'aggregateIssueNumber' }, + 'aggregationtype' => { 478 => 'aggregationType' }, + 'agreement' => { 481 => 'agreement' }, + 'ah2greeninterpolationthreshold' => { 134 => 0xe4e }, + 'aiservocontinuousshooting' => { 80 => 0x15 }, 'aiservofirstimage' => { 2 => 0x5 }, - 'aiservofirstimagepriority' => { 78 => 0x519 }, - 'aiservoimagepriority' => { 78 => 0x503 }, + 'aiservofirstimagepriority' => { 81 => 0x519 }, + 'aiservoimagepriority' => { 81 => 0x503 }, 'aiservosecondimage' => { 2 => 0x6 }, - 'aiservosecondimagepriority' => { 78 => 0x51a }, - 'aiservotrackingmethod' => { 78 => 0x504 }, - 'aiservotrackingsensitivity' => { 77 => 0x14, 78 => 0x502 }, - 'album' => { 466 => 'album' }, - 'alreadyapplied' => { 442 => 'AlreadyApplied' }, - 'alternatetitle' => { 456 => 'alternateTitle' }, - 'alternatetitlea-lang' => { 456 => [\'alternateTitle','alternateTitleA-lang'] }, - 'alternatetitlea-platform' => { 456 => [\'alternateTitle','alternateTitleA-platform'] }, - 'alternatetitletext' => { 456 => [\'alternateTitle','alternateTitleText'] }, - 'altitude' => { 185 => 0x6 }, - 'alttapename' => { 466 => 'altTapeName' }, - 'alttimecode' => { 466 => 'altTimecode' }, - 'alttimecodetimeformat' => { 466 => [\'altTimecode','altTimecodeTimeFormat'] }, - 'alttimecodetimevalue' => { 466 => [\'altTimecode','altTimecodeTimeValue'] }, - 'alttimecodevalue' => { 466 => [\'altTimecode','altTimecodeValue'] }, + 'aiservosecondimagepriority' => { 81 => 0x51a }, + 'aiservotrackingmethod' => { 81 => 0x504 }, + 'aiservotrackingsensitivity' => { 80 => 0x14, 81 => 0x502 }, + 'album' => { 358 => ['albm',"\xa9alb"], 360 => 'album', 366 => ['albm',"\xa9alb"], 488 => 'album' }, + 'albumartist' => { 358 => 'aART', 366 => 'albr' }, + 'albumtitleid' => { 358 => 'atID' }, + 'alreadyapplied' => { 462 => 'AlreadyApplied', 464 => 'AlreadyApplied' }, + 'alternatetitle' => { 478 => 'alternateTitle' }, + 'alternatetitlea-lang' => { 478 => [\'alternateTitle','alternateTitleA-lang'] }, + 'alternatetitlea-platform' => { 478 => [\'alternateTitle','alternateTitleA-platform'] }, + 'alternatetitletext' => { 478 => [\'alternateTitle','alternateTitleText'] }, + 'altitude' => { 190 => 0x6 }, + 'alttapename' => { 488 => 'altTapeName' }, + 'alttimecode' => { 488 => 'altTimecode' }, + 'alttimecodetimeformat' => { 488 => [\'altTimecode','altTimecodeTimeFormat'] }, + 'alttimecodetimevalue' => { 488 => [\'altTimecode','altTimecodeTimeValue'] }, + 'alttimecodevalue' => { 488 => [\'altTimecode','altTimecodeValue'] }, 'ambienceselection' => { 4 => 0x1 }, - 'ambienttemperature' => { 113 => 0x9400, 353 => 0x14, 354 => 0x46, 411 => 0x4, 447 => 'Temperature' }, - 'ambienttemperaturefahrenheit' => { 353 => 0x13, 354 => 0x44 }, - 'analogbalance' => { 113 => 0xc627 }, - 'analogcaptureiso' => { 131 => 0x89e }, - 'analogisotable' => { 131 => 0x89d }, - 'angleadj' => { 97 => 0x10003, 103 => 0x8b }, - 'angleinforoll' => { 437 => 'AngleInfoRoll' }, - 'angleinfoyaw' => { 437 => 'AngleInfoYaw' }, - 'anti-blur' => { 388 => 0xb04b }, - 'antialiasstrength' => { 113 => 0xc632 }, - 'aperturelock' => { 258 => '38.2', 260 => '38.2', 261 => '38.2', 270 => '38.2', 271 => '38.2' }, - 'aperturerange' => { 78 => 0x10d }, - 'apertureringuse' => { 313 => '1.4' }, - 'aperturesetting' => { 174 => 0x7, 376 => 0x30, 377 => 0x29, 378 => 0x1 }, - 'aperturevalue' => { 87 => 0x2, 113 => 0x9202, 279 => 0x1002, 341 => 0x401, 446 => 'ApertureValue' }, - 'applekeywords' => { 283 => 'AAPL:Keywords' }, - 'applicationkeystring' => { 131 => 0x400 }, - 'applicationnotes' => { 113 => 0x2bc, 302 => 0x2bc }, - 'applicationrecordversion' => { 125 => 0x0 }, - 'applyshootingmeteringmode' => { 78 => 0x10e }, - 'approved' => { 448 => 'Approved' }, - 'approvedby' => { 448 => 'ApprovedBy' }, - 'approximatefnumber' => { 292 => 0x313, 299 => 0x3406 }, - 'approximatefocusdistance' => { 438 => 'ApproximateFocusDistance' }, - 'appversion' => { 450 => 'AppVersion' }, - 'aquahsl' => { 97 => 0x20914 }, - 'armidentifier' => { 126 => 0x78 }, - 'armversion' => { 126 => 0x7a }, - 'artfilter' => { 274 => 0x529 }, - 'artfiltereffect' => { 274 => 0x52f }, - 'artist' => { 113 => 0x13b, 287 => 'Artist', 332 => 0x22e, 462 => 'Artist', 466 => 'artist' }, - 'artmode' => { 107 => 0x301b }, - 'artmodeparameters' => { 107 => 0x310b }, - 'artworkcircadatecreated' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCircaDateCreated'] }, - 'artworkcontentdescription' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOContentDescription'] }, - 'artworkcontributiondescription' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOContributionDescription'] }, - 'artworkcopyrightnotice' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCopyrightNotice'] }, - 'artworkcopyrightownerid' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentCopyrightOwnerId'] }, - 'artworkcopyrightownername' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentCopyrightOwnerName'] }, - 'artworkcreator' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCreator'] }, - 'artworkcreatorid' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCreatorId'] }, - 'artworkdatecreated' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAODateCreated'] }, - 'artworklicensorid' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentLicensorId'] }, - 'artworklicensorname' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentLicensorName'] }, - 'artworkorobject' => { 452 => 'ArtworkOrObject' }, - 'artworkphysicaldescription' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOPhysicalDescription'] }, - 'artworksource' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOSource'] }, - 'artworksourceinventoryno' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvNo'] }, - 'artworksourceinvurl' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvURL'] }, - 'artworkstyleperiod' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOStylePeriod'] }, - 'artworktitle' => { 452 => [\'ArtworkOrObject','ArtworkOrObjectAOTitle'] }, - 'aspectframe' => { 278 => 0x1113 }, - 'aspectratio' => { 5 => 0x0, 278 => 0x1112, 332 => 0x80, 376 => 0x55, 377 => 0x55, 378 => 0xa }, - 'assetid' => { 431 => 'AssetID' }, - 'asshoticcprofile' => { 113 => 0xc68f }, - 'asshotneutral' => { 113 => 0xc628 }, - 'asshotpreprofilematrix' => { 113 => 0xc690 }, - 'asshotprofilename' => { 113 => 0xc6f6 }, - 'asshotwhitexy' => { 113 => 0xc629 }, - 'assignbktbutton' => { 257 => '4.2', 258 => '16.1', 260 => '16.1', 261 => '16.1', 270 => '16.1', 271 => '16.1' }, - 'assignfuncbutton' => { 78 => 0x70b }, - 'assignmb-d17af-onbutton' => { 261 => '79.1' }, - 'assignmb-d17funcbutton' => { 261 => '67.1' }, - 'assignmb-d17funcbuttonplusdials' => { 261 => '68.1' }, - 'assignmb-d18af-onbutton' => { 271 => '79.1' }, - 'assignmb-d18funcbutton' => { 271 => '67.1' }, - 'assignmb-d18funcbuttonplusdials' => { 271 => '68.1' }, - 'assignmoviefunc1buttonplusdials' => { 260 => '75.1', 261 => '75.1', 271 => '75.1' }, - 'assignmoviefunc2button' => { 260 => '82.1', 261 => '82.1', 271 => '82.1' }, - 'assignmoviepreviewbuttonplusdials' => { 260 => '75.2', 261 => '75.2', 271 => '75.2' }, - 'assignmovierecordbutton' => { 258 => '43.2', 270 => '45.1' }, - 'assignmovierecordbuttonplusdials' => { 260 => '45.1', 261 => '45.1', 271 => '45.1' }, - 'assignmoviesubselector' => { 260 => '74.1', 261 => '74.1', 271 => '74.1' }, - 'assignmoviesubselectorplusdials' => { 260 => '76.1', 261 => '76.1', 271 => '76.1' }, - 'assignremotefnbutton' => { 258 => '54.1', 270 => '51.1' }, - 'assistbuttonfunction' => { 76 => 0xd }, - 'atcaptureusercrop' => { 131 => 0x943 }, - 'attributionname' => { 439 => 'attributionName' }, - 'attributionurl' => { 439 => 'attributionURL' }, - 'audio' => { 297 => 0x20 }, - 'audiobitrate' => { 63 => 0x6c, 452 => 'audioBitRate' }, - 'audiobitratemode' => { 452 => 'audioBitRateMode' }, - 'audiobitspersample' => { 452 => 'audioBitsPerSample' }, - 'audiochannelcount' => { 452 => 'audioChannelCount' }, - 'audiochannels' => { 63 => 0x70 }, - 'audiochanneltype' => { 466 => 'audioChannelType' }, - 'audiocompression' => { 146 => 'Compression' }, - 'audiocompressor' => { 466 => 'audioCompressor' }, - 'audiodata' => { 425 => 'Data' }, - 'audioduration' => { 125 => 0x99 }, - 'audiomimetype' => { 425 => 'Mime' }, - 'audiomoddate' => { 466 => 'audioModDate' }, - 'audiooutcue' => { 125 => 0x9a }, - 'audiosamplerate' => { 63 => 0x6e, 466 => 'audioSampleRate' }, - 'audiosampletype' => { 466 => 'audioSampleType' }, - 'audiosamplingrate' => { 125 => 0x97 }, - 'audiosamplingresolution' => { 125 => 0x98 }, - 'audiotype' => { 125 => 0x96 }, - 'author' => { 148 => 'Author', 283 => 'Author', 287 => 'Author', 348 => 'Author', 436 => 'author', 453 => 'Author', 464 => 'Author' }, - 'authorsposition' => { 454 => 'AuthorsPosition' }, - 'autoafpointcolortracking' => { 78 => 0x51c }, + 'ambientinfrared' => { 369 => 0x5c }, + 'ambientlight' => { 369 => 0x5e }, + 'ambienttemperature' => { 116 => 0x9400, 367 => 0x14, 368 => 0x46, 369 => 0x50, 429 => 0x4, 469 => 'Temperature' }, + 'ambienttemperaturefahrenheit' => { 367 => 0x13, 368 => 0x44, 369 => 0x4e }, + 'analogbalance' => { 116 => 0xc627 }, + 'analogcaptureiso' => { 134 => 0x89e }, + 'analogisotable' => { 134 => 0x89d }, + 'androidversion' => { 360 => 'com.android.version' }, + 'angleadj' => { 100 => 0x10003, 106 => 0x8b }, + 'angleinforoll' => { 458 => 'AngleInfoRoll' }, + 'angleinfoyaw' => { 458 => 'AngleInfoYaw' }, + 'anti-blur' => { 406 => 0xb04b }, + 'antialiasstrength' => { 116 => 0xc632 }, + 'aperturelock' => { 267 => '38.2', 269 => '38.2', 270 => '38.2', 279 => '38.2', 280 => '38.2' }, + 'aperturemode' => { 366 => 'apmd' }, + 'aperturerange' => { 81 => 0x10d }, + 'apertureringuse' => { 322 => '1.4' }, + 'aperturesetting' => { 179 => 0x7, 393 => 0x30, 394 => 0x29, 395 => 0x1 }, + 'aperturevalue' => { 90 => 0x2, 116 => 0x9202, 288 => 0x1002, 350 => 0x401, 468 => 'ApertureValue' }, + 'appinfo' => { 442 => 'AppInfo' }, + 'appinfoapplication' => { 442 => [\'AppInfo','AppInfoApplication'] }, + 'appinfoitemuri' => { 442 => [\'AppInfo','AppInfoItemURI'] }, + 'appinfoversion' => { 442 => [\'AppInfo','AppInfoVersion'] }, + 'applekeywords' => { 292 => 'AAPL:Keywords' }, + 'applestoreaccount' => { 358 => 'apID' }, + 'applestoreaccounttype' => { 358 => 'akID' }, + 'applestorecatalogid' => { 358 => 'cnID' }, + 'applestorecountry' => { 358 => 'sfID' }, + 'applicationkeystring' => { 134 => 0x400 }, + 'applicationnotes' => { 116 => 0x2bc, 311 => 0x2bc }, + 'applicationrecordversion' => { 128 => 0x0 }, + 'applyshootingmeteringmode' => { 81 => 0x10e }, + 'approved' => { 470 => 'Approved' }, + 'approvedby' => { 470 => 'ApprovedBy' }, + 'approximatefnumber' => { 301 => 0x313, 308 => 0x3406 }, + 'approximatefocusdistance' => { 459 => 'ApproximateFocusDistance' }, + 'appversion' => { 472 => 'AppVersion' }, + 'aps-csizecapture' => { 424 => 0x114, 425 => [0x114,0x1eb,0x1ee,0x21a,0x21c] }, + 'aquahsl' => { 100 => 0x20914 }, + 'armidentifier' => { 129 => 0x78 }, + 'armversion' => { 129 => 0x7a }, + 'arranger' => { 366 => "\xa9arg" }, + 'arrangerkeywords' => { 366 => "\xa9ark" }, + 'artfilter' => { 283 => 0x529 }, + 'artfiltereffect' => { 283 => 0x52f }, + 'artist' => { 116 => 0x13b, 296 => 'Artist', 341 => 0x22e, 358 => "\xa9ART", 360 => 'artist', 366 => "\xa9ART", 484 => 'Artist', 488 => 'artist' }, + 'artmode' => { 110 => 0x301b }, + 'artmodeparameters' => { 110 => 0x310b }, + 'artwork' => { 360 => 'artwork' }, + 'artworkcircadatecreated' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCircaDateCreated'] }, + 'artworkcontentdescription' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOContentDescription'] }, + 'artworkcontributiondescription' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOContributionDescription'] }, + 'artworkcopyrightnotice' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCopyrightNotice'] }, + 'artworkcopyrightownerid' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentCopyrightOwnerId'] }, + 'artworkcopyrightownername' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentCopyrightOwnerName'] }, + 'artworkcreator' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCreator'] }, + 'artworkcreatorid' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCreatorId'] }, + 'artworkdatecreated' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAODateCreated'] }, + 'artworklicensorid' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentLicensorId'] }, + 'artworklicensorname' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentLicensorName'] }, + 'artworkorobject' => { 474 => 'ArtworkOrObject' }, + 'artworkphysicaldescription' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOPhysicalDescription'] }, + 'artworksource' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOSource'] }, + 'artworksourceinventoryno' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvNo'] }, + 'artworksourceinvurl' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvURL'] }, + 'artworkstyleperiod' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOStylePeriod'] }, + 'artworktitle' => { 474 => [\'ArtworkOrObject','ArtworkOrObjectAOTitle'] }, + 'aspectframe' => { 287 => 0x1113 }, + 'aspectratio' => { 5 => 0x0, 287 => 0x1112, 341 => 0x80, 393 => 0x55, 394 => 0x55, 395 => 0xa }, + 'assetid' => { 452 => 'AssetID' }, + 'asshoticcprofile' => { 116 => 0xc68f }, + 'asshotneutral' => { 116 => 0xc628 }, + 'asshotpreprofilematrix' => { 116 => 0xc690 }, + 'asshotprofilename' => { 116 => 0xc6f6 }, + 'asshotwhitexy' => { 116 => 0xc629 }, + 'assignbktbutton' => { 266 => '4.2', 267 => '16.1', 269 => '16.1', 270 => '16.1', 279 => '16.1', 280 => '16.1' }, + 'assignfuncbutton' => { 81 => 0x70b }, + 'assignmb-d17af-onbutton' => { 270 => '79.1' }, + 'assignmb-d17funcbutton' => { 270 => '67.1' }, + 'assignmb-d17funcbuttonplusdials' => { 270 => '68.1' }, + 'assignmb-d18af-onbutton' => { 280 => '79.1' }, + 'assignmb-d18funcbutton' => { 280 => '67.1' }, + 'assignmb-d18funcbuttonplusdials' => { 280 => '68.1' }, + 'assignmoviefunc1buttonplusdials' => { 269 => '75.1', 270 => '75.1', 280 => '75.1' }, + 'assignmoviefunc2button' => { 269 => '82.1', 270 => '82.1', 280 => '82.1' }, + 'assignmoviepreviewbuttonplusdials' => { 269 => '75.2', 270 => '75.2', 280 => '75.2' }, + 'assignmovierecordbutton' => { 267 => '43.2', 279 => '45.1' }, + 'assignmovierecordbuttonplusdials' => { 269 => '45.1', 270 => '45.1', 280 => '45.1' }, + 'assignmoviesubselector' => { 269 => '74.1', 270 => '74.1', 280 => '74.1' }, + 'assignmoviesubselectorplusdials' => { 269 => '76.1', 270 => '76.1', 280 => '76.1' }, + 'assignremotefnbutton' => { 267 => '54.1', 279 => '51.1' }, + 'assistbuttonfunction' => { 79 => 0xd }, + 'atcaptureusercrop' => { 134 => 0x943 }, + 'attributionname' => { 460 => 'attributionName' }, + 'attributionurl' => { 460 => 'attributionURL' }, + 'audio' => { 306 => 0x20 }, + 'audiobitrate' => { 64 => 0x6c, 474 => 'audioBitRate' }, + 'audiobitratemode' => { 474 => 'audioBitRateMode' }, + 'audiobitspersample' => { 474 => 'audioBitsPerSample' }, + 'audiochannelcount' => { 474 => 'audioChannelCount' }, + 'audiochannels' => { 64 => 0x70 }, + 'audiochanneltype' => { 488 => 'audioChannelType' }, + 'audiocompression' => { 81 => 0x816, 151 => 'Compression' }, + 'audiocompressor' => { 488 => 'audioCompressor' }, + 'audiodata' => { 444 => 'Data' }, + 'audioduration' => { 128 => 0x99 }, + 'audiogain' => { 360 => 'player.movie.audio.gain' }, + 'audiomimetype' => { 444 => 'Mime' }, + 'audiomoddate' => { 488 => 'audioModDate' }, + 'audiooutcue' => { 128 => 0x9a }, + 'audiosamplerate' => { 64 => 0x6e, 488 => 'audioSampleRate' }, + 'audiosampletype' => { 488 => 'audioSampleType' }, + 'audiosamplingrate' => { 128 => 0x97 }, + 'audiosamplingresolution' => { 128 => 0x98 }, + 'audiotype' => { 128 => 0x96 }, + 'author' => { 153 => 'Author', 292 => 'Author', 296 => 'Author', 357 => 'Author', 358 => ['auth',"\xa9aut"], 360 => 'author', 366 => 'auth', 457 => 'author', 475 => 'Author', 486 => 'Author' }, + 'authorsposition' => { 476 => 'AuthorsPosition' }, + 'autoafpointcolortracking' => { 81 => 0x51c }, 'autoafpointseleositraf' => { 2 => 0xa }, - 'autoaperture' => { 323 => '0.1' }, - 'autobracket' => { 368 => 0x19 }, - 'autobracketing' => { 121 => 0x1100, 332 => 0x18, 358 => 0x1007 }, - 'autobracketingmode' => { 269 => '12.3' }, - 'autobracketingset' => { 269 => '12.1' }, - 'autobracketmodem' => { 257 => '21.2', 258 => '13.3', 260 => '13.2', 261 => '13.2', 266 => '26.2', 270 => '13.3', 271 => '13.2' }, - 'autobracketorder' => { 174 => 0x43, 257 => '21.3', 258 => '13.2', 260 => '13.1', 261 => '13.1', 266 => '26.3', 267 => '12.2', 268 => '2.2', 269 => '12.2', 270 => '13.2', 271 => '13.1', 272 => '13.2' }, - 'autobracketset' => { 257 => '21.1', 258 => '13.1', 262 => '11.1', 263 => '12.1', 264 => '12.1', 266 => '26.1', 267 => '12.1', 268 => '2.1', 270 => '13.1', 272 => '13.1' }, - 'autobrightness' => { 442 => 'AutoBrightness' }, - 'autocontrast' => { 442 => 'AutoContrast' }, - 'autodistortioncontrol' => { 195 => 0x4 }, - 'autodynamicrange' => { 121 => 0x140b }, - 'autoexposure' => { 442 => 'AutoExposure' }, - 'autoexposurebracketing' => { 72 => 0x10 }, - 'autoflashisosensitivity' => { 260 => '38.5', 261 => '38.5', 271 => '38.5' }, - 'autofocus' => { 277 => 0x209 }, - 'autofp' => { 268 => '7.3', 272 => '31.4' }, - 'autoiso' => { 72 => 0x1, 107 => 0x3008, 259 => '1.1', 268 => '1.1' }, - 'autoisomax' => { 259 => '1.2', 268 => '1.2' }, - 'autoisominshutterspeed' => { 259 => '1.3', 268 => '1.3' }, - 'autolateralca' => { 442 => 'AutoLateralCA' }, - 'autolightingoptimizer' => { 15 => 0xbe, 16 => 0xbf, 19 => 0xbf, 59 => 0x2, 78 => 0x204, 97 => 0x20500, 103 => 0x6f }, - 'autolightingoptimizeron' => { 97 => '0x20500.0', 103 => 0x6e }, - 'autoportraitframed' => { 388 => 0x2016 }, - 'autoredeye' => { 250 => 0xfe28a44f }, - 'autorotate' => { 72 => 0x1b }, - 'autoshadows' => { 442 => 'AutoShadows' }, - 'autowhiteversion' => { 442 => 'AutoWhiteVersion' }, - 'auxiliarylens' => { 211 => 0x82 }, - 'avaperturesetting' => { 313 => 0x13 }, - 'averageblacklevel' => { 42 => 0xe7, 44 => 0xfb, 45 => 0x114, 46 => 0x146 }, - 'averagelv' => { 177 => 0x38 }, - 'avsettingwithoutlens' => { 78 => 0x707 }, - 'azimuth' => { 156 => 'Azimuth' }, - 'babyage' => { 297 => [0x8010,0x33] }, - 'babyname' => { 297 => 0x66 }, - 'backgroundalpha' => { 461 => 'bgalpha' }, - 'baseexposurecompensation' => { 313 => 0x15 }, - 'baseiso' => { 72 => 0x2, 91 => 0x101c, 131 => 0x903, 299 => 0x312a, 417 => 0x6 }, - 'baseisodaylight' => { 131 => 0x910 }, - 'baseisoflash' => { 131 => 0x913 }, - 'baseisofluorescent' => { 131 => 0x912 }, - 'baseisotungsten' => { 131 => 0x911 }, - 'baselineexposure' => { 113 => 0xc62a }, - 'baselineexposureoffset' => { 113 => 0xc7a5 }, - 'baselinenoise' => { 113 => 0xc62b }, - 'baselinesharpness' => { 113 => 0xc62c }, - 'baseurl' => { 464 => 'BaseURL' }, - 'batterylevel' => { 376 => 0x51, 380 => 0xc, 381 => 0x4, 382 => 0x4, 418 => 0x7 }, - 'batterylevelgrip1' => { 418 => 0x6 }, - 'batterylevelgrip2' => { 418 => 0x8 }, - 'batteryorder' => { 257 => '12.5', 266 => '13.2', 267 => '2.1', 270 => '3.1' }, - 'batterystate' => { 174 => 0x60, 376 => 0x50, 382 => 0x14 }, - 'batterytemperature' => { 380 => 0x1, 382 => 0x2, 418 => 0x5 }, - 'batterytype' => { 60 => 0x38 }, - 'batteryunknown' => { 380 => 0x2, 382 => 0x0 }, - 'batteryvoltage' => { 131 => 0x408, 353 => 0x2a, 354 => 0x49, 380 => 0x8 }, - 'batteryvoltage1' => { 382 => 0x6 }, - 'batteryvoltage2' => { 382 => 0x8 }, - 'bayergreensplit' => { 113 => 0xc62d }, - 'bayerpattern' => { 130 => 0xf902, 178 => 0x17 }, - 'beatspliceparams' => { 466 => 'beatSpliceParams' }, - 'beatspliceparamsriseindecibel' => { 466 => [\'beatSpliceParams','beatSpliceParamsRiseInDecibel'] }, - 'beatspliceparamsriseintimeduration' => { 466 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDuration'] }, - 'beatspliceparamsriseintimedurationscale' => { 466 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationScale'] }, - 'beatspliceparamsriseintimedurationvalue' => { 466 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationValue'] }, - 'beatspliceparamsusefilebeatsmarker' => { 466 => [\'beatSpliceParams','beatSpliceParamsUseFileBeatsMarker'] }, - 'beep' => { 257 => '13.1', 258 => '5.4', 259 => '0.1', 262 => '2.1', 263 => '3.1', 264 => '3.1', 266 => '10.1', 268 => '0.1', 270 => '5.5', 272 => '4.1' }, - 'beeppitch' => { 267 => '3.1' }, - 'beepvolume' => { 267 => '4.5' }, - 'bestqualityscale' => { 113 => 0xc65c }, - 'bestshotmode' => { 107 => 0x3007 }, - 'bitdepth' => { 153 => 'BitDepth', 178 => 0x11, 218 => 0x41 }, - 'bitspercomponent' => { 127 => 0x87 }, - 'bitspersample' => { 113 => 0x102, 302 => 0xa, 462 => 'BitsPerSample' }, - 'blackacquirerows' => { 131 => 0x18ba }, - 'blacklevel' => { 113 => 0xc61a, 193 => 0x20, 211 => 0x3d, 279 => [0x401,0x1012], 341 => 0x21d }, - 'blacklevel2' => { 278 => 0x600, 282 => 0x600 }, - 'blacklevelblue' => { 302 => 0x1e }, - 'blacklevelbottom' => { 131 => 0x3f0 }, - 'blackleveldata' => { 341 => 0x223 }, - 'blackleveldeltah' => { 113 => 0xc61b }, - 'blackleveldeltav' => { 113 => 0xc61c }, - 'blacklevelgreen' => { 302 => 0x1d }, - 'blacklevelred' => { 302 => 0x1c }, - 'blacklevelrepeatdim' => { 113 => 0xc619 }, - 'blacklevelrough' => { 131 => 0x40e }, - 'blacklevelroughafter' => { 131 => 0x416 }, - 'blackleveltop' => { 131 => 0x3ef }, - 'blackpoint' => { 332 => 0x200 }, - 'blacks2012' => { 442 => 'Blacks2012' }, - 'blacksadj' => { 421 => 0x9018 }, - 'bleachbypasstoning' => { 332 => 0x7f }, - 'blockshotafresponse' => { 260 => '1.5', 261 => '1.5', 271 => '1.5' }, - 'blogtitle' => { 456 => 'blogTitle' }, - 'blogurl' => { 456 => 'blogURL' }, - 'bluebalance' => { 279 => 0x1018, 302 => 0x12, 332 => 0x1b }, - 'bluecurvelimits' => { 102 => 0x1fe }, - 'bluecurvepoints' => { 101 => 0x79, 102 => 0x1d4 }, - 'bluehsl' => { 97 => 0x20915 }, - 'bluehue' => { 442 => 'BlueHue' }, - 'bluesaturation' => { 442 => 'BlueSaturation' }, - 'bluratinfinity' => { 427 => 'BlurAtInfinity' }, - 'blurcontrol' => { 332 => 0x82 }, - 'blurwarning' => { 121 => 0x1300 }, - 'bodybatteryadload' => { 311 => 0x3 }, - 'bodybatteryadnoload' => { 311 => 0x2 }, - 'bodybatterystate' => { 311 => '1.1' }, - 'bodybatteryvoltage1' => { 311 => 0x2 }, - 'bodybatteryvoltage2' => { 311 => 0x4 }, - 'bodybatteryvoltage3' => { 311 => 0x6 }, - 'bodybatteryvoltage4' => { 311 => 0x8 }, - 'bodyfirmware' => { 359 => 0x0 }, - 'bodyfirmwareversion' => { 275 => 0x104, 276 => 0x100, 279 => 0x104 }, - 'bodyserialnumber' => { 359 => 0x10 }, - 'bookedition' => { 456 => 'bookEdition' }, - 'bootloaderversion' => { 354 => 0x26 }, - 'bracketmode' => { 54 => 0x3 }, - 'bracketsequence' => { 107 => 0x301d }, - 'bracketsettings' => { 297 => 0x45 }, - 'bracketshotnumber' => { 54 => 0x5, 313 => 0x9, 387 => 0x2b }, - 'bracketshotnumber2' => { 387 => 0x2d }, - 'bracketstep' => { 171 => 0xe }, - 'bracketvalue' => { 54 => 0x4 }, - 'brightness' => { 113 => 0xfe53, 147 => 'Brightness', 167 => 'Brightness', 171 => 0x2c, 213 => 0x34, 214 => 0x39, 353 => 0x25, 376 => 0x22, 388 => 0x2007, 442 => 'Brightness' }, - 'brightnessadj' => { 102 => 0x114, 243 => 0x0, 253 => 0x2d, 421 => 0x8018 }, - 'brightnessvalue' => { 113 => 0x9203, 177 => [0x691,0x49c3], 279 => 0x1003, 393 => 0x1e, 396 => 0x1140, 397 => 0x1140, 398 => 0x111c, 399 => 0x1198, 400 => 0x1174, 401 => 0x102c, 402 => 0x224, 403 => 0x224, 404 => 0x219, 446 => 'BrightnessValue' }, - 'bulbduration' => { 72 => 0x18 }, - 'burstcount' => { 131 => 0x40d }, - 'burstmode' => { 133 => 0xa, 297 => 0x2a }, - 'burstmode2' => { 133 => 0x18 }, - 'burstshot' => { 368 => 0x34 }, - 'burstspeed' => { 297 => 0x77 }, + 'autoaperture' => { 332 => '0.1' }, + 'autobracket' => { 383 => 0x19 }, + 'autobracketing' => { 124 => 0x1100, 341 => 0x18, 373 => 0x1007 }, + 'autobracketingmode' => { 278 => '12.3' }, + 'autobracketingset' => { 278 => '12.1' }, + 'autobracketmodem' => { 266 => '21.2', 267 => '13.3', 269 => '13.2', 270 => '13.2', 275 => '26.2', 279 => '13.3', 280 => '13.2' }, + 'autobracketorder' => { 179 => 0x43, 266 => '21.3', 267 => '13.2', 269 => '13.1', 270 => '13.1', 275 => '26.3', 276 => '12.2', 277 => '2.2', 278 => '12.2', 279 => '13.2', 280 => '13.1', 281 => '13.2' }, + 'autobracketset' => { 266 => '21.1', 267 => '13.1', 271 => '11.1', 272 => '12.1', 273 => '12.1', 275 => '26.1', 276 => '12.1', 277 => '2.1', 279 => '13.1', 281 => '13.1' }, + 'autobrightness' => { 462 => 'AutoBrightness', 464 => 'AutoBrightness' }, + 'autocontrast' => { 462 => 'AutoContrast', 464 => 'AutoContrast' }, + 'autodistortioncontrol' => { 200 => 0x4 }, + 'autodynamicrange' => { 124 => 0x140b }, + 'autoexposure' => { 462 => 'AutoExposure', 464 => 'AutoExposure' }, + 'autoexposurebracketing' => { 74 => 0x10 }, + 'autoflashisosensitivity' => { 269 => '38.5', 270 => '38.5', 280 => '38.5' }, + 'autofocus' => { 286 => 0x209 }, + 'autofp' => { 277 => '7.3', 281 => '31.4' }, + 'autoiso' => { 74 => 0x1, 110 => 0x3008, 268 => '1.1', 277 => '1.1' }, + 'autoisomax' => { 268 => '1.2', 277 => '1.2' }, + 'autoisominshutterspeed' => { 268 => '1.3', 277 => '1.3' }, + 'autolateralca' => { 462 => 'AutoLateralCA', 464 => 'AutoLateralCA' }, + 'autolightingoptimizer' => { 16 => 0xbe, 17 => 0xbf, 20 => 0xbf, 60 => 0x2, 81 => 0x204, 100 => 0x20500, 106 => 0x6f }, + 'autolightingoptimizeron' => { 100 => '0x20500.0', 106 => 0x6e }, + 'autoportraitframed' => { 406 => 0x2016 }, + 'autoredeye' => { 259 => 0xfe28a44f }, + 'autorotate' => { 74 => 0x1b }, + 'autoshadows' => { 462 => 'AutoShadows', 464 => 'AutoShadows' }, + 'autotone' => { 462 => 'AutoTone', 464 => 'AutoTone' }, + 'autowhiteversion' => { 462 => 'AutoWhiteVersion', 464 => 'AutoWhiteVersion' }, + 'auxiliarylens' => { 219 => 0x82 }, + 'avaperturesetting' => { 322 => 0x13 }, + 'averageblacklevel' => { 43 => 0xe7, 45 => 0xfb, 46 => 0x114, 47 => 0x146 }, + 'averagelv' => { 182 => 0x38 }, + 'avsettingwithoutlens' => { 81 => 0x707 }, + 'azimuth' => { 161 => 'Azimuth' }, + 'babyage' => { 306 => [0x8010,0x33] }, + 'babyname' => { 306 => 0x66 }, + 'backgroundalpha' => { 483 => 'bgalpha' }, + 'balance' => { 360 => 'player.movie.audio.balance' }, + 'baseexposurecompensation' => { 322 => 0x15 }, + 'baseiso' => { 74 => 0x2, 94 => 0x101c, 134 => 0x903, 308 => 0x312a, 435 => 0x6 }, + 'baseisodaylight' => { 134 => 0x910 }, + 'baseisoflash' => { 134 => 0x913 }, + 'baseisofluorescent' => { 134 => 0x912 }, + 'baseisotungsten' => { 134 => 0x911 }, + 'baselineexposure' => { 116 => 0xc62a }, + 'baselineexposureoffset' => { 116 => 0xc7a5 }, + 'baselinenoise' => { 116 => 0xc62b }, + 'baselinesharpness' => { 116 => 0xc62c }, + 'baseurl' => { 486 => 'BaseURL' }, + 'bass' => { 360 => 'player.movie.audio.bass' }, + 'batterylevel' => { 393 => 0x51, 397 => 0xc, 398 => 0x4, 399 => 0x4, 436 => 0x7 }, + 'batterylevelgrip1' => { 436 => 0x6 }, + 'batterylevelgrip2' => { 436 => 0x8 }, + 'batteryorder' => { 266 => '12.5', 275 => '13.2', 276 => '2.1', 279 => '3.1' }, + 'batterystate' => { 179 => 0x60, 393 => 0x50, 399 => 0x14 }, + 'batterytemperature' => { 397 => 0x1, 399 => 0x2, 436 => 0x5 }, + 'batterytype' => { 61 => 0x38, 369 => 0x66 }, + 'batteryunknown' => { 397 => 0x2, 399 => 0x0 }, + 'batteryvoltage' => { 134 => 0x408, 367 => 0x2a, 368 => 0x49, 369 => 0x62, 397 => 0x8 }, + 'batteryvoltage1' => { 399 => 0x6 }, + 'batteryvoltage2' => { 399 => 0x8 }, + 'batteryvoltageavg' => { 369 => 0x64 }, + 'bayergreensplit' => { 116 => 0xc62d }, + 'bayerpattern' => { 133 => 0xf902, 183 => 0x17 }, + 'beatsperminute' => { 358 => 'tmpo' }, + 'beatspliceparams' => { 488 => 'beatSpliceParams' }, + 'beatspliceparamsriseindecibel' => { 488 => [\'beatSpliceParams','beatSpliceParamsRiseInDecibel'] }, + 'beatspliceparamsriseintimeduration' => { 488 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDuration'] }, + 'beatspliceparamsriseintimedurationscale' => { 488 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationScale'] }, + 'beatspliceparamsriseintimedurationvalue' => { 488 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationValue'] }, + 'beatspliceparamsusefilebeatsmarker' => { 488 => [\'beatSpliceParams','beatSpliceParamsUseFileBeatsMarker'] }, + 'beep' => { 266 => '13.1', 267 => '5.4', 268 => '0.1', 271 => '2.1', 272 => '3.1', 273 => '3.1', 275 => '10.1', 277 => '0.1', 279 => '5.5', 281 => '4.1' }, + 'beeppitch' => { 276 => '3.1' }, + 'beepvolume' => { 276 => '4.5' }, + 'bestqualityscale' => { 116 => 0xc65c }, + 'bestshotmode' => { 110 => 0x3007 }, + 'bitdepth' => { 158 => 'BitDepth', 183 => 0x11, 227 => 0x41 }, + 'bitspercomponent' => { 130 => 0x87 }, + 'bitspersample' => { 116 => 0x102, 311 => 0xa, 484 => 'BitsPerSample' }, + 'blackacquirerows' => { 134 => 0x18ba }, + 'blacklevel' => { 116 => 0xc61a, 198 => 0x20, 219 => 0x3d, 288 => [0x401,0x1012], 350 => 0x21d }, + 'blacklevel2' => { 287 => 0x600, 291 => 0x600 }, + 'blacklevelblue' => { 311 => 0x1e }, + 'blacklevelbottom' => { 134 => 0x3f0 }, + 'blackleveldata' => { 350 => 0x223 }, + 'blackleveldeltah' => { 116 => 0xc61b }, + 'blackleveldeltav' => { 116 => 0xc61c }, + 'blacklevelgreen' => { 311 => 0x1d }, + 'blacklevelred' => { 311 => 0x1c }, + 'blacklevelrepeatdim' => { 116 => 0xc619 }, + 'blacklevelrough' => { 134 => 0x40e }, + 'blacklevelroughafter' => { 134 => 0x416 }, + 'blacklevels' => { 35 => 0x1d }, + 'blackleveltop' => { 134 => 0x3ef }, + 'blackpoint' => { 341 => 0x200 }, + 'blacks2012' => { 462 => 'Blacks2012', 464 => 'Blacks2012' }, + 'blacksadj' => { 439 => 0x9018 }, + 'bleachbypasstoning' => { 341 => 0x7f }, + 'blockshotafresponse' => { 269 => '1.5', 270 => '1.5', 280 => '1.5' }, + 'blogtitle' => { 478 => 'blogTitle' }, + 'blogurl' => { 478 => 'blogURL' }, + 'bluebalance' => { 288 => 0x1018, 311 => 0x12, 341 => 0x1b }, + 'bluecurvelimits' => { 105 => 0x1fe }, + 'bluecurvepoints' => { 104 => 0x79, 105 => 0x1d4 }, + 'bluehsl' => { 100 => 0x20915 }, + 'bluehue' => { 462 => 'BlueHue', 464 => 'BlueHue' }, + 'bluesaturation' => { 462 => 'BlueSaturation', 464 => 'BlueSaturation' }, + 'bluratinfinity' => { 448 => 'BlurAtInfinity' }, + 'blurcontrol' => { 341 => 0x82 }, + 'blurwarning' => { 124 => 0x1300 }, + 'bodybatteryadload' => { 320 => 0x3 }, + 'bodybatteryadnoload' => { 320 => 0x2 }, + 'bodybatterystate' => { 320 => '1.1' }, + 'bodybatteryvoltage1' => { 320 => 0x2 }, + 'bodybatteryvoltage2' => { 320 => 0x4 }, + 'bodybatteryvoltage3' => { 320 => 0x6 }, + 'bodybatteryvoltage4' => { 320 => 0x8 }, + 'bodyfirmware' => { 374 => 0x0 }, + 'bodyfirmwareversion' => { 284 => 0x104, 285 => 0x100, 288 => 0x104 }, + 'bodyserialnumber' => { 374 => 0x10 }, + 'bookedition' => { 478 => 'bookEdition' }, + 'bootloaderversion' => { 368 => 0x26 }, + 'bracketmode' => { 55 => 0x3 }, + 'bracketsequence' => { 110 => 0x301d }, + 'bracketsettings' => { 306 => 0x45 }, + 'bracketshotnumber' => { 55 => 0x5, 322 => 0x9, 404 => 0x2b }, + 'bracketshotnumber2' => { 404 => 0x2d }, + 'bracketstep' => { 176 => 0xe }, + 'bracketvalue' => { 55 => 0x4 }, + 'brightness' => { 116 => 0xfe53, 152 => 'Brightness', 172 => 'Brightness', 176 => 0x2c, 221 => 0x34, 222 => 0x39, 223 => 0x41, 360 => 'player.movie.visual.brightness', 367 => 0x25, 369 => 0x54, 393 => 0x22, 406 => 0x2007, 462 => 'Brightness', 464 => 'Brightness' }, + 'brightnessadj' => { 105 => 0x114, 252 => 0x0, 262 => 0x2d, 439 => 0x8018 }, + 'brightnessvalue' => { 116 => 0x9203, 182 => [0x691,0x49c3], 288 => 0x1003, 411 => 0x1e, 414 => 0x1140, 415 => 0x1140, 416 => 0x111c, 417 => 0x1198, 418 => 0x1174, 419 => 0x102c, 420 => 0x224, 421 => 0x224, 422 => 0x219, 468 => 'BrightnessValue' }, + 'buildnumber' => { 186 => 0x5500 }, + 'bulbduration' => { 74 => 0x18 }, + 'burstcount' => { 134 => 0x40d }, + 'burstid' => { 445 => 'BurstID' }, + 'burstmode' => { 136 => 0xa, 306 => 0x2a }, + 'burstmode2' => { 136 => 0x18 }, + 'burstprimary' => { 445 => 'BurstPrimary' }, + 'burstshot' => { 383 => 0x34 }, + 'burstspeed' => { 306 => 0x77 }, 'burstuuid' => { 1 => 0xb }, - 'buttonfunctioncontroloff' => { 78 => 0x70a }, - 'bwadjustment' => { 121 => 0x1049 }, - 'bwfilter' => { 171 => 0x2a, 179 => 0x39 }, - 'bwmode' => { 279 => 0x203 }, - 'by-line' => { 125 => 0x50 }, - 'by-linetitle' => { 125 => 0x55 }, - 'bytecount' => { 456 => 'byteCount' }, - 'c14configuration' => { 131 => 0x1964 }, - 'cacheversion' => { 113 => 0xc7aa }, - 'calibration' => { 368 => [0x24,0x30] }, - 'calibrationhistory' => { 131 => 0x9c9 }, - 'calibrationilluminant1' => { 113 => 0xc65a }, - 'calibrationilluminant2' => { 113 => 0xc65b }, - 'calibrationversion' => { 131 => 0x9c6 }, - 'callforimage' => { 431 => 'CallForImage' }, - 'cameraangle' => { 466 => 'cameraAngle' }, - 'cameracalibration1' => { 113 => 0xc623 }, - 'cameracalibration2' => { 113 => 0xc624 }, - 'cameracalibrationsig' => { 113 => 0xc6f3 }, - 'cameracolorcalibration01' => { 35 => 0x0, 36 => 0x0 }, - 'cameracolorcalibration02' => { 35 => 0x4, 36 => 0x5 }, - 'cameracolorcalibration03' => { 35 => 0x8, 36 => 0xa }, - 'cameracolorcalibration04' => { 35 => 0xc, 36 => 0xf }, - 'cameracolorcalibration05' => { 35 => 0x10, 36 => 0x14 }, - 'cameracolorcalibration06' => { 35 => 0x14, 36 => 0x19 }, - 'cameracolorcalibration07' => { 35 => 0x18, 36 => 0x1e }, - 'cameracolorcalibration08' => { 35 => 0x1c, 36 => 0x23 }, - 'cameracolorcalibration09' => { 35 => 0x20, 36 => 0x28 }, - 'cameracolorcalibration10' => { 35 => 0x24, 36 => 0x2d }, - 'cameracolorcalibration11' => { 35 => 0x28, 36 => 0x32 }, - 'cameracolorcalibration12' => { 35 => 0x2c, 36 => 0x37 }, - 'cameracolorcalibration13' => { 35 => 0x30, 36 => 0x3c }, - 'cameracolorcalibration14' => { 35 => 0x34, 36 => 0x41 }, - 'cameracolorcalibration15' => { 35 => 0x38, 36 => 0x46 }, - 'camerae-mountversion' => { 420 => 0xb }, - 'cameraelevationangle' => { 113 => 0x9405, 447 => 'CameraElevationAngle' }, - 'camerafilename' => { 431 => 'CameraFilename' }, - 'cameraid' => { 279 => 0x209, 367 => 0x209 }, - 'cameraiso' => { 33 => 0x10 }, - 'cameralabel' => { 113 => 0xc7a1, 466 => 'cameraLabel' }, - 'cameramakemodel' => { 431 => 'CameraMakeModel' }, - 'cameramodel' => { 341 => 0x410, 466 => 'cameraModel' }, - 'cameramodelid' => { 167 => 'CameraModelID' }, - 'cameramove' => { 466 => 'cameraMove' }, - 'cameraorientation' => { 6 => 0x30, 8 => 0x7d, 10 => 0x30, 12 => 0x35, 13 => 0x30, 14 => 0x30, 15 => 0x31, 16 => 0x31, 17 => 0x35, 18 => 0x27, 19 => 0x31, 20 => 0x7d, 21 => 0x38, 22 => 0x36, 23 => 0x7d, 24 => 0x83, 25 => 0x84, 27 => 0x35, 28 => 0x96, 297 => 0x8f, 336 => 0x1, 341 => 0x100, 382 => [0x16,0x18], 408 => 0x28, 409 => 0x24, 410 => 0x29 }, - 'cameraowner' => { 134 => 0xc353 }, - 'cameraparameters' => { 279 => 0x2050 }, - 'camerapicturestyle' => { 27 => 0xaf }, - 'camerapitch' => { 109 => 0x9 }, - 'cameraprofile' => { 442 => 'CameraProfile' }, - 'cameraprofiledigest' => { 442 => 'CameraProfileDigest' }, - 'camerarawcolortone' => { 103 => 0xe1 }, - 'camerarawcontrast' => { 103 => 0xe3 }, - 'camerarawhighlightpoint' => { 103 => 0xe6 }, - 'camerarawlinear' => { 103 => 0xe4 }, - 'camerarawoutputhighlightpoint' => { 103 => 0xe8 }, - 'camerarawoutputshadowpoint' => { 103 => 0xe9 }, - 'camerarawsaturation' => { 103 => 0xe2 }, - 'camerarawshadowpoint' => { 103 => 0xe7 }, - 'camerarawsharpness' => { 103 => 0xe5 }, - 'cameraroll' => { 109 => 0xb }, - 'cameraserialnumber' => { 113 => 0xc62f, 169 => 'CameraSerialNumber', 431 => 'CameraSerialNumber' }, - 'camerasettingsversion' => { 274 => 0x0 }, - 'cameratemperature' => { 6 => 0x18, 8 => 0x1b, 10 => 0x18, 12 => 0x19, 13 => 0x18, 14 => 0x18, 15 => 0x19, 16 => 0x19, 17 => 0x19, 18 => 0x17, 19 => 0x19, 20 => 0x1b, 21 => 0x19, 22 => 0x19, 23 => 0x1b, 24 => 0x1b, 25 => 0x1b, 26 => 0x1b, 27 => 0x19, 28 => 0x1b, 29 => [0x87,0x91], 30 => [0x99,0x9f,0xa4,0xa8,0x105], 32 => ['-3',0x64,0x47,0x53,0x5b,0x5c], 72 => 0xc, 131 => 0x406, 278 => 0x1306, 292 => 0x320, 299 => 0x3402, 332 => 0x47, 365 => 0x43, 412 => 0x5 }, - 'cameratemperature4' => { 337 => 0x14 }, - 'cameratemperature5' => { 337 => 0x16 }, - 'cameratemperaturerangemax' => { 115 => 0x5 }, - 'cameratemperaturerangemin' => { 115 => 0x6 }, - 'cameratype' => { 72 => 0x1a, 279 => 0x207 }, - 'cameratype2' => { 275 => 0x100 }, - 'camerayaw' => { 109 => 0xa }, - 'canondr4' => { 114 => 'CanonDR4' }, - 'canonexposuremode' => { 33 => 0x14 }, - 'canonfiledescription' => { 91 => 0x805 }, - 'canonfilelength' => { 60 => 0xe }, - 'canonfirmwareversion' => { 60 => 0x7, 91 => 0x80b }, - 'canonflashinfo' => { 91 => 0x1028 }, - 'canonflashmode' => { 33 => 0x4 }, - 'canonimagesize' => { 9 => 0x39, 33 => 0xa }, - 'canonimagetype' => { 60 => 0x6, 91 => 0x815 }, - 'canonmodelid' => { 60 => 0x10, 91 => 0x1834 }, - 'canonvrd' => { 114 => 'CanonVRD' }, - 'caption' => { 436 => 'caption' }, - 'caption-abstract' => { 125 => 0x78 }, - 'captionsauthornames' => { 445 => 'CaptionsAuthorNames' }, - 'captionsdatetimestamps' => { 445 => 'CaptionsDateTimeStamps' }, - 'captionwriter' => { 454 => 'CaptionWriter' }, - 'captureframerate' => { 107 => 0x4001 }, - 'captureheightnormal' => { 131 => 0x1839 }, - 'capturelook' => { 131 => 0xc48 }, - 'capturesoftware' => { 429 => 'CaptureSoftware' }, - 'capturewidthnormal' => { 131 => 0x1838 }, - 'capturewidthtest' => { 131 => 0x1842 }, - 'cardshutterlock' => { 174 => 0x49 }, - 'casioimagesize' => { 107 => 0x9 }, - 'catalogsets' => { 125 => 0xff, 424 => 'CatalogSets', 434 => 'CatalogSets' }, - 'categories' => { 60 => 0x23, 436 => 'categories' }, - 'category' => { 125 => 0xf, 273 => 0x30, 454 => 'Category' }, - 'cbcrgain' => { 365 => 0xa036 }, - 'cbcrgaindefault' => { 365 => 0xa035 }, - 'cbcrmatrix' => { 365 => 0xa034 }, - 'cbcrmatrixdefault' => { 365 => 0xa033 }, - 'ccdboardversion' => { 292 => 0x331 }, - 'ccdscanmode' => { 279 => 0x1039 }, - 'ccdsensitivity' => { 240 => 0x6 }, - 'ccdversion' => { 292 => 0x330 }, - 'cellglobalid' => { 440 => 'cgi' }, - 'celllength' => { 113 => 0x109 }, - 'cellr' => { 440 => 'r' }, - 'celltowerid' => { 440 => 'cellid' }, - 'cellwidth' => { 113 => 0x108 }, - 'centerafarea' => { 268 => '15.1' }, - 'centerfocuspoint' => { 272 => '2.2' }, - 'centerpixel' => { 131 => 0x40c }, - 'centerweightedareasize' => { 257 => '7.1', 258 => '8.1', 260 => '8.1', 261 => '8.1', 265 => '7.1', 266 => '5.1', 267 => '7.1', 268 => '6.3', 270 => '8.1', 271 => '8.1', 272 => '8.1' }, - 'certificate' => { 470 => 'Certificate' }, - 'cfainterpolationalgorithm' => { 131 => 0xe60 }, - 'cfainterpolationmetric' => { 131 => 0xe61 }, - 'cfaoffsetcols' => { 131 => 0xc71 }, - 'cfaoffsetrows' => { 131 => 0xc6f }, - 'cfapattern' => { 113 => 0xa302, 302 => 0x9, 446 => 'CFAPattern' }, - 'cfapattern2' => { 113 => 0x828e }, - 'cfapatterncolumns' => { 446 => [\'CFAPattern','CFAPatternColumns'] }, - 'cfapatternrows' => { 446 => [\'CFAPattern','CFAPatternRows'] }, - 'cfapatternvalues' => { 446 => [\'CFAPattern','CFAPatternValues'] }, - 'cfarepeatpatterndim' => { 113 => 0x828d }, - 'cfazipperfixthreshold' => { 131 => 0xe62 }, - 'channel' => { 456 => 'channel' }, - 'channela-lang' => { 456 => [\'channel','channelA-lang'] }, - 'channelchannel' => { 456 => [\'channel','channelChannel'] }, - 'channels' => { 146 => 'Channels' }, - 'channelsubchannel1' => { 456 => [\'channel','channelSubchannel1'] }, - 'channelsubchannel2' => { 456 => [\'channel','channelSubchannel2'] }, - 'channelsubchannel3' => { 456 => [\'channel','channelSubchannel3'] }, - 'channelsubchannel4' => { 456 => [\'channel','channelSubchannel4'] }, - 'checkmark' => { 97 => 0x10101, 102 => 0x26a }, - 'checkmark2' => { 103 => 0x8e }, - 'childfontfiles' => { 471 => [\'Fonts','FontsChildFontFiles'] }, - 'chmodeshootingspeed' => { 257 => '10.3', 258 => '11.2' }, - 'chromablurradius' => { 113 => 0xc631 }, - 'chromanoisecolorspace' => { 131 => 0xe6d }, - 'chromanoiseedgemapthresh' => { 131 => 0xe6c }, - 'chromanoisehighfthresh' => { 131 => 0xe6a }, - 'chromanoiselowfthresh' => { 131 => 0xe6b }, - 'chromaticaberration' => { 97 => 0x20703, 103 => 0x66, 365 => 0xa051 }, - 'chromaticaberrationb' => { 442 => 'ChromaticAberrationB' }, - 'chromaticaberrationblue' => { 97 => 0x20708, 103 => 0x6b }, - 'chromaticaberrationcorr' => { 74 => [0x4,0x5] }, - 'chromaticaberrationcorrection' => { 113 => 0x7034, 322 => 0x1, 421 => 0x900d }, - 'chromaticaberrationcorrparams' => { 113 => 0x7035, 416 => 0x66a, 417 => [0x37c,0x384,0x39c,0x3b0,0x3b8] }, - 'chromaticaberrationon' => { 97 => '0x20703.0', 103 => 0x62 }, - 'chromaticaberrationr' => { 442 => 'ChromaticAberrationR' }, - 'chromaticaberrationred' => { 97 => 0x20707, 103 => 0x6a }, - 'chromaticaberrationsetting' => { 75 => 0x6 }, - 'chrominancenoisereduction' => { 97 => 0x20601, 103 => 0x5e, 368 => 0x1a }, - 'chrominancenr_tiff_jpeg' => { 103 => 0x60 }, - 'circadatecreated' => { 452 => 'CircaDateCreated' }, - 'circgradbasedcorractive' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionActive'] }, - 'circgradbasedcorramount' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionAmount'] }, - 'circgradbasedcorrbrightness' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBrightness'] }, - 'circgradbasedcorrclarity' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity'] }, - 'circgradbasedcorrclarity2012' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity2012'] }, - 'circgradbasedcorrcontrast' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast'] }, - 'circgradbasedcorrcontrast2012' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast2012'] }, - 'circgradbasedcorrdefringe' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDefringe'] }, - 'circgradbasedcorrexposure' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure'] }, - 'circgradbasedcorrexposure2012' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure2012'] }, - 'circgradbasedcorrhighlights2012' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHighlights2012'] }, - 'circgradbasedcorrhue' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalToningHue'] }, - 'circgradbasedcorrluminancenoise' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalLuminanceNoise'] }, - 'circgradbasedcorrmaskalpha' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAlpha'] }, - 'circgradbasedcorrmaskangle' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAngle'] }, - 'circgradbasedcorrmaskbottom' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksBottom'] }, - 'circgradbasedcorrmaskcentervalue' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterValue'] }, - 'circgradbasedcorrmaskcenterweight' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterWeight'] }, - 'circgradbasedcorrmaskdabs' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksDabs'] }, - 'circgradbasedcorrmaskfeather' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFeather'] }, - 'circgradbasedcorrmaskflipped' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlipped'] }, - 'circgradbasedcorrmaskflow' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlow'] }, - 'circgradbasedcorrmaskfullx' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullX'] }, - 'circgradbasedcorrmaskfully' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullY'] }, - 'circgradbasedcorrmaskleft' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksLeft'] }, - 'circgradbasedcorrmaskmidpoint' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMidpoint'] }, - 'circgradbasedcorrmaskperimetervalue' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksPerimeterValue'] }, - 'circgradbasedcorrmaskradius' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRadius'] }, - 'circgradbasedcorrmaskright' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRight'] }, - 'circgradbasedcorrmaskroundness' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRoundness'] }, - 'circgradbasedcorrmasks' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasks'] }, - 'circgradbasedcorrmasksizex' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeX'] }, - 'circgradbasedcorrmasksizey' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeY'] }, - 'circgradbasedcorrmasktop' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksTop'] }, - 'circgradbasedcorrmaskvalue' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMaskValue'] }, - 'circgradbasedcorrmaskversion' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksVersion'] }, - 'circgradbasedcorrmaskwhat' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksWhat'] }, - 'circgradbasedcorrmaskx' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksX'] }, - 'circgradbasedcorrmasky' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksY'] }, - 'circgradbasedcorrmaskzerox' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroX'] }, - 'circgradbasedcorrmaskzeroy' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroY'] }, - 'circgradbasedcorrmoire' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalMoire'] }, - 'circgradbasedcorrsaturation' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSaturation','CircularGradientBasedCorrectionsLocalToningSaturation'] }, - 'circgradbasedcorrshadows2012' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalShadows2012'] }, - 'circgradbasedcorrsharpness' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSharpness'] }, - 'circgradbasedcorrtemperature' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTemperature'] }, - 'circgradbasedcorrtint' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTint'] }, - 'circgradbasedcorrwhat' => { 442 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsWhat'] }, - 'circulargradientbasedcorrections' => { 442 => 'CircularGradientBasedCorrections' }, - 'city' => { 125 => 0x5a, 152 => 'City', 297 => 0x6d, 454 => 'City' }, - 'city2' => { 297 => 0x80 }, - 'clarity' => { 214 => 0x35, 442 => 'Clarity' }, - 'clarity2012' => { 442 => 'Clarity2012' }, - 'claritycontrol' => { 332 => 0x96 }, - 'classifystate' => { 125 => 0xe1 }, - 'clearretouch' => { 297 => 0x7c }, - 'clearretouchvalue' => { 297 => 0xa3 }, - 'client' => { 466 => 'client' }, - 'clientname' => { 448 => 'ClientName' }, - 'clmodeshootingspeed' => { 257 => '10.2', 258 => '11.3', 260 => '11.2', 261 => '11.2', 266 => '11.2', 267 => '10.2', 270 => '11.2', 271 => '11.2', 272 => '11.1' }, - 'cmcontrast' => { 282 => 0x2022 }, - 'cmexposurecompensation' => { 282 => 0x2000 }, - 'cmhue' => { 282 => 0x2021 }, - 'cmsaturation' => { 282 => 0x2020 }, - 'cmsharpness' => { 282 => 0x2023 }, - 'cmwhitebalance' => { 282 => 0x2001 }, - 'cmwhitebalancecomp' => { 282 => 0x2002 }, - 'cmwhitebalancegraypoint' => { 282 => 0x2010 }, - 'codec' => { 160 => 'Codec' }, - 'codedcharacterset' => { 126 => 0x5a }, - 'collection' => { 287 => 'Collection' }, - 'collectionname' => { 161 => [\'Collections','CollectionsCollectionName'] }, - 'collections' => { 161 => 'Collections', 436 => 'collections' }, - 'collectionuri' => { 161 => [\'Collections','CollectionsCollectionURI'] }, - 'color' => { 455 => 'color' }, - 'coloraberrationcontrol' => { 250 => 0xc89224b }, - 'coloradjustment' => { 368 => 0x14 }, - 'coloradjustmentmode' => { 367 => 0x210 }, - 'coloranta' => { 471 => [\'Colorants','ColorantsA'] }, - 'colorantb' => { 471 => [\'Colorants','ColorantsB'] }, - 'colorantblack' => { 471 => [\'Colorants','ColorantsBlack'] }, - 'colorantblue' => { 471 => [\'Colorants','ColorantsBlue'] }, - 'colorantcyan' => { 471 => [\'Colorants','ColorantsCyan'] }, - 'colorantgray' => { 471 => [\'Colorants','ColorantsGray'] }, - 'colorantgreen' => { 471 => [\'Colorants','ColorantsGreen'] }, - 'colorantl' => { 471 => [\'Colorants','ColorantsL'] }, - 'colorantmagenta' => { 471 => [\'Colorants','ColorantsMagenta'] }, - 'colorantmode' => { 471 => [\'Colorants','ColorantsMode'] }, - 'colorantred' => { 471 => [\'Colorants','ColorantsRed'] }, - 'colorants' => { 471 => 'Colorants' }, - 'colorantswatchname' => { 471 => [\'Colorants','ColorantsSwatchName'] }, - 'coloranttint' => { 471 => [\'Colorants','ColorantsTint'] }, - 'coloranttype' => { 471 => [\'Colorants','ColorantsType'] }, - 'colorantyellow' => { 471 => [\'Colorants','ColorantsYellow'] }, - 'colorbalance' => { 147 => 'ColorBalance' }, - 'colorbalanceadj' => { 250 => 0x76a43202 }, - 'colorbalanceblue' => { 171 => 0x1e }, - 'colorbalancegreen' => { 171 => 0x1d }, - 'colorbalancered' => { 171 => 0x1c }, - 'colorbalanceversion' => { 192 => 0x4, 193 => 0x4, 194 => 0x0 }, - 'colorblur' => { 103 => 0x65 }, - 'colorbluron' => { 97 => 0x20704 }, - 'colorbooster' => { 250 => 0x5f0e7d23 }, - 'colorboostlevel' => { 244 => 0x1 }, - 'colorboosttype' => { 244 => 0x0 }, - 'colorchromeeffect' => { 121 => 0x1048 }, - 'colorclass' => { 343 => 0xde, 344 => 'ColorClass' }, - 'colorcompensationfilter' => { 174 => [0x3a,0x5f], 176 => 0x111, 388 => 0xb022 }, - 'colorcompensationfiltercustom' => { 376 => 0xd, 377 => 0xc }, - 'colorcompensationfilterset' => { 376 => 0x8, 377 => 0x7, 378 => 0x18, 393 => 0xf }, - 'colorcontrol' => { 279 => 0x102b }, - 'colorcorrection' => { 421 => 0x8015 }, - 'colorcreatoreffect' => { 274 => 0x532 }, - 'colordataversion' => { 41 => 0x0, 42 => 0x0, 43 => 0x0, 44 => 0x0, 45 => 0x0, 46 => 0x0, 47 => 0x0 }, - 'coloreffect' => { 297 => 0x28 }, - 'colorfilter' => { 106 => 0x17, 107 => 0x3017, 171 => 0x29, 179 => [0x38,0x4d,0x4f], 339 => 0x17 }, - 'colorgain' => { 218 => 0x51 }, - 'colorhue' => { 97 => 0x20900, 211 => 0x8d }, - 'colorimetricreference' => { 113 => 0xc6bf }, - 'colorlabel' => { 445 => 'ColorLabel' }, - 'colormatrix' => { 278 => 0x200, 279 => 0x1011, 365 => 0xa030 }, - 'colormatrix1' => { 113 => 0xc621, 341 => 0x106 }, - 'colormatrix2' => { 113 => 0xc622, 282 => 0x200, 341 => 0x226 }, - 'colormatrixa' => { 332 => 0x203 }, - 'colormatrixadobergb' => { 365 => 0xa032 }, - 'colormatrixb' => { 332 => 0x204 }, - 'colormatrixnumber' => { 279 => 0x1019 }, - 'colormatrixsrgb' => { 365 => 0xa031 }, - 'colormode' => { 107 => 0x3015, 121 => 0x1210, 133 => 0x66, 171 => 0x28, 174 => 0x16, 176 => 0x101, 177 => 0x36, 179 => 0x7, 211 => 0x3, 240 => 0x4, 297 => 0x32, 368 => 0x2c, 388 => 0xb029, 454 => 'ColorMode' }, - 'colormoirereduction' => { 97 => 0x20670, 251 => 0x15 }, - 'colormoirereductionmode' => { 251 => 0x5 }, - 'colormoirereductionon' => { 97 => '0x20670.0' }, - 'colornoisereduction' => { 421 => 0x8029, 442 => 'ColorNoiseReduction' }, - 'colornoisereductiondetail' => { 442 => 'ColorNoiseReductionDetail' }, - 'colornoisereductionintensity' => { 251 => 0x18 }, - 'colornoisereductionsharpness' => { 251 => 0x1c }, - 'colornoisereductionsmoothness' => { 442 => 'ColorNoiseReductionSmoothness' }, - 'colorplanes' => { 117 => 0x2 }, - 'colorprofile' => { 171 => 0x33 }, - 'colorprofilesettings' => { 274 => 0x539 }, - 'colorrepresentation' => { 127 => 0x3c }, - 'colorsaturationadj' => { 97 => 0x20305 }, - 'colorsequence' => { 127 => 0x41 }, - 'colorspace' => { 48 => 0x3, 60 => 0xb4, 91 => 0x10b4, 113 => 0xa001, 153 => 'ColorSpace', 172 => 0x2f, 173 => 0x25, 174 => 0x17, 211 => 0x1e, 274 => 0x507, 332 => 0x37, 365 => 0xa011, 368 => 0xb, 376 => 0x1b, 377 => 0x83, 378 => 0xe, 393 => 0x6, 446 => 'ColorSpace' }, - 'colortempasshot' => { 37 => 0x4, 38 => 0x7, 39 => 0x1d, 40 => 0x26, 41 => 0x43, 44 => 0x43, 45 => 0x43, 46 => 0x43, 47 => 0x4b }, - 'colortempauto' => { 37 => 0x9, 38 => 0xf, 39 => 0x22, 40 => 0x1c, 41 => 0x48, 44 => 0x48, 45 => 0x48, 46 => 0x48, 47 => 0x50 }, - 'colortempcloudy' => { 37 => 0x22, 38 => 0x37, 39 => 0x31, 40 => 0x35, 41 => 0x5c, 44 => 0x75, 45 => 0x8e, 46 => 0x93, 47 => 0x96, 332 => 0x55 }, - 'colortempcustom' => { 41 => 0x84 }, - 'colortempcustom1' => { 39 => 0x45 }, - 'colortempcustom2' => { 39 => 0x4a }, - 'colortempdaylight' => { 37 => 0x18, 38 => 0x27, 39 => 0x27, 40 => 0x2b, 41 => 0x52, 44 => 0x6b, 45 => 0x84, 46 => 0x89, 47 => 0x8c, 332 => 0x53 }, - 'colortemperature' => { 6 => 0x73, 7 => [0x48,0x4e], 8 => 0xc0, 9 => 0x37, 10 => 0x62, 11 => 0x37, 12 => 0x7c, 13 => 0x73, 14 => 0x73, 15 => 0x77, 16 => 0x73, 17 => 0x7c, 18 => 0x58, 19 => 0x73, 20 => 0xc0, 21 => 0x7f, 22 => 0x7d, 23 => 0xc0, 24 => 0xc6, 25 => 0xc7, 26 => 0x135, 27 => 0x7b, 28 => 0x13a, 60 => 0xae, 70 => 0x9, 91 => 0x10ae, 121 => 0x1005, 131 => 0x846, 147 => 'ColorTemperature', 172 => [0x6e,0x49], 173 => 0x3f, 174 => [0x39,0x5e], 176 => 0x10b, 179 => [0x3c,0x4c,0x4e], 292 => 0x321, 332 => 0x50, 358 => 0x1308, 388 => 0xb021, 442 => 'Temperature' }, - 'colortemperatureadj' => { 421 => 0x8013 }, - 'colortemperatureauto' => { 211 => 0x4f }, - 'colortemperaturebg' => { 279 => 0x1013 }, - 'colortemperaturecustom' => { 376 => 0xc, 377 => 0xb }, - 'colortemperaturerg' => { 279 => 0x1014 }, - 'colortemperatureset' => { 376 => 0x7, 377 => 0x6 }, - 'colortemperaturesetting' => { 174 => 0x25, 378 => 0x17, 393 => 0xe }, - 'colortempflash' => { 37 => 0x36, 38 => 0x57, 39 => 0x40, 40 => 0x49, 41 => 0x70, 44 => 0x89, 45 => 0xa2, 46 => 0xa7, 47 => 0xaa, 332 => 0x5a }, - 'colortempflashdata' => { 41 => 0x24a }, - 'colortempfluorescent' => { 37 => 0x2c, 38 => 0x47, 39 => 0x3b, 40 => 0x3f, 41 => 0x66, 44 => 0x7f, 45 => 0x98, 46 => 0x9d, 47 => 0xa0 }, - 'colortempfluorescentd' => { 332 => 0x57 }, - 'colortempfluorescentn' => { 332 => 0x58 }, - 'colortempfluorescentw' => { 332 => 0x59 }, - 'colortempkelvin' => { 37 => 0x31, 38 => 0x4f, 40 => 0x44, 41 => 0x6b, 44 => 0x84, 45 => 0x9d, 46 => 0xa2, 47 => 0xa5, 297 => 0x44, 358 => 0x1307 }, - 'colortempmeasured' => { 37 => 0xe, 38 => 0x17, 41 => 0x4d, 44 => 0x4d, 45 => 0x4d, 46 => 0x4d, 47 => 0x55 }, - 'colortemppc1' => { 40 => 0x94, 41 => 0x75 }, - 'colortemppc2' => { 40 => 0x99, 41 => 0x7a }, - 'colortemppc3' => { 40 => 0x9e, 41 => 0x7f }, - 'colortempshade' => { 37 => 0x1d, 38 => 0x2f, 39 => 0x2c, 40 => 0x30, 41 => 0x57, 44 => 0x70, 45 => 0x89, 46 => 0x8e, 47 => 0x91, 332 => 0x54 }, - 'colortemptungsten' => { 37 => 0x27, 38 => 0x3f, 39 => 0x36, 40 => 0x3a, 41 => 0x61, 44 => 0x7a, 45 => 0x93, 46 => 0x98, 47 => 0x9b, 332 => 0x56 }, - 'colortempunknown' => { 37 => 0x13, 38 => 0x1f, 40 => 0x21, 44 => 0x52, 45 => 0x52, 46 => 0x52, 47 => 0x5a }, - 'colortempunknown10' => { 37 => 0x63, 38 => 0x9f, 40 => 0x76, 44 => 0xa2, 45 => 0x7f, 46 => 0x7f, 47 => 0x87 }, - 'colortempunknown11' => { 37 => 0x68, 38 => 0xa7, 40 => 0x7b, 44 => 0xa7, 45 => 0xa7, 46 => 0x84, 47 => 0xaf }, - 'colortempunknown12' => { 37 => 0x6d, 38 => 0xaf, 40 => 0x80, 44 => 0xac, 45 => 0xac, 46 => 0xac, 47 => 0xb4 }, - 'colortempunknown13' => { 37 => 0x72, 38 => 0xb7, 40 => 0x85, 44 => 0xb1, 45 => 0xb1, 46 => 0xb1, 47 => 0xb9 }, - 'colortempunknown14' => { 40 => 0x8a, 44 => 0xb6, 45 => 0xb6, 46 => 0xb6, 47 => 0xbe }, - 'colortempunknown15' => { 40 => 0x8f, 44 => 0xbb, 45 => 0xbb, 46 => 0xbb, 47 => 0xc3 }, - 'colortempunknown16' => { 40 => 0xa3, 45 => 0xc0, 46 => 0xc0, 47 => 0xc8 }, - 'colortempunknown17' => { 45 => 0xc5, 46 => 0xc5, 47 => 0xcd }, - 'colortempunknown18' => { 45 => 0xca, 46 => 0xca, 47 => 0xd2 }, - 'colortempunknown19' => { 45 => 0xcf, 46 => 0xcf, 47 => 0xd7 }, - 'colortempunknown2' => { 37 => 0x3b, 38 => 0x5f, 40 => 0x4e, 44 => 0x57, 45 => 0x57, 46 => 0x57, 47 => 0x5f }, - 'colortempunknown20' => { 45 => 0xd4, 46 => 0xd4, 47 => 0xdc }, - 'colortempunknown21' => { 46 => 0xd9, 47 => 0xe1 }, - 'colortempunknown22' => { 46 => 0xde, 47 => 0xe6 }, - 'colortempunknown23' => { 46 => 0xe3, 47 => 0xeb }, - 'colortempunknown24' => { 46 => 0xe8, 47 => 0xf0 }, - 'colortempunknown25' => { 46 => 0xed, 47 => 0xf5 }, - 'colortempunknown26' => { 46 => 0xf2, 47 => 0xfa }, - 'colortempunknown27' => { 46 => 0xf7, 47 => 0xff }, - 'colortempunknown28' => { 46 => 0xfc, 47 => 0x104 }, - 'colortempunknown29' => { 46 => 0x101, 47 => 0x109 }, - 'colortempunknown3' => { 37 => 0x40, 38 => 0x67, 40 => 0x53, 44 => 0x5c, 45 => 0x5c, 46 => 0x5c, 47 => 0x64 }, - 'colortempunknown30' => { 46 => 0x106 }, - 'colortempunknown4' => { 37 => 0x45, 38 => 0x6f, 40 => 0x58, 44 => 0x61, 45 => 0x61, 46 => 0x61, 47 => 0x69 }, - 'colortempunknown5' => { 37 => 0x4a, 38 => 0x77, 40 => 0x5d, 44 => 0x66, 45 => 0x66, 46 => 0x66, 47 => 0x6e }, - 'colortempunknown6' => { 37 => 0x4f, 38 => 0x7f, 40 => 0x62, 44 => 0x8e, 45 => 0x6b, 46 => 0x6b, 47 => 0x73 }, - 'colortempunknown7' => { 37 => 0x54, 38 => 0x87, 40 => 0x67, 44 => 0x93, 45 => 0x70, 46 => 0x70, 47 => 0x78 }, - 'colortempunknown8' => { 37 => 0x59, 38 => 0x8f, 40 => 0x6c, 44 => 0x98, 45 => 0x75, 46 => 0x75, 47 => 0x7d }, - 'colortempunknown9' => { 37 => 0x5e, 38 => 0x97, 40 => 0x71, 44 => 0x9d, 45 => 0x7a, 46 => 0x7a, 47 => 0x82 }, - 'colortone' => { 9 => 0x6f, 11 => 0x77, 33 => 0x2a, 48 => 0x2 }, - 'colortoneadj' => { 97 => 0x20304, 102 => 0x11e }, - 'colortoneauto' => { 67 => 0x9c }, - 'colortonefaithful' => { 18 => 0x107, 66 => 0x6c, 67 => 0x6c }, - 'colortonelandscape' => { 18 => 0x105, 66 => 0x3c, 67 => 0x3c }, - 'colortonemonochrome' => { 66 => 0x84, 67 => 0x84 }, - 'colortoneneutral' => { 18 => 0x106, 66 => 0x54, 67 => 0x54 }, - 'colortoneportrait' => { 18 => 0x104, 66 => 0x24, 67 => 0x24 }, - 'colortonestandard' => { 18 => 0x103, 66 => 0xc, 67 => 0xc }, - 'colortoneuserdef1' => { 18 => 0x109, 66 => 0x9c, 67 => 0xb4 }, - 'colortoneuserdef2' => { 18 => 0x10a, 66 => 0xb4, 67 => 0xcc }, - 'colortoneuserdef3' => { 18 => 0x10b, 66 => 0xcc, 67 => 0xe4 }, - 'comlenblksize' => { 131 => 0xfde8 }, - 'commanddials' => { 268 => '5.1' }, - 'commanddialsaperturesetting' => { 257 => '17.3', 258 => '18.3', 260 => '18.3', 261 => '18.3', 266 => '33.3', 267 => '17.3', 270 => '18.3', 271 => '18.3' }, - 'commanddialschangemainsub' => { 257 => '17.2', 258 => '18.1', 260 => '18.1', 261 => '18.1', 266 => '33.2', 267 => '17.2', 270 => '18.1', 271 => '18.1' }, - 'commanddialsmenuandplayback' => { 257 => '17.4', 258 => '18.2', 260 => '18.2', 261 => '18.2', 266 => '33.4', 267 => '17.4', 270 => '18.2', 271 => '18.2' }, - 'commanddialsreverserotation' => { 257 => '17.1', 258 => '6.4', 260 => '6.2', 261 => '6.2', 262 => '16.2', 263 => '17.2', 266 => '33.1', 267 => '17.1', 270 => '6.2', 271 => '6.2', 272 => '18.1' }, - 'commanderchannel' => { 268 => '10.2', 269 => '25.2' }, - 'commandergroupa_ttl-aacomp' => { 268 => '13.1', 269 => '31.1' }, - 'commandergroupa_ttlcomp' => { 272 => '32.1' }, - 'commandergroupamanualoutput' => { 268 => '13.2', 269 => '28.2' }, - 'commandergroupamode' => { 268 => '11.2', 269 => '28.1' }, - 'commandergroupb_ttl-aacomp' => { 268 => '14.1', 269 => '32.1' }, - 'commandergroupb_ttlcomp' => { 272 => '33.1' }, - 'commandergroupbmanualoutput' => { 268 => '14.2', 269 => '29.2' }, - 'commandergroupbmode' => { 268 => '11.3', 269 => '29.1' }, - 'commanderinternalflash' => { 268 => '11.1', 269 => '27.1' }, - 'commanderinternalmanualoutput' => { 268 => '12.2', 269 => '27.2' }, - 'commanderinternalttlchannel' => { 266 => '18.2' }, - 'commanderinternalttlcomp' => { 268 => '12.1', 269 => '30.2', 272 => '31.2' }, - 'commanderinternalttlcompbuiltin' => { 266 => '20.1', 267 => '26.1' }, - 'commanderinternalttlcompgroupa' => { 266 => '21.1', 267 => '27.1' }, - 'commanderinternalttlcompgroupb' => { 266 => '22.1', 267 => '28.1' }, - 'comment' => { 0 => 0x2, 114 => 'Comment', 148 => 'Comment', 287 => 'Comment' }, - 'compass' => { 361 => 0x4 }, - 'complianceprofile' => { 456 => 'complianceProfile' }, - 'componentsconfiguration' => { 113 => 0x9101, 153 => 'Components', 446 => 'ComponentsConfiguration' }, - 'componentversion' => { 91 => 0x80c }, - 'composer' => { 466 => 'composer' }, - 'composition' => { 431 => 'Composition' }, - 'compositionadjust' => { 331 => '0.1' }, - 'compositionadjustrotation' => { 331 => 0x7 }, - 'compositionadjustx' => { 331 => 0x5 }, - 'compositionadjusty' => { 331 => 0x6 }, - 'compressedbitsperpixel' => { 113 => 0x9102, 446 => 'CompressedBitsPerPixel' }, - 'compressedimagesize' => { 176 => 0x40, 279 => 0x40 }, - 'compression' => { 113 => 0x103, 302 => 0xb, 462 => 'Compression' }, - 'compressionfactor' => { 274 => 0x50d }, - 'compressionratio' => { 153 => 'Compression', 279 => 0x1034 }, - 'condadobvfactor' => { 131 => 0xf3e }, - 'condadodaybvthresh' => { 131 => 0xf3c }, - 'condadodayoffsets' => { 131 => 0xf42 }, - 'condadofluoffsets' => { 131 => 0xf44 }, - 'condadofluthresh' => { 131 => 0xf41 }, - 'condadoillfactor' => { 131 => 0xf3f }, - 'condadoneurange' => { 131 => 0xf3d }, - 'condadotunoffsets' => { 131 => 0xf43 }, - 'condadotunthresh' => { 131 => 0xf40 }, - 'confidence' => { 426 => 'Confidence' }, - 'confidencelevel' => { 437 => 'ConfidenceLevel' }, - 'confidencemime' => { 426 => 'ConfidenceMime' }, - 'constrainedcropheight' => { 102 => 0x266, 343 => 0xd6 }, - 'constrainedcropwidth' => { 102 => 0x262, 343 => 0xd5 }, - 'contact' => { 125 => 0x76 }, - 'contactinfo' => { 455 => 'contactInfo' }, - 'containerformat' => { 452 => 'ContainerFormat' }, - 'containerformatidentifier' => { 452 => [\'ContainerFormat','ContainerFormatIdentifier'] }, - 'containerformatname' => { 452 => [\'ContainerFormat','ContainerFormatName'] }, + 'buttonfunctioncontroloff' => { 81 => 0x70a }, + 'bwadjustment' => { 124 => 0x1049 }, + 'bwfilter' => { 176 => 0x2a, 184 => 0x39 }, + 'bwmode' => { 288 => 0x203 }, + 'by-line' => { 128 => 0x50 }, + 'by-linetitle' => { 128 => 0x55 }, + 'bytecount' => { 478 => 'byteCount' }, + 'c14configuration' => { 134 => 0x1964 }, + 'cacheversion' => { 116 => 0xc7aa }, + 'calibratedfocallength' => { 113 => 'CalibratedFocalLength' }, + 'calibratedopticalcenterx' => { 113 => 'CalibratedOpticalCenterX' }, + 'calibratedopticalcentery' => { 113 => 'CalibratedOpticalCenterY' }, + 'calibration' => { 383 => [0x24,0x30] }, + 'calibrationhistory' => { 134 => 0x9c9 }, + 'calibrationilluminant1' => { 116 => 0xc65a }, + 'calibrationilluminant2' => { 116 => 0xc65b }, + 'calibrationversion' => { 134 => 0x9c6 }, + 'callforimage' => { 452 => 'CallForImage' }, + 'camera' => { 442 => [\'Cameras','CamerasCamera'] }, + 'cameraangle' => { 366 => 'angl', 488 => 'cameraAngle' }, + 'cameraappinfo' => { 442 => [\'Cameras','CamerasCameraAppInfo'] }, + 'cameraappinfoapplication' => { 442 => [\'Cameras','CamerasCameraAppInfoApplication'] }, + 'cameraappinfoitemuri' => { 442 => [\'Cameras','CamerasCameraAppInfoItemURI'] }, + 'cameraappinfoversion' => { 442 => [\'Cameras','CamerasCameraAppInfoVersion'] }, + 'cameraburstid' => { 446 => 'CameraBurstID' }, + 'cameracalibration' => { 383 => 0x11f }, + 'cameracalibration1' => { 116 => 0xc623 }, + 'cameracalibration2' => { 116 => 0xc624 }, + 'cameracalibrationsig' => { 116 => 0xc6f3 }, + 'cameracolorcalibration01' => { 36 => 0x0, 37 => 0x0 }, + 'cameracolorcalibration02' => { 36 => 0x4, 37 => 0x5 }, + 'cameracolorcalibration03' => { 36 => 0x8, 37 => 0xa }, + 'cameracolorcalibration04' => { 36 => 0xc, 37 => 0xf }, + 'cameracolorcalibration05' => { 36 => 0x10, 37 => 0x14 }, + 'cameracolorcalibration06' => { 36 => 0x14, 37 => 0x19 }, + 'cameracolorcalibration07' => { 36 => 0x18, 37 => 0x1e }, + 'cameracolorcalibration08' => { 36 => 0x1c, 37 => 0x23 }, + 'cameracolorcalibration09' => { 36 => 0x20, 37 => 0x28 }, + 'cameracolorcalibration10' => { 36 => 0x24, 37 => 0x2d }, + 'cameracolorcalibration11' => { 36 => 0x28, 37 => 0x32 }, + 'cameracolorcalibration12' => { 36 => 0x2c, 37 => 0x37 }, + 'cameracolorcalibration13' => { 36 => 0x30, 37 => 0x3c }, + 'cameracolorcalibration14' => { 36 => 0x34, 37 => 0x41 }, + 'cameracolorcalibration15' => { 36 => 0x38, 37 => 0x46 }, + 'cameradepthmap' => { 442 => [\'Cameras','CamerasCameraDepthMap'] }, + 'cameradepthmapconfidenceuri' => { 442 => [\'Cameras','CamerasCameraDepthMapConfidenceURI'] }, + 'cameradepthmapdepthuri' => { 442 => [\'Cameras','CamerasCameraDepthMapDepthURI'] }, + 'cameradepthmapfar' => { 442 => [\'Cameras','CamerasCameraDepthMapFar'] }, + 'cameradepthmapfocaltable' => { 442 => [\'Cameras','CamerasCameraDepthMapFocalTable'] }, + 'cameradepthmapfocaltableentrycount' => { 442 => [\'Cameras','CamerasCameraDepthMapFocalTableEntryCount'] }, + 'cameradepthmapformat' => { 442 => [\'Cameras','CamerasCameraDepthMapFormat'] }, + 'cameradepthmapitemsemantic' => { 442 => [\'Cameras','CamerasCameraDepthMapItemSemantic'] }, + 'cameradepthmapmeasuretype' => { 442 => [\'Cameras','CamerasCameraDepthMapMeasureType'] }, + 'cameradepthmapnear' => { 442 => [\'Cameras','CamerasCameraDepthMapNear'] }, + 'cameradepthmapsoftware' => { 442 => [\'Cameras','CamerasCameraDepthMapSoftware'] }, + 'cameradepthmapunits' => { 442 => [\'Cameras','CamerasCameraDepthMapUnits'] }, + 'cameradirection' => { 360 => 'direction.facing' }, + 'camerae-mountversion' => { 438 => 0xb }, + 'cameraelevationangle' => { 116 => 0x9405, 469 => 'CameraElevationAngle' }, + 'camerafilename' => { 452 => 'CameraFilename' }, + 'cameraid' => { 288 => 0x209, 366 => 'cmid', 382 => 0x209 }, + 'cameraidentifier' => { 360 => 'camera.identifier' }, + 'cameraimage' => { 442 => [\'Cameras','CamerasCameraImage'] }, + 'cameraimageitemsemantic' => { 442 => [\'Cameras','CamerasCameraImageItemSemantic'] }, + 'cameraimageitemuri' => { 442 => [\'Cameras','CamerasCameraImageItemURI'] }, + 'cameraimagingmodel' => { 442 => [\'Cameras','CamerasCameraImagingModel'] }, + 'cameraimagingmodeldistortion' => { 442 => [\'Cameras','CamerasCameraImagingModelDistortion'] }, + 'cameraimagingmodeldistortioncount' => { 442 => [\'Cameras','CamerasCameraImagingModelDistortionCount'] }, + 'cameraimagingmodelfocallengthx' => { 442 => [\'Cameras','CamerasCameraImagingModelFocalLengthX'] }, + 'cameraimagingmodelfocallengthy' => { 442 => [\'Cameras','CamerasCameraImagingModelFocalLengthY'] }, + 'cameraimagingmodelimageheight' => { 442 => [\'Cameras','CamerasCameraImagingModelImageHeight'] }, + 'cameraimagingmodelimagewidth' => { 442 => [\'Cameras','CamerasCameraImagingModelImageWidth'] }, + 'cameraimagingmodelpixelaspectratio' => { 442 => [\'Cameras','CamerasCameraImagingModelPixelAspectRatio'] }, + 'cameraimagingmodelprincipalpointx' => { 442 => [\'Cameras','CamerasCameraImagingModelPrincipalPointX'] }, + 'cameraimagingmodelprincipalpointy' => { 442 => [\'Cameras','CamerasCameraImagingModelPrincipalPointY'] }, + 'cameraimagingmodelskew' => { 442 => [\'Cameras','CamerasCameraImagingModelSkew'] }, + 'cameraiso' => { 34 => 0x10 }, + 'cameralabel' => { 116 => 0xc7a1, 488 => 'cameraLabel' }, + 'cameralightestimate' => { 442 => [\'Cameras','CamerasCameraLightEstimate'] }, + 'cameralightestimatecolorcorrectionb' => { 442 => [\'Cameras','CamerasCameraLightEstimateColorCorrectionB'] }, + 'cameralightestimatecolorcorrectiong' => { 442 => [\'Cameras','CamerasCameraLightEstimateColorCorrectionG'] }, + 'cameralightestimatecolorcorrectionr' => { 442 => [\'Cameras','CamerasCameraLightEstimateColorCorrectionR'] }, + 'cameralightestimatepixelintensity' => { 442 => [\'Cameras','CamerasCameraLightEstimatePixelIntensity'] }, + 'cameramakemodel' => { 452 => 'CameraMakeModel' }, + 'cameramodel' => { 350 => 0x410, 488 => 'cameraModel' }, + 'cameramodelid' => { 172 => 'CameraModelID' }, + 'cameramotion' => { 360 => 'direction.motion' }, + 'cameramove' => { 488 => 'cameraMove' }, + 'cameraorientation' => { 7 => 0x30, 9 => 0x7d, 11 => 0x30, 13 => 0x35, 14 => 0x30, 15 => 0x30, 16 => 0x31, 17 => 0x31, 18 => 0x35, 19 => 0x27, 20 => 0x31, 21 => 0x7d, 22 => 0x38, 23 => 0x36, 24 => 0x7d, 25 => 0x83, 26 => 0x84, 28 => 0x35, 29 => 0x96, 306 => 0x8f, 345 => 0x1, 350 => 0x100, 399 => [0x16,0x18], 426 => 0x28, 427 => 0x24, 428 => 0x29 }, + 'cameraowner' => { 137 => 0xc353 }, + 'cameraparameters' => { 288 => 0x2050 }, + 'camerapicturestyle' => { 28 => 0xaf }, + 'camerapitch' => { 112 => 0x9, 366 => "\xa9gpt" }, + 'camerapointcloud' => { 442 => [\'Cameras','CamerasCameraPointCloud'] }, + 'camerapointcloudmetric' => { 442 => [\'Cameras','CamerasCameraPointCloudMetric'] }, + 'camerapointcloudpointcloud' => { 442 => [\'Cameras','CamerasCameraPointCloudPointCloud'] }, + 'camerapointcloudpoints' => { 442 => [\'Cameras','CamerasCameraPointCloudPoints'] }, + 'camerapose' => { 442 => [\'Cameras','CamerasCameraPose'] }, + 'cameraposepositionx' => { 442 => [\'Cameras','CamerasCameraPosePositionX'] }, + 'cameraposepositiony' => { 442 => [\'Cameras','CamerasCameraPosePositionY'] }, + 'cameraposepositionz' => { 442 => [\'Cameras','CamerasCameraPosePositionZ'] }, + 'cameraposerotationw' => { 442 => [\'Cameras','CamerasCameraPoseRotationW'] }, + 'cameraposerotationx' => { 442 => [\'Cameras','CamerasCameraPoseRotationX'] }, + 'cameraposerotationy' => { 442 => [\'Cameras','CamerasCameraPoseRotationY'] }, + 'cameraposerotationz' => { 442 => [\'Cameras','CamerasCameraPoseRotationZ'] }, + 'cameraposetimestamp' => { 442 => [\'Cameras','CamerasCameraPoseTimestamp'] }, + 'cameraprofile' => { 462 => 'CameraProfile', 464 => 'CameraProfile' }, + 'cameraprofiledigest' => { 462 => 'CameraProfileDigest', 464 => 'CameraProfileDigest' }, + 'camerarawcolortone' => { 106 => 0xe1 }, + 'camerarawcontrast' => { 106 => 0xe3 }, + 'camerarawhighlightpoint' => { 106 => 0xe6 }, + 'camerarawlinear' => { 106 => 0xe4 }, + 'camerarawoutputhighlightpoint' => { 106 => 0xe8 }, + 'camerarawoutputshadowpoint' => { 106 => 0xe9 }, + 'camerarawsaturation' => { 106 => 0xe2 }, + 'camerarawshadowpoint' => { 106 => 0xe7 }, + 'camerarawsharpness' => { 106 => 0xe5 }, + 'cameraroll' => { 112 => 0xb, 366 => "\xa9grl" }, + 'cameras' => { 442 => 'Cameras' }, + 'cameraserialnumber' => { 116 => 0xc62f, 174 => 'CameraSerialNumber', 452 => 'CameraSerialNumber' }, + 'camerasettingsversion' => { 283 => 0x0 }, + 'cameratemperature' => { 7 => 0x18, 9 => 0x1b, 11 => 0x18, 13 => 0x19, 14 => 0x18, 15 => 0x18, 16 => 0x19, 17 => 0x19, 18 => 0x19, 19 => 0x17, 20 => 0x19, 21 => 0x1b, 22 => 0x19, 23 => 0x19, 24 => 0x1b, 25 => 0x1b, 26 => 0x1b, 27 => 0x1b, 28 => 0x19, 29 => 0x1b, 30 => [0x87,0x91], 31 => [0x99,0x9f,0xa4,0xa8,0x105], 33 => ['-3',0x64,0x47,0x53,0x5b,0x5c], 74 => 0xc, 134 => 0x406, 287 => 0x1306, 301 => 0x320, 308 => 0x3402, 341 => 0x47, 380 => 0x43, 430 => 0x5 }, + 'cameratemperature4' => { 346 => 0x14 }, + 'cameratemperature5' => { 346 => 0x16 }, + 'cameratemperaturerangemax' => { 118 => 0x5 }, + 'cameratemperaturerangemin' => { 118 => 0x6 }, + 'cameratrait' => { 442 => [\'Cameras','CamerasCameraTrait'] }, + 'cameratype' => { 74 => 0x1a, 288 => 0x207 }, + 'cameratype2' => { 284 => 0x100 }, + 'cameravendorinfo' => { 442 => [\'Cameras','CamerasCameraVendorInfo'] }, + 'cameravendorinfomanufacturer' => { 442 => [\'Cameras','CamerasCameraVendorInfoManufacturer'] }, + 'cameravendorinfomodel' => { 442 => [\'Cameras','CamerasCameraVendorInfoModel'] }, + 'cameravendorinfonotes' => { 442 => [\'Cameras','CamerasCameraVendorInfoNotes'] }, + 'camerayaw' => { 112 => 0xa, 366 => "\xa9gyw" }, + 'camreverse' => { 113 => 'CamReverse' }, + 'canondr4' => { 117 => 'CanonDR4' }, + 'canonexposuremode' => { 34 => 0x14 }, + 'canonfiledescription' => { 94 => 0x805 }, + 'canonfilelength' => { 61 => 0xe }, + 'canonfirmwareversion' => { 61 => 0x7, 94 => 0x80b }, + 'canonflashinfo' => { 94 => 0x1028 }, + 'canonflashmode' => { 34 => 0x4 }, + 'canonimagesize' => { 10 => 0x39, 34 => 0xa }, + 'canonimagetype' => { 61 => 0x6, 94 => 0x815 }, + 'canonmodelid' => { 61 => 0x10, 94 => 0x1834 }, + 'canonvrd' => { 117 => 'CanonVRD' }, + 'caption' => { 457 => 'caption' }, + 'caption-abstract' => { 128 => 0x78 }, + 'captionsauthornames' => { 467 => 'CaptionsAuthorNames' }, + 'captionsdatetimestamps' => { 467 => 'CaptionsDateTimeStamps' }, + 'captionwriter' => { 476 => 'CaptionWriter' }, + 'captureframerate' => { 110 => 0x4001 }, + 'captureheightnormal' => { 134 => 0x1839 }, + 'capturelook' => { 134 => 0xc48 }, + 'capturemode' => { 360 => 'com.apple.photos.captureMode' }, + 'capturesoftware' => { 450 => 'CaptureSoftware' }, + 'capturewidthnormal' => { 134 => 0x1838 }, + 'capturewidthtest' => { 134 => 0x1842 }, + 'cardshutterlock' => { 179 => 0x49 }, + 'casioimagesize' => { 110 => 0x9 }, + 'catalogsets' => { 128 => 0xff, 443 => 'CatalogSets', 455 => 'CatalogSets' }, + 'categories' => { 61 => 0x23, 457 => 'categories' }, + 'category' => { 128 => 0xf, 282 => 0x30, 358 => 'catg', 476 => 'Category' }, + 'cbcrgain' => { 380 => 0xa036 }, + 'cbcrgaindefault' => { 380 => 0xa035 }, + 'cbcrmatrix' => { 380 => 0xa034 }, + 'cbcrmatrixdefault' => { 380 => 0xa033 }, + 'ccdboardversion' => { 301 => 0x331 }, + 'ccdscanmode' => { 288 => 0x1039 }, + 'ccdsensitivity' => { 249 => 0x6 }, + 'ccdversion' => { 301 => 0x330 }, + 'cellglobalid' => { 461 => 'cgi' }, + 'celllength' => { 116 => 0x109 }, + 'cellr' => { 461 => 'r' }, + 'celltowerid' => { 461 => 'cellid' }, + 'cellwidth' => { 116 => 0x108 }, + 'centerafarea' => { 277 => '15.1' }, + 'centerfocuspoint' => { 281 => '2.2' }, + 'centerpixel' => { 134 => 0x40c }, + 'centerweightedareasize' => { 266 => '7.1', 267 => '8.1', 269 => '8.1', 270 => '8.1', 274 => '7.1', 275 => '5.1', 276 => '7.1', 277 => '6.3', 279 => '8.1', 280 => '8.1', 281 => '8.1' }, + 'certificate' => { 492 => 'Certificate' }, + 'cfainterpolationalgorithm' => { 134 => 0xe60 }, + 'cfainterpolationmetric' => { 134 => 0xe61 }, + 'cfaoffsetcols' => { 134 => 0xc71 }, + 'cfaoffsetrows' => { 134 => 0xc6f }, + 'cfapattern' => { 116 => 0xa302, 311 => 0x9, 468 => 'CFAPattern' }, + 'cfapattern2' => { 116 => 0x828e }, + 'cfapatterncolumns' => { 468 => [\'CFAPattern','CFAPatternColumns'] }, + 'cfapatternrows' => { 468 => [\'CFAPattern','CFAPatternRows'] }, + 'cfapatternvalues' => { 468 => [\'CFAPattern','CFAPatternValues'] }, + 'cfarepeatpatterndim' => { 116 => 0x828d }, + 'cfazipperfixthreshold' => { 134 => 0xe62 }, + 'channel' => { 478 => 'channel' }, + 'channela-lang' => { 478 => [\'channel','channelA-lang'] }, + 'channelchannel' => { 478 => [\'channel','channelChannel'] }, + 'channels' => { 151 => 'Channels' }, + 'channelsubchannel1' => { 478 => [\'channel','channelSubchannel1'] }, + 'channelsubchannel2' => { 478 => [\'channel','channelSubchannel2'] }, + 'channelsubchannel3' => { 478 => [\'channel','channelSubchannel3'] }, + 'channelsubchannel4' => { 478 => [\'channel','channelSubchannel4'] }, + 'chapterlist' => { 366 => 'chpl' }, + 'checkmark' => { 100 => 0x10101, 105 => 0x26a }, + 'checkmark2' => { 106 => 0x8e }, + 'childfontfiles' => { 493 => [\'Fonts','FontsChildFontFiles'] }, + 'chmodeshootingspeed' => { 266 => '10.3', 267 => '11.2' }, + 'chromablurradius' => { 116 => 0xc631 }, + 'chromanoisecolorspace' => { 134 => 0xe6d }, + 'chromanoiseedgemapthresh' => { 134 => 0xe6c }, + 'chromanoisehighfthresh' => { 134 => 0xe6a }, + 'chromanoiselowfthresh' => { 134 => 0xe6b }, + 'chromaticaberration' => { 100 => 0x20703, 106 => 0x66, 380 => 0xa051 }, + 'chromaticaberrationb' => { 462 => 'ChromaticAberrationB', 464 => 'ChromaticAberrationB' }, + 'chromaticaberrationblue' => { 100 => 0x20708, 106 => 0x6b }, + 'chromaticaberrationcorr' => { 76 => [0x4,0x5] }, + 'chromaticaberrationcorrection' => { 116 => 0x7034, 331 => 0x1, 439 => 0x900d }, + 'chromaticaberrationcorrparams' => { 116 => 0x7035, 434 => 0x66a, 435 => [0x37c,0x384,0x39c,0x3b0,0x3b8] }, + 'chromaticaberrationon' => { 100 => '0x20703.0', 106 => 0x62 }, + 'chromaticaberrationr' => { 462 => 'ChromaticAberrationR', 464 => 'ChromaticAberrationR' }, + 'chromaticaberrationred' => { 100 => 0x20707, 106 => 0x6a }, + 'chromaticaberrationsetting' => { 77 => 0x6 }, + 'chrominancenoisereduction' => { 100 => 0x20601, 106 => 0x5e, 383 => 0x1a }, + 'chrominancenr_tiff_jpeg' => { 106 => 0x60 }, + 'circadatecreated' => { 474 => 'CircaDateCreated' }, + 'circgradbasedcorractive' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionActive'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionActive'] }, + 'circgradbasedcorramount' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionAmount'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionAmount'] }, + 'circgradbasedcorrbrightness' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBrightness'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBrightness'] }, + 'circgradbasedcorrclarity' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity'] }, + 'circgradbasedcorrclarity2012' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity2012'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity2012'] }, + 'circgradbasedcorrcontrast' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast'] }, + 'circgradbasedcorrcontrast2012' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast2012'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast2012'] }, + 'circgradbasedcorrdefringe' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDefringe'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDefringe'] }, + 'circgradbasedcorrexposure' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure'] }, + 'circgradbasedcorrexposure2012' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure2012'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure2012'] }, + 'circgradbasedcorrhighlights2012' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHighlights2012'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHighlights2012'] }, + 'circgradbasedcorrhue' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalToningHue'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalToningHue'] }, + 'circgradbasedcorrluminancenoise' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalLuminanceNoise'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalLuminanceNoise'] }, + 'circgradbasedcorrmaskalpha' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAlpha'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAlpha'] }, + 'circgradbasedcorrmaskangle' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAngle'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAngle'] }, + 'circgradbasedcorrmaskbottom' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksBottom'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksBottom'] }, + 'circgradbasedcorrmaskcentervalue' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterValue'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterValue'] }, + 'circgradbasedcorrmaskcenterweight' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterWeight'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterWeight'] }, + 'circgradbasedcorrmaskdabs' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksDabs'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksDabs'] }, + 'circgradbasedcorrmaskfeather' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFeather'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFeather'] }, + 'circgradbasedcorrmaskflipped' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlipped'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlipped'] }, + 'circgradbasedcorrmaskflow' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlow'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlow'] }, + 'circgradbasedcorrmaskfullx' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullX'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullX'] }, + 'circgradbasedcorrmaskfully' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullY'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullY'] }, + 'circgradbasedcorrmaskleft' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksLeft'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksLeft'] }, + 'circgradbasedcorrmaskmidpoint' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMidpoint'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMidpoint'] }, + 'circgradbasedcorrmaskperimetervalue' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksPerimeterValue'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksPerimeterValue'] }, + 'circgradbasedcorrmaskradius' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRadius'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRadius'] }, + 'circgradbasedcorrmaskright' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRight'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRight'] }, + 'circgradbasedcorrmaskroundness' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRoundness'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRoundness'] }, + 'circgradbasedcorrmasks' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasks'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasks'] }, + 'circgradbasedcorrmasksizex' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeX'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeX'] }, + 'circgradbasedcorrmasksizey' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeY'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeY'] }, + 'circgradbasedcorrmasktop' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksTop'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksTop'] }, + 'circgradbasedcorrmaskvalue' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMaskValue'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMaskValue'] }, + 'circgradbasedcorrmaskversion' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksVersion'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksVersion'] }, + 'circgradbasedcorrmaskwhat' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksWhat'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksWhat'] }, + 'circgradbasedcorrmaskx' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksX'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksX'] }, + 'circgradbasedcorrmasky' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksY'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksY'] }, + 'circgradbasedcorrmaskzerox' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroX'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroX'] }, + 'circgradbasedcorrmaskzeroy' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroY'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroY'] }, + 'circgradbasedcorrmoire' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalMoire'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalMoire'] }, + 'circgradbasedcorrsaturation' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSaturation','CircularGradientBasedCorrectionsLocalToningSaturation'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSaturation','CircularGradientBasedCorrectionsLocalToningSaturation'] }, + 'circgradbasedcorrshadows2012' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalShadows2012'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalShadows2012'] }, + 'circgradbasedcorrsharpness' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSharpness'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSharpness'] }, + 'circgradbasedcorrtemperature' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTemperature'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTemperature'] }, + 'circgradbasedcorrtint' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTint'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTint'] }, + 'circgradbasedcorrwhat' => { 462 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsWhat'], 464 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsWhat'] }, + 'circulargradientbasedcorrections' => { 462 => 'CircularGradientBasedCorrections', 464 => 'CircularGradientBasedCorrections' }, + 'city' => { 128 => 0x5a, 157 => 'City', 306 => 0x6d, 476 => 'City' }, + 'city2' => { 306 => 0x80 }, + 'clarity' => { 222 => 0x35, 223 => 0x3d, 462 => 'Clarity', 464 => 'Clarity' }, + 'clarity2012' => { 462 => 'Clarity2012', 464 => 'Clarity2012' }, + 'claritycontrol' => { 341 => 0x96 }, + 'classifystate' => { 128 => 0xe1 }, + 'clearretouch' => { 306 => 0x7c }, + 'clearretouchvalue' => { 306 => 0xa3 }, + 'client' => { 488 => 'client' }, + 'clientname' => { 470 => 'ClientName' }, + 'clipfilename' => { 366 => 'clfn' }, + 'clipid' => { 366 => 'clid' }, + 'clmodeshootingspeed' => { 266 => '10.2', 267 => '11.3', 269 => '11.2', 270 => '11.2', 275 => '11.2', 276 => '10.2', 279 => '11.2', 280 => '11.2', 281 => '11.1' }, + 'cmcontrast' => { 291 => 0x2022 }, + 'cmexposurecompensation' => { 291 => 0x2000 }, + 'cmhue' => { 291 => 0x2021 }, + 'cmsaturation' => { 291 => 0x2020 }, + 'cmsharpness' => { 291 => 0x2023 }, + 'cmwhitebalance' => { 291 => 0x2001 }, + 'cmwhitebalancecomp' => { 291 => 0x2002 }, + 'cmwhitebalancegraypoint' => { 291 => 0x2010 }, + 'codec' => { 165 => 'Codec' }, + 'codedcharacterset' => { 129 => 0x5a }, + 'codeversion' => { 366 => 'cver' }, + 'collection' => { 296 => 'Collection' }, + 'collectionname' => { 166 => [\'Collections','CollectionsCollectionName'], 366 => 'coll' }, + 'collections' => { 166 => 'Collections', 457 => 'collections' }, + 'collectionuri' => { 166 => [\'Collections','CollectionsCollectionURI'] }, + 'color' => { 360 => 'player.movie.visual.color', 477 => 'color' }, + 'coloraberrationcontrol' => { 259 => 0xc89224b }, + 'coloradjustment' => { 383 => 0x14 }, + 'coloradjustmentmode' => { 382 => 0x210 }, + 'coloranta' => { 493 => [\'Colorants','ColorantsA'] }, + 'colorantb' => { 493 => [\'Colorants','ColorantsB'] }, + 'colorantblack' => { 493 => [\'Colorants','ColorantsBlack'] }, + 'colorantblue' => { 493 => [\'Colorants','ColorantsBlue'] }, + 'colorantcyan' => { 493 => [\'Colorants','ColorantsCyan'] }, + 'colorantgray' => { 493 => [\'Colorants','ColorantsGray'] }, + 'colorantgreen' => { 493 => [\'Colorants','ColorantsGreen'] }, + 'colorantl' => { 493 => [\'Colorants','ColorantsL'] }, + 'colorantmagenta' => { 493 => [\'Colorants','ColorantsMagenta'] }, + 'colorantmode' => { 493 => [\'Colorants','ColorantsMode'] }, + 'colorantred' => { 493 => [\'Colorants','ColorantsRed'] }, + 'colorants' => { 493 => 'Colorants' }, + 'colorantswatchname' => { 493 => [\'Colorants','ColorantsSwatchName'] }, + 'coloranttint' => { 493 => [\'Colorants','ColorantsTint'] }, + 'coloranttype' => { 493 => [\'Colorants','ColorantsType'] }, + 'colorantyellow' => { 493 => [\'Colorants','ColorantsYellow'] }, + 'colorbalance' => { 152 => 'ColorBalance' }, + 'colorbalanceadj' => { 259 => 0x76a43202 }, + 'colorbalanceblue' => { 176 => 0x1e }, + 'colorbalancegreen' => { 176 => 0x1d }, + 'colorbalancered' => { 176 => 0x1c }, + 'colorbalanceversion' => { 197 => 0x4, 198 => 0x4, 199 => 0x0 }, + 'colorblur' => { 106 => 0x65 }, + 'colorbluron' => { 100 => 0x20704 }, + 'colorbooster' => { 259 => 0x5f0e7d23 }, + 'colorboostlevel' => { 253 => 0x1 }, + 'colorboosttype' => { 253 => 0x0 }, + 'colorchromeeffect' => { 124 => 0x1048 }, + 'colorchromefxblue' => { 124 => 0x104e }, + 'colorclass' => { 352 => 0xde, 353 => 'ColorClass' }, + 'colorcompensationfilter' => { 179 => [0x3a,0x5f], 181 => 0x111, 406 => 0xb022 }, + 'colorcompensationfiltercustom' => { 393 => 0xd, 394 => 0xc }, + 'colorcompensationfilterset' => { 393 => 0x8, 394 => 0x7, 395 => 0x18, 411 => 0xf }, + 'colorcontrol' => { 288 => 0x102b }, + 'colorcorrection' => { 439 => 0x8015 }, + 'colorcreatoreffect' => { 283 => 0x532 }, + 'colordataversion' => { 42 => 0x0, 43 => 0x0, 44 => 0x0, 45 => 0x0, 46 => 0x0, 47 => 0x0, 48 => 0x0 }, + 'coloreffect' => { 306 => 0x28 }, + 'colorfilter' => { 109 => 0x17, 110 => 0x3017, 176 => 0x29, 184 => [0x38,0x4d,0x4f], 348 => 0x17 }, + 'colorgain' => { 227 => 0x51 }, + 'colorhue' => { 100 => 0x20900, 219 => 0x8d }, + 'colorimetricreference' => { 116 => 0xc6bf }, + 'colorlabel' => { 467 => 'ColorLabel' }, + 'colormatrix' => { 287 => 0x200, 288 => 0x1011, 380 => 0xa030 }, + 'colormatrix1' => { 116 => 0xc621, 350 => 0x106 }, + 'colormatrix2' => { 116 => 0xc622, 291 => 0x200, 350 => 0x226 }, + 'colormatrixa' => { 341 => 0x203 }, + 'colormatrixadobergb' => { 380 => 0xa032 }, + 'colormatrixb' => { 341 => 0x204 }, + 'colormatrixnumber' => { 288 => 0x1019 }, + 'colormatrixsrgb' => { 380 => 0xa031 }, + 'colormode' => { 110 => 0x3015, 124 => 0x1210, 136 => 0x66, 176 => 0x28, 179 => 0x16, 181 => 0x101, 182 => 0x36, 184 => 0x7, 219 => 0x3, 249 => 0x4, 306 => 0x32, 383 => 0x2c, 406 => 0xb029, 476 => 'ColorMode' }, + 'colormoirereduction' => { 100 => 0x20670, 260 => 0x15 }, + 'colormoirereductionmode' => { 260 => 0x5 }, + 'colormoirereductionon' => { 100 => '0x20670.0' }, + 'colornoisereduction' => { 439 => 0x8029, 462 => 'ColorNoiseReduction', 464 => 'ColorNoiseReduction' }, + 'colornoisereductiondetail' => { 462 => 'ColorNoiseReductionDetail', 464 => 'ColorNoiseReductionDetail' }, + 'colornoisereductionintensity' => { 260 => 0x18 }, + 'colornoisereductionsharpness' => { 260 => 0x1c }, + 'colornoisereductionsmoothness' => { 462 => 'ColorNoiseReductionSmoothness', 464 => 'ColorNoiseReductionSmoothness' }, + 'colorplanes' => { 120 => 0x2 }, + 'colorprofile' => { 176 => 0x33 }, + 'colorprofilesettings' => { 283 => 0x539 }, + 'colorrepresentation' => { 130 => 0x3c }, + 'colorsaturationadj' => { 100 => 0x20305 }, + 'colorsequence' => { 130 => 0x41 }, + 'colorspace' => { 49 => 0x3, 61 => 0xb4, 94 => 0x10b4, 116 => 0xa001, 158 => 'ColorSpace', 177 => 0x2f, 178 => 0x25, 179 => 0x17, 219 => 0x1e, 283 => 0x507, 341 => 0x37, 380 => 0xa011, 383 => 0xb, 393 => 0x1b, 394 => 0x83, 395 => 0xe, 411 => 0x6, 468 => 'ColorSpace' }, + 'colortempasshot' => { 38 => 0x4, 39 => 0x7, 40 => 0x1d, 41 => 0x26, 42 => 0x43, 45 => 0x43, 46 => 0x43, 47 => 0x43, 48 => 0x4b }, + 'colortempauto' => { 38 => 0x9, 39 => 0xf, 40 => 0x22, 41 => 0x1c, 42 => 0x48, 45 => 0x48, 46 => 0x48, 47 => 0x48, 48 => 0x50 }, + 'colortempcloudy' => { 38 => 0x22, 39 => 0x37, 40 => 0x31, 41 => 0x35, 42 => 0x5c, 45 => 0x75, 46 => 0x8e, 47 => 0x93, 48 => 0x96, 341 => 0x55 }, + 'colortempcustom' => { 42 => 0x84 }, + 'colortempcustom1' => { 40 => 0x45 }, + 'colortempcustom2' => { 40 => 0x4a }, + 'colortempdaylight' => { 38 => 0x18, 39 => 0x27, 40 => 0x27, 41 => 0x2b, 42 => 0x52, 45 => 0x6b, 46 => 0x84, 47 => 0x89, 48 => 0x8c, 341 => 0x53 }, + 'colortemperature' => { 7 => 0x73, 8 => [0x48,0x4e], 9 => 0xc0, 10 => 0x37, 11 => 0x62, 12 => 0x37, 13 => 0x7c, 14 => 0x73, 15 => 0x73, 16 => 0x77, 17 => 0x73, 18 => 0x7c, 19 => 0x58, 20 => 0x73, 21 => 0xc0, 22 => 0x7f, 23 => 0x7d, 24 => 0xc0, 25 => 0xc6, 26 => 0xc7, 27 => 0x135, 28 => 0x7b, 29 => 0x13a, 61 => 0xae, 71 => 0x9, 94 => 0x10ae, 124 => 0x1005, 134 => 0x846, 152 => 'ColorTemperature', 177 => [0x6e,0x49], 178 => 0x3f, 179 => [0x39,0x5e], 181 => 0x10b, 184 => [0x3c,0x4c,0x4e], 301 => 0x321, 341 => 0x50, 373 => 0x1308, 406 => 0xb021, 462 => 'Temperature', 464 => 'Temperature' }, + 'colortemperatureadj' => { 439 => 0x8013 }, + 'colortemperatureauto' => { 219 => 0x4f }, + 'colortemperaturebg' => { 288 => 0x1013 }, + 'colortemperaturecustom' => { 393 => 0xc, 394 => 0xb }, + 'colortemperaturerg' => { 288 => 0x1014 }, + 'colortemperatureset' => { 393 => 0x7, 394 => 0x6 }, + 'colortemperaturesetting' => { 179 => 0x25, 395 => 0x17, 411 => 0xe }, + 'colortempflash' => { 38 => 0x36, 39 => 0x57, 40 => 0x40, 41 => 0x49, 42 => 0x70, 45 => 0x89, 46 => 0xa2, 47 => 0xa7, 48 => 0xaa, 341 => 0x5a }, + 'colortempflashdata' => { 42 => 0x24a }, + 'colortempfluorescent' => { 38 => 0x2c, 39 => 0x47, 40 => 0x3b, 41 => 0x3f, 42 => 0x66, 45 => 0x7f, 46 => 0x98, 47 => 0x9d, 48 => 0xa0 }, + 'colortempfluorescentd' => { 341 => 0x57 }, + 'colortempfluorescentn' => { 341 => 0x58 }, + 'colortempfluorescentw' => { 341 => 0x59 }, + 'colortempkelvin' => { 38 => 0x31, 39 => 0x4f, 41 => 0x44, 42 => 0x6b, 45 => 0x84, 46 => 0x9d, 47 => 0xa2, 48 => 0xa5, 306 => 0x44, 373 => 0x1307 }, + 'colortempmeasured' => { 38 => 0xe, 39 => 0x17, 42 => 0x4d, 45 => 0x4d, 46 => 0x4d, 47 => 0x4d, 48 => 0x55 }, + 'colortemppc1' => { 41 => 0x94, 42 => 0x75 }, + 'colortemppc2' => { 41 => 0x99, 42 => 0x7a }, + 'colortemppc3' => { 41 => 0x9e, 42 => 0x7f }, + 'colortempshade' => { 38 => 0x1d, 39 => 0x2f, 40 => 0x2c, 41 => 0x30, 42 => 0x57, 45 => 0x70, 46 => 0x89, 47 => 0x8e, 48 => 0x91, 341 => 0x54 }, + 'colortemptungsten' => { 38 => 0x27, 39 => 0x3f, 40 => 0x36, 41 => 0x3a, 42 => 0x61, 45 => 0x7a, 46 => 0x93, 47 => 0x98, 48 => 0x9b, 341 => 0x56 }, + 'colortempunknown' => { 38 => 0x13, 39 => 0x1f, 41 => 0x21, 45 => 0x52, 46 => 0x52, 47 => 0x52, 48 => 0x5a }, + 'colortempunknown10' => { 38 => 0x63, 39 => 0x9f, 41 => 0x76, 45 => 0xa2, 46 => 0x7f, 47 => 0x7f, 48 => 0x87 }, + 'colortempunknown11' => { 38 => 0x68, 39 => 0xa7, 41 => 0x7b, 45 => 0xa7, 46 => 0xa7, 47 => 0x84, 48 => 0xaf }, + 'colortempunknown12' => { 38 => 0x6d, 39 => 0xaf, 41 => 0x80, 45 => 0xac, 46 => 0xac, 47 => 0xac, 48 => 0xb4 }, + 'colortempunknown13' => { 38 => 0x72, 39 => 0xb7, 41 => 0x85, 45 => 0xb1, 46 => 0xb1, 47 => 0xb1, 48 => 0xb9 }, + 'colortempunknown14' => { 41 => 0x8a, 45 => 0xb6, 46 => 0xb6, 47 => 0xb6, 48 => 0xbe }, + 'colortempunknown15' => { 41 => 0x8f, 45 => 0xbb, 46 => 0xbb, 47 => 0xbb, 48 => 0xc3 }, + 'colortempunknown16' => { 41 => 0xa3, 46 => 0xc0, 47 => 0xc0, 48 => 0xc8 }, + 'colortempunknown17' => { 46 => 0xc5, 47 => 0xc5, 48 => 0xcd }, + 'colortempunknown18' => { 46 => 0xca, 47 => 0xca, 48 => 0xd2 }, + 'colortempunknown19' => { 46 => 0xcf, 47 => 0xcf, 48 => 0xd7 }, + 'colortempunknown2' => { 38 => 0x3b, 39 => 0x5f, 41 => 0x4e, 45 => 0x57, 46 => 0x57, 47 => 0x57, 48 => 0x5f }, + 'colortempunknown20' => { 46 => 0xd4, 47 => 0xd4, 48 => 0xdc }, + 'colortempunknown21' => { 47 => 0xd9, 48 => 0xe1 }, + 'colortempunknown22' => { 47 => 0xde, 48 => 0xe6 }, + 'colortempunknown23' => { 47 => 0xe3, 48 => 0xeb }, + 'colortempunknown24' => { 47 => 0xe8, 48 => 0xf0 }, + 'colortempunknown25' => { 47 => 0xed, 48 => 0xf5 }, + 'colortempunknown26' => { 47 => 0xf2, 48 => 0xfa }, + 'colortempunknown27' => { 47 => 0xf7, 48 => 0xff }, + 'colortempunknown28' => { 47 => 0xfc, 48 => 0x104 }, + 'colortempunknown29' => { 47 => 0x101, 48 => 0x109 }, + 'colortempunknown3' => { 38 => 0x40, 39 => 0x67, 41 => 0x53, 45 => 0x5c, 46 => 0x5c, 47 => 0x5c, 48 => 0x64 }, + 'colortempunknown30' => { 47 => 0x106 }, + 'colortempunknown4' => { 38 => 0x45, 39 => 0x6f, 41 => 0x58, 45 => 0x61, 46 => 0x61, 47 => 0x61, 48 => 0x69 }, + 'colortempunknown5' => { 38 => 0x4a, 39 => 0x77, 41 => 0x5d, 45 => 0x66, 46 => 0x66, 47 => 0x66, 48 => 0x6e }, + 'colortempunknown6' => { 38 => 0x4f, 39 => 0x7f, 41 => 0x62, 45 => 0x8e, 46 => 0x6b, 47 => 0x6b, 48 => 0x73 }, + 'colortempunknown7' => { 38 => 0x54, 39 => 0x87, 41 => 0x67, 45 => 0x93, 46 => 0x70, 47 => 0x70, 48 => 0x78 }, + 'colortempunknown8' => { 38 => 0x59, 39 => 0x8f, 41 => 0x6c, 45 => 0x98, 46 => 0x75, 47 => 0x75, 48 => 0x7d }, + 'colortempunknown9' => { 38 => 0x5e, 39 => 0x97, 41 => 0x71, 45 => 0x9d, 46 => 0x7a, 47 => 0x7a, 48 => 0x82 }, + 'colortone' => { 10 => 0x6f, 12 => 0x77, 34 => 0x2a, 49 => 0x2 }, + 'colortoneadj' => { 100 => 0x20304, 105 => 0x11e }, + 'colortoneauto' => { 68 => 0x9c }, + 'colortonefaithful' => { 19 => 0x107, 67 => 0x6c, 68 => 0x6c }, + 'colortonelandscape' => { 19 => 0x105, 67 => 0x3c, 68 => 0x3c }, + 'colortonemonochrome' => { 67 => 0x84, 68 => 0x84 }, + 'colortoneneutral' => { 19 => 0x106, 67 => 0x54, 68 => 0x54 }, + 'colortoneportrait' => { 19 => 0x104, 67 => 0x24, 68 => 0x24 }, + 'colortonestandard' => { 19 => 0x103, 67 => 0xc, 68 => 0xc }, + 'colortoneuserdef1' => { 19 => 0x109, 67 => 0x9c, 68 => 0xb4 }, + 'colortoneuserdef2' => { 19 => 0x10a, 67 => 0xb4, 68 => 0xcc }, + 'colortoneuserdef3' => { 19 => 0x10b, 67 => 0xcc, 68 => 0xe4 }, + 'comlenblksize' => { 134 => 0xfde8 }, + 'commanddials' => { 277 => '5.1' }, + 'commanddialsaperturesetting' => { 266 => '17.3', 267 => '18.3', 269 => '18.3', 270 => '18.3', 275 => '33.3', 276 => '17.3', 279 => '18.3', 280 => '18.3' }, + 'commanddialschangemainsub' => { 266 => '17.2', 267 => '18.1', 269 => '18.1', 270 => '18.1', 275 => '33.2', 276 => '17.2', 279 => '18.1', 280 => '18.1' }, + 'commanddialsmenuandplayback' => { 266 => '17.4', 267 => '18.2', 269 => '18.2', 270 => '18.2', 275 => '33.4', 276 => '17.4', 279 => '18.2', 280 => '18.2' }, + 'commanddialsreverserotation' => { 266 => '17.1', 267 => '6.4', 269 => '6.2', 270 => '6.2', 271 => '16.2', 272 => '17.2', 275 => '33.1', 276 => '17.1', 279 => '6.2', 280 => '6.2', 281 => '18.1' }, + 'commanderchannel' => { 277 => '10.2', 278 => '25.2' }, + 'commandergroupa_ttl-aacomp' => { 277 => '13.1', 278 => '31.1' }, + 'commandergroupa_ttlcomp' => { 281 => '32.1' }, + 'commandergroupamanualoutput' => { 277 => '13.2', 278 => '28.2' }, + 'commandergroupamode' => { 277 => '11.2', 278 => '28.1' }, + 'commandergroupb_ttl-aacomp' => { 277 => '14.1', 278 => '32.1' }, + 'commandergroupb_ttlcomp' => { 281 => '33.1' }, + 'commandergroupbmanualoutput' => { 277 => '14.2', 278 => '29.2' }, + 'commandergroupbmode' => { 277 => '11.3', 278 => '29.1' }, + 'commanderinternalflash' => { 277 => '11.1', 278 => '27.1' }, + 'commanderinternalmanualoutput' => { 277 => '12.2', 278 => '27.2' }, + 'commanderinternalttlchannel' => { 275 => '18.2' }, + 'commanderinternalttlcomp' => { 277 => '12.1', 278 => '30.2', 281 => '31.2' }, + 'commanderinternalttlcompbuiltin' => { 275 => '20.1', 276 => '26.1' }, + 'commanderinternalttlcompgroupa' => { 275 => '21.1', 276 => '27.1' }, + 'commanderinternalttlcompgroupb' => { 275 => '22.1', 276 => '28.1' }, + 'comment' => { 0 => 0x2, 117 => 'Comment', 153 => 'Comment', 296 => 'Comment', 358 => "\xa9cmt", 360 => 'comment', 366 => "\xa9cmt" }, + 'compass' => { 376 => 0x4 }, + 'compilation' => { 358 => 'cpil' }, + 'compimageimagespersequence' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesNumberOfImagesInSequences'] }, + 'compimagemaxexposureall' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMaxExposureTimesOfAll'] }, + 'compimagemaxexposureused' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMaxExposureTimesOfUsed'] }, + 'compimageminexposureall' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMinExposureTimesOfAll'] }, + 'compimageminexposureused' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMinExposureTimesOfUsed'] }, + 'compimagenumsequences' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesNumberOfSequences'] }, + 'compimagesumexposureall' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesSumOfExposureTimesOfAll'] }, + 'compimagesumexposureused' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesSumOfExposureTimesOfUsed'] }, + 'compimagetotalexposureperiod' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesTotalExposurePeriod'] }, + 'compimagevalues' => { 469 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesValues'] }, + 'complianceprofile' => { 478 => 'complianceProfile' }, + 'componentsconfiguration' => { 116 => 0x9101, 158 => 'Components', 468 => 'ComponentsConfiguration' }, + 'componentversion' => { 94 => 0x80c }, + 'composer' => { 358 => ["\xa9com","\xa9wrt"], 366 => ["\xa9com","\xa9wrt"], 488 => 'composer' }, + 'composerkeywords' => { 366 => "\xa9cok" }, + 'compositeimage' => { 116 => 0xa460, 469 => 'CompositeImage' }, + 'compositeimagecount' => { 116 => 0xa461, 469 => 'CompositeImageCount' }, + 'compositeimageexposuretimes' => { 116 => 0xa462, 469 => 'CompositeImageExposureTimes' }, + 'composition' => { 452 => 'Composition' }, + 'compositionadjust' => { 340 => '0.1' }, + 'compositionadjustrotation' => { 340 => 0x7 }, + 'compositionadjustx' => { 340 => 0x5 }, + 'compositionadjusty' => { 340 => 0x6 }, + 'compressedbitsperpixel' => { 116 => 0x9102, 468 => 'CompressedBitsPerPixel' }, + 'compressedimagesize' => { 181 => 0x40, 288 => 0x40 }, + 'compression' => { 116 => 0x103, 311 => 0xb, 484 => 'Compression' }, + 'compressionfactor' => { 283 => 0x50d }, + 'compressionratio' => { 158 => 'Compression', 288 => 0x1034 }, + 'compressorversion' => { 366 => 'CNCV' }, + 'condadobvfactor' => { 134 => 0xf3e }, + 'condadodaybvthresh' => { 134 => 0xf3c }, + 'condadodayoffsets' => { 134 => 0xf42 }, + 'condadofluoffsets' => { 134 => 0xf44 }, + 'condadofluthresh' => { 134 => 0xf41 }, + 'condadoillfactor' => { 134 => 0xf3f }, + 'condadoneurange' => { 134 => 0xf3d }, + 'condadotunoffsets' => { 134 => 0xf43 }, + 'condadotunthresh' => { 134 => 0xf40 }, + 'confidence' => { 447 => 'Confidence' }, + 'confidencelevel' => { 458 => 'ConfidenceLevel' }, + 'confidencemime' => { 447 => 'ConfidenceMime' }, + 'constrainedcropheight' => { 105 => 0x266, 352 => 0xd6 }, + 'constrainedcropwidth' => { 105 => 0x262, 352 => 0xd5 }, + 'contact' => { 128 => 0x76 }, + 'contactinfo' => { 477 => 'contactInfo' }, + 'container' => { 442 => 'Container' }, + 'containerdirectory' => { 442 => [\'Container','ContainerDirectory'] }, + 'containerdirectoryitem' => { 442 => [\'Container','ContainerDirectoryItem'] }, + 'containerdirectoryitemdatauri' => { 442 => [\'Container','ContainerDirectoryItemDataURI'] }, + 'containerdirectoryitemlength' => { 442 => [\'Container','ContainerDirectoryItemLength'] }, + 'containerdirectoryitemmime' => { 442 => [\'Container','ContainerDirectoryItemMime'] }, + 'containerdirectoryitempadding' => { 442 => [\'Container','ContainerDirectoryItemPadding'] }, + 'containerformat' => { 474 => 'ContainerFormat' }, + 'containerformatidentifier' => { 474 => [\'ContainerFormat','ContainerFormatIdentifier'] }, + 'containerformatname' => { 474 => [\'ContainerFormat','ContainerFormatName'] }, + 'contentcreatedate' => { 358 => "\xa9day", 366 => "\xa9day" }, + 'contentdistributorid' => { 366 => 'cdis' }, + 'contentid' => { 366 => 'ccid' }, 'contentidentifier' => { 1 => 0x11 }, - 'contentlocationcode' => { 125 => 0x1a }, - 'contentlocationname' => { 125 => 0x1b }, - 'contenttype' => { 456 => 'contentType' }, - 'continuousbracketing' => { 174 => 0x20 }, - 'continuousdrive' => { 33 => 0x5 }, - 'continuousmodeliveview' => { 271 => '77.2' }, - 'continuousshootingspeed' => { 78 => 0x610 }, - 'continuousshotlimit' => { 78 => 0x611 }, - 'contrast' => { 9 => 0x73, 11 => 0x75, 33 => 0xd, 106 => 0xc, 107 => [0x3012,0x20], 113 => [0xa408,0xfe54], 121 => [0x1004,0x1006], 147 => 'Contrast', 167 => 'Contrast', 171 => 0x20, 172 => 0x31, 173 => 0x27, 174 => 0x19, 179 => 0x2, 213 => 0x33, 214 => 0x37, 279 => 0x1029, 297 => 0x39, 299 => 0x300a, 332 => 0x20, 339 => 0xc, 353 => 0x24, 358 => 0x1012, 368 => 0xd, 376 => 0x1d, 377 => 0x1a, 388 => 0x2004, 442 => 'Contrast', 446 => 'Contrast' }, - 'contrast2012' => { 442 => 'Contrast2012' }, - 'contrastadj' => { 97 => 0x20303, 102 => 0x115, 253 => 0x2c, 421 => 0x8017 }, - 'contrastauto' => { 67 => 0x90 }, - 'contrastcurve' => { 211 => 0x8c }, - 'contrastdetectaf' => { 183 => 0x4 }, - 'contrastdetectafarea' => { 332 => 0x231 }, - 'contrastdetectafinfocus' => { 183 => [0x1c,0x52] }, - 'contrastfaithful' => { 18 => 0xec, 66 => 0x60, 67 => 0x60 }, - 'contrasthighlight' => { 332 => 0x6d }, - 'contrasthighlightshadowadj' => { 332 => 0x6f }, - 'contrastlandscape' => { 18 => 0xea, 66 => 0x30, 67 => 0x30 }, - 'contrastmode' => { 297 => 0x2c }, - 'contrastmonochrome' => { 18 => 0xed, 66 => 0x78, 67 => 0x78 }, - 'contrastneutral' => { 18 => 0xeb, 66 => 0x48, 67 => 0x48 }, - 'contrastportrait' => { 18 => 0xe9, 66 => 0x18, 67 => 0x18 }, - 'contrastsetting' => { 274 => 0x505, 282 => 0x1012, 378 => 0x10, 393 => 0x8 }, - 'contrastshadow' => { 332 => 0x6e }, - 'contraststandard' => { 18 => 0xe8, 66 => 0x0, 67 => 0x0 }, - 'contrastuserdef1' => { 18 => 0xee, 66 => 0x90, 67 => 0xa8 }, - 'contrastuserdef2' => { 18 => 0xef, 66 => 0xa8, 67 => 0xc0 }, - 'contrastuserdef3' => { 18 => 0xf0, 66 => 0xc0, 67 => 0xd8 }, - 'contributedmedia' => { 466 => 'contributedMedia' }, - 'contributedmediaduration' => { 466 => [\'contributedMedia','contributedMediaDuration'] }, - 'contributedmediadurationscale' => { 466 => [\'contributedMedia','contributedMediaDurationScale'] }, - 'contributedmediadurationvalue' => { 466 => [\'contributedMedia','contributedMediaDurationValue'] }, - 'contributedmediamanaged' => { 466 => [\'contributedMedia','contributedMediaManaged'] }, - 'contributedmediapath' => { 466 => [\'contributedMedia','contributedMediaPath'] }, - 'contributedmediastarttime' => { 466 => [\'contributedMedia','contributedMediaStartTime'] }, - 'contributedmediastarttimescale' => { 466 => [\'contributedMedia','contributedMediaStartTimeScale'] }, - 'contributedmediastarttimevalue' => { 466 => [\'contributedMedia','contributedMediaStartTimeValue'] }, - 'contributedmediatrack' => { 466 => [\'contributedMedia','contributedMediaTrack'] }, - 'contributedmediawebstatement' => { 466 => [\'contributedMedia','contributedMediaWebStatement'] }, - 'contributor' => { 443 => 'contributor', 452 => 'Contributor' }, - 'contributoridentifier' => { 452 => [\'Contributor','ContributorIdentifier'] }, - 'contributorname' => { 452 => [\'Contributor','ContributorName'] }, - 'contributorrole' => { 452 => [\'Contributor','ContributorRole'] }, - 'contributors' => { 148 => 'Contributors' }, - 'controldialset' => { 174 => 0x46 }, - 'controlledvocabularyterm' => { 452 => 'CVterm' }, - 'controllerboardversion' => { 292 => 0x332 }, - 'controlmode' => { 72 => 0x12 }, - 'controlringrotation' => { 78 => 0x712 }, - 'conversionlens' => { 275 => 0x403, 297 => 0x35 }, - 'converter' => { 113 => 0xfe4d, 240 => 0xb, 442 => 'Converter' }, - 'converttograyscale' => { 442 => 'ConvertToGrayscale' }, - 'cookingequipment' => { 458 => 'cookingEquipment' }, - 'cookingmethod' => { 458 => 'cookingMethod' }, - 'copyright' => { 0 => 0x3, 113 => 0x8298, 148 => 'Copyright', 287 => 'Copyright', 332 => 0x22f, 348 => 'Copyright', 453 => 'Copyright', 459 => 'copyright', 462 => 'Copyright', 466 => 'copyright' }, - 'copyrightflag' => { 346 => 0x40a }, - 'copyrightnotice' => { 125 => 0x74 }, - 'copyrightowner' => { 284 => 'CopyrightOwner' }, - 'copyrightownerid' => { 284 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerID'] }, - 'copyrightownerimageid' => { 284 => 'CopyrightOwnerImageID' }, - 'copyrightownername' => { 284 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerName'] }, - 'copyrightregistrationnumber' => { 284 => 'CopyrightRegistrationNumber' }, - 'copyrightstatus' => { 284 => 'CopyrightStatus' }, - 'copyrightyear' => { 452 => 'CopyrightYear', 456 => 'copyrightYear' }, - 'coringfilter' => { 278 => 0x310, 279 => 0x102d, 282 => 0x310 }, - 'coringvalues' => { 278 => 0x311, 282 => 0x311 }, - 'corporateentity' => { 456 => 'corporateEntity' }, - 'country' => { 152 => 'Country', 297 => 0x69, 454 => 'Country' }, - 'country-primarylocationcode' => { 125 => 0x64 }, - 'country-primarylocationname' => { 125 => 0x65 }, - 'countrycode' => { 210 => 0x5, 344 => 'CountryCode', 451 => 'CountryCode' }, - 'course' => { 458 => 'course' }, - 'coverage' => { 443 => 'coverage' }, - 'coverdate' => { 456 => 'coverDate' }, - 'coverdisplaydate' => { 456 => 'coverDisplayDate' }, - 'cpufirmwareversion' => { 332 => 0x28 }, - 'crc32' => { 444 => 'crc32' }, - 'createdate' => { 113 => 0x9004, 148 => 'CreateDate', 283 => 'CreationDate', 287 => 'create-date', 348 => 'CreationDate', 350 => 0x1, 464 => 'CreateDate' }, - 'creationdate' => { 453 => 'CreationDate', 456 => 'creationDate' }, - 'creationtime' => { 287 => 'Creation Time' }, - 'creativestyle' => { 376 => 0x1a, 377 => 0x18, 387 => 0x41, 388 => 0xb020, 417 => 0x4a }, - 'creativestylesetting' => { 378 => 0xf, 393 => 0x7 }, - 'creativestylewaschanged' => { 421 => 0x8001 }, - 'creator' => { 283 => 'Creator', 348 => 'Creator', 443 => 'creator', 452 => 'Creator', 453 => 'Creator' }, - 'creatoraddress' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiAdrExtadr'] }, - 'creatorappid' => { 169 => 'CreatorAppId' }, - 'creatorcity' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCity'] }, - 'creatorcontactinfo' => { 451 => 'CreatorContactInfo' }, - 'creatorcountry' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCtry'] }, - 'creatoridentifier' => { 452 => [\'Creator','CreatorIdentifier'] }, - 'creatorname' => { 452 => [\'Creator','CreatorName'] }, - 'creatoropenwithuioptions' => { 169 => 'CreatorOpenWithUIOptions' }, - 'creatorpostalcode' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiAdrPcode'] }, - 'creatorregion' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiAdrRegion'] }, - 'creatorrole' => { 452 => [\'Creator','CreatorRole'] }, - 'creatortool' => { 464 => 'CreatorTool' }, - 'creatorworkemail' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiEmailWork'] }, - 'creatorworktelephone' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiTelWork'] }, - 'creatorworkurl' => { 451 => [\'CreatorContactInfo','CreatorContactInfoCiUrlWork'] }, - 'credit' => { 125 => 0x6e, 454 => 'Credit' }, - 'creditline' => { 459 => 'creditLine' }, - 'creditlinereq' => { 469 => 'CreditLineReq' }, - 'creditlinerequired' => { 284 => 'CreditLineRequired' }, - 'cropactive' => { 95 => 0x0, 102 => 0x244 }, - 'cropangle' => { 442 => 'CropAngle' }, - 'croparea' => { 421 => 0x9011 }, - 'cropaspectratio' => { 97 => 0x30101, 102 => 0x260 }, - 'cropaspectratiocustom' => { 97 => 0x30102 }, - 'cropbottom' => { 117 => 0x9, 245 => 0x36, 302 => 0x31, 343 => 0xdc, 442 => 'CropBottom' }, - 'cropbottommargin' => { 50 => 0x3 }, - 'cropcircleactive' => { 103 => 0xd6 }, - 'cropcircleradius' => { 103 => 0xd9 }, - 'cropcirclex' => { 103 => 0xd7 }, - 'cropcircley' => { 103 => 0xd8 }, - 'cropconstraintowarp' => { 442 => 'CropConstrainToWarp' }, - 'croph' => { 435 => 'CropH' }, - 'cropheight' => { 95 => 0x6, 102 => 0x24c, 278 => 0x615, 282 => 0x615, 442 => 'CropHeight' }, - 'crophispeed' => { 211 => 0x1b }, - 'cropleft' => { 102 => 0x246, 117 => 0x6, 245 => 0x1e, 278 => 0x612, 282 => 0x612, 302 => 0x30, 343 => 0xd9, 442 => 'CropLeft' }, - 'cropleftmargin' => { 50 => 0x0 }, - 'cropmode35mm' => { 358 => 0x1018 }, - 'croporiginalheight' => { 95 => 0xb }, - 'croporiginalwidth' => { 95 => 0xa }, - 'cropoutputheight' => { 245 => 0xce }, - 'cropoutputheightinches' => { 245 => 0x96 }, - 'cropoutputpixels' => { 245 => 0xd6 }, - 'cropoutputresolution' => { 245 => 0xb6 }, - 'cropoutputscale' => { 245 => 0xbe }, - 'cropoutputwidth' => { 245 => 0xc6 }, - 'cropoutputwidthinches' => { 245 => 0x8e }, - 'croppedareaimageheightpixels' => { 429 => 'CroppedAreaImageHeightPixels', 430 => 'CroppedAreaImageHeightPixels' }, - 'croppedareaimagewidthpixels' => { 429 => 'CroppedAreaImageWidthPixels', 430 => 'CroppedAreaImageWidthPixels' }, - 'croppedarealeftpixels' => { 429 => 'CroppedAreaLeftPixels', 430 => 'CroppedAreaLeftPixels' }, - 'croppedareatoppixels' => { 429 => 'CroppedAreaTopPixels', 430 => 'CroppedAreaTopPixels' }, - 'croppedimageheight' => { 5 => 0x2, 358 => 0x1604 }, + 'contentlocationcode' => { 128 => 0x1a }, + 'contentlocationname' => { 128 => 0x1b }, + 'contenttype' => { 478 => 'contentType' }, + 'continuousbracketing' => { 179 => 0x20 }, + 'continuousdrive' => { 34 => 0x5 }, + 'continuousmodeliveview' => { 280 => '77.2' }, + 'continuousshootingspeed' => { 81 => 0x610 }, + 'continuousshotlimit' => { 81 => 0x611 }, + 'contrast' => { 10 => 0x73, 12 => 0x75, 34 => 0xd, 109 => 0xc, 110 => [0x3012,0x20], 116 => [0xa408,0xfe54], 124 => [0x1004,0x1006], 152 => 'Contrast', 172 => 'Contrast', 176 => 0x20, 177 => 0x31, 178 => 0x27, 179 => 0x19, 184 => 0x2, 221 => 0x33, 222 => 0x37, 223 => 0x3f, 288 => 0x1029, 306 => 0x39, 308 => 0x300a, 341 => 0x20, 348 => 0xc, 360 => 'player.movie.visual.contrast', 367 => 0x24, 369 => 0x52, 373 => 0x1012, 383 => 0xd, 393 => 0x1d, 394 => 0x1a, 406 => 0x2004, 462 => 'Contrast', 464 => 'Contrast', 468 => 'Contrast' }, + 'contrast2012' => { 462 => 'Contrast2012', 464 => 'Contrast2012' }, + 'contrastadj' => { 100 => 0x20303, 105 => 0x115, 262 => 0x2c, 439 => 0x8017 }, + 'contrastauto' => { 68 => 0x90 }, + 'contrastcurve' => { 219 => 0x8c }, + 'contrastdetectaf' => { 188 => 0x4 }, + 'contrastdetectafarea' => { 341 => 0x231 }, + 'contrastdetectafinfocus' => { 188 => [0x1c,0x52] }, + 'contrastfaithful' => { 19 => 0xec, 67 => 0x60, 68 => 0x60 }, + 'contrasthighlight' => { 341 => 0x6d }, + 'contrasthighlightshadowadj' => { 341 => 0x6f }, + 'contrastlandscape' => { 19 => 0xea, 67 => 0x30, 68 => 0x30 }, + 'contrastmode' => { 306 => 0x2c }, + 'contrastmonochrome' => { 19 => 0xed, 67 => 0x78, 68 => 0x78 }, + 'contrastneutral' => { 19 => 0xeb, 67 => 0x48, 68 => 0x48 }, + 'contrastportrait' => { 19 => 0xe9, 67 => 0x18, 68 => 0x18 }, + 'contrastsetting' => { 283 => 0x505, 291 => 0x1012, 395 => 0x10, 411 => 0x8 }, + 'contrastshadow' => { 341 => 0x6e }, + 'contraststandard' => { 19 => 0xe8, 67 => 0x0, 68 => 0x0 }, + 'contrastuserdef1' => { 19 => 0xee, 67 => 0x90, 68 => 0xa8 }, + 'contrastuserdef2' => { 19 => 0xef, 67 => 0xa8, 68 => 0xc0 }, + 'contrastuserdef3' => { 19 => 0xf0, 67 => 0xc0, 68 => 0xd8 }, + 'contributedmedia' => { 488 => 'contributedMedia' }, + 'contributedmediaduration' => { 488 => [\'contributedMedia','contributedMediaDuration'] }, + 'contributedmediadurationscale' => { 488 => [\'contributedMedia','contributedMediaDurationScale'] }, + 'contributedmediadurationvalue' => { 488 => [\'contributedMedia','contributedMediaDurationValue'] }, + 'contributedmediamanaged' => { 488 => [\'contributedMedia','contributedMediaManaged'] }, + 'contributedmediapath' => { 488 => [\'contributedMedia','contributedMediaPath'] }, + 'contributedmediastarttime' => { 488 => [\'contributedMedia','contributedMediaStartTime'] }, + 'contributedmediastarttimescale' => { 488 => [\'contributedMedia','contributedMediaStartTimeScale'] }, + 'contributedmediastarttimevalue' => { 488 => [\'contributedMedia','contributedMediaStartTimeValue'] }, + 'contributedmediatrack' => { 488 => [\'contributedMedia','contributedMediaTrack'] }, + 'contributedmediawebstatement' => { 488 => [\'contributedMedia','contributedMediaWebStatement'] }, + 'contributor' => { 465 => 'contributor', 474 => 'Contributor' }, + 'contributoridentifier' => { 474 => [\'Contributor','ContributorIdentifier'] }, + 'contributorname' => { 474 => [\'Contributor','ContributorName'] }, + 'contributorrole' => { 474 => [\'Contributor','ContributorRole'] }, + 'contributors' => { 153 => 'Contributors' }, + 'controldialset' => { 179 => 0x46 }, + 'controlledvocabularyterm' => { 474 => 'CVterm' }, + 'controllerboardversion' => { 301 => 0x332 }, + 'controlmode' => { 74 => 0x12 }, + 'controlringrotation' => { 81 => 0x712 }, + 'conversionlens' => { 284 => 0x403, 306 => 0x35 }, + 'converter' => { 116 => 0xfe4d, 249 => 0xb, 462 => 'Converter', 464 => 'Converter' }, + 'converttograyscale' => { 462 => 'ConvertToGrayscale', 464 => 'ConvertToGrayscale' }, + 'cookingequipment' => { 480 => 'cookingEquipment' }, + 'cookingmethod' => { 480 => 'cookingMethod' }, + 'copyright' => { 0 => 0x3, 116 => 0x8298, 153 => 'Copyright', 296 => 'Copyright', 341 => 0x22f, 357 => 'Copyright', 358 => ['cprt',"\xa9cpy"], 360 => 'copyright', 366 => ['cprt',"\xa9cpy"], 475 => 'Copyright', 481 => 'copyright', 484 => 'Copyright', 488 => 'copyright' }, + 'copyrightflag' => { 355 => 0x40a }, + 'copyrightnotice' => { 128 => 0x74 }, + 'copyrightowner' => { 293 => 'CopyrightOwner' }, + 'copyrightownerid' => { 293 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerID'] }, + 'copyrightownerimageid' => { 293 => 'CopyrightOwnerImageID' }, + 'copyrightownername' => { 293 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerName'] }, + 'copyrightregistrationnumber' => { 293 => 'CopyrightRegistrationNumber' }, + 'copyrightstatus' => { 293 => 'CopyrightStatus' }, + 'copyrightyear' => { 474 => 'CopyrightYear', 478 => 'copyrightYear' }, + 'coringfilter' => { 287 => 0x310, 288 => 0x102d, 291 => 0x310 }, + 'coringvalues' => { 287 => 0x311, 291 => 0x311 }, + 'corporateentity' => { 478 => 'corporateEntity' }, + 'country' => { 157 => 'Country', 306 => 0x69, 476 => 'Country' }, + 'country-primarylocationcode' => { 128 => 0x64 }, + 'country-primarylocationname' => { 128 => 0x65 }, + 'countrycode' => { 218 => 0x5, 353 => 'CountryCode', 473 => 'CountryCode' }, + 'course' => { 480 => 'course' }, + 'coverage' => { 465 => 'coverage' }, + 'coverart' => { 358 => 'covr' }, + 'coverdate' => { 478 => 'coverDate' }, + 'coverdisplaydate' => { 478 => 'coverDisplayDate' }, + 'coveruri' => { 366 => 'cvru' }, + 'cpufirmwareversion' => { 341 => 0x28 }, + 'crc32' => { 466 => 'crc32' }, + 'createdate' => { 116 => 0x9004, 153 => 'CreateDate', 292 => 'CreationDate', 296 => 'create-date', 357 => 'CreationDate', 363 => 0x1, 486 => 'CreateDate' }, + 'creationdate' => { 360 => 'creationdate', 475 => 'CreationDate', 478 => 'creationDate' }, + 'creationtime' => { 296 => 'Creation Time' }, + 'creativestyle' => { 393 => 0x1a, 394 => 0x18, 404 => 0x41, 406 => 0xb020, 435 => 0x4a }, + 'creativestylesetting' => { 395 => 0xf, 411 => 0x7 }, + 'creativestylewaschanged' => { 439 => 0x8001 }, + 'creator' => { 292 => 'Creator', 357 => 'Creator', 465 => 'creator', 474 => 'Creator', 475 => 'Creator' }, + 'creatoraddress' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiAdrExtadr'] }, + 'creatorappid' => { 174 => 'CreatorAppId' }, + 'creatorcity' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCity'] }, + 'creatorcontactinfo' => { 473 => 'CreatorContactInfo' }, + 'creatorcountry' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCtry'] }, + 'creatoridentifier' => { 474 => [\'Creator','CreatorIdentifier'] }, + 'creatorname' => { 474 => [\'Creator','CreatorName'] }, + 'creatoropenwithuioptions' => { 174 => 'CreatorOpenWithUIOptions' }, + 'creatorpostalcode' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiAdrPcode'] }, + 'creatorregion' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiAdrRegion'] }, + 'creatorrole' => { 474 => [\'Creator','CreatorRole'] }, + 'creatortool' => { 486 => 'CreatorTool' }, + 'creatorworkemail' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiEmailWork'] }, + 'creatorworktelephone' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiTelWork'] }, + 'creatorworkurl' => { 473 => [\'CreatorContactInfo','CreatorContactInfoCiUrlWork'] }, + 'credit' => { 128 => 0x6e, 476 => 'Credit' }, + 'creditline' => { 481 => 'creditLine' }, + 'creditlinereq' => { 491 => 'CreditLineReq' }, + 'creditlinerequired' => { 293 => 'CreditLineRequired' }, + 'cropactive' => { 98 => 0x0, 105 => 0x244 }, + 'cropangle' => { 462 => 'CropAngle', 464 => 'CropAngle' }, + 'croparea' => { 219 => 0x45, 439 => 0x9011 }, + 'cropaspectratio' => { 100 => 0x30101, 105 => 0x260 }, + 'cropaspectratiocustom' => { 100 => 0x30102 }, + 'cropbottom' => { 120 => 0x9, 254 => 0x36, 311 => 0x31, 352 => 0xdc, 462 => 'CropBottom', 464 => 'CropBottom' }, + 'cropbottommargin' => { 51 => 0x3 }, + 'cropcircleactive' => { 106 => 0xd6 }, + 'cropcircleradius' => { 106 => 0xd9 }, + 'cropcirclex' => { 106 => 0xd7 }, + 'cropcircley' => { 106 => 0xd8 }, + 'cropconstraintowarp' => { 462 => 'CropConstrainToWarp', 464 => 'CropConstrainToWarp' }, + 'croph' => { 456 => 'CropH' }, + 'cropheight' => { 98 => 0x6, 105 => 0x24c, 287 => 0x615, 291 => 0x615, 462 => 'CropHeight', 464 => 'CropHeight' }, + 'crophispeed' => { 219 => 0x1b }, + 'cropleft' => { 105 => 0x246, 120 => 0x6, 254 => 0x1e, 287 => 0x612, 291 => 0x612, 311 => 0x30, 352 => 0xd9, 462 => 'CropLeft', 464 => 'CropLeft' }, + 'cropleftmargin' => { 51 => 0x0 }, + 'cropmode' => { 124 => 0x104d, 373 => 0x1018 }, + 'croporiginalheight' => { 98 => 0xb }, + 'croporiginalwidth' => { 98 => 0xa }, + 'cropoutputheight' => { 254 => 0xce }, + 'cropoutputheightinches' => { 254 => 0x96 }, + 'cropoutputpixels' => { 254 => 0xd6 }, + 'cropoutputresolution' => { 254 => 0xb6 }, + 'cropoutputscale' => { 254 => 0xbe }, + 'cropoutputwidth' => { 254 => 0xc6 }, + 'cropoutputwidthinches' => { 254 => 0x8e }, + 'croppedareaimageheightpixels' => { 450 => 'CroppedAreaImageHeightPixels', 451 => 'CroppedAreaImageHeightPixels' }, + 'croppedareaimagewidthpixels' => { 450 => 'CroppedAreaImageWidthPixels', 451 => 'CroppedAreaImageWidthPixels' }, + 'croppedarealeftpixels' => { 450 => 'CroppedAreaLeftPixels', 451 => 'CroppedAreaLeftPixels' }, + 'croppedareatoppixels' => { 450 => 'CroppedAreaTopPixels', 451 => 'CroppedAreaTopPixels' }, + 'croppedimageheight' => { 5 => 0x2, 373 => 0x1604 }, 'croppedimageleft' => { 5 => 0x3 }, 'croppedimagetop' => { 5 => 0x4 }, - 'croppedimagewidth' => { 5 => 0x1, 358 => 0x1603 }, - 'cropping' => { 421 => 0x9010 }, - 'cropright' => { 117 => 0x8, 245 => 0x2e, 302 => 0x32, 343 => 0xdb, 442 => 'CropRight' }, - 'croprightmargin' => { 50 => 0x1 }, - 'croprotatedoriginalheight' => { 95 => 0x2 }, - 'croprotatedoriginalwidth' => { 95 => 0x1 }, - 'croprotation' => { 95 => 0x8, 117 => 0xb }, - 'cropscaledresolution' => { 245 => 0x9e }, - 'cropsourceresolution' => { 245 => 0xae }, - 'croptop' => { 102 => 0x248, 117 => 0x7, 245 => 0x26, 278 => 0x613, 282 => 0x613, 302 => 0x2f, 343 => 0xda, 442 => 'CropTop' }, - 'croptopmargin' => { 50 => 0x2 }, - 'cropunit' => { 442 => 'CropUnit' }, - 'cropunits' => { 442 => 'CropUnits' }, - 'cropw' => { 435 => 'CropW' }, - 'cropwidth' => { 95 => 0x5, 102 => 0x24a, 278 => 0x614, 282 => 0x614, 442 => 'CropWidth' }, - 'cropx' => { 95 => 0x3, 435 => 'CropX' }, - 'cropy' => { 95 => 0x4, 435 => 'CropY' }, - 'crossprocess' => { 332 => 0x7b }, - 'crossprocessparams' => { 332 => 0x235 }, - 'cuisine' => { 458 => 'cuisine' }, - 'currenticcprofile' => { 113 => 0xc691 }, - 'currentpreprofilematrix' => { 113 => 0xc692 }, - 'currentversion' => { 421 => 0xd000 }, - 'curve0x' => { 435 => 'Curve0x' }, - 'curve0y' => { 435 => 'Curve0y' }, - 'curve1x' => { 435 => 'Curve1x' }, - 'curve1y' => { 435 => 'Curve1y' }, - 'curve2x' => { 435 => 'Curve2x' }, - 'curve2y' => { 435 => 'Curve2y' }, - 'curve3x' => { 435 => 'Curve3x' }, - 'curve3y' => { 435 => 'Curve3y' }, - 'curve4x' => { 435 => 'Curve4x' }, - 'curve4y' => { 435 => 'Curve4y' }, - 'curves' => { 250 => 0x76a43201 }, - 'custom1' => { 284 => 'Custom1' }, - 'custom10' => { 284 => 'Custom10' }, - 'custom2' => { 284 => 'Custom2' }, - 'custom3' => { 284 => 'Custom3' }, - 'custom4' => { 284 => 'Custom4' }, - 'custom5' => { 284 => 'Custom5' }, - 'custom6' => { 284 => 'Custom6' }, - 'custom7' => { 284 => 'Custom7' }, - 'custom8' => { 284 => 'Custom8' }, - 'custom9' => { 284 => 'Custom9' }, - 'customcolortone' => { 103 => 0x4c }, - 'customcontrast' => { 103 => 0x4e }, - 'customcontrols' => { 78 => 0x70c }, - 'customdefaultunsharpfineness' => { 103 => 0xbe }, - 'customdefaultunsharpstrength' => { 103 => 0xbc }, - 'customdefaultunsharpthreshold' => { 103 => 0xc0 }, - 'customilluminant' => { 131 => 0x405 }, - 'customizedials' => { 78 => 0x715 }, - 'customlinear' => { 103 => 0x4f }, - 'customoutputhighlightpoint' => { 103 => 0x53 }, - 'customoutputshadowpoint' => { 103 => 0x54 }, - 'custompicturestyle' => { 97 => 0x10021 }, - 'custompicturestyledata' => { 97 => 0xf0500 }, - 'custompicturestylefilename' => { 60 => 0x4010 }, - 'customrawhighlight' => { 103 => 0x7c }, - 'customrawhighlightpoint' => { 103 => 0x51 }, - 'customrawshadow' => { 103 => 0x85 }, - 'customrawshadowpoint' => { 103 => 0x52 }, - 'customrendered' => { 113 => 0xa401, 446 => 'CustomRendered' }, - 'customsaturation' => { 103 => 0x4d, 274 => 0x503 }, - 'customsettingsalldefault' => { 257 => '0.2', 266 => '0.2' }, - 'customsettingsbank' => { 257 => '0.1', 258 => '0.1', 260 => '0.1', 261 => '0.1', 266 => '0.1', 270 => '0.2', 271 => '0.2' }, - 'customsharpness' => { 103 => 0x50 }, - 'customunsharpmaskfineness' => { 103 => 0xb8 }, - 'customunsharpmaskstrength' => { 103 => 0xb6 }, - 'customunsharpmaskthreshold' => { 103 => 0xba }, - 'customwb_rblevels' => { 393 => 0x1a }, - 'customwb_rgblevels' => { 377 => 0x8, 378 => 0x19 }, - 'customwbbluelevel' => { 174 => 0x36 }, - 'customwberror' => { 174 => 0x37 }, - 'customwbgreenlevel' => { 174 => 0x35 }, - 'customwbredlevel' => { 174 => 0x34 }, - 'customwbsetting' => { 174 => 0x26 }, - 'd-lightinghq' => { 250 => 0x2175eb78 }, - 'd-lightinghqcolorboost' => { 246 => 0x2 }, - 'd-lightinghqhighlight' => { 246 => 0x1 }, - 'd-lightinghqselected' => { 250 => 0x6a6e36b6 }, - 'd-lightinghqshadow' => { 246 => 0x0 }, - 'd-lightinghs' => { 250 => 0xce5554aa }, - 'd-lightinghsadjustment' => { 247 => 0x0 }, - 'd-lightinghscolorboost' => { 247 => 0x1 }, - 'd-rangeoptimizerhighlight' => { 421 => 0x8024 }, - 'd-rangeoptimizermode' => { 421 => 0x8022 }, - 'd-rangeoptimizershadow' => { 421 => 0x802d }, - 'd-rangeoptimizervalue' => { 421 => 0x8023 }, - 'd810meteringmode' => { 237 => 0x175e }, - 'darkblacksegrows' => { 131 => 0x18d8 }, - 'darkfocusenvironment' => { 297 => 0x8003 }, - 'darkframecountfactor' => { 131 => 0xc85 }, - 'darkframelongexposure' => { 131 => 0xc84 }, - 'darkframeshortexposure' => { 131 => 0xc83 }, - 'darkpedestal' => { 131 => 0xc7f }, - 'data' => { 426 => 'Data' }, - 'datacompressionmethod' => { 127 => 0x6e }, - 'dataimprint' => { 171 => 0x34 }, - 'dataonscreen' => { 452 => 'DataOnScreen' }, - 'dataonscreenregion' => { 452 => [\'DataOnScreen','DataOnScreenRegion'] }, - 'dataonscreenregiond' => { 452 => [\'DataOnScreen','DataOnScreenRegionD'] }, - 'dataonscreenregionh' => { 452 => [\'DataOnScreen','DataOnScreenRegionH'] }, - 'dataonscreenregiontext' => { 452 => [\'DataOnScreen','DataOnScreenRegionText'] }, - 'dataonscreenregionunit' => { 452 => [\'DataOnScreen','DataOnScreenRegionUnit'] }, - 'dataonscreenregionw' => { 452 => [\'DataOnScreen','DataOnScreenRegionW'] }, - 'dataonscreenregionx' => { 452 => [\'DataOnScreen','DataOnScreenRegionX'] }, - 'dataonscreenregiony' => { 452 => [\'DataOnScreen','DataOnScreenRegionY'] }, - 'datascaling' => { 332 => 0x3d }, - 'date' => { 332 => 0x6, 443 => 'date' }, - 'dateacquired' => { 169 => 'DateAcquired' }, - 'datecreated' => { 125 => 0x37, 454 => 'DateCreated' }, - 'datedisplayformat' => { 242 => 0x3 }, - 'dateidentified' => { 112 => [\'Identification','IdentificationDateIdentified'] }, - 'dateimprint' => { 262 => '4.2' }, - 'daterecieved' => { 456 => 'dateRecieved' }, - 'datesent' => { 126 => 0x46 }, - 'datestampmode' => { 60 => 0x1c }, - 'datetime' => { 436 => 'datetime', 462 => 'DateTime' }, - 'datetimedigitized' => { 446 => 'DateTimeDigitized' }, - 'datetimeoriginal' => { 94 => 0x0, 113 => 0x9003, 145 => 0x14, 148 => 'OriginalDate', 353 => 0xb, 354 => 0x3b, 446 => 'DateTimeOriginal' }, - 'datetimestamp' => { 133 => 0x64 }, - 'datetimeutc' => { 274 => 0x908 }, - 'daylightsavings' => { 73 => 0x3, 242 => 0x2 }, - 'dayofweek' => { 354 => 0x42 }, - 'dccontinent' => { 112 => [\'dctermsLocation','dctermsLocationContinent'] }, - 'dccoordinateprecision' => { 112 => [\'dctermsLocation','dctermsLocationCoordinatePrecision'] }, - 'dccoordinateuncertaintyinmeters' => { 112 => [\'dctermsLocation','dctermsLocationCoordinateUncertaintyInMeters'] }, - 'dccountry' => { 112 => [\'dctermsLocation','dctermsLocationCountry'] }, - 'dccountrycode' => { 112 => [\'dctermsLocation','dctermsLocationCountryCode'] }, - 'dccounty' => { 112 => [\'dctermsLocation','dctermsLocationCounty'] }, - 'dcdecimallatitude' => { 112 => [\'dctermsLocation','dctermsLocationDecimalLatitude'] }, - 'dcdecimallongitude' => { 112 => [\'dctermsLocation','dctermsLocationDecimalLongitude'] }, - 'dcevent' => { 112 => 'Event' }, - 'dcfootprintspatialfit' => { 112 => [\'dctermsLocation','dctermsLocationFootprintSpatialFit'] }, - 'dcfootprintsrs' => { 112 => [\'dctermsLocation','dctermsLocationFootprintSRS'] }, - 'dcfootprintwkt' => { 112 => [\'dctermsLocation','dctermsLocationFootprintWKT'] }, - 'dcgeodeticdatum' => { 112 => [\'dctermsLocation','dctermsLocationGeodeticDatum'] }, - 'dcgeoreferencedby' => { 112 => [\'dctermsLocation','dctermsLocationGeoreferencedBy'] }, - 'dcgeoreferenceddate' => { 112 => [\'dctermsLocation','dctermsLocationGeoreferencedDate'] }, - 'dcgeoreferenceprotocol' => { 112 => [\'dctermsLocation','dctermsLocationGeoreferenceProtocol'] }, - 'dcgeoreferenceremarks' => { 112 => [\'dctermsLocation','dctermsLocationGeoreferenceRemarks'] }, - 'dcgeoreferencesources' => { 112 => [\'dctermsLocation','dctermsLocationGeoreferenceSources'] }, - 'dcgeoreferenceverificationstatus' => { 112 => [\'dctermsLocation','dctermsLocationGeoreferenceVerificationStatus'] }, - 'dchighergeography' => { 112 => [\'dctermsLocation','dctermsLocationHigherGeography'] }, - 'dchighergeographyid' => { 112 => [\'dctermsLocation','dctermsLocationHigherGeographyID'] }, - 'dcisland' => { 112 => [\'dctermsLocation','dctermsLocationIsland'] }, - 'dcislandgroup' => { 112 => [\'dctermsLocation','dctermsLocationIslandGroup'] }, - 'dclocality' => { 112 => [\'dctermsLocation','dctermsLocationLocality'] }, - 'dclocationaccordingto' => { 112 => [\'dctermsLocation','dctermsLocationLocationAccordingTo'] }, - 'dclocationid' => { 112 => [\'dctermsLocation','dctermsLocationLocationID'] }, - 'dclocationremarks' => { 112 => [\'dctermsLocation','dctermsLocationLocationRemarks'] }, - 'dcmaximumdepthinmeters' => { 112 => [\'dctermsLocation','dctermsLocationMaximumDepthInMeters'] }, - 'dcmaximumdistanceabovesurfaceinmeters' => { 112 => [\'dctermsLocation','dctermsLocationMaximumDistanceAboveSurfaceInMeters'] }, - 'dcmaximumelevationinmeters' => { 112 => [\'dctermsLocation','dctermsLocationMaximumElevationInMeters'] }, - 'dcminimumdepthinmeters' => { 112 => [\'dctermsLocation','dctermsLocationMinimumDepthInMeters'] }, - 'dcminimumdistanceabovesurfaceinmeters' => { 112 => [\'dctermsLocation','dctermsLocationMinimumDistanceAboveSurfaceInMeters'] }, - 'dcminimumelevationinmeters' => { 112 => [\'dctermsLocation','dctermsLocationMinimumElevationInMeters'] }, - 'dcmunicipality' => { 112 => [\'dctermsLocation','dctermsLocationMunicipality'] }, - 'dcpointradiusspatialfit' => { 112 => [\'dctermsLocation','dctermsLocationPointRadiusSpatialFit'] }, - 'dcstateprovince' => { 112 => [\'dctermsLocation','dctermsLocationStateProvince'] }, - 'dctermslocation' => { 112 => 'dctermsLocation' }, - 'dcverbatimcoordinates' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimCoordinates'] }, - 'dcverbatimcoordinatesystem' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimCoordinateSystem'] }, - 'dcverbatimdepth' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimDepth'] }, - 'dcverbatimelevation' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimElevation'] }, - 'dcverbatimlatitude' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimLatitude'] }, - 'dcverbatimlocality' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimLocality'] }, - 'dcverbatimlongitude' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimLongitude'] }, - 'dcverbatimsrs' => { 112 => [\'dctermsLocation','dctermsLocationVerbatimSRS'] }, - 'dcwaterbody' => { 112 => [\'dctermsLocation','dctermsLocationWaterBody'] }, - 'declination' => { 156 => 'Declination' }, - 'decposition' => { 171 => 0x32 }, - 'defaultautogray' => { 442 => 'DefaultAutoGray' }, - 'defaultautotone' => { 442 => 'DefaultAutoTone' }, - 'defaultblackrender' => { 113 => 0xc7a6 }, - 'defaultcroporigin' => { 113 => 0xc61f }, - 'defaultcropsize' => { 113 => 0xc620 }, - 'defaulteraseoption' => { 78 => 0x813 }, - 'defaultscale' => { 113 => 0xc61e }, - 'defaultsspecifictoiso' => { 442 => 'DefaultsSpecificToISO' }, - 'defaultsspecifictoserial' => { 442 => 'DefaultsSpecificToSerial' }, - 'defaultusercrop' => { 113 => 0xc7b5 }, - 'defectisocode' => { 131 => 0x90f }, - 'defringe' => { 442 => 'Defringe' }, - 'defringegreenamount' => { 442 => 'DefringeGreenAmount' }, - 'defringegreenhuehi' => { 442 => 'DefringeGreenHueHi' }, - 'defringegreenhuelo' => { 442 => 'DefringeGreenHueLo' }, - 'defringepurpleamount' => { 442 => 'DefringePurpleAmount' }, - 'defringepurplehuehi' => { 442 => 'DefringePurpleHueHi' }, - 'defringepurplehuelo' => { 442 => 'DefringePurpleHueLo' }, - 'dehaze' => { 442 => 'Dehaze' }, - 'deletedimagecount' => { 211 => 0xa6, 219 => 0x6e }, - 'deprecatedon' => { 439 => 'deprecatedOn' }, - 'derivedfrom' => { 467 => 'DerivedFrom' }, - 'derivedfromalternatepaths' => { 467 => [\'DerivedFrom','DerivedFromAlternatePaths'] }, - 'derivedfromdocumentid' => { 467 => [\'DerivedFrom','DerivedFromDocumentID'] }, - 'derivedfromfilepath' => { 467 => [\'DerivedFrom','DerivedFromFilePath'] }, - 'derivedfromfrompart' => { 467 => [\'DerivedFrom','DerivedFromFromPart'] }, - 'derivedfrominstanceid' => { 467 => [\'DerivedFrom','DerivedFromInstanceID'] }, - 'derivedfromlastmodifydate' => { 467 => [\'DerivedFrom','DerivedFromLastModifyDate'] }, - 'derivedfromlasturl' => { 467 => [\'DerivedFrom','DerivedFromLastURL'] }, - 'derivedfromlinkcategory' => { 467 => [\'DerivedFrom','DerivedFromLinkCategory'] }, - 'derivedfromlinkform' => { 467 => [\'DerivedFrom','DerivedFromLinkForm'] }, - 'derivedfrommanager' => { 467 => [\'DerivedFrom','DerivedFromManager'] }, - 'derivedfrommanagervariant' => { 467 => [\'DerivedFrom','DerivedFromManagerVariant'] }, - 'derivedfrommanageto' => { 467 => [\'DerivedFrom','DerivedFromManageTo'] }, - 'derivedfrommanageui' => { 467 => [\'DerivedFrom','DerivedFromManageUI'] }, - 'derivedfrommaskmarkers' => { 467 => [\'DerivedFrom','DerivedFromMaskMarkers'] }, - 'derivedfromoriginaldocumentid' => { 467 => [\'DerivedFrom','DerivedFromOriginalDocumentID'] }, - 'derivedfrompartmapping' => { 467 => [\'DerivedFrom','DerivedFromPartMapping'] }, - 'derivedfromplacedresolutionunit' => { 467 => [\'DerivedFrom','DerivedFromPlacedResolutionUnit'] }, - 'derivedfromplacedxresolution' => { 467 => [\'DerivedFrom','DerivedFromPlacedXResolution'] }, - 'derivedfromplacedyresolution' => { 467 => [\'DerivedFrom','DerivedFromPlacedYResolution'] }, - 'derivedfromrenditionclass' => { 467 => [\'DerivedFrom','DerivedFromRenditionClass'] }, - 'derivedfromrenditionparams' => { 467 => [\'DerivedFrom','DerivedFromRenditionParams'] }, - 'derivedfromtopart' => { 467 => [\'DerivedFrom','DerivedFromToPart'] }, - 'derivedfromversionid' => { 467 => [\'DerivedFrom','DerivedFromVersionID'] }, - 'description' => { 287 => 'Description', 443 => 'description', 464 => 'Description' }, - 'destination' => { 126 => 0x5 }, - 'destinationcity' => { 332 => 0x24, 338 => 0x3 }, - 'destinationcitycode' => { 339 => 0x1001 }, - 'destinationdst' => { 332 => 0x26, 338 => '0.3' }, - 'developmentdynamicrange' => { 121 => 0x1403 }, - 'deviantmatrixcustom' => { 131 => 0x7de }, - 'deviantmatrixdaylight' => { 131 => 0x7da }, - 'deviantmatrixflash' => { 131 => 0x7dd }, - 'deviantmatrixfluorescent' => { 131 => 0x7dc }, - 'deviantmatrixtungsten' => { 131 => 0x7db }, - 'deviantwhitecustom' => { 131 => 0x842 }, - 'deviantwhitedaylight' => { 131 => 0x83e }, - 'deviantwhiteflash' => { 131 => 0x841 }, - 'deviantwhitefluorescent' => { 131 => 0x840 }, - 'deviantwhitetungsten' => { 131 => 0x83f }, - 'device' => { 456 => 'device' }, - 'devicesettingdescription' => { 446 => 'DeviceSettingDescription' }, - 'devicesettingdescriptioncolumns' => { 446 => [\'DeviceSettingDescription','DeviceSettingDescriptionColumns'] }, - 'devicesettingdescriptionrows' => { 446 => [\'DeviceSettingDescription','DeviceSettingDescriptionRows'] }, - 'devicesettingdescriptionsettings' => { 446 => [\'DeviceSettingDescription','DeviceSettingDescriptionSettings'] }, - 'devicetype' => { 365 => 0x2 }, - 'dialdirectiontvav' => { 78 => 0x706 }, - 'dietaryneeds' => { 458 => 'dietaryNeeds' }, - 'diffractioncorrection' => { 297 => 0xbc, 322 => 0x3 }, - 'diffractioncorrectionon' => { 97 => 0x2070b }, - 'digitalcreationdate' => { 125 => 0x3e }, - 'digitalcreationtime' => { 125 => 0x3f }, - 'digitaldeehighlightadj' => { 218 => 0x202 }, - 'digitaldeeshadowadj' => { 218 => 0x200 }, - 'digitaldeethreshold' => { 218 => 0x201 }, - 'digitalfilter' => { 368 => 0x59 }, - 'digitalfilter01' => { 319 => 0x5 }, - 'digitalfilter02' => { 319 => 0x16 }, - 'digitalfilter03' => { 319 => 0x27 }, - 'digitalfilter04' => { 319 => 0x38 }, - 'digitalfilter05' => { 319 => 0x49 }, - 'digitalfilter06' => { 319 => 0x5a }, - 'digitalfilter07' => { 319 => 0x6b }, - 'digitalfilter08' => { 319 => 0x7c }, - 'digitalfilter09' => { 319 => 0x8d }, - 'digitalfilter10' => { 319 => 0x9e }, - 'digitalfilter11' => { 319 => 0xaf }, - 'digitalfilter12' => { 319 => 0xc0 }, - 'digitalfilter13' => { 319 => 0xd1 }, - 'digitalfilter14' => { 319 => 0xe2 }, - 'digitalfilter15' => { 319 => 0xf3 }, - 'digitalfilter16' => { 319 => 0x104 }, - 'digitalfilter17' => { 319 => 0x115 }, - 'digitalfilter18' => { 319 => 0x126 }, - 'digitalfilter19' => { 319 => 0x137 }, - 'digitalfilter20' => { 319 => 0x148 }, - 'digitalgain' => { 70 => 0xb }, - 'digitalgem' => { 203 => 0x0 }, - 'digitalice' => { 218 => 0x100 }, - 'digitalimageguid' => { 452 => 'DigImageGUID' }, - 'digitalroc' => { 216 => 0x0 }, - 'digitalsourcefiletype' => { 452 => 'DigitalSourcefileType' }, - 'digitalsourcetype' => { 452 => 'DigitalSourceType' }, - 'digitalzoom' => { 33 => 0xc, 106 => 0xa, 121 => 0x1044, 133 => 0x68, 147 => 'DigitalZoom', 171 => 0xc, 211 => 0x86, 240 => 0xa, 279 => 0x204, 332 => 0x1e, 339 => 0xa, 367 => 0x204, 408 => 0x12, 409 => 0x12 }, - 'digitalzoomon' => { 367 => 0x21b }, - 'digitalzoomratio' => { 113 => 0xa404, 398 => 0x200, 400 => 0x21c, 446 => 'DigitalZoomRatio' }, - 'director' => { 466 => 'director' }, - 'directorphotography' => { 466 => 'directorPhotography' }, - 'directory' => { 114 => 'Directory' }, - 'directoryindex' => { 6 => 0x137, 8 => 0x2dc, 10 => 0x17e, 12 => 0x238, 13 => 0x13f, 14 => 0x133, 15 => 0x1df, 16 => 0x1a7, 17 => 0x1f0, 18 => 0xcc, 19 => 0x1c7, 20 => 0x298, 21 => 0x1e7, 22 => 0x1e5, 23 => [0x27c,0x280], 24 => 0x2b6, 25 => 0x2bf, 27 => 0x1f7, 28 => 0x4ba }, - 'directoryindex2' => { 20 => 0x29c }, - 'directorynumber' => { 197 => 0x3 }, - 'disclaimer' => { 287 => 'Disclaimer' }, - 'discnumber' => { 466 => 'discNumber' }, - 'dishtype' => { 458 => 'dishType' }, - 'displayallafpoints' => { 78 => 0x514 }, - 'displayaperture' => { 33 => 0x23 }, - 'displayedunitsx' => { 347 => 0x2 }, - 'displayedunitsy' => { 347 => 0x6 }, - 'displayname' => { 455 => 'displayName' }, - 'distance1' => { 133 => 0x28 }, - 'distance2' => { 133 => 0x2c }, - 'distance3' => { 133 => 0x30 }, - 'distance4' => { 133 => 0x34 }, - 'distortion' => { 365 => 0xa050 }, - 'distortioncompensation' => { 421 => 0x8040 }, - 'distortioncontrol' => { 219 => 0x10 }, - 'distortioncorrection' => { 97 => 0x20705, 103 => 0x67, 113 => 0x7036, 274 => 0x50b, 301 => '7.1', 322 => 0x0, 416 => 0x601, 417 => 0x5b }, - 'distortioncorrection2' => { 278 => 0x1011 }, - 'distortioncorrectionalreadyapplied' => { 438 => 'DistortionCorrectionAlreadyApplied' }, - 'distortioncorrectionon' => { 97 => '0x20705.0', 103 => 0x63 }, - 'distortioncorrectionsetting' => { 388 => 0x2013 }, - 'distortioncorrparams' => { 113 => 0x7037, 397 => 0x1a23, 400 => 0x1870, 402 => 0x189c, 403 => 0x18cc, 404 => 0x17d0, 416 => 0x6ca, 417 => 0x64 }, - 'distortioncorrparamsnumber' => { 400 => 0x1899, 402 => 0x18c5, 403 => 0x18f5, 404 => 0x17f9 }, - 'distortioncorrparamspresent' => { 400 => 0x1898, 402 => 0x18c4, 403 => 0x18f4, 404 => 0x17f8, 406 => 0x10b, 407 => 0x10b, 416 => 0x600, 417 => 0x5a }, - 'distortioneffect' => { 97 => 0x20709 }, - 'distortionn' => { 301 => 0xc }, - 'distortionparam02' => { 301 => 0x2 }, - 'distortionparam04' => { 301 => 0x4 }, - 'distortionparam08' => { 301 => 0x8 }, - 'distortionparam09' => { 301 => 0x9 }, - 'distortionparam11' => { 301 => 0xb }, - 'distortionscale' => { 301 => 0x5 }, - 'distributor' => { 456 => 'distributor' }, - 'distributorproductid' => { 455 => 'distributorProductID' }, - 'dloon' => { 97 => '0x20706.0', 103 => 0xdc }, - 'dlosetting' => { 97 => 0x20706, 103 => 0xdd }, - 'dlosettingapplied' => { 96 => 0x4 }, - 'dloshootingdistance' => { 103 => 0xde }, - 'dloversion' => { 96 => 0x5 }, - 'dmcomment' => { 466 => 'comment' }, - 'dmdithermatrix' => { 131 => 0xc7a }, - 'dmdithermatrixheight' => { 131 => 0xc7c }, - 'dmdithermatrixwidth' => { 131 => 0xc7b }, - 'dngadobedata' => { 113 => 0xc634 }, - 'dngbackwardversion' => { 113 => 0xc613 }, - 'dngignoresidecars' => { 442 => 'DNGIgnoreSidecars' }, - 'dnglensinfo' => { 113 => 0xc630 }, - 'dngprivatedata' => { 113 => 0xc634 }, - 'dngversion' => { 113 => 0xc612 }, - 'document' => { 287 => 'Document' }, - 'documentancestors' => { 454 => 'DocumentAncestors' }, - 'documenthistory' => { 125 => 0xe7 }, - 'documentid' => { 467 => 'DocumentID' }, - 'documentname' => { 113 => 0x10d }, - 'documentnotes' => { 125 => 0xe6 }, - 'doi' => { 456 => 'doi' }, - 'dopesheet' => { 452 => 'Dopesheet' }, - 'dopesheetlink' => { 452 => 'DopesheetLink' }, - 'dopesheetlinklink' => { 452 => [\'DopesheetLink','DopesheetLinkLink'] }, - 'dopesheetlinklinkqualifier' => { 452 => [\'DopesheetLink','DopesheetLinkLinkQualifier'] }, - 'doublingmicrovolts' => { 131 => 0xc82 }, - 'dpp' => { 436 => 'dpp' }, - 'dr4cameramodel' => { 98 => 0x3 }, - 'drangepriority' => { 121 => 0x1443 }, - 'drangepriorityauto' => { 121 => 0x1444 }, - 'drangepriorityfixed' => { 121 => 0x1445 }, - 'drivemode' => { 107 => 0x3103, 119 => '0.1', 171 => 0x6, 174 => 0x1e, 177 => 0xe, 274 => 0x600, 332 => 0x34, 358 => 0x1002, 368 => 0x3, 376 => 0x4, 377 => 0x7e, 378 => 0x34 }, - 'drivemode2' => { 174 => 0xa, 313 => 0x7, 387 => 0xe, 393 => 0x1 }, - 'drivemodesetting' => { 378 => 0x4 }, - 'drivespeed' => { 119 => '0.2' }, - 'dspfirmwareversion' => { 332 => 0x27 }, - 'duration' => { 63 => 0x6a, 146 => 'Duration', 160 => 'Duration', 458 => 'duration', 466 => 'duration' }, - 'durationscale' => { 466 => [\'duration','durationScale'] }, - 'durationvalue' => { 466 => [\'duration','durationValue'] }, - 'dustremovaldata' => { 60 => 0x97 }, - 'dynamicafarea' => { 257 => '1.4', 266 => '1.4' }, - 'dynamicareaafdisplay' => { 258 => '46.1', 260 => '47.1', 261 => '47.1', 270 => '47.1', 271 => '47.1' }, - 'dynamicrange' => { 121 => 0x1400 }, - 'dynamicrangeexpansion' => { 332 => 0x69, 358 => 0x100e }, - 'dynamicrangemax' => { 102 => 0x7c }, - 'dynamicrangemin' => { 102 => 0x7a }, - 'dynamicrangeoptimizer' => { 174 => 0x15, 388 => [0xb025,0xb04f], 396 => 0x1144, 397 => [0x1144,0x324], 398 => [0x1120,0x300], 399 => [0x119c,0x37c], 400 => [0x1178,0x328], 401 => [0x1030,0x50], 402 => [0x228,0x50], 403 => [0x228,0x50], 404 => [0x21b,0x4e] }, - 'dynamicrangeoptimizerbracket' => { 387 => 0x2e }, - 'dynamicrangeoptimizerlevel' => { 376 => 0x19, 377 => 0x17, 378 => 0xd, 387 => 0x79, 393 => 0x5 }, - 'dynamicrangeoptimizermode' => { 177 => 0x15, 376 => 0x18, 377 => 0x16, 387 => [0x77,0x15] }, - 'dynamicrangeoptimizersetting' => { 174 => 0x27, 378 => 0xc, 393 => 0x4 }, - 'dynamicrangesetting' => { 121 => 0x1402 }, - 'e-dialinprogram' => { 313 => '1.3' }, - 'earliestageorloweststage' => { 112 => [\'GeologicalContext','GeologicalContextEarliestAgeOrLowestStage'] }, - 'earliesteonorlowesteonothem' => { 112 => [\'GeologicalContext','GeologicalContextEarliestEonOrLowestEonothem'] }, - 'earliestepochorlowestseries' => { 112 => [\'GeologicalContext','GeologicalContextEarliestEpochOrLowestSeries'] }, - 'earliesteraorlowesterathem' => { 112 => [\'GeologicalContext','GeologicalContextEarliestEraOrLowestErathem'] }, - 'earliestperiodorlowestsystem' => { 112 => [\'GeologicalContext','GeologicalContextEarliestPeriodOrLowestSystem'] }, - 'easyexposurecomp' => { 272 => '6.1' }, - 'easyexposurecompensation' => { 257 => '6.4', 258 => '6.5', 260 => '6.3', 261 => '6.3', 265 => '5.1', 266 => '4.4', 267 => '5.2', 270 => '6.3', 271 => '6.3' }, - 'easymode' => { 33 => 0xb }, - 'edgemapslope' => { 131 => 0x930 }, - 'edgemapx1' => { 131 => 0x931 }, - 'edgemapx2' => { 131 => 0x932 }, - 'edgemapx3' => { 131 => 0x934 }, - 'edgemapx4' => { 131 => 0x935 }, - 'edgenoisereduction' => { 251 => 0x4, 421 => 0x8028 }, - 'edition' => { 456 => 'edition' }, - 'editorialupdate' => { 125 => 0x8 }, - 'editstatus' => { 125 => 0x7, 344 => 'EditStatus', 436 => 'EditStatus' }, - 'editversionname' => { 250 => 0x3d136244 }, - 'effectivelv' => { 332 => 0x2d }, - 'effectivemaxaperture' => { 207 => 0x12, 208 => 0x13 }, - 'eissn' => { 456 => 'eIssn' }, - 'electricalblackcolumns' => { 131 => 0x1810 }, - 'electronicfront-curtainshutter' => { 260 => '5.2', 261 => '5.2', 270 => '5.3', 271 => '5.2' }, - 'electronicfrontcurtainshutter' => { 388 => 0x201a }, - 'elevation' => { 156 => 'Elevation' }, - 'email' => { 148 => 'EMail' }, - 'embargodate' => { 459 => 'embargoDate' }, - 'embdencrightsexpr' => { 452 => 'EmbdEncRightsExpr' }, - 'embeddedencodedrightsexpr' => { 452 => [\'EmbdEncRightsExpr','EmbdEncRightsExprEncRightsExpr'] }, - 'embeddedencodedrightsexprlangid' => { 452 => [\'EmbdEncRightsExpr','EmbdEncRightsExprRightsExprLangId'] }, - 'embeddedencodedrightsexprtype' => { 452 => [\'EmbdEncRightsExpr','EmbdEncRightsExprRightsExprEncType'] }, - 'embeddedxmpdigest' => { 454 => 'EmbeddedXMPDigest' }, - 'emissivity' => { 115 => 0x3 }, - 'enablechromanoisereduction' => { 131 => 0xe6e }, - 'enablesharpening' => { 131 => 0x92e }, - 'encryptionkey' => { 365 => 0xa020 }, - 'endingpage' => { 456 => 'endingPage' }, - 'enduser' => { 284 => 'EndUser' }, - 'enduserid' => { 284 => [\'EndUser','EndUserEndUserID'] }, - 'endusername' => { 284 => [\'EndUser','EndUserEndUserName'] }, - 'engineer' => { 466 => 'engineer' }, - 'enhancedarktones' => { 243 => 0x8 }, - 'enhancement' => { 106 => 0x16, 107 => 0x3016 }, - 'enhancer' => { 278 => 0x300 }, - 'enhancervalues' => { 278 => 0x301 }, - 'envelopenumber' => { 126 => 0x28 }, - 'envelopepriority' => { 126 => 0x3c }, - 'enveloperecordversion' => { 126 => 0x0 }, - 'episode' => { 452 => 'Episode' }, - 'episodeidentifier' => { 452 => [\'Episode','EpisodeIdentifier'] }, - 'episodename' => { 452 => [\'Episode','EpisodeName'] }, - 'episodenumber' => { 452 => [\'Episode','EpisodeNumber'] }, - 'epsonimageheight' => { 279 => 0x20c }, - 'epsonimagewidth' => { 279 => 0x20b }, - 'epsonsoftware' => { 279 => 0x20d }, - 'equipmentinstitution' => { 423 => 'EquipmentInstitution' }, - 'equipmentmanufacturer' => { 423 => 'EquipmentManufacturer' }, - 'equipmentversion' => { 275 => 0x0 }, - 'ettlii' => { 78 => 0x304, 79 => 0xd, 80 => 0xe, 81 => 0x7, 82 => 0x7, 83 => 0xe }, - 'event' => { 424 => 'Event', 434 => 'Event', 452 => 'Event', 456 => 'event' }, - 'eventalias' => { 455 => 'eventAlias' }, - 'eventdate' => { 112 => [\'Event','EventEventDate'] }, - 'eventday' => { 112 => [\'Event','EventDay'] }, - 'eventearliestdate' => { 112 => [\'Event','EventEarliestDate'] }, - 'eventend' => { 455 => 'eventEnd' }, - 'eventenddayofyear' => { 112 => [\'Event','EventEndDayOfYear'] }, - 'eventfieldnotes' => { 112 => [\'Event','EventFieldNotes'] }, - 'eventfieldnumber' => { 112 => [\'Event','EventFieldNumber'] }, - 'eventhabitat' => { 112 => [\'Event','EventHabitat'] }, - 'eventid' => { 112 => [\'Event','EventEventID'] }, - 'eventlatestdate' => { 112 => [\'Event','EventLatestDate'] }, - 'eventmonth' => { 112 => [\'Event','EventMonth'] }, - 'eventnumber' => { 353 => 0x9, 354 => 0x37 }, - 'eventparenteventid' => { 112 => [\'Event','EventParentEventID'] }, - 'eventremarks' => { 112 => [\'Event','EventEventRemarks'] }, - 'eventsamplesizeunit' => { 112 => [\'Event','EventSampleSizeUnit'] }, - 'eventsamplesizevalue' => { 112 => [\'Event','EventSampleSizeValue'] }, - 'eventsamplingeffort' => { 112 => [\'Event','EventSamplingEffort'] }, - 'eventsamplingprotocol' => { 112 => [\'Event','EventSamplingProtocol'] }, - 'eventstart' => { 455 => 'eventStart' }, - 'eventstartdayofyear' => { 112 => [\'Event','EventStartDayOfYear'] }, - 'eventsubtype' => { 455 => 'eventSubtype' }, - 'eventtime' => { 112 => [\'Event','EventEventTime'] }, - 'eventtype' => { 455 => 'eventType' }, - 'eventverbatimeventdate' => { 112 => [\'Event','EventVerbatimEventDate'] }, - 'eventyear' => { 112 => [\'Event','EventYear'] }, - 'evsteps' => { 313 => '1.2', 315 => 0x0 }, - 'evstepsize' => { 262 => '5.1', 263 => '6.1', 264 => '6.1', 268 => '0.7' }, - 'exclusivecoverage' => { 431 => 'ExclusiveCoverage' }, - 'exclusivityenddate' => { 459 => 'exclusivityEndDate' }, - 'excursiontolerance' => { 127 => 0x82 }, - 'exif' => { 114 => 'EXIF' }, - 'exifbyteorder' => { 114 => 'ExifByteOrder' }, - 'exifcamerainfo' => { 125 => 0xe8 }, - 'exifimageheight' => { 113 => 0xa003, 446 => 'PixelYDimension' }, - 'exifimagewidth' => { 113 => 0xa002, 446 => 'PixelXDimension' }, - 'exifunicodebyteorder' => { 114 => 'ExifUnicodeByteOrder' }, - 'exifversion' => { 113 => 0x9000, 446 => 'ExifVersion' }, - 'exitpupilposition' => { 207 => 0x4, 208 => 0x4 }, - 'expirationdate' => { 125 => 0x25, 459 => 'expirationDate' }, - 'expirationtime' => { 125 => 0x26 }, - 'exposure' => { 113 => 0xfe51, 442 => 'Exposure' }, - 'exposure2012' => { 442 => 'Exposure2012' }, - 'exposureadj' => { 248 => 0x0 }, - 'exposureadj2' => { 248 => 0x12 }, - 'exposureadjust' => { 368 => 0xc }, - 'exposurebracketingindicatorlast' => { 174 => 0x52 }, - 'exposurebracketshotnumber' => { 177 => 0x2d, 387 => 0x2f }, - 'exposurebracketstepsize' => { 313 => 0x8 }, - 'exposurebracketvalue' => { 211 => 0x19 }, - 'exposurecompautocancel' => { 78 => 0x113 }, - 'exposurecompensation' => { 72 => 0x6, 87 => 0x0, 113 => 0x9204, 133 => 0x24, 147 => 'ExposureComp', 167 => 'ExposureCompensation', 171 => 0xd, 172 => 0x53, 173 => 0x1e, 177 => 0x49c0, 279 => 0x1006, 332 => 0x16, 341 => 0x402, 365 => 0xa013, 368 => [0xc,0x35,0x4d], 396 => 0x114c, 397 => 0x114c, 398 => 0x1128, 400 => 0x1180, 401 => 0x1038, 402 => 0x230, 403 => 0x230, 404 => 0x223, 446 => 'ExposureBiasValue' }, - 'exposurecompensation2' => { 393 => [0x24,0x26,0x2a] }, - 'exposurecompensationmode' => { 174 => 0x47, 177 => 0x2a }, - 'exposurecompensationset' => { 376 => 0x3, 377 => 0x3, 378 => 0x3, 393 => 0x1e }, - 'exposurecompensationsetting' => { 174 => 0x1 }, - 'exposurecompstepsize' => { 257 => '6.3', 258 => '7.3', 260 => '7.3', 261 => '7.3', 266 => '4.3', 270 => '7.3', 271 => '7.3' }, - 'exposurecontrolstep' => { 265 => '6.1', 267 => '6.1' }, - 'exposurecontrolstepsize' => { 257 => '6.2', 258 => '7.1', 260 => '7.1', 261 => '7.1', 266 => '4.2', 270 => '7.1', 271 => '7.1', 272 => '7.1' }, - 'exposurecount' => { 121 => 0x1032 }, - 'exposuredelaymode' => { 257 => '10.1', 258 => '11.1', 260 => '11.1', 261 => '11.1', 262 => '9.1', 263 => '10.1', 264 => '10.1', 266 => '10.4', 267 => '10.1', 268 => '6.4', 270 => '11.1', 271 => '11.1', 272 => '11.2' }, - 'exposuredifference' => { 211 => 0xe }, - 'exposuregaincustom' => { 131 => 0x89c }, - 'exposuregaindaylight' => { 131 => 0x898 }, - 'exposuregainflash' => { 131 => 0x89b }, - 'exposuregainfluorescent' => { 131 => 0x89a }, - 'exposuregaintungsten' => { 131 => 0x899 }, - 'exposureindex' => { 113 => 0xa215, 446 => 'ExposureIndex' }, - 'exposureindicator' => { 174 => 0x50 }, - 'exposurelevelincrements' => { 76 => 0x6, 77 => 0x6, 78 => 0x101, 79 => 0x5, 80 => 0x6, 81 => 0x5, 82 => 0x5, 83 => 0x6, 84 => 0x4, 376 => 0x58, 377 => 0x58 }, - 'exposurelockused' => { 429 => 'ExposureLockUsed' }, - 'exposuremode' => { 113 => 0xa402, 147 => 'ExposureMode', 171 => 0x1, 172 => 0xa, 173 => 0x0, 174 => 0x0, 177 => 0x34, 274 => 0x200, 294 => 0x40d, 368 => 0x8, 388 => 0xb041, 446 => 'ExposureMode' }, - 'exposuremodeinmanual' => { 78 => 0x10b }, - 'exposureprogram' => { 113 => 0x8822, 358 => 0x1001, 369 => [0x17e,0x43], 376 => 0x3c, 377 => 0x3c, 378 => 0x5, 382 => 0x14, 387 => 0x3f, 393 => 0x2, 396 => 0x1175, 397 => 0x1179, 398 => 0x1155, 399 => 0x11d1, 400 => 0x11ad, 401 => 0x1065, 402 => 0x25d, 403 => 0x25d, 404 => 0x24c, 413 => 0xb, 414 => 0xc, 415 => 0xb, 417 => 0x48, 446 => 'ExposureProgram' }, - 'exposureshift' => { 274 => 0x203 }, - 'exposurestandardadjustment' => { 388 => 0x202d }, - 'exposuretime' => { 6 => 0x4, 7 => 0x4, 8 => 0x4, 9 => 0x4, 10 => 0x4, 11 => 0x4, 12 => 0x4, 13 => 0x4, 14 => 0x4, 15 => 0x4, 16 => 0x4, 17 => 0x4, 18 => 0x4, 19 => 0x4, 20 => 0x4, 21 => 0x4, 22 => 0x4, 23 => 0x4, 24 => 0x4, 25 => 0x4, 26 => 0x4, 27 => 0x4, 28 => 0x4, 29 => 0x6, 30 => 0x7, 72 => 0x16, 113 => 0x829a, 130 => 0xfd05, 133 => 0x20, 135 => 0xfa24, 137 => 0xf104, 140 => 0x12, 142 => 0x38, 145 => 0x10, 147 => 'ExposureTime', 171 => 0x9, 172 => 0x35, 173 => 0x48, 174 => 0x8, 177 => 0x49b8, 332 => 0x12, 365 => 0xa018, 368 => [0x32,0x4a], 376 => 0x0, 377 => 0x0, 393 => [0x21,0x23,0x27], 417 => 0x10, 446 => 'ExposureTime' }, - 'exposuretime2' => { 368 => [0x33,0x4b] }, - 'exposuretuning' => { 211 => 0x1c }, - 'exposurevalue' => { 131 => 0x3 }, - 'exposurewarning' => { 121 => 0x1302 }, - 'exrauto' => { 121 => 0x1033 }, - 'exrmode' => { 121 => 0x1034 }, - 'extendedwbdetect' => { 274 => 0x902 }, - 'extender' => { 275 => 0x301 }, - 'extenderfirmwareversion' => { 275 => 0x304 }, - 'extendermagnification' => { 149 => 'Magnification' }, - 'extendermake' => { 149 => 'Make' }, - 'extendermodel' => { 149 => 'Model', 275 => 0x303 }, - 'extenderserialnumber' => { 149 => 'SerialNumber', 275 => 0x302 }, - 'extenderstatus' => { 330 => 0x3 }, - 'externalflash' => { 277 => 0x1201 }, - 'externalflashae1' => { 279 => 0x101f }, - 'externalflashae1_0' => { 279 => 0x101b }, - 'externalflashae2' => { 279 => 0x1020 }, - 'externalflashae2_0' => { 279 => 0x101c }, - 'externalflashbounce' => { 277 => 0x1204, 279 => 0x1026, 320 => 0x1a }, - 'externalflashcompensation' => { 200 => 0x1b }, - 'externalflashexposurecomp' => { 211 => 0x17, 320 => 0x19 }, - 'externalflashfirmware' => { 198 => 0x6, 199 => 0x6, 200 => 0x6, 201 => 0x6, 202 => 0x6 }, - 'externalflashflags' => { 198 => 0x8, 199 => 0x8, 200 => 0x8, 201 => 0x8 }, - 'externalflashguidenumber' => { 277 => 0x1203, 320 => '24.1' }, - 'externalflashgvalue' => { 279 => 0x1025 }, - 'externalflashmode' => { 279 => 0x1028, 320 => 0x2 }, - 'externalflashreadystate' => { 202 => '9.1' }, - 'externalflashstatus' => { 202 => '8.2' }, - 'externalflashzoom' => { 277 => 0x1205, 279 => 0x1027 }, - 'externalflashzoomoverride' => { 202 => '8.1' }, - 'externalmetadatalink' => { 452 => 'ExternalMetadataLink' }, - 'externalsensorbrightnessvalue' => { 292 => 0x311, 295 => 0x311, 296 => 0x311, 299 => 0x3408 }, - 'extrainfoversion' => { 380 => 0x1a }, - 'eyestartaf' => { 174 => 0x40 }, - 'fac100per' => { 131 => 0xe94 }, - 'fac170per' => { 131 => 0xe93 }, - 'fac18per' => { 131 => 0xe92 }, - 'face10position' => { 104 => 0x3f4, 105 => 0x1ec, 196 => 0x28, 317 => 0x12 }, - 'face10size' => { 318 => 0x12 }, - 'face11position' => { 196 => 0x2c, 317 => 0x14 }, - 'face11size' => { 318 => 0x14 }, - 'face12position' => { 196 => 0x30, 317 => 0x16 }, - 'face12size' => { 318 => 0x16 }, - 'face13position' => { 317 => 0x18 }, - 'face13size' => { 318 => 0x18 }, - 'face14position' => { 317 => 0x1a }, - 'face14size' => { 318 => 0x1a }, - 'face15position' => { 317 => 0x1c }, - 'face15size' => { 318 => 0x1c }, - 'face16position' => { 317 => 0x1e }, - 'face16size' => { 318 => 0x1e }, - 'face17position' => { 317 => 0x20 }, - 'face17size' => { 318 => 0x20 }, - 'face18position' => { 317 => 0x22 }, - 'face18size' => { 318 => 0x22 }, - 'face19position' => { 317 => 0x24 }, - 'face19size' => { 318 => 0x24 }, - 'face1position' => { 51 => 0x8, 104 => 0xd, 105 => 0x18, 196 => 0x4, 289 => 0x1, 317 => 0x0, 355 => 0xbc, 383 => 0x1, 384 => 0x0, 385 => 0x0, 386 => 0x5b }, - 'face1size' => { 318 => 0x0 }, - 'face20position' => { 317 => 0x26 }, - 'face20size' => { 318 => 0x26 }, - 'face21position' => { 317 => 0x28 }, - 'face21size' => { 318 => 0x28 }, - 'face22position' => { 317 => 0x2a }, - 'face22size' => { 318 => 0x2a }, - 'face23position' => { 317 => 0x2c }, - 'face23size' => { 318 => 0x2c }, - 'face24position' => { 317 => 0x2e }, - 'face24size' => { 318 => 0x2e }, - 'face25position' => { 317 => 0x30 }, - 'face25size' => { 318 => 0x30 }, - 'face26position' => { 317 => 0x32 }, - 'face26size' => { 318 => 0x32 }, - 'face27position' => { 317 => 0x34 }, - 'face27size' => { 318 => 0x34 }, - 'face28position' => { 317 => 0x36 }, - 'face28size' => { 318 => 0x36 }, - 'face29position' => { 317 => 0x38 }, - 'face29size' => { 318 => 0x38 }, - 'face2position' => { 51 => 0xa, 104 => 0x7c, 105 => 0x4c, 196 => 0x8, 289 => 0x5, 317 => 0x2, 355 => 0xc8, 383 => 0x6, 384 => 0x20, 385 => 0x25, 386 => 0x65 }, - 'face2size' => { 318 => 0x2 }, - 'face30position' => { 317 => 0x3a }, - 'face30size' => { 318 => 0x3a }, - 'face31position' => { 317 => 0x3c }, - 'face31size' => { 318 => 0x3c }, - 'face32position' => { 317 => 0x3e }, - 'face32size' => { 318 => 0x3e }, - 'face3position' => { 51 => 0xc, 104 => 0xeb, 105 => 0x80, 196 => 0xc, 289 => 0x9, 317 => 0x4, 355 => 0xd4, 383 => 0xb, 384 => 0x40, 385 => 0x4a, 386 => 0x6f }, - 'face3size' => { 318 => 0x4 }, - 'face4position' => { 51 => 0xe, 104 => 0x15a, 105 => 0xb4, 196 => 0x10, 289 => 0xd, 317 => 0x6, 355 => 0xe0, 383 => 0x10, 384 => 0x60, 385 => 0x6f, 386 => 0x79 }, - 'face4size' => { 318 => 0x6 }, - 'face5position' => { 51 => 0x10, 104 => 0x1c9, 105 => 0xe8, 196 => 0x14, 289 => 0x11, 317 => 0x8, 355 => 0xec, 383 => 0x15, 384 => 0x80, 385 => 0x94 }, - 'face5size' => { 318 => 0x8 }, - 'face6position' => { 51 => 0x12, 104 => 0x238, 105 => 0x11c, 196 => 0x18, 317 => 0xa, 355 => 0xf8, 383 => 0x1a, 384 => 0xa0, 385 => 0xb9 }, - 'face6size' => { 318 => 0xa }, - 'face7position' => { 51 => 0x14, 104 => 0x2a7, 105 => 0x150, 196 => 0x1c, 317 => 0xc, 355 => 0x104, 383 => 0x1f, 384 => 0xc0, 385 => 0xde }, - 'face7size' => { 318 => 0xc }, - 'face8position' => { 51 => 0x16, 104 => 0x316, 105 => 0x184, 196 => 0x20, 317 => 0xe, 355 => 0x110, 383 => 0x24, 384 => 0xe0, 385 => 0x103 }, - 'face8size' => { 318 => 0xe }, - 'face9position' => { 51 => 0x18, 104 => 0x385, 105 => 0x1b8, 196 => 0x24, 317 => 0x10 }, - 'face9size' => { 318 => 0x10 }, - 'facebalanceorigi' => { 435 => 'FaceBalanceOrigI' }, - 'facebalanceorigq' => { 435 => 'FaceBalanceOrigQ' }, - 'facebalancestrength' => { 435 => 'FaceBalanceStrength' }, - 'facebalancewarmth' => { 435 => 'FaceBalanceWarmth' }, - 'facedetect' => { 332 => 0x76, 365 => 0x100 }, - 'facedetectarea' => { 278 => 0x1201 }, - 'facedetectframecrop' => { 278 => 0x1207 }, - 'facedetectframesize' => { 51 => 0x3, 104 => 0x1, 105 => 0x4, 196 => 0x1, 278 => 0x1203, 332 => 0x77, 355 => 0xb6 }, - 'facedetection' => { 378 => 0x30, 393 => 0x19 }, - 'faceelementpositions' => { 121 => 0x4203 }, - 'faceelementtypes' => { 121 => 0x4201 }, - 'faceid' => { 437 => 'FaceID' }, - 'faceinfounknown' => { 107 => 0x2089 }, - 'facename' => { 365 => 0x123 }, - 'faceorientation' => { 105 => 0x8 }, - 'faceposition' => { 316 => 0x2, 366 => 0x4 }, - 'facepositions' => { 121 => 0x4103 }, - 'facerecognition' => { 365 => 0x120 }, - 'facesdetected' => { 51 => 0x2, 52 => 0x2, 53 => 0x3, 104 => 0x0, 105 => 0x2, 107 => 0x211c, 121 => 0x4100, 196 => 0x3, 278 => 0x1200, 297 => 0x3f, 316 => 0x0, 355 => 0xb5, 366 => 0x0, 383 => 0x0, 386 => 0x3, 395 => 0x30 }, - 'facesrecognized' => { 290 => 0x0 }, - 'facewidth' => { 52 => 0x1 }, - 'faithfuloutputhighlightpoint' => { 103 => 0x38 }, - 'faithfuloutputshadowpoint' => { 103 => 0x39 }, - 'faithfulrawcolortone' => { 103 => 0x31 }, - 'faithfulrawcontrast' => { 103 => 0x33 }, - 'faithfulrawhighlight' => { 103 => 0x79 }, - 'faithfulrawhighlightpoint' => { 103 => 0x36 }, - 'faithfulrawlinear' => { 103 => 0x34 }, - 'faithfulrawsaturation' => { 103 => 0x32 }, - 'faithfulrawshadow' => { 103 => 0x82 }, - 'faithfulrawshadowpoint' => { 103 => 0x37 }, - 'faithfulrawsharpness' => { 103 => 0x35 }, - 'faithfulunsharpmaskfineness' => { 103 => 0xac }, - 'faithfulunsharpmaskstrength' => { 103 => 0xaa }, - 'faithfulunsharpmaskthreshold' => { 103 => 0xae }, - 'far' => { 426 => 'Far' }, - 'fastresetlinetime' => { 131 => 0x1860 }, - 'feedidentifier' => { 452 => 'FeedIdentifier' }, - 'femicroadjustment' => { 78 => 0x111 }, - 'ffid' => { 444 => 'ffid' }, - 'field' => { 455 => 'field' }, - 'fieldcount' => { 279 => 0x103f }, - 'fifoenonepixeldelay' => { 131 => 0x1901 }, - 'filecreatedate' => { 114 => 'FileCreateDate' }, - 'filedatarate' => { 466 => 'fileDataRate' }, - 'fileformat' => { 89 => 0x0, 126 => 0x14, 368 => [0x22,0x26], 388 => 0xb000 }, - 'filegroupid' => { 114 => 'FileGroupID' }, - 'fileindex' => { 6 => 0x143, 8 => 0x2d0, 10 => 0x172, 12 => 0x22c, 13 => 0x133, 14 => 0x13f, 15 => 0x1d3, 16 => 0x19b, 17 => 0x1e4, 18 => 0xd0, 19 => 0x1bb, 20 => 0x28c, 21 => 0x1db, 22 => 0x1d9, 23 => [0x270,0x274], 24 => 0x2aa, 25 => 0x2b3, 27 => 0x1eb, 28 => 0x4ae, 298 => 0x0 }, - 'fileindex2' => { 20 => 0x290 }, - 'filemodifydate' => { 114 => 'FileModifyDate' }, - 'filename' => { 114 => 'FileName' }, - 'filenameasdelivered' => { 284 => 'FileNameAsDelivered' }, - 'filenumber' => { 54 => 0x1, 60 => 0x8, 91 => 0x1817, 108 => 'FileNumber', 197 => 0x4 }, - 'filenumbermemory' => { 171 => 0x1a }, - 'filenumbersequence' => { 257 => '12.2', 262 => '3.1', 263 => '4.1', 264 => '4.1', 266 => '11.1', 267 => '4.3', 272 => '5.2' }, - 'filepermissions' => { 114 => 'FilePermissions' }, - 'filesource' => { 113 => 0xa300, 121 => 0x8000, 446 => 'FileSource' }, - 'fileuserid' => { 114 => 'FileUserID' }, - 'fileversion' => { 126 => 0x16 }, - 'fillflashautoreduction' => { 76 => 0xe, 77 => 0xe, 84 => 0xa }, - 'filllight' => { 442 => 'FillLight' }, - 'fillorder' => { 113 => 0x10a }, - 'filmgraineffect' => { 274 => 0x538 }, - 'filmmode' => { 121 => 0x1401, 294 => 0x412, 297 => 0x42 }, - 'filmtype' => { 218 => 0x2 }, - 'filtereffect' => { 54 => 0xe, 213 => 0x37, 214 => 0x3f }, - 'filtereffectauto' => { 67 => 0xa0 }, - 'filtereffectfaithful' => { 66 => 0x70, 67 => 0x70 }, - 'filtereffectlandscape' => { 66 => 0x40, 67 => 0x40 }, - 'filtereffectmonochrome' => { 18 => 0xff, 66 => 0x88, 67 => 0x88 }, - 'filtereffectneutral' => { 66 => 0x58, 67 => 0x58 }, - 'filtereffectportrait' => { 66 => 0x28, 67 => 0x28 }, - 'filtereffectstandard' => { 66 => 0x10, 67 => 0x10 }, - 'filtereffectuserdef1' => { 66 => 0xa0, 67 => 0xb8 }, - 'filtereffectuserdef2' => { 66 => 0xb8, 67 => 0xd0 }, - 'filtereffectuserdef3' => { 66 => 0xd0, 67 => 0xe8 }, - 'finderdisplayduringexposure' => { 77 => 0x1 }, - 'finesharpness' => { 332 => 0x70 }, - 'finetuneoptcenterweighted' => { 257 => '7.2', 258 => '9.1', 260 => '9.1', 261 => '9.1', 265 => '8.1', 270 => '9.1', 271 => '9.1', 272 => '9.1' }, - 'finetuneopthighlightweighted' => { 260 => '46.1', 261 => '46.1', 270 => '46.1', 271 => '46.1' }, - 'finetuneoptmatrixmetering' => { 257 => '8.1', 258 => '8.2', 260 => '8.2', 261 => '8.2', 265 => '7.2', 266 => '6.1', 270 => '8.2', 271 => '8.2', 272 => '8.2' }, - 'finetuneoptspotmetering' => { 257 => '8.2', 258 => '9.2', 260 => '9.2', 261 => '9.2', 265 => '8.2', 266 => '6.2', 270 => '9.2', 271 => '9.2', 272 => '9.2' }, - 'finishexposure' => { 131 => 0xdbd }, - 'finishfiletype' => { 131 => 0xdb8 }, - 'finishlook' => { 131 => 0xdbc }, - 'finishnoise' => { 131 => 0xdba }, - 'finishresolution' => { 131 => 0xdb9 }, - 'finishsharpening' => { 131 => 0xdbb }, - 'firmware' => { 279 => 0x405, 368 => [0x17,0x3b,0x57], 438 => 'Firmware' }, - 'firmwaredate' => { 106 => 0x15, 107 => 0x2001, 353 => 0x4 }, - 'firmwareid' => { 178 => 0x0 }, - 'firmwarename' => { 365 => 0xa001 }, - 'firmwarerevision' => { 18 => 0xa4, 60 => 0x1e, 356 => 0x0 }, - 'firmwarerevision2' => { 356 => 0xc }, - 'firmwareversion' => { 6 => 0x10b, 10 => 0x136, 13 => 0xff, 14 => 0x107, 131 => [0x415,0xce5], 145 => 0x57, 147 => 'FirmwareVersion', 295 => 0x320, 297 => 0x2, 299 => 0x3109, 332 => 0x230, 354 => 0x18, 358 => 0x2 }, - 'firmwareversions' => { 341 => 0x301 }, - 'firstphotodate' => { 429 => 'FirstPhotoDate' }, - 'firstpublicationdate' => { 284 => 'FirstPublicationDate' }, - 'fixtureidentifier' => { 125 => 0x16, 436 => 'FixtureIdentifier' }, - 'flash' => { 108 => 'Flash', 113 => 0x9209, 172 => 0x1f, 173 => 0x15, 446 => 'Flash' }, - 'flashaction' => { 376 => 0x3e, 377 => 0x3e, 388 => 0x2017, 393 => [0x2a,0x2c,0x30] }, - 'flashaction2' => { 376 => 0x4c, 377 => 0x4c, 393 => 0x77 }, - 'flashactionexternal' => { 393 => [0x78,0x7c] }, - 'flashactivity' => { 33 => 0x1c }, - 'flashbatterylevel' => { 41 => 0x249 }, - 'flashbias' => { 297 => 0x24 }, - 'flashbits' => { 33 => 0x1d }, - 'flashbuttonfunction' => { 78 => 0x70e }, - 'flashchargelevel' => { 279 => 0x1010 }, - 'flashcolorfilter' => { 200 => 0x10, 201 => 0x10 }, - 'flashcommandermode' => { 198 => '9.1', 199 => '9.1', 200 => '9.1', 201 => '9.1' }, - 'flashcompensation' => { 131 => 0x3f3, 198 => 0xa, 199 => 0xa, 200 => 0xa, 201 => 0x27, 202 => 0xa, 438 => 'FlashCompensation' }, - 'flashcontrol' => { 376 => 0x23, 377 => 0x1f, 378 => 0x21 }, - 'flashcontrolbuilt-in' => { 266 => '16.1', 267 => '23.1', 269 => '23.1', 270 => '24.1' }, - 'flashcontrolmode' => { 198 => '9.2', 199 => '9.2', 200 => '9.2', 201 => '9.2', 274 => 0x404 }, - 'flashcurtain' => { 297 => 0x48 }, - 'flashdefault' => { 174 => 0x42 }, - 'flashdevice' => { 279 => 0x1005 }, - 'flashdistance' => { 107 => 0x2034 }, - 'flashenergy' => { 113 => 0xa20b, 446 => 'FlashEnergy' }, - 'flashexposurebracketvalue' => { 211 => 0x18 }, - 'flashexposurecomp' => { 72 => 0xf, 121 => 0x1011, 150 => 'ExposureComp', 171 => 0x23, 176 => 0x104, 177 => 0x49c1, 211 => 0x12, 274 => 0x401, 279 => 0x1023, 332 => 0x4d, 358 => 0x100b, 368 => [0x3a,0x56], 388 => 0x104 }, - 'flashexposurecomp2' => { 236 => 0x4d2 }, - 'flashexposurecomp3' => { 200 => 0x1d }, - 'flashexposurecomp4' => { 200 => 0x27 }, - 'flashexposurecomparea' => { 258 => '38.4', 260 => '38.4', 261 => '38.4', 270 => '38.4', 271 => '38.4' }, - 'flashexposurecompset' => { 174 => 0x10, 305 => 0xe, 376 => 0x14, 377 => 0x12, 378 => 0x23, 393 => 0x1f }, - 'flashexposurecompset2' => { 393 => [0x26,0x2c] }, - 'flashexposureindicator' => { 174 => 0x54 }, - 'flashexposureindicatorlast' => { 174 => 0x56 }, - 'flashexposureindicatornext' => { 174 => 0x55 }, - 'flashexposurelock' => { 54 => 0x19 }, - 'flashfired' => { 133 => 0x5d, 150 => 'Fired', 171 => 0x14, 235 => '590.3', 446 => [\'Flash','FlashFired'] }, - 'flashfiring' => { 78 => 0x306, 79 => 0x6, 80 => 0x7, 83 => 0x7 }, - 'flashfirmwareversion' => { 275 => 0x1002 }, - 'flashfocallength' => { 198 => 0xb, 199 => 0xc, 200 => 0xc, 201 => 0xc, 202 => 0xc }, - 'flashfunction' => { 177 => 0x31, 446 => [\'Flash','FlashFunction'] }, - 'flashgndistance' => { 198 => 0xe, 199 => 0xf, 200 => 0xf, 201 => 0xf, 202 => 0xf }, - 'flashgroupacompensation' => { 198 => 0x11, 199 => 0x12, 200 => 0x13, 201 => 0x28, 202 => 0x28 }, - 'flashgroupacontrolmode' => { 198 => 0xf, 199 => '16.1', 200 => '17.1', 201 => '17.1', 202 => '17.1' }, - 'flashgroupaoutput' => { 198 => 0x11, 199 => 0x12, 200 => 0x13, 201 => 0x28, 202 => 0x28 }, - 'flashgroupbcompensation' => { 198 => 0x12, 199 => 0x13, 200 => 0x14, 201 => 0x29, 202 => 0x29 }, - 'flashgroupbcontrolmode' => { 198 => 0x10, 199 => '17.1', 200 => '18.1', 201 => '18.1', 202 => '18.1' }, - 'flashgroupboutput' => { 198 => 0x12, 199 => 0x13, 200 => 0x14, 201 => 0x29, 202 => 0x29 }, - 'flashgroupccompensation' => { 199 => 0x14, 200 => 0x15, 201 => 0x2a, 202 => 0x2a }, - 'flashgroupccontrolmode' => { 199 => '17.2', 200 => '18.2', 201 => '18.2', 202 => '18.2' }, - 'flashgroupcoutput' => { 199 => 0x14, 200 => 0x15, 201 => 0x2a, 202 => 0x2a }, - 'flashguidenumber' => { 72 => 0xd, 88 => 0x0, 150 => 'GuideNumber' }, - 'flashintensity' => { 106 => [0x19,0x5], 274 => 0x405 }, - 'flashlevel' => { 259 => 0x9, 388 => 0xb048 }, - 'flashmake' => { 150 => 'Make' }, - 'flashmanufacturer' => { 169 => 'FlashManufacturer' }, - 'flashmetering' => { 171 => 0x3f, 174 => 0x1c }, - 'flashmeteringmode' => { 6 => 0x15, 12 => 0x15, 13 => 0x15, 14 => 0x15, 15 => 0x15, 16 => 0x15, 17 => 0x15, 19 => 0x15, 21 => 0x15, 27 => 0x15 }, - 'flashmeteringsegments' => { 332 => 0x20a }, - 'flashmode' => { 106 => 0x4, 131 => 0x3f2, 133 => 0x5c, 150 => 'Mode', 171 => 0x2, 172 => 0x20, 173 => 0x16, 174 => 0xf, 211 => 0x87, 274 => 0x400, 279 => 0x1004, 332 => 0xc, 339 => 0x4, 357 => 0x20, 358 => 0x100a, 367 => 0x225, 376 => 0x13, 377 => 0x7f, 378 => 0x20, 393 => 0x10, 396 => 0x1138, 397 => 0x1138, 398 => 0x1114, 399 => 0x1190, 400 => 0x116c, 401 => 0x1024, 402 => 0x21c, 403 => 0x21c, 404 => 0x211, 446 => [\'Flash','FlashMode'] }, - 'flashmodel' => { 150 => 'Model', 169 => 'FlashModel', 275 => 0x1001 }, - 'flashoptions' => { 313 => 0x2 }, - 'flashoptions2' => { 313 => 0x10 }, - 'flashoutput' => { 41 => 0x248, 72 => 0x21, 198 => 0xa, 199 => 0xa, 200 => 0xa, 201 => 0x27 }, - 'flashpixversion' => { 113 => 0xa000, 446 => 'FlashpixVersion' }, - 'flashredeyemode' => { 446 => [\'Flash','FlashRedEyeMode'] }, - 'flashremotecontrol' => { 274 => 0x403 }, - 'flashreturn' => { 446 => [\'Flash','FlashReturn'] }, - 'flashserialnumber' => { 150 => 'SerialNumber', 275 => 0x1003 }, - 'flashsetting' => { 211 => 0x8 }, - 'flashshutterspeed' => { 257 => '20.2', 258 => '23.2', 260 => '23.2', 261 => '23.2', 266 => '15.2', 267 => '22.2', 268 => '7.2', 269 => '22.2', 270 => '23.2', 271 => '23.2', 272 => '23.1' }, - 'flashsource' => { 198 => 0x4, 199 => 0x4, 200 => 0x4, 201 => 0x4, 202 => 0x4 }, - 'flashstatus' => { 320 => 0x0, 393 => [0x82,0x86], 406 => 0x31, 407 => 0x39 }, - 'flashstatusbuilt-in' => { 378 => [0x87,0x287] }, - 'flashstatusexternal' => { 378 => [0x88,0x288] }, - 'flashsyncspeed' => { 257 => '20.1', 258 => '23.1', 260 => '23.1', 261 => '23.1', 266 => '15.1', 267 => '22.1', 269 => '22.1', 270 => '23.1', 271 => '23.1' }, - 'flashsyncspeedav' => { 76 => 0x3, 78 => 0x10f, 79 => 0x2, 80 => 0x3, 81 => 0x2, 82 => 0x2, 83 => 0x3, 84 => 0x6 }, - 'flashthreshold' => { 88 => 0x1 }, - 'flashtype' => { 150 => 'Type', 174 => 0x59, 211 => 0x9, 275 => 0x1000 }, - 'flashwarning' => { 267 => '30.1', 268 => '7.1', 272 => '31.1', 297 => 0x62 }, - 'flexiblespotposition' => { 388 => 0x201d }, - 'flickerreduce' => { 367 => 0x218 }, - 'flickerreduction' => { 121 => 0x1446, 229 => 0xe84 }, - 'flickerreductionindicator' => { 229 => 0x5e2 }, - 'flightpitchdegree' => { 110 => 'FlightPitchDegree' }, - 'flightrolldegree' => { 110 => 'FlightRollDegree' }, - 'flightyawdegree' => { 110 => 'FlightYawDegree' }, - 'fliphorizontal' => { 250 => 0x76a43206 }, - 'fnumber' => { 6 => 0x3, 8 => 0x3, 10 => 0x3, 12 => 0x3, 13 => 0x3, 14 => 0x3, 15 => 0x3, 16 => 0x3, 17 => 0x3, 18 => 0x3, 19 => 0x3, 20 => 0x3, 21 => 0x3, 22 => 0x3, 23 => 0x3, 24 => 0x3, 25 => 0x3, 26 => 0x3, 27 => 0x3, 28 => 0x3, 29 => 0x5, 30 => 0x6, 72 => 0x15, 113 => 0x829d, 130 => 0xfd04, 133 => 0x1e, 135 => 0xfa23, 137 => 0xf103, 140 => 0x13, 142 => 0x3c, 145 => 0xc, 154 => 'FNumber', 171 => 0xa, 172 => 0x36, 173 => 0x47, 174 => 0x9, 177 => 0x49c7, 332 => 0x13, 365 => 0xa019, 368 => [0x31,0x49], 376 => 0x1, 377 => 0x1, 393 => [0x20,0x22,0x26], 446 => 'FNumber' }, - 'focaldistance' => { 427 => 'FocalDistance' }, - 'focallength' => { 6 => 0x1d, 7 => 0xa, 8 => 0x23, 9 => 0x9, 10 => 0x1d, 11 => 0x9, 12 => 0x1e, 13 => 0x1d, 14 => 0x1d, 15 => 0x1e, 16 => 0x1e, 17 => 0x1e, 18 => 0x28, 19 => 0x1e, 20 => 0x23, 21 => 0x1e, 22 => 0x1e, 23 => 0x23, 24 => 0x23, 25 => 0x23, 26 => 0x23, 27 => 0x1e, 28 => 0x23, 56 => 0x1, 107 => 0x1d, 113 => 0x920a, 140 => 0x1d, 154 => 'FocalLength', 171 => 0x12, 207 => 0xa, 208 => 0xb, 291 => 0x1, 332 => 0x1d, 341 => 0x403, 358 => 0x1500, 375 => 0xe, 400 => 0x1278, 401 => 0x1134, 402 => 0x32c, 403 => 0x32c, 404 => 0x30a, 446 => 'FocalLength' }, - 'focallength2' => { 393 => [0x23,0x25,0x29] }, - 'focallengthin35mmformat' => { 113 => 0xa405, 365 => 0xa01a, 446 => 'FocalLengthIn35mmFilm' }, - 'focallengthtelezoom' => { 375 => 0x10 }, - 'focalplaneafpointarea' => { 405 => 0x2 }, - 'focalplaneafpointlocation1' => { 405 => 0x6 }, - 'focalplaneafpointlocation10' => { 405 => 0x2a }, - 'focalplaneafpointlocation11' => { 405 => 0x2e }, - 'focalplaneafpointlocation12' => { 405 => 0x32 }, - 'focalplaneafpointlocation13' => { 405 => 0x36 }, - 'focalplaneafpointlocation14' => { 405 => 0x3a }, - 'focalplaneafpointlocation15' => { 405 => 0x3e }, - 'focalplaneafpointlocation2' => { 405 => 0xa }, - 'focalplaneafpointlocation3' => { 405 => 0xe }, - 'focalplaneafpointlocation4' => { 405 => 0x12 }, - 'focalplaneafpointlocation5' => { 405 => 0x16 }, - 'focalplaneafpointlocation6' => { 405 => 0x1a }, - 'focalplaneafpointlocation7' => { 405 => 0x1e }, - 'focalplaneafpointlocation8' => { 405 => 0x22 }, - 'focalplaneafpointlocation9' => { 405 => 0x26 }, - 'focalplaneafpointsused' => { 405 => 0x1 }, - 'focalplanediagonal' => { 275 => 0x103, 279 => 0x205 }, - 'focalplaneresolutionunit' => { 113 => 0xa210, 446 => 'FocalPlaneResolutionUnit' }, - 'focalplanexresolution' => { 113 => 0xa20e, 446 => 'FocalPlaneXResolution' }, - 'focalplanexsize' => { 56 => 0x2 }, - 'focalplanexunknown' => { 56 => 0x2 }, - 'focalplaneyresolution' => { 113 => 0xa20f, 446 => 'FocalPlaneYResolution' }, - 'focalplaneysize' => { 56 => 0x3 }, - 'focalplaneyunknown' => { 56 => 0x3 }, - 'focalpointx' => { 427 => 'FocalPointX' }, - 'focalpointy' => { 427 => 'FocalPointY' }, - 'focaltype' => { 9 => 0x2d, 56 => 0x0 }, - 'focalunits' => { 33 => 0x19 }, - 'focus' => { 240 => 0x8 }, - 'focusarea' => { 171 => 0x31 }, - 'focusareaselection' => { 268 => '15.2' }, - 'focuscontinuous' => { 33 => 0x20 }, - 'focusdisplayaiservoandmf' => { 78 => 0x515 }, - 'focusdistance' => { 154 => 'FocusDistance', 171 => 0x13, 177 => 0x49bb, 207 => 0x9, 208 => 0xa, 277 => 0x305, 291 => 0x0, 295 => 0x304, 296 => 0x304 }, - 'focusdistancelower' => { 6 => 0x45, 8 => 0x8e, 10 => 0x45, 12 => 0x56, 13 => 0x45, 14 => 0x45, 15 => 0x52, 16 => 0x52, 17 => 0x56, 19 => 0x52, 20 => 0x8e, 21 => 0x59, 22 => 0x57, 23 => 0x8e, 24 => 0x94, 25 => 0x95, 26 => 0xa7, 27 => 0x56, 28 => 0xa7, 54 => 0x15, 72 => 0x14 }, - 'focusdistanceupper' => { 6 => 0x43, 8 => 0x8c, 10 => 0x43, 12 => 0x54, 13 => 0x43, 14 => 0x43, 15 => 0x50, 16 => 0x50, 17 => 0x54, 19 => 0x50, 20 => 0x8c, 21 => 0x57, 22 => 0x55, 23 => 0x8c, 24 => 0x92, 25 => 0x93, 26 => 0xa5, 27 => 0x54, 28 => 0xa5, 54 => 0x14, 72 => 0x13 }, - 'focusholdbutton' => { 174 => 0x44 }, - 'focusinfoversion' => { 277 => 0x0 }, - 'focusingscreen' => { 77 => 0x0, 78 => 0x80b, 83 => 0x0 }, - 'focuslocation' => { 388 => 0x2027 }, - 'focuslocked' => { 170 => 0x14 }, - 'focusmode' => { 33 => 0x7, 106 => 0x3, 107 => [0x3003,0xd], 121 => 0x1021, 131 => 0x3f5, 133 => 0x38, 147 => 'FocusMode', 171 => 0x30, 173 => 0xe, 174 => 0xc, 211 => 0x7, 274 => 0x301, 279 => 0x100b, 297 => 0x7, 332 => 0xd, 339 => 0x3, 358 => 0x1006, 369 => [0xb,0x5], 375 => [0x15,0x1d], 376 => 0x4d, 377 => 0x4d, 388 => [0xb042,0xb04e,0x201b], 393 => 0x13, 411 => 0x16 }, - 'focusmode2' => { 120 => '0.1', 313 => '3.1', 393 => [0x2c,0x2e,0x32] }, - 'focusmodesetting' => { 259 => '10.1', 373 => 0x14, 374 => 0x15, 376 => 0x10, 377 => 0xf, 378 => 0x6 }, - 'focusmodeswitch' => { 174 => 0x58, 376 => 0x2e }, - 'focuspixel' => { 121 => 0x1023 }, - 'focuspointwrap' => { 257 => '2.2', 258 => '2.2', 260 => '2.1', 261 => '2.1', 265 => '1.1', 266 => '2.2', 267 => '1.1', 270 => '2.2', 271 => '2.1', 272 => '2.5' }, - 'focusposition' => { 207 => 0x8, 208 => 0x8, 332 => 0x10, 387 => 0x9bb }, - 'focusposition2' => { 393 => [0x29,0x2b,0x2f], 411 => 0x2d, 414 => 0x20 }, - 'focusprocess' => { 274 => 0x302 }, - 'focusrange' => { 33 => 0x12, 279 => 0x100a }, - 'focusrangeindex' => { 323 => '3.1' }, - 'focusringrotation' => { 78 => 0x713 }, - 'focussetting' => { 368 => 0x6 }, - 'focusstatus' => { 375 => 0x19, 376 => 0x53, 377 => 0x53 }, - 'focusstepcount' => { 277 => 0x301, 279 => 0x100e }, - 'focusstepinfinity' => { 277 => 0x303, 279 => 0x103b }, - 'focusstepnear' => { 277 => 0x304, 279 => 0x103c }, - 'focustrackinglockon' => { 257 => ['1.5','4.1'], 258 => '1.4', 265 => '0.4', 266 => '3.1', 267 => '0.4', 270 => '1.4' }, - 'focuswarning' => { 121 => 0x1301 }, - 'foldername' => { 171 => 0x27 }, - 'foldernumber' => { 376 => 0x9a, 378 => [0x402,0x114,0x316] }, - 'fontcomposite' => { 471 => [\'Fonts','FontsComposite'] }, - 'fontface' => { 471 => [\'Fonts','FontsFontFace'] }, - 'fontfamily' => { 471 => [\'Fonts','FontsFontFamily'] }, - 'fontfilename' => { 471 => [\'Fonts','FontsFontFileName'] }, - 'fontname' => { 471 => [\'Fonts','FontsFontName'] }, - 'fonts' => { 471 => 'Fonts' }, - 'fonttype' => { 471 => [\'Fonts','FontsFontType'] }, - 'fontversion' => { 471 => [\'Fonts','FontsVersionString'] }, - 'for' => { 348 => 'For' }, - 'forcewrite' => { 114 => 'ForceWrite' }, - 'format' => { 426 => 'Format', 443 => 'format', 464 => 'Format' }, - 'forwardlock' => { 461 => 'forwardlock' }, - 'forwardmatrix1' => { 113 => 0xc714 }, - 'forwardmatrix2' => { 113 => 0xc715 }, - 'fossilspecimen' => { 112 => 'FossilSpecimen' }, - 'fossilspecimenmaterialsampleid' => { 112 => [\'FossilSpecimen','FossilSpecimenMaterialSampleID'] }, - 'framecount' => { 63 => [0x2,0x4] }, - 'frameheight' => { 121 => 0x3822 }, - 'framenum' => { 343 => 0xd7 }, - 'framenumber' => { 121 => 0x8003, 177 => 0x3c, 332 => 0x29 }, - 'framerate' => { 63 => [0x1,0x6], 113 => 0xc764, 121 => 0x3820 }, - 'framewidth' => { 121 => 0x3821 }, - 'framing' => { 455 => 'framing' }, - 'freebytes' => { 91 => 0x1 }, - 'freememorycardimages' => { 172 => [0x37,0x54], 173 => [0x2d,0x4a], 174 => 0x32 }, - 'fujiflashmode' => { 121 => 0x1010 }, - 'fullimagesize' => { 388 => 0xb02b }, - 'fullpanoheightpixels' => { 429 => 'FullPanoHeightPixels', 430 => 'FullPanoHeightPixels' }, - 'fullpanowidthpixels' => { 429 => 'FullPanoWidthPixels', 430 => 'FullPanoWidthPixels' }, - 'fullpresssnap' => { 358 => 0x100d }, - 'fullsizeimage' => { 153 => 'data' }, - 'fullsizeimagename' => { 153 => '1Name' }, - 'fullsizeimagetype' => { 153 => '0Type' }, - 'func1button' => { 260 => '14.1', 261 => '14.1', 271 => '14.1' }, - 'func1buttonplusdials' => { 260 => '42.1', 261 => '42.1', 271 => '42.1' }, - 'func2button' => { 260 => '80.1', 261 => '80.1', 271 => '80.1' }, - 'func2buttonplusdials' => { 260 => '81.1' }, - 'func3button' => { 260 => '83.1' }, - 'funcbutton' => { 257 => ['14.1','15.1'], 258 => '14.1', 266 => '28.1', 267 => '13.1', 270 => '14.1', 272 => '14.1' }, - 'funcbuttonplusdials' => { 257 => ['14.2','15.2'], 258 => '14.2', 266 => '31.1', 270 => '42.1' }, - 'functionbutton' => { 264 => '13.1', 268 => '5.2' }, - 'gainbase' => { 278 => 0x610 }, - 'gaincontrol' => { 113 => 0xa407, 446 => 'GainControl' }, - 'gamma' => { 113 => 0xa500, 131 => 0x8fe, 302 => 0x11c, 447 => 'Gamma' }, - 'gammablackpoint' => { 99 => 0xc }, - 'gammacolortone' => { 99 => 0x3 }, - 'gammacompensatedvalue' => { 127 => 0x91 }, - 'gammacontrast' => { 99 => 0x2 }, - 'gammacurveoutputrange' => { 99 => 0xf }, - 'gammahighlight' => { 99 => 0xa }, - 'gammalinear' => { 97 => 0x20200 }, - 'gammamidpoint' => { 99 => 0xe }, - 'gammasaturation' => { 99 => 0x4 }, - 'gammashadow' => { 99 => 0x9 }, - 'gammasharpnessstrength' => { 99 => 0x8 }, - 'gammaunsharpmaskfineness' => { 99 => 0x6 }, - 'gammaunsharpmaskstrength' => { 99 => 0x5 }, - 'gammaunsharpmaskthreshold' => { 99 => 0x7 }, - 'gammawhitepoint' => { 99 => 0xd }, - 'geimagesize' => { 121 => 0x1304 }, - 'gemake' => { 123 => 0x300 }, - 'gemodel' => { 123 => 0x207 }, - 'genre' => { 452 => 'Genre', 456 => 'genre', 466 => 'genre' }, - 'genrecvid' => { 452 => [\'Genre','GenreCvId'] }, - 'genrecvtermid' => { 452 => [\'Genre','GenreCvTermId'] }, - 'genrecvtermname' => { 452 => [\'Genre','GenreCvTermName'] }, - 'genrecvtermrefinedabout' => { 452 => [\'Genre','GenreCvTermRefinedAbout'] }, - 'geography' => { 457 => 'geography' }, - 'geologicalcontext' => { 112 => 'GeologicalContext' }, - 'geologicalcontextbed' => { 112 => [\'GeologicalContext','GeologicalContextBed'] }, - 'geologicalcontextformation' => { 112 => [\'GeologicalContext','GeologicalContextFormation'] }, - 'geologicalcontextgroup' => { 112 => [\'GeologicalContext','GeologicalContextGroup'] }, - 'geologicalcontextid' => { 112 => [\'GeologicalContext','GeologicalContextGeologicalContextID'] }, - 'geologicalcontextmember' => { 112 => [\'GeologicalContext','GeologicalContextMember'] }, - 'geosync' => { 114 => 'Geosync' }, - 'geotag' => { 114 => 'Geotag' }, - 'geotiffasciiparams' => { 113 => 0x87b1 }, - 'geotiffdirectory' => { 113 => 0x87af }, - 'geotiffdoubleparams' => { 113 => 0x87b0 }, - 'geotime' => { 114 => 'Geotime' }, - 'giftftppriority' => { 431 => 'GIFTFtpPriority' }, - 'gimbalpitchdegree' => { 110 => 'GimbalPitchDegree' }, - 'gimbalrolldegree' => { 110 => 'GimbalRollDegree' }, - 'gimbalyawdegree' => { 110 => 'GimbalYawDegree' }, - 'globalaltitude' => { 346 => 0x419 }, - 'globalangle' => { 346 => 0x40d }, - 'good' => { 466 => 'good' }, - 'googleplusuploadcode' => { 113 => 0x9009 }, - 'gpsaltitude' => { 124 => 0x6, 151 => 'Altitude', 446 => 'GPSAltitude' }, - 'gpsaltituderef' => { 124 => 0x5, 446 => 'GPSAltitudeRef' }, - 'gpsareainformation' => { 124 => 0x1c, 446 => 'GPSAreaInformation' }, - 'gpsdatestamp' => { 124 => 0x1d }, - 'gpsdatetime' => { 151 => 'DateTime', 446 => 'GPSTimeStamp' }, - 'gpsdestbearing' => { 124 => 0x18, 151 => 'Bearing', 446 => 'GPSDestBearing' }, - 'gpsdestbearingref' => { 124 => 0x17, 446 => 'GPSDestBearingRef' }, - 'gpsdestdistance' => { 124 => 0x1a, 151 => 'Distance', 446 => 'GPSDestDistance' }, - 'gpsdestdistanceref' => { 124 => 0x19, 446 => 'GPSDestDistanceRef' }, - 'gpsdestlatitude' => { 124 => 0x14, 446 => 'GPSDestLatitude' }, - 'gpsdestlatituderef' => { 124 => 0x13 }, - 'gpsdestlongitude' => { 124 => 0x16, 446 => 'GPSDestLongitude' }, - 'gpsdestlongituderef' => { 124 => 0x15 }, - 'gpsdifferential' => { 124 => 0x1e, 151 => 'Differential', 446 => 'GPSDifferential' }, - 'gpsdop' => { 124 => 0xb, 446 => 'GPSDOP' }, - 'gpshpositioningerror' => { 124 => 0x1f, 446 => 'GPSHPositioningError' }, - 'gpsimgdirection' => { 124 => 0x11, 446 => 'GPSImgDirection' }, - 'gpsimgdirectionref' => { 124 => 0x10, 446 => 'GPSImgDirectionRef' }, - 'gpslatitude' => { 124 => 0x2, 151 => 'Latitude', 446 => 'GPSLatitude' }, - 'gpslatituderef' => { 124 => 0x1 }, - 'gpslongitude' => { 124 => 0x4, 151 => 'Longitude', 446 => 'GPSLongitude' }, - 'gpslongituderef' => { 124 => 0x3 }, - 'gpsmapdatum' => { 124 => 0x12, 151 => 'Datum', 446 => 'GPSMapDatum' }, - 'gpsmeasuremode' => { 124 => 0xa, 151 => 'MeasureMode', 446 => 'GPSMeasureMode' }, - 'gpsprocessingmethod' => { 124 => 0x1b, 446 => 'GPSProcessingMethod' }, - 'gpssatellites' => { 124 => 0x8, 151 => 'Satellites', 446 => 'GPSSatellites' }, - 'gpsspeed' => { 124 => 0xd, 151 => 'Speed', 446 => 'GPSSpeed' }, - 'gpsspeedref' => { 124 => 0xc, 446 => 'GPSSpeedRef' }, - 'gpsstatus' => { 124 => 0x9, 446 => 'GPSStatus' }, - 'gpsstring' => { 131 => 0x402 }, - 'gpstimestamp' => { 124 => 0x7 }, - 'gpstrack' => { 124 => 0xf, 151 => 'Heading', 446 => 'GPSTrack' }, - 'gpstrackref' => { 124 => 0xe, 446 => 'GPSTrackRef' }, - 'gpsversionid' => { 124 => 0x0, 446 => 'GPSVersionID' }, - 'gradation' => { 274 => 0x50f }, - 'gradientbasedcorractive' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'] }, - 'gradientbasedcorramount' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'] }, - 'gradientbasedcorrbrightness' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'] }, - 'gradientbasedcorrclarity' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'] }, - 'gradientbasedcorrclarity2012' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity2012'] }, - 'gradientbasedcorrcontrast' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'] }, - 'gradientbasedcorrcontrast2012' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast2012'] }, - 'gradientbasedcorrdefringe' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDefringe'] }, - 'gradientbasedcorrections' => { 442 => 'GradientBasedCorrections' }, - 'gradientbasedcorrexposure' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'] }, - 'gradientbasedcorrexposure2012' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure2012'] }, - 'gradientbasedcorrhighlights2012' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHighlights2012'] }, - 'gradientbasedcorrhue' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalToningHue'] }, - 'gradientbasedcorrluminancenoise' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalLuminanceNoise'] }, - 'gradientbasedcorrmaskalpha' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAlpha'] }, - 'gradientbasedcorrmaskangle' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAngle'] }, - 'gradientbasedcorrmaskbottom' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksBottom'] }, - 'gradientbasedcorrmaskcentervalue' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterValue'] }, - 'gradientbasedcorrmaskcenterweight' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'] }, - 'gradientbasedcorrmaskdabs' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'] }, - 'gradientbasedcorrmaskfeather' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFeather'] }, - 'gradientbasedcorrmaskflipped' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlipped'] }, - 'gradientbasedcorrmaskflow' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'] }, - 'gradientbasedcorrmaskfullx' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'] }, - 'gradientbasedcorrmaskfully' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'] }, - 'gradientbasedcorrmaskleft' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksLeft'] }, - 'gradientbasedcorrmaskmidpoint' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMidpoint'] }, - 'gradientbasedcorrmaskperimetervalue' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksPerimeterValue'] }, - 'gradientbasedcorrmaskradius' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'] }, - 'gradientbasedcorrmaskright' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRight'] }, - 'gradientbasedcorrmaskroundness' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRoundness'] }, - 'gradientbasedcorrmasks' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'] }, - 'gradientbasedcorrmasksizex' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeX'] }, - 'gradientbasedcorrmasksizey' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeY'] }, - 'gradientbasedcorrmasktop' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksTop'] }, - 'gradientbasedcorrmaskvalue' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'] }, - 'gradientbasedcorrmaskversion' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksVersion'] }, - 'gradientbasedcorrmaskwhat' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'] }, - 'gradientbasedcorrmaskx' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksX'] }, - 'gradientbasedcorrmasky' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksY'] }, - 'gradientbasedcorrmaskzerox' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'] }, - 'gradientbasedcorrmaskzeroy' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'] }, - 'gradientbasedcorrmoire' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalMoire'] }, - 'gradientbasedcorrsaturation' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'] }, - 'gradientbasedcorrshadows2012' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalShadows2012'] }, - 'gradientbasedcorrsharpness' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'] }, - 'gradientbasedcorrtemperature' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTemperature'] }, - 'gradientbasedcorrtint' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTint'] }, - 'gradientbasedcorrwhat' => { 442 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'] }, - 'grainamount' => { 442 => 'GrainAmount' }, - 'graineffect' => { 121 => 0x1047 }, - 'grainfrequency' => { 442 => 'GrainFrequency' }, - 'grainsize' => { 442 => 'GrainSize' }, - 'graymixeraqua' => { 442 => 'GrayMixerAqua' }, - 'graymixerblue' => { 442 => 'GrayMixerBlue' }, - 'graymixergreen' => { 442 => 'GrayMixerGreen' }, - 'graymixermagenta' => { 442 => 'GrayMixerMagenta' }, - 'graymixerorange' => { 442 => 'GrayMixerOrange' }, - 'graymixerpurple' => { 442 => 'GrayMixerPurple' }, - 'graymixerred' => { 442 => 'GrayMixerRed' }, - 'graymixeryellow' => { 442 => 'GrayMixerYellow' }, - 'graypoint' => { 421 => 0x8021 }, - 'grayresponseunit' => { 113 => 0x122 }, - 'greencurvelimits' => { 102 => 0x1c4 }, - 'greencurvepoints' => { 101 => 0x53, 102 => 0x19a }, - 'greenhsl' => { 97 => 0x20913 }, - 'greenhue' => { 442 => 'GreenHue' }, - 'greensaturation' => { 442 => 'GreenSaturation' }, - 'griddisplay' => { 257 => '13.3', 258 => '4.3', 260 => '4.2', 261 => '4.2', 262 => '2.2', 266 => '10.5', 267 => '3.4', 268 => '6.1', 270 => '4.4', 271 => '4.2', 272 => '4.2' }, - 'gripbatteryadload' => { 311 => 0x5 }, - 'gripbatteryadnoload' => { 311 => 0x4 }, - 'gripbatterystate' => { 311 => '1.2' }, - 'groupareaafillumination' => { 258 => '46.4', 261 => '47.4', 270 => '47.4' }, - 'h2resetblackpixels' => { 131 => 0x18a6 }, - 'h3resetblackcolumns' => { 131 => 0x18ce }, - 'h3resetblackpixels' => { 131 => 0x18b0 }, - 'halftonehints' => { 113 => 0x141 }, - 'hardlink' => { 114 => 'HardLink' }, - 'hasalternative' => { 456 => 'hasAlternative' }, - 'hascorrection' => { 456 => 'hasCorrection' }, - 'hascorrectiona-lang' => { 456 => [\'hasCorrection','hasCorrectionA-lang'] }, - 'hascorrectiona-platform' => { 456 => [\'hasCorrection','hasCorrectionA-platform'] }, - 'hascorrectiontext' => { 456 => [\'hasCorrection','hasCorrectionText'] }, - 'hascrop' => { 442 => 'HasCrop' }, - 'hasextendedxmp' => { 468 => 'HasExtendedXMP' }, - 'hassettings' => { 442 => 'HasSettings' }, - 'hastranslation' => { 456 => 'hasTranslation' }, - 'hasvisibleoverprint' => { 471 => 'HasVisibleOverprint' }, - 'hasvisibletransparency' => { 471 => 'HasVisibleTransparency' }, - 'hdr' => { 57 => 0x1, 204 => 0x4, 297 => 0x9e, 332 => 0x85, 388 => 0x200a }, - 'hdreffect' => { 57 => 0x2 }, + 'croppedimagewidth' => { 5 => 0x1, 373 => 0x1603 }, + 'cropping' => { 439 => 0x9010 }, + 'cropright' => { 120 => 0x8, 254 => 0x2e, 311 => 0x32, 352 => 0xdb, 462 => 'CropRight', 464 => 'CropRight' }, + 'croprightmargin' => { 51 => 0x1 }, + 'croprotatedoriginalheight' => { 98 => 0x2 }, + 'croprotatedoriginalwidth' => { 98 => 0x1 }, + 'croprotation' => { 98 => 0x8, 120 => 0xb }, + 'cropscaledresolution' => { 254 => 0x9e }, + 'cropsourceresolution' => { 254 => 0xae }, + 'croptop' => { 105 => 0x248, 120 => 0x7, 254 => 0x26, 287 => 0x613, 291 => 0x613, 311 => 0x2f, 352 => 0xda, 462 => 'CropTop', 464 => 'CropTop' }, + 'croptopmargin' => { 51 => 0x2 }, + 'cropunit' => { 462 => 'CropUnit', 464 => 'CropUnit' }, + 'cropunits' => { 462 => 'CropUnits', 464 => 'CropUnits' }, + 'cropw' => { 456 => 'CropW' }, + 'cropwidth' => { 98 => 0x5, 105 => 0x24a, 287 => 0x614, 291 => 0x614, 462 => 'CropWidth', 464 => 'CropWidth' }, + 'cropx' => { 98 => 0x3, 456 => 'CropX' }, + 'cropy' => { 98 => 0x4, 456 => 'CropY' }, + 'crossprocess' => { 341 => 0x7b }, + 'crossprocessparams' => { 341 => 0x235 }, + 'cuisine' => { 480 => 'cuisine' }, + 'currenticcprofile' => { 116 => 0xc691 }, + 'currentpreprofilematrix' => { 116 => 0xc692 }, + 'currentversion' => { 439 => 0xd000 }, + 'curve0x' => { 456 => 'Curve0x' }, + 'curve0y' => { 456 => 'Curve0y' }, + 'curve1x' => { 456 => 'Curve1x' }, + 'curve1y' => { 456 => 'Curve1y' }, + 'curve2x' => { 456 => 'Curve2x' }, + 'curve2y' => { 456 => 'Curve2y' }, + 'curve3x' => { 456 => 'Curve3x' }, + 'curve3y' => { 456 => 'Curve3y' }, + 'curve4x' => { 456 => 'Curve4x' }, + 'curve4y' => { 456 => 'Curve4y' }, + 'curves' => { 259 => 0x76a43201 }, + 'custom1' => { 293 => 'Custom1' }, + 'custom10' => { 293 => 'Custom10' }, + 'custom2' => { 293 => 'Custom2' }, + 'custom3' => { 293 => 'Custom3' }, + 'custom4' => { 293 => 'Custom4' }, + 'custom5' => { 293 => 'Custom5' }, + 'custom6' => { 293 => 'Custom6' }, + 'custom7' => { 293 => 'Custom7' }, + 'custom8' => { 293 => 'Custom8' }, + 'custom9' => { 293 => 'Custom9' }, + 'customcolortone' => { 106 => 0x4c }, + 'customcontrast' => { 106 => 0x4e }, + 'customcontrols' => { 81 => 0x70c }, + 'customdefaultunsharpfineness' => { 106 => 0xbe }, + 'customdefaultunsharpstrength' => { 106 => 0xbc }, + 'customdefaultunsharpthreshold' => { 106 => 0xc0 }, + 'customilluminant' => { 134 => 0x405 }, + 'customizedials' => { 81 => 0x715 }, + 'customlinear' => { 106 => 0x4f }, + 'customoutputhighlightpoint' => { 106 => 0x53 }, + 'customoutputshadowpoint' => { 106 => 0x54 }, + 'custompicturestyle' => { 100 => 0x10021 }, + 'custompicturestyledata' => { 100 => 0xf0500 }, + 'custompicturestylefilename' => { 61 => 0x4010 }, + 'customrawhighlight' => { 106 => 0x7c }, + 'customrawhighlightpoint' => { 106 => 0x51 }, + 'customrawshadow' => { 106 => 0x85 }, + 'customrawshadowpoint' => { 106 => 0x52 }, + 'customrendered' => { 116 => 0xa401, 468 => 'CustomRendered' }, + 'customsaturation' => { 106 => 0x4d, 283 => 0x503 }, + 'customsettingsalldefault' => { 266 => '0.2', 275 => '0.2' }, + 'customsettingsbank' => { 266 => '0.1', 267 => '0.1', 269 => '0.1', 270 => '0.1', 275 => '0.1', 279 => '0.2', 280 => '0.2' }, + 'customsharpness' => { 106 => 0x50 }, + 'customunsharpmaskfineness' => { 106 => 0xb8 }, + 'customunsharpmaskstrength' => { 106 => 0xb6 }, + 'customunsharpmaskthreshold' => { 106 => 0xba }, + 'customwb_rblevels' => { 411 => 0x1a }, + 'customwb_rgblevels' => { 394 => 0x8, 395 => 0x19 }, + 'customwbbluelevel' => { 179 => 0x36 }, + 'customwberror' => { 179 => 0x37 }, + 'customwbgreenlevel' => { 179 => 0x35 }, + 'customwbredlevel' => { 179 => 0x34 }, + 'customwbsetting' => { 179 => 0x26 }, + 'cx' => { 366 => '_cx_' }, + 'cy' => { 366 => '_cy_' }, + 'd-lightinghq' => { 259 => 0x2175eb78 }, + 'd-lightinghqcolorboost' => { 255 => 0x2 }, + 'd-lightinghqhighlight' => { 255 => 0x1 }, + 'd-lightinghqselected' => { 259 => 0x6a6e36b6 }, + 'd-lightinghqshadow' => { 255 => 0x0 }, + 'd-lightinghs' => { 259 => 0xce5554aa }, + 'd-lightinghsadjustment' => { 256 => 0x0 }, + 'd-lightinghscolorboost' => { 256 => 0x1 }, + 'd-rangeoptimizerhighlight' => { 439 => 0x8024 }, + 'd-rangeoptimizermode' => { 439 => 0x8022 }, + 'd-rangeoptimizershadow' => { 439 => 0x802d }, + 'd-rangeoptimizervalue' => { 439 => 0x8023 }, + 'darkblacksegrows' => { 134 => 0x18d8 }, + 'darkfocusenvironment' => { 306 => 0x8003 }, + 'darkframecountfactor' => { 134 => 0xc85 }, + 'darkframelongexposure' => { 134 => 0xc84 }, + 'darkframeshortexposure' => { 134 => 0xc83 }, + 'darkpedestal' => { 134 => 0xc7f }, + 'datacompressionmethod' => { 130 => 0x6e }, + 'dataimprint' => { 176 => 0x34 }, + 'dataonscreen' => { 474 => 'DataOnScreen' }, + 'dataonscreenregion' => { 474 => [\'DataOnScreen','DataOnScreenRegion'] }, + 'dataonscreenregiond' => { 474 => [\'DataOnScreen','DataOnScreenRegionD'] }, + 'dataonscreenregionh' => { 474 => [\'DataOnScreen','DataOnScreenRegionH'] }, + 'dataonscreenregiontext' => { 474 => [\'DataOnScreen','DataOnScreenRegionText'] }, + 'dataonscreenregionunit' => { 474 => [\'DataOnScreen','DataOnScreenRegionUnit'] }, + 'dataonscreenregionw' => { 474 => [\'DataOnScreen','DataOnScreenRegionW'] }, + 'dataonscreenregionx' => { 474 => [\'DataOnScreen','DataOnScreenRegionX'] }, + 'dataonscreenregiony' => { 474 => [\'DataOnScreen','DataOnScreenRegionY'] }, + 'datascaling' => { 341 => 0x3d }, + 'date' => { 341 => 0x6, 465 => 'date' }, + 'dateacquired' => { 174 => 'DateAcquired' }, + 'datecreated' => { 128 => 0x37, 476 => 'DateCreated' }, + 'datedisplayformat' => { 251 => 0x3 }, + 'dateidentified' => { 115 => [\'Identification','IdentificationDateIdentified'] }, + 'dateimprint' => { 271 => '4.2' }, + 'daterecieved' => { 478 => 'dateRecieved' }, + 'datesent' => { 129 => 0x46 }, + 'datestampmode' => { 61 => 0x1c, 219 => 0x9d }, + 'datetime' => { 457 => 'datetime', 484 => 'DateTime' }, + 'datetimedigitized' => { 468 => 'DateTimeDigitized' }, + 'datetimeoriginal' => { 97 => 0x0, 116 => 0x9003, 150 => 0x14, 153 => 'OriginalDate', 361 => 'IDIT', 366 => 'date', 367 => 0xb, 368 => 0x3b, 369 => 0x3e, 468 => 'DateTimeOriginal' }, + 'datetimestamp' => { 136 => 0x64 }, + 'datetimeutc' => { 283 => 0x908 }, + 'daylightsavings' => { 75 => 0x3, 251 => 0x2 }, + 'dayofweek' => { 368 => 0x42, 369 => 0x4a }, + 'dccontinent' => { 115 => [\'dctermsLocation','dctermsLocationContinent'] }, + 'dccoordinateprecision' => { 115 => [\'dctermsLocation','dctermsLocationCoordinatePrecision'] }, + 'dccoordinateuncertaintyinmeters' => { 115 => [\'dctermsLocation','dctermsLocationCoordinateUncertaintyInMeters'] }, + 'dccountry' => { 115 => [\'dctermsLocation','dctermsLocationCountry'] }, + 'dccountrycode' => { 115 => [\'dctermsLocation','dctermsLocationCountryCode'] }, + 'dccounty' => { 115 => [\'dctermsLocation','dctermsLocationCounty'] }, + 'dcdecimallatitude' => { 115 => [\'dctermsLocation','dctermsLocationDecimalLatitude'] }, + 'dcdecimallongitude' => { 115 => [\'dctermsLocation','dctermsLocationDecimalLongitude'] }, + 'dcevent' => { 115 => 'Event' }, + 'dcfootprintspatialfit' => { 115 => [\'dctermsLocation','dctermsLocationFootprintSpatialFit'] }, + 'dcfootprintsrs' => { 115 => [\'dctermsLocation','dctermsLocationFootprintSRS'] }, + 'dcfootprintwkt' => { 115 => [\'dctermsLocation','dctermsLocationFootprintWKT'] }, + 'dcgeodeticdatum' => { 115 => [\'dctermsLocation','dctermsLocationGeodeticDatum'] }, + 'dcgeoreferencedby' => { 115 => [\'dctermsLocation','dctermsLocationGeoreferencedBy'] }, + 'dcgeoreferenceddate' => { 115 => [\'dctermsLocation','dctermsLocationGeoreferencedDate'] }, + 'dcgeoreferenceprotocol' => { 115 => [\'dctermsLocation','dctermsLocationGeoreferenceProtocol'] }, + 'dcgeoreferenceremarks' => { 115 => [\'dctermsLocation','dctermsLocationGeoreferenceRemarks'] }, + 'dcgeoreferencesources' => { 115 => [\'dctermsLocation','dctermsLocationGeoreferenceSources'] }, + 'dcgeoreferenceverificationstatus' => { 115 => [\'dctermsLocation','dctermsLocationGeoreferenceVerificationStatus'] }, + 'dchighergeography' => { 115 => [\'dctermsLocation','dctermsLocationHigherGeography'] }, + 'dchighergeographyid' => { 115 => [\'dctermsLocation','dctermsLocationHigherGeographyID'] }, + 'dcisland' => { 115 => [\'dctermsLocation','dctermsLocationIsland'] }, + 'dcislandgroup' => { 115 => [\'dctermsLocation','dctermsLocationIslandGroup'] }, + 'dclocality' => { 115 => [\'dctermsLocation','dctermsLocationLocality'] }, + 'dclocationaccordingto' => { 115 => [\'dctermsLocation','dctermsLocationLocationAccordingTo'] }, + 'dclocationid' => { 115 => [\'dctermsLocation','dctermsLocationLocationID'] }, + 'dclocationremarks' => { 115 => [\'dctermsLocation','dctermsLocationLocationRemarks'] }, + 'dcmaximumdepthinmeters' => { 115 => [\'dctermsLocation','dctermsLocationMaximumDepthInMeters'] }, + 'dcmaximumdistanceabovesurfaceinmeters' => { 115 => [\'dctermsLocation','dctermsLocationMaximumDistanceAboveSurfaceInMeters'] }, + 'dcmaximumelevationinmeters' => { 115 => [\'dctermsLocation','dctermsLocationMaximumElevationInMeters'] }, + 'dcminimumdepthinmeters' => { 115 => [\'dctermsLocation','dctermsLocationMinimumDepthInMeters'] }, + 'dcminimumdistanceabovesurfaceinmeters' => { 115 => [\'dctermsLocation','dctermsLocationMinimumDistanceAboveSurfaceInMeters'] }, + 'dcminimumelevationinmeters' => { 115 => [\'dctermsLocation','dctermsLocationMinimumElevationInMeters'] }, + 'dcmunicipality' => { 115 => [\'dctermsLocation','dctermsLocationMunicipality'] }, + 'dcpointradiusspatialfit' => { 115 => [\'dctermsLocation','dctermsLocationPointRadiusSpatialFit'] }, + 'dcstateprovince' => { 115 => [\'dctermsLocation','dctermsLocationStateProvince'] }, + 'dctermslocation' => { 115 => 'dctermsLocation' }, + 'dcverbatimcoordinates' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimCoordinates'] }, + 'dcverbatimcoordinatesystem' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimCoordinateSystem'] }, + 'dcverbatimdepth' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimDepth'] }, + 'dcverbatimelevation' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimElevation'] }, + 'dcverbatimlatitude' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimLatitude'] }, + 'dcverbatimlocality' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimLocality'] }, + 'dcverbatimlongitude' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimLongitude'] }, + 'dcverbatimsrs' => { 115 => [\'dctermsLocation','dctermsLocationVerbatimSRS'] }, + 'dcwaterbody' => { 115 => [\'dctermsLocation','dctermsLocationWaterBody'] }, + 'declination' => { 161 => 'Declination' }, + 'decposition' => { 176 => 0x32 }, + 'defaultautogray' => { 462 => 'DefaultAutoGray', 464 => 'DefaultAutoGray' }, + 'defaultautotone' => { 462 => 'DefaultAutoTone', 464 => 'DefaultAutoTone' }, + 'defaultblackrender' => { 116 => 0xc7a6 }, + 'defaultcroporigin' => { 116 => 0xc61f }, + 'defaultcropsize' => { 116 => 0xc620 }, + 'defaulteraseoption' => { 81 => 0x813 }, + 'defaultscale' => { 116 => 0xc61e }, + 'defaultsspecifictoiso' => { 462 => 'DefaultsSpecificToISO', 464 => 'DefaultsSpecificToISO' }, + 'defaultsspecifictoserial' => { 462 => 'DefaultsSpecificToSerial', 464 => 'DefaultsSpecificToSerial' }, + 'defaultusercrop' => { 116 => 0xc7b5 }, + 'defectisocode' => { 134 => 0x90f }, + 'defringe' => { 462 => 'Defringe', 464 => 'Defringe' }, + 'defringegreenamount' => { 462 => 'DefringeGreenAmount', 464 => 'DefringeGreenAmount' }, + 'defringegreenhuehi' => { 462 => 'DefringeGreenHueHi', 464 => 'DefringeGreenHueHi' }, + 'defringegreenhuelo' => { 462 => 'DefringeGreenHueLo', 464 => 'DefringeGreenHueLo' }, + 'defringepurpleamount' => { 462 => 'DefringePurpleAmount', 464 => 'DefringePurpleAmount' }, + 'defringepurplehuehi' => { 462 => 'DefringePurpleHueHi', 464 => 'DefringePurpleHueHi' }, + 'defringepurplehuelo' => { 462 => 'DefringePurpleHueLo', 464 => 'DefringePurpleHueLo' }, + 'dehaze' => { 462 => 'Dehaze', 464 => 'Dehaze' }, + 'deletedimagecount' => { 219 => 0xa6, 228 => 0x6e }, + 'deprecatedon' => { 460 => 'deprecatedOn' }, + 'depthfar' => { 116 => 0xc7eb }, + 'depthformat' => { 116 => 0xc7e9 }, + 'depthimage' => { 447 => 'Data' }, + 'depthmeasuretype' => { 116 => 0xc7ed }, + 'depthnear' => { 116 => 0xc7ea }, + 'depthunits' => { 116 => 0xc7ec }, + 'derivedfrom' => { 489 => 'DerivedFrom' }, + 'derivedfromalternatepaths' => { 489 => [\'DerivedFrom','DerivedFromAlternatePaths'] }, + 'derivedfromdocumentid' => { 489 => [\'DerivedFrom','DerivedFromDocumentID'] }, + 'derivedfromfilepath' => { 489 => [\'DerivedFrom','DerivedFromFilePath'] }, + 'derivedfromfrompart' => { 489 => [\'DerivedFrom','DerivedFromFromPart'] }, + 'derivedfrominstanceid' => { 489 => [\'DerivedFrom','DerivedFromInstanceID'] }, + 'derivedfromlastmodifydate' => { 489 => [\'DerivedFrom','DerivedFromLastModifyDate'] }, + 'derivedfromlasturl' => { 489 => [\'DerivedFrom','DerivedFromLastURL'] }, + 'derivedfromlinkcategory' => { 489 => [\'DerivedFrom','DerivedFromLinkCategory'] }, + 'derivedfromlinkform' => { 489 => [\'DerivedFrom','DerivedFromLinkForm'] }, + 'derivedfrommanager' => { 489 => [\'DerivedFrom','DerivedFromManager'] }, + 'derivedfrommanagervariant' => { 489 => [\'DerivedFrom','DerivedFromManagerVariant'] }, + 'derivedfrommanageto' => { 489 => [\'DerivedFrom','DerivedFromManageTo'] }, + 'derivedfrommanageui' => { 489 => [\'DerivedFrom','DerivedFromManageUI'] }, + 'derivedfrommaskmarkers' => { 489 => [\'DerivedFrom','DerivedFromMaskMarkers'] }, + 'derivedfromoriginaldocumentid' => { 489 => [\'DerivedFrom','DerivedFromOriginalDocumentID'] }, + 'derivedfrompartmapping' => { 489 => [\'DerivedFrom','DerivedFromPartMapping'] }, + 'derivedfromplacedresolutionunit' => { 489 => [\'DerivedFrom','DerivedFromPlacedResolutionUnit'] }, + 'derivedfromplacedxresolution' => { 489 => [\'DerivedFrom','DerivedFromPlacedXResolution'] }, + 'derivedfromplacedyresolution' => { 489 => [\'DerivedFrom','DerivedFromPlacedYResolution'] }, + 'derivedfromrenditionclass' => { 489 => [\'DerivedFrom','DerivedFromRenditionClass'] }, + 'derivedfromrenditionparams' => { 489 => [\'DerivedFrom','DerivedFromRenditionParams'] }, + 'derivedfromtopart' => { 489 => [\'DerivedFrom','DerivedFromToPart'] }, + 'derivedfromversionid' => { 489 => [\'DerivedFrom','DerivedFromVersionID'] }, + 'description' => { 296 => 'Description', 358 => ['desc','dscp',"\xa9des"], 360 => 'description', 366 => 'dscp', 465 => 'description', 486 => 'Description' }, + 'destination' => { 129 => 0x5 }, + 'destinationcity' => { 341 => 0x24, 347 => 0x3 }, + 'destinationcitycode' => { 348 => 0x1001 }, + 'destinationdst' => { 341 => 0x26, 347 => '0.3' }, + 'developmentdynamicrange' => { 124 => 0x1403 }, + 'deviantmatrixcustom' => { 134 => 0x7de }, + 'deviantmatrixdaylight' => { 134 => 0x7da }, + 'deviantmatrixflash' => { 134 => 0x7dd }, + 'deviantmatrixfluorescent' => { 134 => 0x7dc }, + 'deviantmatrixtungsten' => { 134 => 0x7db }, + 'deviantwhitecustom' => { 134 => 0x842 }, + 'deviantwhitedaylight' => { 134 => 0x83e }, + 'deviantwhiteflash' => { 134 => 0x841 }, + 'deviantwhitefluorescent' => { 134 => 0x840 }, + 'deviantwhitetungsten' => { 134 => 0x83f }, + 'device' => { 478 => 'device' }, + 'devicesettingdescription' => { 468 => 'DeviceSettingDescription' }, + 'devicesettingdescriptioncolumns' => { 468 => [\'DeviceSettingDescription','DeviceSettingDescriptionColumns'] }, + 'devicesettingdescriptionrows' => { 468 => [\'DeviceSettingDescription','DeviceSettingDescriptionRows'] }, + 'devicesettingdescriptionsettings' => { 468 => [\'DeviceSettingDescription','DeviceSettingDescriptionSettings'] }, + 'devicetype' => { 380 => 0x2 }, + 'dewarpdata' => { 113 => 'DewarpData' }, + 'dewarpflag' => { 113 => 'DewarpFlag' }, + 'dialdirectiontvav' => { 81 => 0x706 }, + 'dietaryneeds' => { 480 => 'dietaryNeeds' }, + 'diffractioncorrection' => { 306 => 0xbc, 331 => 0x3 }, + 'diffractioncorrectionon' => { 100 => 0x2070b }, + 'digitalcreationdate' => { 128 => 0x3e }, + 'digitalcreationtime' => { 128 => 0x3f }, + 'digitaldeehighlightadj' => { 227 => 0x202 }, + 'digitaldeeshadowadj' => { 227 => 0x200 }, + 'digitaldeethreshold' => { 227 => 0x201 }, + 'digitalfilter' => { 383 => 0x59 }, + 'digitalfilter01' => { 328 => 0x5 }, + 'digitalfilter02' => { 328 => 0x16 }, + 'digitalfilter03' => { 328 => 0x27 }, + 'digitalfilter04' => { 328 => 0x38 }, + 'digitalfilter05' => { 328 => 0x49 }, + 'digitalfilter06' => { 328 => 0x5a }, + 'digitalfilter07' => { 328 => 0x6b }, + 'digitalfilter08' => { 328 => 0x7c }, + 'digitalfilter09' => { 328 => 0x8d }, + 'digitalfilter10' => { 328 => 0x9e }, + 'digitalfilter11' => { 328 => 0xaf }, + 'digitalfilter12' => { 328 => 0xc0 }, + 'digitalfilter13' => { 328 => 0xd1 }, + 'digitalfilter14' => { 328 => 0xe2 }, + 'digitalfilter15' => { 328 => 0xf3 }, + 'digitalfilter16' => { 328 => 0x104 }, + 'digitalfilter17' => { 328 => 0x115 }, + 'digitalfilter18' => { 328 => 0x126 }, + 'digitalfilter19' => { 328 => 0x137 }, + 'digitalfilter20' => { 328 => 0x148 }, + 'digitalgain' => { 71 => 0xb }, + 'digitalgem' => { 208 => 0x0 }, + 'digitalice' => { 227 => 0x100 }, + 'digitalimageguid' => { 474 => 'DigImageGUID' }, + 'digitalroc' => { 225 => 0x0 }, + 'digitalsourcefiletype' => { 474 => 'DigitalSourcefileType' }, + 'digitalsourcetype' => { 474 => 'DigitalSourceType' }, + 'digitalzoom' => { 34 => 0xc, 109 => 0xa, 124 => 0x1044, 136 => 0x68, 147 => 0x22, 148 => 0x1e, 152 => 'DigitalZoom', 176 => 0xc, 219 => 0x86, 249 => 0xa, 288 => 0x204, 341 => 0x1e, 348 => 0xa, 382 => 0x204, 426 => 0x12, 427 => 0x12 }, + 'digitalzoomon' => { 382 => 0x21b }, + 'digitalzoomratio' => { 116 => 0xa404, 416 => 0x200, 418 => 0x21c, 468 => 'DigitalZoomRatio' }, + 'director' => { 360 => 'director', 366 => "\xa9dir", 488 => 'director' }, + 'directorphotography' => { 488 => 'directorPhotography' }, + 'directory' => { 117 => 'Directory' }, + 'directoryindex' => { 7 => 0x137, 9 => 0x2dc, 11 => 0x17e, 13 => 0x238, 14 => 0x13f, 15 => 0x133, 16 => 0x1df, 17 => 0x1a7, 18 => 0x1f0, 19 => 0xcc, 20 => 0x1c7, 21 => 0x298, 22 => 0x1e7, 23 => 0x1e5, 24 => [0x27c,0x280], 25 => 0x2b6, 26 => 0x2bf, 28 => 0x1f7, 29 => 0x4ba }, + 'directoryindex2' => { 21 => 0x29c }, + 'directorynumber' => { 202 => 0x3, 369 => 0x12 }, + 'disableautocreation' => { 445 => 'DisableAutoCreation' }, + 'disclaimer' => { 296 => 'Disclaimer' }, + 'discnumber' => { 488 => 'discNumber' }, + 'dishtype' => { 480 => 'dishType' }, + 'disknumber' => { 358 => 'disk' }, + 'displayallafpoints' => { 81 => 0x514 }, + 'displayaperture' => { 34 => 0x23 }, + 'displayedunitsx' => { 356 => 0x2 }, + 'displayedunitsy' => { 356 => 0x6 }, + 'displayname' => { 360 => 'displayname', 477 => 'displayName' }, + 'distance1' => { 136 => 0x28 }, + 'distance2' => { 136 => 0x2c }, + 'distance3' => { 136 => 0x30 }, + 'distance4' => { 136 => 0x34 }, + 'distortion' => { 380 => 0xa050 }, + 'distortioncompensation' => { 439 => 0x8040 }, + 'distortioncontrol' => { 228 => 0x10 }, + 'distortioncorrection' => { 76 => 0x3, 100 => 0x20705, 106 => 0x67, 116 => 0x7036, 283 => 0x50b, 310 => '7.1', 331 => 0x0, 434 => 0x601, 435 => 0x5b }, + 'distortioncorrection2' => { 287 => 0x1011 }, + 'distortioncorrectionalreadyapplied' => { 459 => 'DistortionCorrectionAlreadyApplied' }, + 'distortioncorrectionon' => { 100 => '0x20705.0', 106 => 0x63 }, + 'distortioncorrectionsetting' => { 77 => 0x7, 406 => 0x2013 }, + 'distortioncorrectionvalue' => { 76 => 0x9 }, + 'distortioncorrparams' => { 116 => 0x7037, 415 => 0x1a23, 418 => 0x1870, 420 => 0x189c, 421 => 0x18cc, 422 => 0x17d0, 434 => 0x6ca, 435 => 0x64 }, + 'distortioncorrparamsnumber' => { 418 => 0x1899, 420 => 0x18c5, 421 => 0x18f5, 422 => 0x17f9 }, + 'distortioncorrparamspresent' => { 418 => 0x1898, 420 => 0x18c4, 421 => 0x18f4, 422 => 0x17f8, 424 => 0x10b, 425 => 0x10b, 434 => 0x600, 435 => 0x5a }, + 'distortioneffect' => { 100 => 0x20709 }, + 'distortionn' => { 310 => 0xc }, + 'distortionparam02' => { 310 => 0x2 }, + 'distortionparam04' => { 310 => 0x4 }, + 'distortionparam08' => { 310 => 0x8 }, + 'distortionparam09' => { 310 => 0x9 }, + 'distortionparam11' => { 310 => 0xb }, + 'distortionscale' => { 310 => 0x5 }, + 'distributor' => { 478 => 'distributor' }, + 'distributorproductid' => { 477 => 'distributorProductID' }, + 'dloon' => { 100 => '0x20706.0', 106 => 0xdc }, + 'dlosetting' => { 100 => 0x20706, 106 => 0xdd }, + 'dlosettingapplied' => { 99 => 0x4 }, + 'dloshootingdistance' => { 106 => 0xde }, + 'dloversion' => { 99 => 0x5 }, + 'dmcomment' => { 488 => 'comment' }, + 'dmdithermatrix' => { 134 => 0xc7a }, + 'dmdithermatrixheight' => { 134 => 0xc7c }, + 'dmdithermatrixwidth' => { 134 => 0xc7b }, + 'dngadobedata' => { 116 => 0xc634 }, + 'dngbackwardversion' => { 116 => 0xc613 }, + 'dngignoresidecars' => { 462 => 'DNGIgnoreSidecars', 464 => 'DNGIgnoreSidecars' }, + 'dnglensinfo' => { 116 => 0xc630 }, + 'dngprivatedata' => { 116 => 0xc634 }, + 'dngversion' => { 116 => 0xc612 }, + 'document' => { 296 => 'Document' }, + 'documentancestors' => { 476 => 'DocumentAncestors' }, + 'documenthistory' => { 128 => 0xe7 }, + 'documentid' => { 489 => 'DocumentID' }, + 'documentname' => { 116 => 0x10d }, + 'documentnotes' => { 128 => 0xe6 }, + 'doi' => { 478 => 'doi' }, + 'dopesheet' => { 474 => 'Dopesheet' }, + 'dopesheetlink' => { 474 => 'DopesheetLink' }, + 'dopesheetlinklink' => { 474 => [\'DopesheetLink','DopesheetLinkLink'] }, + 'dopesheetlinklinkqualifier' => { 474 => [\'DopesheetLink','DopesheetLinkLinkQualifier'] }, + 'doublingmicrovolts' => { 134 => 0xc82 }, + 'dpp' => { 457 => 'dpp' }, + 'dr4cameramodel' => { 101 => 0x3 }, + 'drangepriority' => { 124 => 0x1443 }, + 'drangepriorityauto' => { 124 => 0x1444 }, + 'drangepriorityfixed' => { 124 => 0x1445 }, + 'drivemode' => { 110 => 0x3103, 122 => '0.1', 176 => 0x6, 179 => 0x1e, 182 => 0xe, 283 => 0x600, 341 => 0x34, 373 => 0x1002, 383 => 0x3, 393 => 0x4, 394 => 0x7e, 395 => 0x34 }, + 'drivemode2' => { 179 => 0xa, 322 => 0x7, 404 => 0xe, 411 => 0x1 }, + 'drivemodesetting' => { 395 => 0x4 }, + 'drivespeed' => { 122 => '0.2' }, + 'dspfirmwareversion' => { 341 => 0x27 }, + 'duration' => { 64 => 0x6a, 151 => 'Duration', 165 => 'Duration', 480 => 'duration', 488 => 'duration' }, + 'durationscale' => { 488 => [\'duration','durationScale'] }, + 'durationvalue' => { 488 => [\'duration','durationValue'] }, + 'dustremovaldata' => { 61 => 0x97 }, + 'dynamicafarea' => { 266 => '1.4', 275 => '1.4' }, + 'dynamicareaafdisplay' => { 267 => '46.1', 269 => '47.1', 270 => '47.1', 279 => '47.1', 280 => '47.1' }, + 'dynamicrange' => { 124 => 0x1400 }, + 'dynamicrangeexpansion' => { 341 => 0x69, 373 => 0x100e }, + 'dynamicrangemax' => { 105 => 0x7c }, + 'dynamicrangemin' => { 105 => 0x7a }, + 'dynamicrangeoptimizer' => { 179 => 0x15, 406 => [0xb025,0xb04f], 414 => 0x1144, 415 => [0x1144,0x324], 416 => [0x1120,0x300], 417 => [0x119c,0x37c], 418 => [0x1178,0x328], 419 => [0x1030,0x50], 420 => [0x228,0x50], 421 => [0x228,0x50], 422 => [0x21b,0x4e] }, + 'dynamicrangeoptimizerbracket' => { 404 => 0x2e }, + 'dynamicrangeoptimizerlevel' => { 393 => 0x19, 394 => 0x17, 395 => 0xd, 404 => 0x79, 411 => 0x5 }, + 'dynamicrangeoptimizermode' => { 182 => 0x15, 393 => 0x18, 394 => 0x16, 404 => [0x77,0x15] }, + 'dynamicrangeoptimizersetting' => { 179 => 0x27, 395 => 0xc, 411 => 0x4 }, + 'dynamicrangesetting' => { 124 => 0x1402 }, + 'e-dialinprogram' => { 322 => '1.3' }, + 'earliestageorloweststage' => { 115 => [\'GeologicalContext','GeologicalContextEarliestAgeOrLowestStage'] }, + 'earliesteonorlowesteonothem' => { 115 => [\'GeologicalContext','GeologicalContextEarliestEonOrLowestEonothem'] }, + 'earliestepochorlowestseries' => { 115 => [\'GeologicalContext','GeologicalContextEarliestEpochOrLowestSeries'] }, + 'earliesteraorlowesterathem' => { 115 => [\'GeologicalContext','GeologicalContextEarliestEraOrLowestErathem'] }, + 'earliestperiodorlowestsystem' => { 115 => [\'GeologicalContext','GeologicalContextEarliestPeriodOrLowestSystem'] }, + 'earthpos' => { 442 => 'EarthPos' }, + 'earthposaltitude' => { 442 => [\'EarthPos','EarthPosAltitude'] }, + 'earthposlatitude' => { 442 => [\'EarthPos','EarthPosLatitude'] }, + 'earthposlongitude' => { 442 => [\'EarthPos','EarthPosLongitude'] }, + 'earthposrotationw' => { 442 => [\'EarthPos','EarthPosRotationW'] }, + 'earthposrotationx' => { 442 => [\'EarthPos','EarthPosRotationX'] }, + 'earthposrotationy' => { 442 => [\'EarthPos','EarthPosRotationY'] }, + 'earthposrotationz' => { 442 => [\'EarthPos','EarthPosRotationZ'] }, + 'earthpostimestamp' => { 442 => [\'EarthPos','EarthPosTimestamp'] }, + 'easyexposurecomp' => { 281 => '6.1' }, + 'easyexposurecompensation' => { 266 => '6.4', 267 => '6.5', 269 => '6.3', 270 => '6.3', 274 => '5.1', 275 => '4.4', 276 => '5.2', 279 => '6.3', 280 => '6.3' }, + 'easymode' => { 34 => 0xb }, + 'edgemapslope' => { 134 => 0x930 }, + 'edgemapx1' => { 134 => 0x931 }, + 'edgemapx2' => { 134 => 0x932 }, + 'edgemapx3' => { 134 => 0x934 }, + 'edgemapx4' => { 134 => 0x935 }, + 'edgenoisereduction' => { 260 => 0x4, 439 => 0x8028 }, + 'edit1' => { 366 => "\xa9ed1" }, + 'edit2' => { 366 => "\xa9ed2" }, + 'edit3' => { 366 => "\xa9ed3" }, + 'edit4' => { 366 => "\xa9ed4" }, + 'edit5' => { 366 => "\xa9ed5" }, + 'edit6' => { 366 => "\xa9ed6" }, + 'edit7' => { 366 => "\xa9ed7" }, + 'edit8' => { 366 => "\xa9ed8" }, + 'edit9' => { 366 => "\xa9ed9" }, + 'edition' => { 478 => 'edition' }, + 'editorialupdate' => { 128 => 0x8 }, + 'editstatus' => { 128 => 0x7, 353 => 'EditStatus', 457 => 'EditStatus' }, + 'editversionname' => { 259 => 0x3d136244 }, + 'effectivelv' => { 341 => 0x2d }, + 'effectivemaxaperture' => { 212 => 0x12, 213 => 0x13, 217 => 0x14 }, + 'eissn' => { 478 => 'eIssn' }, + 'electricalblackcolumns' => { 134 => 0x1810 }, + 'electronicfront-curtainshutter' => { 269 => '5.2', 270 => '5.2', 279 => '5.3', 280 => '5.2' }, + 'electronicfrontcurtainshutter' => { 406 => 0x201a }, + 'elevation' => { 161 => 'Elevation' }, + 'email' => { 153 => 'EMail' }, + 'embargodate' => { 481 => 'embargoDate' }, + 'embdencrightsexpr' => { 474 => 'EmbdEncRightsExpr' }, + 'embeddedencodedrightsexpr' => { 474 => [\'EmbdEncRightsExpr','EmbdEncRightsExprEncRightsExpr'] }, + 'embeddedencodedrightsexprlangid' => { 474 => [\'EmbdEncRightsExpr','EmbdEncRightsExprRightsExprLangId'] }, + 'embeddedencodedrightsexprtype' => { 474 => [\'EmbdEncRightsExpr','EmbdEncRightsExprRightsExprEncType'] }, + 'embeddedxmpdigest' => { 476 => 'EmbeddedXMPDigest' }, + 'emissivity' => { 118 => 0x3 }, + 'enablechromanoisereduction' => { 134 => 0xe6e }, + 'enablesharpening' => { 134 => 0x92e }, + 'encodedby' => { 358 => "\xa9enc" }, + 'encodedwith' => { 360 => 'Encoded_With' }, + 'encoder' => { 358 => "\xa9too", 366 => "\xa9too" }, + 'encoderid' => { 366 => "\xa9enc" }, + 'encryptionkey' => { 380 => 0xa020 }, + 'endingpage' => { 478 => 'endingPage' }, + 'enduser' => { 293 => 'EndUser' }, + 'enduserid' => { 293 => [\'EndUser','EndUserEndUserID'] }, + 'endusername' => { 293 => [\'EndUser','EndUserEndUserName'] }, + 'engineer' => { 488 => 'engineer' }, + 'enhancedarktones' => { 252 => 0x8 }, + 'enhancement' => { 109 => 0x16, 110 => 0x3016 }, + 'enhanceparams' => { 116 => 0xc7ee }, + 'enhancer' => { 287 => 0x300 }, + 'enhancervalues' => { 287 => 0x301 }, + 'envelopenumber' => { 129 => 0x28 }, + 'envelopepriority' => { 129 => 0x3c }, + 'enveloperecordversion' => { 129 => 0x0 }, + 'episode' => { 474 => 'Episode' }, + 'episodeglobaluniqueid' => { 358 => 'egid' }, + 'episodeidentifier' => { 474 => [\'Episode','EpisodeIdentifier'] }, + 'episodename' => { 474 => [\'Episode','EpisodeName'] }, + 'episodenumber' => { 474 => [\'Episode','EpisodeNumber'] }, + 'epsonimageheight' => { 288 => 0x20c }, + 'epsonimagewidth' => { 288 => 0x20b }, + 'epsonsoftware' => { 288 => 0x20d }, + 'equipmentinstitution' => { 441 => 'EquipmentInstitution' }, + 'equipmentmanufacturer' => { 441 => 'EquipmentManufacturer' }, + 'equipmentversion' => { 284 => 0x0 }, + 'ettlii' => { 81 => 0x304, 82 => 0xd, 83 => 0xe, 84 => 0x7, 85 => 0x7, 86 => 0xe }, + 'event' => { 443 => 'Event', 455 => 'Event', 474 => 'Event', 478 => 'event' }, + 'eventalias' => { 477 => 'eventAlias' }, + 'eventdate' => { 115 => [\'Event','EventEventDate'] }, + 'eventday' => { 115 => [\'Event','EventDay'] }, + 'eventearliestdate' => { 115 => [\'Event','EventEarliestDate'] }, + 'eventend' => { 477 => 'eventEnd' }, + 'eventenddayofyear' => { 115 => [\'Event','EventEndDayOfYear'] }, + 'eventfieldnotes' => { 115 => [\'Event','EventFieldNotes'] }, + 'eventfieldnumber' => { 115 => [\'Event','EventFieldNumber'] }, + 'eventhabitat' => { 115 => [\'Event','EventHabitat'] }, + 'eventid' => { 115 => [\'Event','EventEventID'] }, + 'eventlatestdate' => { 115 => [\'Event','EventLatestDate'] }, + 'eventmonth' => { 115 => [\'Event','EventMonth'] }, + 'eventnumber' => { 367 => 0x9, 368 => 0x37, 369 => 0x3a }, + 'eventparenteventid' => { 115 => [\'Event','EventParentEventID'] }, + 'eventremarks' => { 115 => [\'Event','EventEventRemarks'] }, + 'eventsamplesizeunit' => { 115 => [\'Event','EventSampleSizeUnit'] }, + 'eventsamplesizevalue' => { 115 => [\'Event','EventSampleSizeValue'] }, + 'eventsamplingeffort' => { 115 => [\'Event','EventSamplingEffort'] }, + 'eventsamplingprotocol' => { 115 => [\'Event','EventSamplingProtocol'] }, + 'eventstart' => { 477 => 'eventStart' }, + 'eventstartdayofyear' => { 115 => [\'Event','EventStartDayOfYear'] }, + 'eventsubtype' => { 477 => 'eventSubtype' }, + 'eventtime' => { 115 => [\'Event','EventEventTime'] }, + 'eventtype' => { 477 => 'eventType' }, + 'eventverbatimeventdate' => { 115 => [\'Event','EventVerbatimEventDate'] }, + 'eventyear' => { 115 => [\'Event','EventYear'] }, + 'evsteps' => { 322 => '1.2', 324 => 0x0 }, + 'evstepsize' => { 271 => '5.1', 272 => '6.1', 273 => '6.1', 277 => '0.7' }, + 'exclusivecoverage' => { 452 => 'ExclusiveCoverage' }, + 'exclusivityenddate' => { 481 => 'exclusivityEndDate' }, + 'excursiontolerance' => { 130 => 0x82 }, + 'exif' => { 117 => 'EXIF' }, + 'exifbyteorder' => { 117 => 'ExifByteOrder' }, + 'exifcamerainfo' => { 128 => 0xe8 }, + 'exifimageheight' => { 116 => 0xa003, 468 => 'PixelYDimension' }, + 'exifimagewidth' => { 116 => 0xa002, 468 => 'PixelXDimension' }, + 'exifunicodebyteorder' => { 117 => 'ExifUnicodeByteOrder' }, + 'exifversion' => { 116 => 0x9000, 468 => 'ExifVersion' }, + 'exitpupilposition' => { 212 => 0x4, 213 => 0x4, 217 => 0x4 }, + 'expirationdate' => { 128 => 0x25, 481 => 'expirationDate' }, + 'expirationtime' => { 128 => 0x26 }, + 'exposure' => { 116 => 0xfe51, 462 => 'Exposure', 464 => 'Exposure' }, + 'exposure2012' => { 462 => 'Exposure2012', 464 => 'Exposure2012' }, + 'exposureadj' => { 257 => 0x0 }, + 'exposureadj2' => { 257 => 0x12 }, + 'exposureadjust' => { 383 => 0xc }, + 'exposurebracketingindicatorlast' => { 179 => 0x52 }, + 'exposurebracketshotnumber' => { 182 => 0x2d, 404 => 0x2f }, + 'exposurebracketstepsize' => { 322 => 0x8 }, + 'exposurebracketvalue' => { 219 => 0x19 }, + 'exposurecompautocancel' => { 81 => 0x113 }, + 'exposurecompensation' => { 74 => 0x6, 90 => 0x0, 116 => 0x9204, 136 => 0x24, 152 => 'ExposureComp', 172 => 'ExposureCompensation', 176 => 0xd, 177 => 0x53, 178 => 0x1e, 182 => 0x49c0, 288 => 0x1006, 341 => 0x16, 350 => 0x402, 380 => 0xa013, 383 => [0xc,0x35,0x4d], 414 => 0x114c, 415 => 0x114c, 416 => 0x1128, 418 => 0x1180, 419 => 0x1038, 420 => 0x230, 421 => 0x230, 422 => 0x223, 468 => 'ExposureBiasValue' }, + 'exposurecompensation2' => { 411 => [0x24,0x26,0x2a] }, + 'exposurecompensationmode' => { 179 => 0x47, 182 => 0x2a }, + 'exposurecompensationset' => { 393 => 0x3, 394 => 0x3, 395 => 0x3, 411 => 0x1e }, + 'exposurecompensationsetting' => { 179 => 0x1 }, + 'exposurecompstepsize' => { 266 => '6.3', 267 => '7.3', 269 => '7.3', 270 => '7.3', 275 => '4.3', 279 => '7.3', 280 => '7.3' }, + 'exposurecontrolstep' => { 274 => '6.1', 276 => '6.1' }, + 'exposurecontrolstepsize' => { 266 => '6.2', 267 => '7.1', 269 => '7.1', 270 => '7.1', 275 => '4.2', 279 => '7.1', 280 => '7.1', 281 => '7.1' }, + 'exposurecount' => { 124 => 0x1032 }, + 'exposuredelaymode' => { 266 => '10.1', 267 => '11.1', 269 => '11.1', 270 => '11.1', 271 => '9.1', 272 => '10.1', 273 => '10.1', 275 => '10.4', 276 => '10.1', 277 => '6.4', 279 => '11.1', 280 => '11.1', 281 => '11.2' }, + 'exposuredifference' => { 219 => 0xe }, + 'exposuregaincustom' => { 134 => 0x89c }, + 'exposuregaindaylight' => { 134 => 0x898 }, + 'exposuregainflash' => { 134 => 0x89b }, + 'exposuregainfluorescent' => { 134 => 0x89a }, + 'exposuregaintungsten' => { 134 => 0x899 }, + 'exposureindex' => { 116 => 0xa215, 468 => 'ExposureIndex' }, + 'exposureindicator' => { 179 => 0x50 }, + 'exposurelevelincrements' => { 79 => 0x6, 80 => 0x6, 81 => 0x101, 82 => 0x5, 83 => 0x6, 84 => 0x5, 85 => 0x5, 86 => 0x6, 87 => 0x4, 393 => 0x58, 394 => 0x58 }, + 'exposurelockused' => { 450 => 'ExposureLockUsed' }, + 'exposuremode' => { 116 => 0xa402, 152 => 'ExposureMode', 176 => 0x1, 177 => 0xa, 178 => 0x0, 179 => 0x0, 182 => 0x34, 283 => 0x200, 303 => 0x40d, 383 => 0x8, 406 => 0xb041, 468 => 'ExposureMode' }, + 'exposuremodeinmanual' => { 81 => 0x10b }, + 'exposureprogram' => { 116 => 0x8822, 373 => 0x1001, 386 => [0x17e,0x43], 393 => 0x3c, 394 => 0x3c, 395 => 0x5, 399 => 0x14, 404 => 0x3f, 411 => 0x2, 414 => 0x1175, 415 => 0x1179, 416 => 0x1155, 417 => 0x11d1, 418 => 0x11ad, 419 => 0x1065, 420 => 0x25d, 421 => 0x25d, 422 => 0x24c, 431 => 0xb, 432 => 0xc, 433 => 0xb, 435 => 0x48, 468 => 'ExposureProgram' }, + 'exposureshift' => { 283 => 0x203 }, + 'exposurestandardadjustment' => { 406 => 0x202d }, + 'exposuretime' => { 7 => 0x4, 8 => 0x4, 9 => 0x4, 10 => 0x4, 11 => 0x4, 12 => 0x4, 13 => 0x4, 14 => 0x4, 15 => 0x4, 16 => 0x4, 17 => 0x4, 18 => 0x4, 19 => 0x4, 20 => 0x4, 21 => 0x4, 22 => 0x4, 23 => 0x4, 24 => 0x4, 25 => 0x4, 26 => 0x4, 27 => 0x4, 28 => 0x4, 29 => 0x4, 30 => 0x6, 31 => 0x7, 74 => 0x16, 116 => 0x829a, 133 => 0xfd05, 136 => 0x20, 138 => 0xfa24, 140 => 0xf104, 143 => 0x12, 145 => 0x38, 147 => 0x14, 148 => 0x10, 150 => 0x10, 152 => 'ExposureTime', 176 => 0x9, 177 => 0x35, 178 => 0x48, 179 => 0x8, 182 => 0x49b8, 341 => 0x12, 380 => 0xa018, 383 => [0x32,0x4a], 393 => 0x0, 394 => 0x0, 411 => [0x21,0x23,0x27], 435 => 0x10, 468 => 'ExposureTime' }, + 'exposuretime2' => { 383 => [0x33,0x4b] }, + 'exposuretuning' => { 219 => 0x1c }, + 'exposurevalue' => { 134 => 0x3 }, + 'exposurewarning' => { 124 => 0x1302 }, + 'exrauto' => { 124 => 0x1033 }, + 'exrmode' => { 124 => 0x1034 }, + 'extendedwbdetect' => { 283 => 0x902 }, + 'extender' => { 284 => 0x301 }, + 'extenderfirmwareversion' => { 284 => 0x304 }, + 'extendermagnification' => { 154 => 'Magnification' }, + 'extendermake' => { 154 => 'Make' }, + 'extendermodel' => { 154 => 'Model', 284 => 0x303 }, + 'extenderserialnumber' => { 154 => 'SerialNumber', 284 => 0x302 }, + 'extenderstatus' => { 339 => 0x3 }, + 'externalflash' => { 286 => 0x1201 }, + 'externalflashae1' => { 288 => 0x101f }, + 'externalflashae1_0' => { 288 => 0x101b }, + 'externalflashae2' => { 288 => 0x1020 }, + 'externalflashae2_0' => { 288 => 0x101c }, + 'externalflashbounce' => { 286 => 0x1204, 288 => 0x1026, 329 => 0x1a }, + 'externalflashcompensation' => { 205 => 0x1b }, + 'externalflashexposurecomp' => { 219 => 0x17, 329 => 0x19 }, + 'externalflashfirmware' => { 203 => 0x6, 204 => 0x6, 205 => 0x6, 206 => 0x6, 207 => 0x6 }, + 'externalflashflags' => { 203 => 0x8, 204 => 0x8, 205 => 0x8, 206 => 0x8 }, + 'externalflashguidenumber' => { 286 => 0x1203, 329 => '24.1' }, + 'externalflashgvalue' => { 288 => 0x1025 }, + 'externalflashmode' => { 288 => 0x1028, 329 => 0x2 }, + 'externalflashreadystate' => { 207 => '9.1' }, + 'externalflashstatus' => { 207 => '8.2' }, + 'externalflashzoom' => { 286 => 0x1205, 288 => 0x1027 }, + 'externalflashzoomoverride' => { 207 => '8.1' }, + 'externalmetadatalink' => { 474 => 'ExternalMetadataLink' }, + 'externalsensorbrightnessvalue' => { 301 => 0x311, 304 => 0x311, 305 => 0x311, 308 => 0x3408 }, + 'extrainfoversion' => { 397 => 0x1a }, + 'eyestartaf' => { 179 => 0x40 }, + 'fac100per' => { 134 => 0xe94 }, + 'fac170per' => { 134 => 0xe93 }, + 'fac18per' => { 134 => 0xe92 }, + 'face10position' => { 107 => 0x3f4, 108 => 0x1ec, 201 => 0x28, 326 => 0x12 }, + 'face10size' => { 327 => 0x12 }, + 'face11position' => { 201 => 0x2c, 326 => 0x14 }, + 'face11size' => { 327 => 0x14 }, + 'face12position' => { 201 => 0x30, 326 => 0x16 }, + 'face12size' => { 327 => 0x16 }, + 'face13position' => { 326 => 0x18 }, + 'face13size' => { 327 => 0x18 }, + 'face14position' => { 326 => 0x1a }, + 'face14size' => { 327 => 0x1a }, + 'face15position' => { 326 => 0x1c }, + 'face15size' => { 327 => 0x1c }, + 'face16position' => { 326 => 0x1e }, + 'face16size' => { 327 => 0x1e }, + 'face17position' => { 326 => 0x20 }, + 'face17size' => { 327 => 0x20 }, + 'face18position' => { 326 => 0x22 }, + 'face18size' => { 327 => 0x22 }, + 'face19position' => { 326 => 0x24 }, + 'face19size' => { 327 => 0x24 }, + 'face1position' => { 52 => 0x8, 107 => 0xd, 108 => 0x18, 201 => 0x4, 298 => 0x1, 326 => 0x0, 370 => 0xbc, 400 => 0x1, 401 => 0x0, 402 => 0x0, 403 => 0x5b }, + 'face1size' => { 327 => 0x0 }, + 'face20position' => { 326 => 0x26 }, + 'face20size' => { 327 => 0x26 }, + 'face21position' => { 326 => 0x28 }, + 'face21size' => { 327 => 0x28 }, + 'face22position' => { 326 => 0x2a }, + 'face22size' => { 327 => 0x2a }, + 'face23position' => { 326 => 0x2c }, + 'face23size' => { 327 => 0x2c }, + 'face24position' => { 326 => 0x2e }, + 'face24size' => { 327 => 0x2e }, + 'face25position' => { 326 => 0x30 }, + 'face25size' => { 327 => 0x30 }, + 'face26position' => { 326 => 0x32 }, + 'face26size' => { 327 => 0x32 }, + 'face27position' => { 326 => 0x34 }, + 'face27size' => { 327 => 0x34 }, + 'face28position' => { 326 => 0x36 }, + 'face28size' => { 327 => 0x36 }, + 'face29position' => { 326 => 0x38 }, + 'face29size' => { 327 => 0x38 }, + 'face2position' => { 52 => 0xa, 107 => 0x7c, 108 => 0x4c, 201 => 0x8, 298 => 0x5, 326 => 0x2, 370 => 0xc8, 400 => 0x6, 401 => 0x20, 402 => 0x25, 403 => 0x65 }, + 'face2size' => { 327 => 0x2 }, + 'face30position' => { 326 => 0x3a }, + 'face30size' => { 327 => 0x3a }, + 'face31position' => { 326 => 0x3c }, + 'face31size' => { 327 => 0x3c }, + 'face32position' => { 326 => 0x3e }, + 'face32size' => { 327 => 0x3e }, + 'face3position' => { 52 => 0xc, 107 => 0xeb, 108 => 0x80, 201 => 0xc, 298 => 0x9, 326 => 0x4, 370 => 0xd4, 400 => 0xb, 401 => 0x40, 402 => 0x4a, 403 => 0x6f }, + 'face3size' => { 327 => 0x4 }, + 'face4position' => { 52 => 0xe, 107 => 0x15a, 108 => 0xb4, 201 => 0x10, 298 => 0xd, 326 => 0x6, 370 => 0xe0, 400 => 0x10, 401 => 0x60, 402 => 0x6f, 403 => 0x79 }, + 'face4size' => { 327 => 0x6 }, + 'face5position' => { 52 => 0x10, 107 => 0x1c9, 108 => 0xe8, 201 => 0x14, 298 => 0x11, 326 => 0x8, 370 => 0xec, 400 => 0x15, 401 => 0x80, 402 => 0x94 }, + 'face5size' => { 327 => 0x8 }, + 'face6position' => { 52 => 0x12, 107 => 0x238, 108 => 0x11c, 201 => 0x18, 326 => 0xa, 370 => 0xf8, 400 => 0x1a, 401 => 0xa0, 402 => 0xb9 }, + 'face6size' => { 327 => 0xa }, + 'face7position' => { 52 => 0x14, 107 => 0x2a7, 108 => 0x150, 201 => 0x1c, 326 => 0xc, 370 => 0x104, 400 => 0x1f, 401 => 0xc0, 402 => 0xde }, + 'face7size' => { 327 => 0xc }, + 'face8position' => { 52 => 0x16, 107 => 0x316, 108 => 0x184, 201 => 0x20, 326 => 0xe, 370 => 0x110, 400 => 0x24, 401 => 0xe0, 402 => 0x103 }, + 'face8size' => { 327 => 0xe }, + 'face9position' => { 52 => 0x18, 107 => 0x385, 108 => 0x1b8, 201 => 0x24, 326 => 0x10 }, + 'face9size' => { 327 => 0x10 }, + 'facebalanceorigi' => { 456 => 'FaceBalanceOrigI' }, + 'facebalanceorigq' => { 456 => 'FaceBalanceOrigQ' }, + 'facebalancestrength' => { 456 => 'FaceBalanceStrength' }, + 'facebalancewarmth' => { 456 => 'FaceBalanceWarmth' }, + 'facedetect' => { 341 => 0x76, 380 => 0x100 }, + 'facedetectarea' => { 287 => 0x1201 }, + 'facedetectframecrop' => { 287 => 0x1207 }, + 'facedetectframesize' => { 52 => 0x3, 107 => 0x1, 108 => 0x4, 201 => 0x1, 287 => 0x1203, 341 => 0x77, 370 => 0xb6 }, + 'facedetection' => { 395 => 0x30, 411 => 0x19 }, + 'faceelementpositions' => { 124 => 0x4203 }, + 'faceelementselected' => { 124 => 0x4005 }, + 'faceelementtypes' => { 124 => 0x4201 }, + 'faceid' => { 458 => 'FaceID' }, + 'faceinfounknown' => { 110 => 0x2089 }, + 'facename' => { 380 => 0x123 }, + 'faceorientation' => { 108 => 0x8 }, + 'faceposition' => { 325 => 0x2, 381 => 0x4 }, + 'facepositions' => { 124 => 0x4103 }, + 'facerecognition' => { 380 => 0x120 }, + 'facesdetected' => { 52 => 0x2, 53 => 0x2, 54 => 0x3, 107 => 0x0, 108 => 0x2, 110 => 0x211c, 124 => 0x4100, 201 => 0x3, 287 => 0x1200, 306 => 0x3f, 325 => 0x0, 370 => 0xb5, 381 => 0x0, 400 => 0x0, 403 => 0x3, 413 => 0x30 }, + 'facesrecognized' => { 299 => 0x0 }, + 'facewidth' => { 53 => 0x1 }, + 'faithfuloutputhighlightpoint' => { 106 => 0x38 }, + 'faithfuloutputshadowpoint' => { 106 => 0x39 }, + 'faithfulrawcolortone' => { 106 => 0x31 }, + 'faithfulrawcontrast' => { 106 => 0x33 }, + 'faithfulrawhighlight' => { 106 => 0x79 }, + 'faithfulrawhighlightpoint' => { 106 => 0x36 }, + 'faithfulrawlinear' => { 106 => 0x34 }, + 'faithfulrawsaturation' => { 106 => 0x32 }, + 'faithfulrawshadow' => { 106 => 0x82 }, + 'faithfulrawshadowpoint' => { 106 => 0x37 }, + 'faithfulrawsharpness' => { 106 => 0x35 }, + 'faithfulunsharpmaskfineness' => { 106 => 0xac }, + 'faithfulunsharpmaskstrength' => { 106 => 0xaa }, + 'faithfulunsharpmaskthreshold' => { 106 => 0xae }, + 'far' => { 447 => 'Far' }, + 'fastresetlinetime' => { 134 => 0x1860 }, + 'feedidentifier' => { 474 => 'FeedIdentifier' }, + 'femicroadjustment' => { 81 => 0x111 }, + 'ffid' => { 466 => 'ffid' }, + 'field' => { 477 => 'field' }, + 'fieldcount' => { 288 => 0x103f }, + 'fieldofview' => { 366 => "FOV\x00" }, + 'fifoenonepixeldelay' => { 134 => 0x1901 }, + 'filecreatedate' => { 117 => 'FileCreateDate' }, + 'filedatarate' => { 488 => 'fileDataRate' }, + 'fileformat' => { 92 => 0x0, 129 => 0x14, 383 => [0x22,0x26], 406 => 0xb000 }, + 'filegroupid' => { 117 => 'FileGroupID' }, + 'fileindex' => { 7 => 0x143, 9 => 0x2d0, 11 => 0x172, 13 => 0x22c, 14 => 0x133, 15 => 0x13f, 16 => 0x1d3, 17 => 0x19b, 18 => 0x1e4, 19 => 0xd0, 20 => 0x1bb, 21 => 0x28c, 22 => 0x1db, 23 => 0x1d9, 24 => [0x270,0x274], 25 => 0x2aa, 26 => 0x2b3, 28 => 0x1eb, 29 => 0x4ae, 307 => 0x0 }, + 'fileindex2' => { 21 => 0x290 }, + 'filemodifydate' => { 117 => 'FileModifyDate' }, + 'filename' => { 117 => 'FileName' }, + 'filenameasdelivered' => { 293 => 'FileNameAsDelivered' }, + 'filenumber' => { 55 => 0x1, 61 => 0x8, 94 => 0x1817, 111 => 'Canon::FileNumber', 202 => 0x4, 369 => 0x10 }, + 'filenumbermemory' => { 176 => 0x1a }, + 'filenumbersequence' => { 266 => '12.2', 271 => '3.1', 272 => '4.1', 273 => '4.1', 275 => '11.1', 276 => '4.3', 281 => '5.2' }, + 'filepermissions' => { 117 => 'FilePermissions' }, + 'filesource' => { 116 => 0xa300, 124 => 0x8000, 468 => 'FileSource' }, + 'fileuserid' => { 117 => 'FileUserID' }, + 'fileversion' => { 129 => 0x16 }, + 'fillflashautoreduction' => { 79 => 0xe, 80 => 0xe, 87 => 0xa }, + 'filllight' => { 462 => 'FillLight', 464 => 'FillLight' }, + 'fillorder' => { 116 => 0x10a }, + 'filmgraineffect' => { 283 => 0x538 }, + 'filmmode' => { 124 => 0x1401, 303 => 0x412, 306 => 0x42 }, + 'filmtype' => { 227 => 0x2 }, + 'filtereffect' => { 55 => 0xe, 221 => 0x37, 222 => 0x3f, 223 => 0x47 }, + 'filtereffectauto' => { 68 => 0xa0 }, + 'filtereffectfaithful' => { 67 => 0x70, 68 => 0x70 }, + 'filtereffectlandscape' => { 67 => 0x40, 68 => 0x40 }, + 'filtereffectmonochrome' => { 19 => 0xff, 67 => 0x88, 68 => 0x88 }, + 'filtereffectneutral' => { 67 => 0x58, 68 => 0x58 }, + 'filtereffectportrait' => { 67 => 0x28, 68 => 0x28 }, + 'filtereffectstandard' => { 67 => 0x10, 68 => 0x10 }, + 'filtereffectuserdef1' => { 67 => 0xa0, 68 => 0xb8 }, + 'filtereffectuserdef2' => { 67 => 0xb8, 68 => 0xd0 }, + 'filtereffectuserdef3' => { 67 => 0xd0, 68 => 0xe8 }, + 'finderdisplayduringexposure' => { 80 => 0x1 }, + 'finesharpness' => { 341 => 0x70 }, + 'finetuneoptcenterweighted' => { 266 => '7.2', 267 => '9.1', 269 => '9.1', 270 => '9.1', 274 => '8.1', 279 => '9.1', 280 => '9.1', 281 => '9.1' }, + 'finetuneopthighlightweighted' => { 269 => '46.1', 270 => '46.1', 279 => '46.1', 280 => '46.1' }, + 'finetuneoptmatrixmetering' => { 266 => '8.1', 267 => '8.2', 269 => '8.2', 270 => '8.2', 274 => '7.2', 275 => '6.1', 279 => '8.2', 280 => '8.2', 281 => '8.2' }, + 'finetuneoptspotmetering' => { 266 => '8.2', 267 => '9.2', 269 => '9.2', 270 => '9.2', 274 => '8.2', 275 => '6.2', 279 => '9.2', 280 => '9.2', 281 => '9.2' }, + 'finishexposure' => { 134 => 0xdbd }, + 'finishfiletype' => { 134 => 0xdb8 }, + 'finishlook' => { 134 => 0xdbc }, + 'finishnoise' => { 134 => 0xdba }, + 'finishresolution' => { 134 => 0xdb9 }, + 'finishsharpening' => { 134 => 0xdbb }, + 'firmware' => { 288 => 0x405, 383 => [0x8c,0x17,0x3b], 459 => 'Firmware' }, + 'firmware2' => { 383 => 0x57 }, + 'firmwaredate' => { 109 => 0x15, 110 => 0x2001, 367 => 0x4, 369 => 0x30 }, + 'firmwareid' => { 183 => 0x0 }, + 'firmwarename' => { 380 => 0xa001 }, + 'firmwarerevision' => { 19 => 0xa4, 61 => 0x1e, 371 => 0x0 }, + 'firmwarerevision2' => { 371 => 0xc }, + 'firmwareversion' => { 7 => 0x10b, 11 => 0x136, 14 => 0xff, 15 => 0x107, 134 => [0x415,0xce5], 150 => 0x57, 152 => 'FirmwareVersion', 304 => 0x320, 306 => 0x2, 308 => 0x3109, 341 => 0x230, 366 => ['CNFV','FIRM'], 368 => 0x18, 369 => 0x2a, 373 => 0x2 }, + 'firmwareversions' => { 350 => 0x301 }, + 'firstphotodate' => { 450 => 'FirstPhotoDate' }, + 'firstpublicationdate' => { 293 => 'FirstPublicationDate' }, + 'fixtureidentifier' => { 128 => 0x16, 457 => 'FixtureIdentifier' }, + 'flash' => { 111 => 'XMP::Flash', 116 => 0x9209, 148 => 0x22, 177 => 0x1f, 178 => 0x15, 369 => 0x5a, 468 => 'Flash' }, + 'flashaction' => { 393 => 0x3e, 394 => 0x3e, 406 => 0x2017, 411 => [0x2a,0x2c,0x30] }, + 'flashaction2' => { 393 => 0x4c, 394 => 0x4c, 411 => 0x77 }, + 'flashactionexternal' => { 411 => [0x78,0x7c] }, + 'flashactivity' => { 34 => 0x1c }, + 'flashbatterylevel' => { 42 => 0x249 }, + 'flashbias' => { 306 => 0x24 }, + 'flashbits' => { 34 => 0x1d }, + 'flashbuttonfunction' => { 81 => 0x70e }, + 'flashchargelevel' => { 288 => 0x1010 }, + 'flashcolorfilter' => { 205 => 0x10, 206 => 0x10 }, + 'flashcommandermode' => { 203 => '9.1', 204 => '9.1', 205 => '9.1', 206 => '9.1' }, + 'flashcompensation' => { 134 => 0x3f3, 203 => 0xa, 204 => 0xa, 205 => 0xa, 206 => 0x27, 207 => 0xa, 459 => 'FlashCompensation' }, + 'flashcontrol' => { 393 => 0x23, 394 => 0x1f, 395 => 0x21 }, + 'flashcontrolbuilt-in' => { 275 => '16.1', 276 => '23.1', 278 => '23.1', 279 => '24.1' }, + 'flashcontrolmode' => { 203 => '9.2', 204 => '9.2', 205 => '9.2', 206 => '9.2', 283 => 0x404 }, + 'flashcurtain' => { 306 => 0x48 }, + 'flashdefault' => { 179 => 0x42 }, + 'flashdevice' => { 288 => 0x1005 }, + 'flashdistance' => { 110 => 0x2034 }, + 'flashenergy' => { 116 => 0xa20b, 468 => 'FlashEnergy' }, + 'flashexposurebracketvalue' => { 219 => 0x18 }, + 'flashexposurecomp' => { 74 => 0xf, 124 => 0x1011, 155 => 'ExposureComp', 176 => 0x23, 181 => 0x104, 182 => 0x49c1, 219 => 0x12, 283 => 0x401, 288 => 0x1023, 341 => 0x4d, 373 => 0x100b, 383 => [0x3a,0x56], 406 => 0x104 }, + 'flashexposurecomp2' => { 245 => 0x4d2 }, + 'flashexposurecomp3' => { 205 => 0x1d }, + 'flashexposurecomp4' => { 205 => 0x27 }, + 'flashexposurecomparea' => { 267 => '38.4', 269 => '38.4', 270 => '38.4', 279 => '38.4', 280 => '38.4' }, + 'flashexposurecompset' => { 179 => 0x10, 314 => 0xe, 393 => 0x14, 394 => 0x12, 395 => 0x23, 411 => 0x1f }, + 'flashexposurecompset2' => { 411 => [0x26,0x2c] }, + 'flashexposureindicator' => { 179 => 0x54 }, + 'flashexposureindicatorlast' => { 179 => 0x56 }, + 'flashexposureindicatornext' => { 179 => 0x55 }, + 'flashexposurelock' => { 55 => 0x19 }, + 'flashfired' => { 136 => 0x5d, 155 => 'Fired', 176 => 0x14, 244 => '590.3', 468 => [\'Flash','FlashFired'] }, + 'flashfiring' => { 81 => 0x306, 82 => 0x6, 83 => 0x7, 86 => 0x7 }, + 'flashfirmwareversion' => { 284 => 0x1002 }, + 'flashfocallength' => { 203 => 0xb, 204 => 0xc, 205 => 0xc, 206 => 0xc, 207 => 0xc }, + 'flashfunction' => { 182 => 0x31, 468 => [\'Flash','FlashFunction'] }, + 'flashgndistance' => { 203 => 0xe, 204 => 0xf, 205 => 0xf, 206 => 0xf, 207 => 0xf }, + 'flashgroupacompensation' => { 203 => 0x11, 204 => 0x12, 205 => 0x13, 206 => 0x28, 207 => 0x28 }, + 'flashgroupacontrolmode' => { 203 => 0xf, 204 => '16.1', 205 => '17.1', 206 => '17.1', 207 => '17.1' }, + 'flashgroupaoutput' => { 203 => 0x11, 204 => 0x12, 205 => 0x13, 206 => 0x28, 207 => 0x28 }, + 'flashgroupbcompensation' => { 203 => 0x12, 204 => 0x13, 205 => 0x14, 206 => 0x29, 207 => 0x29 }, + 'flashgroupbcontrolmode' => { 203 => 0x10, 204 => '17.1', 205 => '18.1', 206 => '18.1', 207 => '18.1' }, + 'flashgroupboutput' => { 203 => 0x12, 204 => 0x13, 205 => 0x14, 206 => 0x29, 207 => 0x29 }, + 'flashgroupccompensation' => { 204 => 0x14, 205 => 0x15, 206 => 0x2a, 207 => 0x2a }, + 'flashgroupccontrolmode' => { 204 => '17.2', 205 => '18.2', 206 => '18.2', 207 => '18.2' }, + 'flashgroupcoutput' => { 204 => 0x14, 205 => 0x15, 206 => 0x2a, 207 => 0x2a }, + 'flashguidenumber' => { 74 => 0xd, 91 => 0x0, 155 => 'GuideNumber' }, + 'flashintensity' => { 109 => [0x19,0x5], 283 => 0x405 }, + 'flashlevel' => { 268 => 0x9, 406 => 0xb048 }, + 'flashmake' => { 155 => 'Make' }, + 'flashmanufacturer' => { 174 => 'FlashManufacturer' }, + 'flashmetering' => { 176 => 0x3f, 179 => 0x1c }, + 'flashmeteringmode' => { 7 => 0x15, 13 => 0x15, 14 => 0x15, 15 => 0x15, 16 => 0x15, 17 => 0x15, 18 => 0x15, 20 => 0x15, 22 => 0x15, 28 => 0x15 }, + 'flashmeteringsegments' => { 341 => 0x20a }, + 'flashmode' => { 109 => 0x4, 134 => 0x3f2, 136 => 0x5c, 147 => 0x27, 155 => 'Mode', 176 => 0x2, 177 => 0x20, 178 => 0x16, 179 => 0xf, 219 => 0x87, 283 => 0x400, 288 => 0x1004, 341 => 0xc, 348 => 0x4, 372 => 0x20, 373 => 0x100a, 382 => 0x225, 393 => 0x13, 394 => 0x7f, 395 => 0x20, 411 => 0x10, 414 => 0x1138, 415 => 0x1138, 416 => 0x1114, 417 => 0x1190, 418 => 0x116c, 419 => 0x1024, 420 => 0x21c, 421 => 0x21c, 422 => 0x211, 468 => [\'Flash','FlashMode'] }, + 'flashmodel' => { 155 => 'Model', 174 => 'FlashModel', 284 => 0x1001 }, + 'flashoptions' => { 322 => 0x2 }, + 'flashoptions2' => { 322 => 0x10 }, + 'flashoutput' => { 42 => 0x248, 74 => 0x21, 203 => 0xa, 204 => 0xa, 205 => 0xa, 206 => 0x27 }, + 'flashpixversion' => { 116 => 0xa000, 468 => 'FlashpixVersion' }, + 'flashredeyemode' => { 468 => [\'Flash','FlashRedEyeMode'] }, + 'flashremotecontrol' => { 283 => 0x403 }, + 'flashreturn' => { 468 => [\'Flash','FlashReturn'] }, + 'flashserialnumber' => { 155 => 'SerialNumber', 284 => 0x1003 }, + 'flashsetting' => { 219 => 0x8 }, + 'flashshutterspeed' => { 266 => '20.2', 267 => '23.2', 269 => '23.2', 270 => '23.2', 275 => '15.2', 276 => '22.2', 277 => '7.2', 278 => '22.2', 279 => '23.2', 280 => '23.2', 281 => '23.1' }, + 'flashsource' => { 203 => 0x4, 204 => 0x4, 205 => 0x4, 206 => 0x4, 207 => 0x4 }, + 'flashstatus' => { 329 => 0x0, 411 => [0x82,0x86], 424 => 0x31, 425 => 0x39 }, + 'flashstatusbuilt-in' => { 395 => [0x87,0x287] }, + 'flashstatusexternal' => { 395 => [0x88,0x288] }, + 'flashsyncspeed' => { 266 => '20.1', 267 => '23.1', 269 => '23.1', 270 => '23.1', 275 => '15.1', 276 => '22.1', 278 => '22.1', 279 => '23.1', 280 => '23.1' }, + 'flashsyncspeedav' => { 79 => 0x3, 81 => 0x10f, 82 => 0x2, 83 => 0x3, 84 => 0x2, 85 => 0x2, 86 => 0x3, 87 => 0x6 }, + 'flashthreshold' => { 91 => 0x1 }, + 'flashtype' => { 155 => 'Type', 179 => 0x59, 219 => 0x9, 284 => 0x1000 }, + 'flashwarning' => { 276 => '30.1', 277 => '7.1', 281 => '31.1', 306 => 0x62 }, + 'flexiblespotposition' => { 406 => 0x201d }, + 'flickerreduce' => { 382 => 0x218 }, + 'flickerreduction' => { 124 => 0x1446, 238 => 0xe84 }, + 'flickerreductionindicator' => { 238 => 0x5e2 }, + 'flightpitchdegree' => { 113 => 'FlightPitchDegree' }, + 'flightrolldegree' => { 113 => 'FlightRollDegree' }, + 'flightxspeed' => { 113 => 'FlightXSpeed' }, + 'flightyawdegree' => { 113 => 'FlightYawDegree' }, + 'flightyspeed' => { 113 => 'FlightYSpeed' }, + 'flightzspeed' => { 113 => 'FlightZSpeed' }, + 'fliphorizontal' => { 259 => 0x76a43206 }, + 'fnumber' => { 7 => 0x3, 9 => 0x3, 11 => 0x3, 13 => 0x3, 14 => 0x3, 15 => 0x3, 16 => 0x3, 17 => 0x3, 18 => 0x3, 19 => 0x3, 20 => 0x3, 21 => 0x3, 22 => 0x3, 23 => 0x3, 24 => 0x3, 25 => 0x3, 26 => 0x3, 27 => 0x3, 28 => 0x3, 29 => 0x3, 30 => 0x5, 31 => 0x6, 74 => 0x15, 116 => 0x829d, 133 => 0xfd04, 136 => 0x1e, 138 => 0xfa23, 140 => 0xf103, 143 => 0x13, 145 => 0x3c, 147 => 0x1c, 148 => 0x18, 150 => 0xc, 159 => 'FNumber', 176 => 0xa, 177 => 0x36, 178 => 0x47, 179 => 0x9, 182 => 0x49c7, 217 => 0x38, 305 => 0x35a, 341 => 0x13, 380 => 0xa019, 383 => [0x31,0x49], 393 => 0x1, 394 => 0x1, 411 => [0x20,0x22,0x26], 468 => 'FNumber' }, + 'focaldistance' => { 448 => 'FocalDistance' }, + 'focallength' => { 7 => 0x1d, 8 => 0xa, 9 => 0x23, 10 => 0x9, 11 => 0x1d, 12 => 0x9, 13 => 0x1e, 14 => 0x1d, 15 => 0x1d, 16 => 0x1e, 17 => 0x1e, 18 => 0x1e, 19 => 0x28, 20 => 0x1e, 21 => 0x23, 22 => 0x1e, 23 => 0x1e, 24 => 0x23, 25 => 0x23, 26 => 0x23, 27 => 0x23, 28 => 0x1e, 29 => 0x23, 57 => 0x1, 110 => 0x1d, 116 => 0x920a, 143 => 0x1d, 159 => 'FocalLength', 176 => 0x12, 212 => 0xa, 213 => 0xb, 217 => [0xc,0x3c], 300 => 0x1, 341 => 0x1d, 350 => 0x403, 373 => 0x1500, 392 => 0xe, 418 => 0x1278, 419 => 0x1134, 420 => 0x32c, 421 => 0x32c, 422 => 0x30a, 468 => 'FocalLength' }, + 'focallength2' => { 411 => [0x23,0x25,0x29] }, + 'focallengthin35mmformat' => { 116 => 0xa405, 380 => 0xa01a, 468 => 'FocalLengthIn35mmFilm' }, + 'focallengthtelezoom' => { 392 => 0x10 }, + 'focalplaneafpointarea' => { 423 => 0x2 }, + 'focalplaneafpointlocation1' => { 423 => 0x6 }, + 'focalplaneafpointlocation10' => { 423 => 0x2a }, + 'focalplaneafpointlocation11' => { 423 => 0x2e }, + 'focalplaneafpointlocation12' => { 423 => 0x32 }, + 'focalplaneafpointlocation13' => { 423 => 0x36 }, + 'focalplaneafpointlocation14' => { 423 => 0x3a }, + 'focalplaneafpointlocation15' => { 423 => 0x3e }, + 'focalplaneafpointlocation2' => { 423 => 0xa }, + 'focalplaneafpointlocation3' => { 423 => 0xe }, + 'focalplaneafpointlocation4' => { 423 => 0x12 }, + 'focalplaneafpointlocation5' => { 423 => 0x16 }, + 'focalplaneafpointlocation6' => { 423 => 0x1a }, + 'focalplaneafpointlocation7' => { 423 => 0x1e }, + 'focalplaneafpointlocation8' => { 423 => 0x22 }, + 'focalplaneafpointlocation9' => { 423 => 0x26 }, + 'focalplaneafpointsused' => { 423 => 0x1 }, + 'focalplanediagonal' => { 284 => 0x103, 288 => 0x205 }, + 'focalplaneresolutionunit' => { 116 => 0xa210, 468 => 'FocalPlaneResolutionUnit' }, + 'focalplanexresolution' => { 116 => 0xa20e, 468 => 'FocalPlaneXResolution' }, + 'focalplanexsize' => { 57 => 0x2 }, + 'focalplanexunknown' => { 57 => 0x2 }, + 'focalplaneyresolution' => { 116 => 0xa20f, 468 => 'FocalPlaneYResolution' }, + 'focalplaneysize' => { 57 => 0x3 }, + 'focalplaneyunknown' => { 57 => 0x3 }, + 'focalpointx' => { 448 => 'FocalPointX' }, + 'focalpointy' => { 448 => 'FocalPointY' }, + 'focaltype' => { 10 => 0x2d, 57 => 0x0 }, + 'focalunits' => { 34 => 0x19 }, + 'focus' => { 249 => 0x8 }, + 'focusarea' => { 176 => 0x31 }, + 'focusareaselection' => { 277 => '15.2' }, + 'focuscontinuous' => { 34 => 0x20 }, + 'focusdisplayaiservoandmf' => { 81 => 0x515 }, + 'focusdistance' => { 159 => 'FocusDistance', 176 => 0x13, 182 => 0x49bb, 212 => 0x9, 213 => 0xa, 217 => [0xb,0x4f], 286 => 0x305, 300 => 0x0, 304 => 0x304, 305 => 0x304 }, + 'focusdistancelower' => { 7 => 0x45, 9 => 0x8e, 11 => 0x45, 13 => 0x56, 14 => 0x45, 15 => 0x45, 16 => 0x52, 17 => 0x52, 18 => 0x56, 20 => 0x52, 21 => 0x8e, 22 => 0x59, 23 => 0x57, 24 => 0x8e, 25 => 0x94, 26 => 0x95, 27 => 0xa7, 28 => 0x56, 29 => 0xa7, 55 => 0x15, 74 => 0x14 }, + 'focusdistanceupper' => { 7 => 0x43, 9 => 0x8c, 11 => 0x43, 13 => 0x54, 14 => 0x43, 15 => 0x43, 16 => 0x50, 17 => 0x50, 18 => 0x54, 20 => 0x50, 21 => 0x8c, 22 => 0x57, 23 => 0x55, 24 => 0x8c, 25 => 0x92, 26 => 0x93, 27 => 0xa5, 28 => 0x54, 29 => 0xa5, 55 => 0x14, 74 => 0x13 }, + 'focusholdbutton' => { 179 => 0x44 }, + 'focusinfoversion' => { 286 => 0x0 }, + 'focusingscreen' => { 80 => 0x0, 81 => 0x80b, 86 => 0x0 }, + 'focuslocation' => { 406 => 0x2027 }, + 'focuslocked' => { 175 => 0x14 }, + 'focusmode' => { 34 => 0x7, 109 => 0x3, 110 => [0x3003,0xd], 124 => 0x1021, 134 => 0x3f5, 136 => 0x38, 152 => 'FocusMode', 176 => 0x30, 178 => 0xe, 179 => 0xc, 219 => 0x7, 283 => 0x301, 288 => 0x100b, 306 => 0x7, 341 => 0xd, 348 => 0x3, 373 => 0x1006, 386 => [0xb,0x5], 392 => [0x15,0x1d], 393 => 0x4d, 394 => 0x4d, 406 => [0xb042,0xb04e,0x201b], 411 => 0x13, 429 => 0x16 }, + 'focusmode2' => { 123 => '0.1', 322 => '3.1', 411 => [0x2c,0x2e,0x32] }, + 'focusmodesetting' => { 268 => '10.1', 390 => 0x14, 391 => 0x15, 393 => 0x10, 394 => 0xf, 395 => 0x6 }, + 'focusmodeswitch' => { 179 => 0x58, 393 => 0x2e }, + 'focuspixel' => { 124 => 0x1023 }, + 'focuspointwrap' => { 266 => '2.2', 267 => '2.2', 269 => '2.1', 270 => '2.1', 274 => '1.1', 275 => '2.2', 276 => '1.1', 279 => '2.2', 280 => '2.1', 281 => '2.5' }, + 'focusposition' => { 212 => 0x8, 213 => 0x8, 217 => 0x9, 341 => 0x10, 404 => 0x9bb }, + 'focusposition2' => { 411 => [0x29,0x2b,0x2f], 429 => 0x2d, 432 => 0x20 }, + 'focusprocess' => { 283 => 0x302 }, + 'focusrange' => { 34 => 0x12, 288 => 0x100a }, + 'focusrangeindex' => { 332 => '3.1' }, + 'focusringrotation' => { 81 => 0x713 }, + 'focussetting' => { 383 => 0x6 }, + 'focusstatus' => { 392 => 0x19, 393 => 0x53, 394 => 0x53 }, + 'focusstepcount' => { 286 => 0x301, 288 => 0x100e }, + 'focusstepinfinity' => { 286 => 0x303, 288 => 0x103b }, + 'focusstepnear' => { 286 => 0x304, 288 => 0x103c }, + 'focustrackinglockon' => { 266 => ['1.5','4.1'], 267 => '1.4', 274 => '0.4', 275 => '3.1', 276 => '0.4', 279 => '1.4' }, + 'focuswarning' => { 124 => 0x1301 }, + 'foldername' => { 176 => 0x27 }, + 'foldernumber' => { 393 => 0x9a, 395 => [0x402,0x114,0x316] }, + 'fontcomposite' => { 493 => [\'Fonts','FontsComposite'] }, + 'fontface' => { 493 => [\'Fonts','FontsFontFace'] }, + 'fontfamily' => { 493 => [\'Fonts','FontsFontFamily'] }, + 'fontfilename' => { 493 => [\'Fonts','FontsFontFileName'] }, + 'fontname' => { 493 => [\'Fonts','FontsFontName'] }, + 'fonts' => { 493 => 'Fonts' }, + 'fonttype' => { 493 => [\'Fonts','FontsFontType'] }, + 'fontversion' => { 493 => [\'Fonts','FontsVersionString'] }, + 'for' => { 357 => 'For' }, + 'forcewrite' => { 117 => 'ForceWrite' }, + 'format' => { 366 => "\xa9fmt", 447 => 'Format', 465 => 'format', 486 => 'Format' }, + 'forwardlock' => { 483 => 'forwardlock' }, + 'forwardmatrix1' => { 116 => 0xc714 }, + 'forwardmatrix2' => { 116 => 0xc715 }, + 'fossilspecimen' => { 115 => 'FossilSpecimen' }, + 'fossilspecimenmaterialsampleid' => { 115 => [\'FossilSpecimen','FossilSpecimenMaterialSampleID'] }, + 'framecount' => { 64 => [0x2,0x4] }, + 'frameheight' => { 124 => 0x3822 }, + 'framenum' => { 352 => 0xd7 }, + 'framenumber' => { 124 => 0x8003, 182 => 0x3c, 341 => 0x29 }, + 'framerate' => { 64 => [0x1,0x6], 116 => 0xc764, 124 => 0x3820 }, + 'framereadouttime' => { 360 => 'camera.framereadouttimeinmicroseconds' }, + 'framewidth' => { 124 => 0x3821 }, + 'framing' => { 477 => 'framing' }, + 'freebytes' => { 94 => 0x1 }, + 'freememorycardimages' => { 177 => [0x37,0x54], 178 => [0x2d,0x4a], 179 => 0x32 }, + 'fujiflashmode' => { 124 => 0x1010 }, + 'fullhdhighspeedrec' => { 124 => 0x3824 }, + 'fullimagesize' => { 406 => 0xb02b }, + 'fullpanoheightpixels' => { 450 => 'FullPanoHeightPixels', 451 => 'FullPanoHeightPixels' }, + 'fullpanowidthpixels' => { 450 => 'FullPanoWidthPixels', 451 => 'FullPanoWidthPixels' }, + 'fullpresssnap' => { 373 => 0x100d }, + 'fullsizeimage' => { 158 => 'data' }, + 'fullsizeimagename' => { 158 => '1Name' }, + 'fullsizeimagetype' => { 158 => '0Type' }, + 'func1button' => { 269 => '14.1', 270 => '14.1', 280 => '14.1' }, + 'func1buttonplusdials' => { 269 => '42.1', 270 => '42.1', 280 => '42.1' }, + 'func2button' => { 269 => '80.1', 270 => '80.1', 280 => '80.1' }, + 'func2buttonplusdials' => { 269 => '81.1' }, + 'func3button' => { 269 => '83.1' }, + 'funcbutton' => { 266 => ['14.1','15.1'], 267 => '14.1', 275 => '28.1', 276 => '13.1', 279 => '14.1', 281 => '14.1' }, + 'funcbuttonplusdials' => { 266 => ['14.2','15.2'], 267 => '14.2', 275 => '31.1', 279 => '42.1' }, + 'functionbutton' => { 273 => '13.1', 277 => '5.2' }, + 'gainbase' => { 287 => 0x610 }, + 'gaincontrol' => { 116 => 0xa407, 468 => 'GainControl' }, + 'gamma' => { 116 => 0xa500, 134 => 0x8fe, 311 => 0x11c, 469 => 'Gamma' }, + 'gammablackpoint' => { 102 => 0xc }, + 'gammacolortone' => { 102 => 0x3 }, + 'gammacompensatedvalue' => { 130 => 0x91 }, + 'gammacontrast' => { 102 => 0x2 }, + 'gammacurveoutputrange' => { 102 => 0xf }, + 'gammahighlight' => { 102 => 0xa }, + 'gammalinear' => { 100 => 0x20200 }, + 'gammamidpoint' => { 102 => 0xe }, + 'gammasaturation' => { 102 => 0x4 }, + 'gammashadow' => { 102 => 0x9 }, + 'gammasharpnessstrength' => { 102 => 0x8 }, + 'gammaunsharpmaskfineness' => { 102 => 0x6 }, + 'gammaunsharpmaskstrength' => { 102 => 0x5 }, + 'gammaunsharpmaskthreshold' => { 102 => 0x7 }, + 'gammawhitepoint' => { 102 => 0xd }, + 'gdalmetadata' => { 116 => 0xa480 }, + 'gdalnodata' => { 116 => 0xa481 }, + 'geimagesize' => { 124 => 0x1304 }, + 'gemake' => { 126 => 0x300 }, + 'gemodel' => { 126 => 0x207 }, + 'genre' => { 358 => ['gnre',"\xa9gen"], 360 => 'genre', 366 => ['gnre',"\xa9gen"], 474 => 'Genre', 478 => 'genre', 488 => 'genre' }, + 'genrecvid' => { 474 => [\'Genre','GenreCvId'] }, + 'genrecvtermid' => { 474 => [\'Genre','GenreCvTermId'] }, + 'genrecvtermname' => { 474 => [\'Genre','GenreCvTermName'] }, + 'genrecvtermrefinedabout' => { 474 => [\'Genre','GenreCvTermRefinedAbout'] }, + 'genreid' => { 358 => 'geID' }, + 'geography' => { 479 => 'geography' }, + 'geologicalcontext' => { 115 => 'GeologicalContext' }, + 'geologicalcontextbed' => { 115 => [\'GeologicalContext','GeologicalContextBed'] }, + 'geologicalcontextformation' => { 115 => [\'GeologicalContext','GeologicalContextFormation'] }, + 'geologicalcontextgroup' => { 115 => [\'GeologicalContext','GeologicalContextGroup'] }, + 'geologicalcontextid' => { 115 => [\'GeologicalContext','GeologicalContextGeologicalContextID'] }, + 'geologicalcontextmember' => { 115 => [\'GeologicalContext','GeologicalContextMember'] }, + 'geosync' => { 117 => 'Geosync' }, + 'geotag' => { 117 => 'Geotag' }, + 'geotiffasciiparams' => { 116 => 0x87b1 }, + 'geotiffdirectory' => { 116 => 0x87af }, + 'geotiffdoubleparams' => { 116 => 0x87b0 }, + 'geotime' => { 117 => 'Geotime' }, + 'giftftppriority' => { 452 => 'GIFTFtpPriority' }, + 'gimbalpitchdegree' => { 113 => 'GimbalPitchDegree' }, + 'gimbalreverse' => { 113 => 'GimbalReverse' }, + 'gimbalrolldegree' => { 113 => 'GimbalRollDegree' }, + 'gimbalyawdegree' => { 113 => 'GimbalYawDegree' }, + 'globalaltitude' => { 355 => 0x419 }, + 'globalangle' => { 355 => 0x40d }, + 'good' => { 488 => 'good' }, + 'googlehostheader' => { 358 => 'gshh' }, + 'googlepingmessage' => { 358 => 'gspm' }, + 'googlepingurl' => { 358 => 'gspu' }, + 'googleplusuploadcode' => { 116 => 0x9009 }, + 'googlesourcedata' => { 358 => 'gssd' }, + 'googlestarttime' => { 358 => 'gsst' }, + 'googletrackduration' => { 358 => 'gstd' }, + 'goprotype' => { 366 => 'GoPr' }, + 'gpsaltitude' => { 127 => 0x6, 156 => 'Altitude', 468 => 'GPSAltitude' }, + 'gpsaltituderef' => { 127 => 0x5, 468 => 'GPSAltitudeRef' }, + 'gpsareainformation' => { 127 => 0x1c, 468 => 'GPSAreaInformation' }, + 'gpscoordinates' => { 360 => 'location.ISO6709', 366 => "\xa9xyz" }, + 'gpsdatestamp' => { 127 => 0x1d }, + 'gpsdatetime' => { 156 => 'DateTime', 468 => 'GPSTimeStamp' }, + 'gpsdestbearing' => { 127 => 0x18, 156 => 'Bearing', 468 => 'GPSDestBearing' }, + 'gpsdestbearingref' => { 127 => 0x17, 468 => 'GPSDestBearingRef' }, + 'gpsdestdistance' => { 127 => 0x1a, 156 => 'Distance', 468 => 'GPSDestDistance' }, + 'gpsdestdistanceref' => { 127 => 0x19, 468 => 'GPSDestDistanceRef' }, + 'gpsdestlatitude' => { 127 => 0x14, 468 => 'GPSDestLatitude' }, + 'gpsdestlatituderef' => { 127 => 0x13 }, + 'gpsdestlongitude' => { 127 => 0x16, 468 => 'GPSDestLongitude' }, + 'gpsdestlongituderef' => { 127 => 0x15 }, + 'gpsdifferential' => { 127 => 0x1e, 156 => 'Differential', 468 => 'GPSDifferential' }, + 'gpsdop' => { 127 => 0xb, 468 => 'GPSDOP' }, + 'gpshpositioningerror' => { 127 => 0x1f, 468 => 'GPSHPositioningError' }, + 'gpsimgdirection' => { 127 => 0x11, 468 => 'GPSImgDirection' }, + 'gpsimgdirectionref' => { 127 => 0x10, 468 => 'GPSImgDirectionRef' }, + 'gpslatitude' => { 113 => 'GpsLatitude', 127 => 0x2, 156 => 'Latitude', 468 => 'GPSLatitude' }, + 'gpslatituderef' => { 127 => 0x1 }, + 'gpslongitude' => { 113 => 'GpsLongitude', 127 => 0x4, 156 => 'Longitude', 468 => 'GPSLongitude' }, + 'gpslongituderef' => { 127 => 0x3 }, + 'gpslongtitude' => { 113 => 'GpsLongtitude' }, + 'gpsmapdatum' => { 127 => 0x12, 156 => 'Datum', 468 => 'GPSMapDatum' }, + 'gpsmeasuremode' => { 127 => 0xa, 156 => 'MeasureMode', 468 => 'GPSMeasureMode' }, + 'gpsprocessingmethod' => { 127 => 0x1b, 468 => 'GPSProcessingMethod' }, + 'gpssatellites' => { 127 => 0x8, 156 => 'Satellites', 468 => 'GPSSatellites' }, + 'gpsspeed' => { 127 => 0xd, 156 => 'Speed', 468 => 'GPSSpeed' }, + 'gpsspeedref' => { 127 => 0xc, 468 => 'GPSSpeedRef' }, + 'gpsstatus' => { 127 => 0x9, 468 => 'GPSStatus' }, + 'gpsstring' => { 134 => 0x402 }, + 'gpstimestamp' => { 127 => 0x7 }, + 'gpstrack' => { 127 => 0xf, 156 => 'Heading', 468 => 'GPSTrack' }, + 'gpstrackref' => { 127 => 0xe, 468 => 'GPSTrackRef' }, + 'gpsversionid' => { 127 => 0x0, 468 => 'GPSVersionID' }, + 'gradation' => { 283 => 0x50f }, + 'gradientbasedcorractive' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'] }, + 'gradientbasedcorramount' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'] }, + 'gradientbasedcorrbrightness' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'] }, + 'gradientbasedcorrclarity' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'] }, + 'gradientbasedcorrclarity2012' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity2012'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity2012'] }, + 'gradientbasedcorrcontrast' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'] }, + 'gradientbasedcorrcontrast2012' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast2012'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast2012'] }, + 'gradientbasedcorrdefringe' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDefringe'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDefringe'] }, + 'gradientbasedcorrections' => { 462 => 'GradientBasedCorrections', 464 => 'GradientBasedCorrections' }, + 'gradientbasedcorrexposure' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'] }, + 'gradientbasedcorrexposure2012' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure2012'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure2012'] }, + 'gradientbasedcorrhighlights2012' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHighlights2012'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHighlights2012'] }, + 'gradientbasedcorrhue' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalToningHue'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalToningHue'] }, + 'gradientbasedcorrluminancenoise' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalLuminanceNoise'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalLuminanceNoise'] }, + 'gradientbasedcorrmaskalpha' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAlpha'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAlpha'] }, + 'gradientbasedcorrmaskangle' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAngle'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAngle'] }, + 'gradientbasedcorrmaskbottom' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksBottom'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksBottom'] }, + 'gradientbasedcorrmaskcentervalue' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterValue'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterValue'] }, + 'gradientbasedcorrmaskcenterweight' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'] }, + 'gradientbasedcorrmaskdabs' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'] }, + 'gradientbasedcorrmaskfeather' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFeather'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFeather'] }, + 'gradientbasedcorrmaskflipped' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlipped'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlipped'] }, + 'gradientbasedcorrmaskflow' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'] }, + 'gradientbasedcorrmaskfullx' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'] }, + 'gradientbasedcorrmaskfully' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'] }, + 'gradientbasedcorrmaskleft' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksLeft'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksLeft'] }, + 'gradientbasedcorrmaskmidpoint' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMidpoint'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMidpoint'] }, + 'gradientbasedcorrmaskperimetervalue' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksPerimeterValue'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksPerimeterValue'] }, + 'gradientbasedcorrmaskradius' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'] }, + 'gradientbasedcorrmaskright' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRight'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRight'] }, + 'gradientbasedcorrmaskroundness' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRoundness'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRoundness'] }, + 'gradientbasedcorrmasks' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'] }, + 'gradientbasedcorrmasksizex' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeX'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeX'] }, + 'gradientbasedcorrmasksizey' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeY'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeY'] }, + 'gradientbasedcorrmasktop' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksTop'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksTop'] }, + 'gradientbasedcorrmaskvalue' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'] }, + 'gradientbasedcorrmaskversion' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksVersion'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksVersion'] }, + 'gradientbasedcorrmaskwhat' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'] }, + 'gradientbasedcorrmaskx' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksX'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksX'] }, + 'gradientbasedcorrmasky' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksY'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksY'] }, + 'gradientbasedcorrmaskzerox' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'] }, + 'gradientbasedcorrmaskzeroy' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'] }, + 'gradientbasedcorrmoire' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalMoire'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalMoire'] }, + 'gradientbasedcorrsaturation' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'] }, + 'gradientbasedcorrshadows2012' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalShadows2012'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalShadows2012'] }, + 'gradientbasedcorrsharpness' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'] }, + 'gradientbasedcorrtemperature' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTemperature'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTemperature'] }, + 'gradientbasedcorrtint' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTint'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTint'] }, + 'gradientbasedcorrwhat' => { 462 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'], 464 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'] }, + 'grainamount' => { 462 => 'GrainAmount', 464 => 'GrainAmount' }, + 'graineffect' => { 124 => 0x1047 }, + 'grainfrequency' => { 462 => 'GrainFrequency', 464 => 'GrainFrequency' }, + 'grainsize' => { 462 => 'GrainSize', 464 => 'GrainSize' }, + 'graymixeraqua' => { 462 => 'GrayMixerAqua', 464 => 'GrayMixerAqua' }, + 'graymixerblue' => { 462 => 'GrayMixerBlue', 464 => 'GrayMixerBlue' }, + 'graymixergreen' => { 462 => 'GrayMixerGreen', 464 => 'GrayMixerGreen' }, + 'graymixermagenta' => { 462 => 'GrayMixerMagenta', 464 => 'GrayMixerMagenta' }, + 'graymixerorange' => { 462 => 'GrayMixerOrange', 464 => 'GrayMixerOrange' }, + 'graymixerpurple' => { 462 => 'GrayMixerPurple', 464 => 'GrayMixerPurple' }, + 'graymixerred' => { 462 => 'GrayMixerRed', 464 => 'GrayMixerRed' }, + 'graymixeryellow' => { 462 => 'GrayMixerYellow', 464 => 'GrayMixerYellow' }, + 'graypoint' => { 439 => 0x8021 }, + 'grayresponseunit' => { 116 => 0x122 }, + 'greencurvelimits' => { 105 => 0x1c4 }, + 'greencurvepoints' => { 104 => 0x53, 105 => 0x19a }, + 'greenhsl' => { 100 => 0x20913 }, + 'greenhue' => { 462 => 'GreenHue', 464 => 'GreenHue' }, + 'greensaturation' => { 462 => 'GreenSaturation', 464 => 'GreenSaturation' }, + 'griddisplay' => { 266 => '13.3', 267 => '4.3', 269 => '4.2', 270 => '4.2', 271 => '2.2', 275 => '10.5', 276 => '3.4', 277 => '6.1', 279 => '4.4', 280 => '4.2', 281 => '4.2' }, + 'gripbatteryadload' => { 320 => 0x5 }, + 'gripbatteryadnoload' => { 320 => 0x4 }, + 'gripbatterystate' => { 320 => '1.2' }, + 'groupareaafillumination' => { 267 => '46.4', 270 => '47.4', 279 => '47.4' }, + 'grouping' => { 358 => ['grup',"\xa9grp"], 366 => "\xa9grp" }, + 'guid' => { 358 => 'GUID' }, + 'h2resetblackpixels' => { 134 => 0x18a6 }, + 'h3resetblackcolumns' => { 134 => 0x18ce }, + 'h3resetblackpixels' => { 134 => 0x18b0 }, + 'halftonehints' => { 116 => 0x141 }, + 'hardlink' => { 117 => 'HardLink' }, + 'hasalternative' => { 478 => 'hasAlternative' }, + 'hascorrection' => { 478 => 'hasCorrection' }, + 'hascorrectiona-lang' => { 478 => [\'hasCorrection','hasCorrectionA-lang'] }, + 'hascorrectiona-platform' => { 478 => [\'hasCorrection','hasCorrectionA-platform'] }, + 'hascorrectiontext' => { 478 => [\'hasCorrection','hasCorrectionText'] }, + 'hascrop' => { 462 => 'HasCrop', 464 => 'HasCrop' }, + 'hasextendedxmp' => { 490 => 'HasExtendedXMP' }, + 'hassettings' => { 462 => 'HasSettings', 464 => 'HasSettings' }, + 'hastranslation' => { 478 => 'hasTranslation' }, + 'hasvisibleoverprint' => { 493 => 'HasVisibleOverprint' }, + 'hasvisibletransparency' => { 493 => 'HasVisibleTransparency' }, + 'hdr' => { 58 => 0x1, 209 => 0x4, 306 => 0x9e, 341 => 0x85, 406 => 0x200a }, + 'hdreffect' => { 58 => 0x2 }, 'hdrimagetype' => { 1 => 0xa }, - 'hdrinfoversion' => { 204 => 0x0 }, - 'hdrlevel' => { 204 => 0x5, 378 => 0x2e, 393 => 0x17 }, - 'hdrlevel2' => { 204 => 0x7 }, - 'hdrsetting' => { 378 => 0x2d, 393 => 0x16, 396 => 0x1148, 397 => 0x1148, 398 => 0x1124, 399 => 0x11a0, 400 => 0x117c, 401 => 0x1034, 402 => 0x22c, 403 => 0x22c, 404 => 0x21f }, - 'hdrshot' => { 297 => 0x76 }, - 'hdrsmoothing' => { 204 => 0x6 }, - 'headline' => { 125 => 0x69, 452 => 'Headline', 454 => 'Headline' }, - 'hierarchicalkeywords' => { 162 => [\'Keywords','KeywordsHierarchy'] }, - 'hierarchicalkeywords1' => { 162 => [\'Keywords','KeywordsHierarchyKeyword'] }, - 'hierarchicalkeywords1applied' => { 162 => [\'Keywords','KeywordsHierarchyApplied'] }, - 'hierarchicalkeywords1children' => { 162 => [\'Keywords','KeywordsHierarchyChildren'] }, - 'hierarchicalkeywords2' => { 162 => [\'Keywords','KeywordsHierarchyChildrenKeyword'] }, - 'hierarchicalkeywords2applied' => { 162 => [\'Keywords','KeywordsHierarchyChildrenApplied'] }, - 'hierarchicalkeywords2children' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildren'] }, - 'hierarchicalkeywords3' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenKeyword'] }, - 'hierarchicalkeywords3applied' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenApplied'] }, - 'hierarchicalkeywords3children' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildren'] }, - 'hierarchicalkeywords4' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenKeyword'] }, - 'hierarchicalkeywords4applied' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenApplied'] }, - 'hierarchicalkeywords4children' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildren'] }, - 'hierarchicalkeywords5' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenKeyword'] }, - 'hierarchicalkeywords5applied' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenApplied'] }, - 'hierarchicalkeywords5children' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildren'] }, - 'hierarchicalkeywords6' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenKeyword'] }, - 'hierarchicalkeywords6applied' => { 162 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenApplied'] }, - 'hierarchicalsubject' => { 433 => 'hierarchicalSubject' }, - 'highestbiostratigraphiczone' => { 112 => [\'GeologicalContext','GeologicalContextHighestBiostratigraphicZone'] }, - 'highisomultiplierblue' => { 302 => 0x1a }, - 'highisomultipliergreen' => { 302 => 0x19 }, - 'highisomultiplierred' => { 302 => 0x18 }, - 'highisonoisereduction' => { 15 => 0xbc, 16 => 0xbd, 19 => 0xbd, 27 => 0xc9, 59 => 0x5, 78 => 0x202, 211 => 0xb1, 332 => 0x71, 376 => 0x2c, 377 => 0x26, 378 => 0x26, 388 => 0x2009, 393 => 0x12, 417 => 0x42 }, - 'highisonoisereduction2' => { 388 => 0xb050 }, - 'highlight' => { 368 => 0xf }, - 'highlightadj' => { 97 => 0x2030c }, - 'highlightcolordistortreduct' => { 421 => 0x8026 }, - 'highlightlinearitylimit' => { 365 => 0xa025 }, - 'highlightprotection' => { 249 => 0x6 }, - 'highlightrecovery' => { 442 => 'HighlightRecovery' }, - 'highlights' => { 435 => 'Highlights' }, - 'highlights2012' => { 442 => 'Highlights2012' }, - 'highlightsadj' => { 421 => 0x9019 }, - 'highlightshadow' => { 297 => 0xad }, - 'highlighttone' => { 121 => 0x1041 }, - 'highlighttonepriority' => { 12 => 0x7, 15 => 0x7, 16 => 0x7, 17 => 0x7, 19 => 0x7, 21 => 0x7, 27 => 0x7, 59 => 0x3, 78 => 0x203 }, - 'highlightwarning' => { 297 => 0x8002 }, - 'highlowkeyadj' => { 332 => 0x6c }, - 'highspeedsync' => { 174 => 0x5, 376 => 0x2, 377 => 0x2 }, - 'histogramxml' => { 250 => 0x83a1a25 }, - 'history' => { 454 => 'History', 467 => 'History' }, - 'historyaction' => { 467 => [\'History','HistoryAction'] }, - 'historychanged' => { 467 => [\'History','HistoryChanged'] }, - 'historyinstanceid' => { 467 => [\'History','HistoryInstanceID'] }, - 'historyparameters' => { 467 => [\'History','HistoryParameters'] }, - 'historysoftwareagent' => { 467 => [\'History','HistorySoftwareAgent'] }, - 'historywhen' => { 467 => [\'History','HistoryWhen'] }, - 'holefilldarkdeltathreshold' => { 131 => 0xc88 }, - 'holefilldeltathreshold' => { 131 => 0xc7e }, - 'hometowncity' => { 107 => 0x3006, 332 => 0x23, 338 => 0x2 }, - 'hometowncitycode' => { 339 => 0x1000 }, - 'hometowndst' => { 332 => 0x25, 338 => '0.2' }, - 'hostcomputer' => { 113 => 0x13c }, - 'hostsoftwarerendering' => { 131 => 0xce7 }, - 'hue' => { 179 => 0x3b, 214 => 0x3d, 332 => 0x67 }, - 'hueadj' => { 253 => 0x2f, 421 => 0x8019 }, - 'hueadjust' => { 358 => 0x1016 }, - 'hueadjustment' => { 172 => 0x4a, 173 => 0x40, 211 => 0x92, 213 => 0x36 }, - 'hueadjustmentaqua' => { 442 => 'HueAdjustmentAqua' }, - 'hueadjustmentblue' => { 442 => 'HueAdjustmentBlue' }, - 'hueadjustmentgreen' => { 442 => 'HueAdjustmentGreen' }, - 'hueadjustmentmagenta' => { 442 => 'HueAdjustmentMagenta' }, - 'hueadjustmentorange' => { 442 => 'HueAdjustmentOrange' }, - 'hueadjustmentpurple' => { 442 => 'HueAdjustmentPurple' }, - 'hueadjustmentred' => { 442 => 'HueAdjustmentRed' }, - 'hueadjustmentyellow' => { 442 => 'HueAdjustmentYellow' }, - 'huesetting' => { 282 => 0x1011 }, - 'humanobservation' => { 112 => 'HumanObservation' }, - 'humanobservationday' => { 112 => [\'HumanObservation','HumanObservationDay'] }, - 'humanobservationearliestdate' => { 112 => [\'HumanObservation','HumanObservationEarliestDate'] }, - 'humanobservationenddayofyear' => { 112 => [\'HumanObservation','HumanObservationEndDayOfYear'] }, - 'humanobservationeventdate' => { 112 => [\'HumanObservation','HumanObservationEventDate'] }, - 'humanobservationeventid' => { 112 => [\'HumanObservation','HumanObservationEventID'] }, - 'humanobservationeventremarks' => { 112 => [\'HumanObservation','HumanObservationEventRemarks'] }, - 'humanobservationeventtime' => { 112 => [\'HumanObservation','HumanObservationEventTime'] }, - 'humanobservationfieldnotes' => { 112 => [\'HumanObservation','HumanObservationFieldNotes'] }, - 'humanobservationfieldnumber' => { 112 => [\'HumanObservation','HumanObservationFieldNumber'] }, - 'humanobservationhabitat' => { 112 => [\'HumanObservation','HumanObservationHabitat'] }, - 'humanobservationlatestdate' => { 112 => [\'HumanObservation','HumanObservationLatestDate'] }, - 'humanobservationmonth' => { 112 => [\'HumanObservation','HumanObservationMonth'] }, - 'humanobservationparenteventid' => { 112 => [\'HumanObservation','HumanObservationParentEventID'] }, - 'humanobservationsamplesizeunit' => { 112 => [\'HumanObservation','HumanObservationSampleSizeUnit'] }, - 'humanobservationsamplesizevalue' => { 112 => [\'HumanObservation','HumanObservationSampleSizeValue'] }, - 'humanobservationsamplingeffort' => { 112 => [\'HumanObservation','HumanObservationSamplingEffort'] }, - 'humanobservationsamplingprotocol' => { 112 => [\'HumanObservation','HumanObservationSamplingProtocol'] }, - 'humanobservationstartdayofyear' => { 112 => [\'HumanObservation','HumanObservationStartDayOfYear'] }, - 'humanobservationverbatimeventdate' => { 112 => [\'HumanObservation','HumanObservationVerbatimEventDate'] }, - 'humanobservationyear' => { 112 => [\'HumanObservation','HumanObservationYear'] }, - 'humidity' => { 113 => 0x9401, 447 => 'Humidity' }, - 'icc_profile' => { 114 => 'ICC_Profile' }, - 'iccprofilename' => { 454 => 'ICCProfile' }, - 'idccreativestyle' => { 421 => 0x8000 }, - 'idcpreviewlength' => { 421 => 0x202 }, - 'idcpreviewstart' => { 421 => 0x201 }, - 'identification' => { 112 => 'Identification' }, - 'identificationid' => { 112 => [\'Identification','IdentificationIdentificationID'] }, - 'identificationqualifier' => { 112 => [\'Identification','IdentificationIdentificationQualifier'] }, - 'identificationreferences' => { 112 => [\'Identification','IdentificationIdentificationReferences'] }, - 'identificationremarks' => { 112 => [\'Identification','IdentificationIdentificationRemarks'] }, - 'identificationverificationstatus' => { 112 => [\'Identification','IdentificationIdentificationVerificationStatus'] }, - 'identifiedby' => { 112 => [\'Identification','IdentificationIdentifiedBy'] }, - 'identifier' => { 443 => 'identifier', 464 => 'Identifier' }, - 'ifcameramodel' => { 131 => 0x9c8 }, - 'illumination' => { 268 => '0.5', 354 => 0x48 }, - 'imageabsolutex' => { 131 => 0x3fe }, - 'imageabsolutey' => { 131 => 0x3ff }, - 'imageadjustment' => { 211 => 0x80, 240 => 0x5 }, - 'imagealterationconstraints' => { 284 => 'ImageAlterationConstraints' }, - 'imagearea' => { 223 => 0x10, 226 => 0x10 }, - 'imageareaoffset' => { 332 => 0x38 }, - 'imageauthentication' => { 211 => 0x20 }, - 'imageboundary' => { 211 => 0x16 }, - 'imagecount' => { 121 => 0x1438, 211 => 0xa5, 391 => 0x11b, 406 => 0x32, 407 => 0x3a }, - 'imagecount2' => { 406 => 0x4c, 407 => [0x52,0x58] }, - 'imagecount3' => { 406 => [0x1a0,0x1aa,0x1bd], 407 => [0x19f,0x1cb,0x1cd] }, - 'imagecreator' => { 284 => 'ImageCreator' }, - 'imagecreatorid' => { 284 => [\'ImageCreator','ImageCreatorImageCreatorID'] }, - 'imagecreatorimageid' => { 284 => 'ImageCreatorImageID' }, - 'imagecreatorname' => { 284 => [\'ImageCreator','ImageCreatorImageCreatorName'] }, - 'imagecropx' => { 131 => 0x41f }, - 'imagecropy' => { 131 => 0x420 }, - 'imagedata' => { 428 => 'Data' }, - 'imagedatasize' => { 211 => 0xa2 }, - 'imagedescription' => { 113 => 0x10e, 462 => 'ImageDescription' }, - 'imageduplicationconstraints' => { 284 => 'ImageDuplicationConstraints' }, - 'imagedustoff' => { 250 => 0xfe443a45 }, - 'imageeditcount' => { 332 => 0x41 }, - 'imageediting' => { 332 => 0x32 }, - 'imageeffects' => { 358 => 0x1010 }, - 'imagefileconstraints' => { 284 => 'ImageFileConstraints' }, - 'imagefileformatasdelivered' => { 284 => 'ImageFileFormatAsDelivered' }, - 'imagefilesizeasdelivered' => { 284 => 'ImageFileSizeAsDelivered' }, - 'imagegeneration' => { 121 => 0x1436 }, - 'imageheight' => { 113 => 0x101, 178 => 0xc, 341 => 0x10d, 426 => 'ImageHeight', 462 => 'ImageLength' }, - 'imagehistory' => { 113 => 0x9213, 445 => 'ImageHistory' }, - 'imageidnumber' => { 292 => 0x340 }, - 'imagemimetype' => { 428 => 'Mime' }, - 'imagenumber' => { 113 => 0x9211, 147 => 'ImageNumber', 172 => 0xae, 173 => 0x5e, 341 => 0x113, 376 => 0x9b, 378 => [0x400,'276.1',0x314], 438 => 'ImageNumber' }, - 'imagenumber2' => { 173 => 0x62 }, - 'imageoptimization' => { 211 => 0xa9 }, - 'imageorientation' => { 125 => 0x83 }, - 'imageprocessing' => { 211 => 0x1a }, - 'imageprocessingfiledatecreated' => { 131 => 0xc81 }, - 'imageprocessingfiletagsversionnumber' => { 131 => 0xc80 }, - 'imageprocessingversion' => { 278 => 0x0 }, - 'imagequality' => { 147 => 'ImageQuality', 225 => '723.2', 226 => '732.2', 235 => '708.1', 297 => 0x1 }, - 'imagequality2' => { 274 => 0x603 }, - 'imagerank' => { 431 => 'ImageRank' }, - 'imagerbiassettlingdelaymsec' => { 131 => 0x600 }, - 'imagerboardversion' => { 131 => 0x439 }, - 'imagercols' => { 131 => 0x17d4 }, - 'imageref' => { 450 => 'ImageRef' }, - 'imageresolution' => { 131 => 0x944 }, - 'imageresolutionjpg' => { 131 => 0x945 }, - 'imagereview' => { 259 => '0.4', 268 => '0.4' }, - 'imagereviewmonitorofftime' => { 258 => '21.1', 260 => '21.1', 261 => '21.1', 265 => '20.1', 270 => '21.1', 271 => '21.1' }, - 'imagereviewtime' => { 257 => '25.1', 259 => '2.1', 262 => '19.1', 263 => '20.1', 264 => '20.1', 266 => '9.2', 267 => '20.1', 272 => '21.2' }, - 'imagerfiledatecreated' => { 131 => 0x9c5 }, - 'imagerfileproductionlevel' => { 131 => 0x9c4 }, - 'imagerfiletagsversionstandard' => { 131 => 0x9c7 }, - 'imagerpowerondelaymsec' => { 131 => 0x5fd }, - 'imagerrows' => { 131 => 0x17de }, - 'imagesegmentlines' => { 131 => 0x184d }, - 'imagesegmentstartline' => { 131 => 0x184c }, - 'imagesize' => { 153 => 'ImageSize' }, - 'imagesizerestriction' => { 459 => 'imageSizeRestriction' }, - 'imagesourcedata' => { 113 => 0x935c }, - 'imagespace' => { 131 => 0x909 }, - 'imagestabilization' => { 33 => 0x22, 107 => 0x3020, 121 => 0x1422, 147 => 'ImageStabilization', 172 => 0xbd, 173 => 0x71, 174 => 0x57, 175 => 0x0, 176 => [0x18,0x107,0x113], 177 => 0x49c2, 211 => 0xac, 274 => 0x604, 277 => 0x1600, 297 => 0x1a, 381 => 0x12, 382 => 0x11, 388 => 0xb026 }, - 'imagestabilization2' => { 380 => 0xa }, - 'imagestabilizationsetting' => { 177 => 0x14, 376 => 0x3d, 377 => 0x3d, 387 => 0x14 }, - 'imagestyle' => { 376 => 0x2d, 377 => 0x27 }, - 'imagesupplier' => { 284 => 'ImageSupplier' }, - 'imagesupplierid' => { 284 => [\'ImageSupplier','ImageSupplierImageSupplierID'] }, - 'imagesupplierimageid' => { 284 => 'ImageSupplierImageID' }, - 'imagesuppliername' => { 284 => [\'ImageSupplier','ImageSupplierImageSupplierName'] }, - 'imagetemperaturemax' => { 115 => 0x1 }, - 'imagetemperaturemin' => { 115 => 0x2 }, - 'imagetone' => { 332 => 0x4f }, - 'imagetype' => { 125 => 0x82, 284 => 'ImageType' }, - 'imageuniqueid' => { 1 => 0x15, 60 => 0x28, 113 => 0xa420, 445 => 'ImageUniqueID', 446 => 'ImageUniqueID' }, - 'imagewidth' => { 113 => 0x100, 178 => 0xe, 341 => 0x10c, 426 => 'ImageWidth', 462 => 'ImageWidth' }, - 'inclinationangle' => { 421 => 0x900f }, - 'inclinationcorrection' => { 421 => 0x900e }, - 'incrementaltemperature' => { 442 => 'IncrementalTemperature' }, - 'incrementaltint' => { 442 => 'IncrementalTint' }, - 'industry' => { 456 => 'industry', 457 => 'industry' }, - 'infobuttonwhenshooting' => { 78 => 0x409 }, - 'infraredilluminator' => { 353 => 0x28 }, - 'ingredientexclusion' => { 458 => 'ingredientExclusion' }, - 'ingredients' => { 467 => 'Ingredients' }, - 'ingredientsalternatepaths' => { 467 => [\'Ingredients','IngredientsAlternatePaths'] }, - 'ingredientsdocumentid' => { 467 => [\'Ingredients','IngredientsDocumentID'] }, - 'ingredientsfilepath' => { 467 => [\'Ingredients','IngredientsFilePath'] }, - 'ingredientsfrompart' => { 467 => [\'Ingredients','IngredientsFromPart'] }, - 'ingredientsinstanceid' => { 467 => [\'Ingredients','IngredientsInstanceID'] }, - 'ingredientslastmodifydate' => { 467 => [\'Ingredients','IngredientsLastModifyDate'] }, - 'ingredientslasturl' => { 467 => [\'Ingredients','IngredientsLastURL'] }, - 'ingredientslinkcategory' => { 467 => [\'Ingredients','IngredientsLinkCategory'] }, - 'ingredientslinkform' => { 467 => [\'Ingredients','IngredientsLinkForm'] }, - 'ingredientsmanager' => { 467 => [\'Ingredients','IngredientsManager'] }, - 'ingredientsmanagervariant' => { 467 => [\'Ingredients','IngredientsManagerVariant'] }, - 'ingredientsmanageto' => { 467 => [\'Ingredients','IngredientsManageTo'] }, - 'ingredientsmanageui' => { 467 => [\'Ingredients','IngredientsManageUI'] }, - 'ingredientsmaskmarkers' => { 467 => [\'Ingredients','IngredientsMaskMarkers'] }, - 'ingredientsoriginaldocumentid' => { 467 => [\'Ingredients','IngredientsOriginalDocumentID'] }, - 'ingredientspartmapping' => { 467 => [\'Ingredients','IngredientsPartMapping'] }, - 'ingredientsplacedresolutionunit' => { 467 => [\'Ingredients','IngredientsPlacedResolutionUnit'] }, - 'ingredientsplacedxresolution' => { 467 => [\'Ingredients','IngredientsPlacedXResolution'] }, - 'ingredientsplacedyresolution' => { 467 => [\'Ingredients','IngredientsPlacedYResolution'] }, - 'ingredientsrenditionclass' => { 467 => [\'Ingredients','IngredientsRenditionClass'] }, - 'ingredientsrenditionparams' => { 467 => [\'Ingredients','IngredientsRenditionParams'] }, - 'ingredientstopart' => { 467 => [\'Ingredients','IngredientsToPart'] }, - 'ingredientsversionid' => { 467 => [\'Ingredients','IngredientsVersionID'] }, - 'initialafpointaiservoaf' => { 78 => 0x51e }, + 'hdrinfoversion' => { 209 => 0x0 }, + 'hdrlevel' => { 209 => 0x5, 395 => 0x2e, 411 => 0x17 }, + 'hdrlevel2' => { 209 => 0x7 }, + 'hdrpmakernote' => { 445 => 'hdrp_makernote' }, + 'hdrsetting' => { 395 => 0x2d, 411 => 0x16, 414 => 0x1148, 415 => 0x1148, 416 => 0x1124, 417 => 0x11a0, 418 => 0x117c, 419 => 0x1034, 420 => 0x22c, 421 => 0x22c, 422 => 0x21f }, + 'hdrshot' => { 306 => 0x76 }, + 'hdrsmoothing' => { 209 => 0x6 }, + 'hdvideo' => { 358 => 'hdvd' }, + 'headline' => { 128 => 0x69, 474 => 'Headline', 476 => 'Headline' }, + 'hierarchicalkeywords' => { 167 => [\'Keywords','KeywordsHierarchy'] }, + 'hierarchicalkeywords1' => { 167 => [\'Keywords','KeywordsHierarchyKeyword'] }, + 'hierarchicalkeywords1applied' => { 167 => [\'Keywords','KeywordsHierarchyApplied'] }, + 'hierarchicalkeywords1children' => { 167 => [\'Keywords','KeywordsHierarchyChildren'] }, + 'hierarchicalkeywords2' => { 167 => [\'Keywords','KeywordsHierarchyChildrenKeyword'] }, + 'hierarchicalkeywords2applied' => { 167 => [\'Keywords','KeywordsHierarchyChildrenApplied'] }, + 'hierarchicalkeywords2children' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildren'] }, + 'hierarchicalkeywords3' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenKeyword'] }, + 'hierarchicalkeywords3applied' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenApplied'] }, + 'hierarchicalkeywords3children' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildren'] }, + 'hierarchicalkeywords4' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenKeyword'] }, + 'hierarchicalkeywords4applied' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenApplied'] }, + 'hierarchicalkeywords4children' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildren'] }, + 'hierarchicalkeywords5' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenKeyword'] }, + 'hierarchicalkeywords5applied' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenApplied'] }, + 'hierarchicalkeywords5children' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildren'] }, + 'hierarchicalkeywords6' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenKeyword'] }, + 'hierarchicalkeywords6applied' => { 167 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenApplied'] }, + 'hierarchicalsubject' => { 454 => 'hierarchicalSubject' }, + 'highestbiostratigraphiczone' => { 115 => [\'GeologicalContext','GeologicalContextHighestBiostratigraphicZone'] }, + 'highisomultiplierblue' => { 311 => 0x1a }, + 'highisomultipliergreen' => { 311 => 0x19 }, + 'highisomultiplierred' => { 311 => 0x18 }, + 'highisonoisereduction' => { 16 => 0xbc, 17 => 0xbd, 20 => 0xbd, 28 => 0xc9, 60 => 0x5, 81 => 0x202, 219 => 0xb1, 341 => 0x71, 393 => 0x2c, 394 => 0x26, 395 => 0x26, 406 => 0x2009, 411 => 0x12, 435 => 0x42 }, + 'highisonoisereduction2' => { 406 => 0xb050 }, + 'highlight' => { 383 => 0xf }, + 'highlight2012' => { 462 => 'Highlight2012', 464 => 'Highlight2012' }, + 'highlightadj' => { 100 => 0x2030c }, + 'highlightcolordistortreduct' => { 439 => 0x8026 }, + 'highlightlinearitylimit' => { 380 => 0xa025 }, + 'highlightprotection' => { 258 => 0x6 }, + 'highlightrecovery' => { 462 => 'HighlightRecovery', 464 => 'HighlightRecovery' }, + 'highlights' => { 456 => 'Highlights' }, + 'highlights2012' => { 462 => 'Highlights2012', 464 => 'Highlights2012' }, + 'highlightsadj' => { 439 => 0x9019 }, + 'highlightshadow' => { 306 => 0xad }, + 'highlighttone' => { 124 => 0x1041 }, + 'highlighttonepriority' => { 13 => 0x7, 16 => 0x7, 17 => 0x7, 18 => 0x7, 20 => 0x7, 22 => 0x7, 28 => 0x7, 60 => 0x3, 81 => 0x203 }, + 'highlightwarning' => { 306 => 0x8002 }, + 'highlowkeyadj' => { 341 => 0x6c }, + 'highspeedsync' => { 179 => 0x5, 393 => 0x2, 394 => 0x2 }, + 'hintversion' => { 366 => 'hinv' }, + 'histogramxml' => { 259 => 0x83a1a25 }, + 'history' => { 476 => 'History', 489 => 'History' }, + 'historyaction' => { 489 => [\'History','HistoryAction'] }, + 'historychanged' => { 489 => [\'History','HistoryChanged'] }, + 'historyinstanceid' => { 489 => [\'History','HistoryInstanceID'] }, + 'historyparameters' => { 489 => [\'History','HistoryParameters'] }, + 'historysoftwareagent' => { 489 => [\'History','HistorySoftwareAgent'] }, + 'historywhen' => { 489 => [\'History','HistoryWhen'] }, + 'holefilldarkdeltathreshold' => { 134 => 0xc88 }, + 'holefilldeltathreshold' => { 134 => 0xc7e }, + 'hometowncity' => { 110 => 0x3006, 341 => 0x23, 347 => 0x2 }, + 'hometowncitycode' => { 348 => 0x1000 }, + 'hometowndst' => { 341 => 0x25, 347 => '0.2' }, + 'hostcomputer' => { 116 => 0x13c }, + 'hostsoftwarerendering' => { 134 => 0xce7 }, + 'hue' => { 184 => 0x3b, 222 => 0x3d, 223 => 0x45, 341 => 0x67 }, + 'hueadj' => { 262 => 0x2f, 439 => 0x8019 }, + 'hueadjust' => { 373 => 0x1016 }, + 'hueadjustment' => { 177 => 0x4a, 178 => 0x40, 219 => 0x92, 221 => 0x36 }, + 'hueadjustmentaqua' => { 462 => 'HueAdjustmentAqua', 464 => 'HueAdjustmentAqua' }, + 'hueadjustmentblue' => { 462 => 'HueAdjustmentBlue', 464 => 'HueAdjustmentBlue' }, + 'hueadjustmentgreen' => { 462 => 'HueAdjustmentGreen', 464 => 'HueAdjustmentGreen' }, + 'hueadjustmentmagenta' => { 462 => 'HueAdjustmentMagenta', 464 => 'HueAdjustmentMagenta' }, + 'hueadjustmentorange' => { 462 => 'HueAdjustmentOrange', 464 => 'HueAdjustmentOrange' }, + 'hueadjustmentpurple' => { 462 => 'HueAdjustmentPurple', 464 => 'HueAdjustmentPurple' }, + 'hueadjustmentred' => { 462 => 'HueAdjustmentRed', 464 => 'HueAdjustmentRed' }, + 'hueadjustmentyellow' => { 462 => 'HueAdjustmentYellow', 464 => 'HueAdjustmentYellow' }, + 'huesetting' => { 291 => 0x1011 }, + 'humanobservation' => { 115 => 'HumanObservation' }, + 'humanobservationday' => { 115 => [\'HumanObservation','HumanObservationDay'] }, + 'humanobservationearliestdate' => { 115 => [\'HumanObservation','HumanObservationEarliestDate'] }, + 'humanobservationenddayofyear' => { 115 => [\'HumanObservation','HumanObservationEndDayOfYear'] }, + 'humanobservationeventdate' => { 115 => [\'HumanObservation','HumanObservationEventDate'] }, + 'humanobservationeventid' => { 115 => [\'HumanObservation','HumanObservationEventID'] }, + 'humanobservationeventremarks' => { 115 => [\'HumanObservation','HumanObservationEventRemarks'] }, + 'humanobservationeventtime' => { 115 => [\'HumanObservation','HumanObservationEventTime'] }, + 'humanobservationfieldnotes' => { 115 => [\'HumanObservation','HumanObservationFieldNotes'] }, + 'humanobservationfieldnumber' => { 115 => [\'HumanObservation','HumanObservationFieldNumber'] }, + 'humanobservationhabitat' => { 115 => [\'HumanObservation','HumanObservationHabitat'] }, + 'humanobservationlatestdate' => { 115 => [\'HumanObservation','HumanObservationLatestDate'] }, + 'humanobservationmonth' => { 115 => [\'HumanObservation','HumanObservationMonth'] }, + 'humanobservationparenteventid' => { 115 => [\'HumanObservation','HumanObservationParentEventID'] }, + 'humanobservationsamplesizeunit' => { 115 => [\'HumanObservation','HumanObservationSampleSizeUnit'] }, + 'humanobservationsamplesizevalue' => { 115 => [\'HumanObservation','HumanObservationSampleSizeValue'] }, + 'humanobservationsamplingeffort' => { 115 => [\'HumanObservation','HumanObservationSamplingEffort'] }, + 'humanobservationsamplingprotocol' => { 115 => [\'HumanObservation','HumanObservationSamplingProtocol'] }, + 'humanobservationstartdayofyear' => { 115 => [\'HumanObservation','HumanObservationStartDayOfYear'] }, + 'humanobservationverbatimeventdate' => { 115 => [\'HumanObservation','HumanObservationVerbatimEventDate'] }, + 'humanobservationyear' => { 115 => [\'HumanObservation','HumanObservationYear'] }, + 'humidity' => { 116 => 0x9401, 469 => 'Humidity' }, + 'icc_profile' => { 117 => 'ICC_Profile' }, + 'iccprofilename' => { 476 => 'ICCProfile' }, + 'iconuri' => { 366 => 'icnu' }, + 'idccreativestyle' => { 439 => 0x8000 }, + 'idcpreviewlength' => { 439 => 0x202 }, + 'idcpreviewstart' => { 439 => 0x201 }, + 'identification' => { 115 => 'Identification' }, + 'identificationid' => { 115 => [\'Identification','IdentificationIdentificationID'] }, + 'identificationqualifier' => { 115 => [\'Identification','IdentificationIdentificationQualifier'] }, + 'identificationreferences' => { 115 => [\'Identification','IdentificationIdentificationReferences'] }, + 'identificationremarks' => { 115 => [\'Identification','IdentificationIdentificationRemarks'] }, + 'identificationverificationstatus' => { 115 => [\'Identification','IdentificationIdentificationVerificationStatus'] }, + 'identifiedby' => { 115 => [\'Identification','IdentificationIdentifiedBy'] }, + 'identifier' => { 465 => 'identifier', 486 => 'Identifier' }, + 'ifcameramodel' => { 134 => 0x9c8 }, + 'illumination' => { 277 => '0.5', 368 => 0x48 }, + 'imageabsolutex' => { 134 => 0x3fe }, + 'imageabsolutey' => { 134 => 0x3ff }, + 'imageadjustment' => { 219 => 0x80, 249 => 0x5 }, + 'imagealterationconstraints' => { 293 => 'ImageAlterationConstraints' }, + 'imagearea' => { 232 => 0x10, 235 => 0x10 }, + 'imageareaoffset' => { 341 => 0x38 }, + 'imageauthentication' => { 219 => 0x20 }, + 'imageboundary' => { 219 => 0x16 }, + 'imagecount' => { 124 => 0x1438, 219 => 0xa5, 409 => 0x11b }, + 'imagecreator' => { 293 => 'ImageCreator' }, + 'imagecreatorid' => { 293 => [\'ImageCreator','ImageCreatorImageCreatorID'] }, + 'imagecreatorimageid' => { 293 => 'ImageCreatorImageID' }, + 'imagecreatorname' => { 293 => [\'ImageCreator','ImageCreatorImageCreatorName'] }, + 'imagecropx' => { 134 => 0x41f }, + 'imagecropy' => { 134 => 0x420 }, + 'imagedata' => { 449 => 'Data' }, + 'imagedatasize' => { 219 => 0xa2 }, + 'imagedescription' => { 116 => 0x10e, 484 => 'ImageDescription' }, + 'imageduplicationconstraints' => { 293 => 'ImageDuplicationConstraints' }, + 'imagedustoff' => { 259 => 0xfe443a45 }, + 'imageeditcount' => { 341 => 0x41 }, + 'imageediting' => { 341 => 0x32 }, + 'imageeffects' => { 373 => 0x1010 }, + 'imagefileconstraints' => { 293 => 'ImageFileConstraints' }, + 'imagefileformatasdelivered' => { 293 => 'ImageFileFormatAsDelivered' }, + 'imagefilesizeasdelivered' => { 293 => 'ImageFileSizeAsDelivered' }, + 'imagegeneration' => { 124 => 0x1436 }, + 'imageheight' => { 116 => 0x101, 183 => 0xc, 350 => 0x10d, 447 => 'ImageHeight', 484 => 'ImageLength' }, + 'imagehistory' => { 116 => 0x9213, 467 => 'ImageHistory' }, + 'imageidnumber' => { 301 => 0x340 }, + 'imagemimetype' => { 449 => 'Mime' }, + 'imagenumber' => { 116 => 0x9211, 152 => 'ImageNumber', 177 => 0xae, 178 => 0x5e, 350 => 0x113, 393 => 0x9b, 395 => [0x400,'276.1',0x314], 459 => 'ImageNumber' }, + 'imagenumber2' => { 178 => 0x62 }, + 'imageoptimization' => { 219 => 0xa9 }, + 'imageorientation' => { 128 => 0x83 }, + 'imageprocessing' => { 219 => 0x1a }, + 'imageprocessingfiledatecreated' => { 134 => 0xc81 }, + 'imageprocessingfiletagsversionnumber' => { 134 => 0xc80 }, + 'imageprocessingversion' => { 287 => 0x0 }, + 'imagequality' => { 152 => 'ImageQuality', 234 => '723.2', 235 => '732.2', 244 => '708.1', 306 => 0x1 }, + 'imagequality2' => { 283 => 0x603 }, + 'imagerank' => { 452 => 'ImageRank' }, + 'imagerbiassettlingdelaymsec' => { 134 => 0x600 }, + 'imagerboardversion' => { 134 => 0x439 }, + 'imagercols' => { 134 => 0x17d4 }, + 'imageref' => { 472 => 'ImageRef' }, + 'imageregion' => { 474 => 'ImageRegion' }, + 'imageregionboundary' => { 474 => [\'ImageRegion','ImageRegionRegionBoundary'] }, + 'imageregionboundaryh' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbH'] }, + 'imageregionboundaryrx' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbRx'] }, + 'imageregionboundaryshape' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbShape'] }, + 'imageregionboundaryunit' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbUnit'] }, + 'imageregionboundaryvertices' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbVertices'] }, + 'imageregionboundaryverticesx' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbVerticesRbX'] }, + 'imageregionboundaryverticesy' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbVerticesRbY'] }, + 'imageregionboundaryw' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbW'] }, + 'imageregionboundaryx' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbX'] }, + 'imageregionboundaryy' => { 474 => [\'ImageRegion','ImageRegionRegionBoundaryRbY'] }, + 'imageregionctype' => { 474 => [\'ImageRegion','ImageRegionRCtype'] }, + 'imageregionctypeidentifier' => { 474 => [\'ImageRegion','ImageRegionRCtypeIdentifier'] }, + 'imageregionctypename' => { 474 => [\'ImageRegion','ImageRegionRCtypeName'] }, + 'imageregionid' => { 474 => [\'ImageRegion','ImageRegionRId'] }, + 'imageregionname' => { 474 => [\'ImageRegion','ImageRegionName'] }, + 'imageregionrole' => { 474 => [\'ImageRegion','ImageRegionRRole'] }, + 'imageregionroleidentifier' => { 474 => [\'ImageRegion','ImageRegionRRoleIdentifier'] }, + 'imageregionrolename' => { 474 => [\'ImageRegion','ImageRegionRRoleName'] }, + 'imageresolution' => { 134 => 0x944 }, + 'imageresolutionjpg' => { 134 => 0x945 }, + 'imagereview' => { 268 => '0.4', 277 => '0.4' }, + 'imagereviewmonitorofftime' => { 267 => '21.1', 269 => '21.1', 270 => '21.1', 274 => '20.1', 279 => '21.1', 280 => '21.1' }, + 'imagereviewtime' => { 266 => '25.1', 268 => '2.1', 271 => '19.1', 272 => '20.1', 273 => '20.1', 275 => '9.2', 276 => '20.1', 281 => '21.2' }, + 'imagerfiledatecreated' => { 134 => 0x9c5 }, + 'imagerfileproductionlevel' => { 134 => 0x9c4 }, + 'imagerfiletagsversionstandard' => { 134 => 0x9c7 }, + 'imagerotated' => { 147 => 0x2a }, + 'imagerpowerondelaymsec' => { 134 => 0x5fd }, + 'imagerrows' => { 134 => 0x17de }, + 'imagesegmentlines' => { 134 => 0x184d }, + 'imagesegmentstartline' => { 134 => 0x184c }, + 'imagesize' => { 158 => 'ImageSize' }, + 'imagesizerestriction' => { 481 => 'imageSizeRestriction' }, + 'imagesourcedata' => { 116 => 0x935c }, + 'imagespace' => { 134 => 0x909 }, + 'imagestabilization' => { 34 => 0x22, 110 => 0x3020, 124 => 0x1422, 152 => 'ImageStabilization', 177 => 0xbd, 178 => 0x71, 179 => 0x57, 180 => 0x0, 181 => [0x18,0x107,0x113], 182 => 0x49c2, 219 => 0xac, 283 => 0x604, 286 => 0x1600, 306 => 0x1a, 398 => 0x12, 399 => 0x11, 406 => 0xb026 }, + 'imagestabilization2' => { 397 => 0xa }, + 'imagestabilizationsetting' => { 182 => 0x14, 393 => 0x3d, 394 => 0x3d, 404 => 0x14 }, + 'imagestyle' => { 393 => 0x2d, 394 => 0x27 }, + 'imagesupplier' => { 293 => 'ImageSupplier' }, + 'imagesupplierid' => { 293 => [\'ImageSupplier','ImageSupplierImageSupplierID'] }, + 'imagesupplierimageid' => { 293 => 'ImageSupplierImageID' }, + 'imagesuppliername' => { 293 => [\'ImageSupplier','ImageSupplierImageSupplierName'] }, + 'imagetemperaturemax' => { 118 => 0x1 }, + 'imagetemperaturemin' => { 118 => 0x2 }, + 'imagetone' => { 341 => 0x4f }, + 'imagetype' => { 128 => 0x82, 293 => 'ImageType' }, + 'imageuniqueid' => { 1 => 0x15, 61 => 0x28, 116 => 0xa420, 467 => 'ImageUniqueID', 468 => 'ImageUniqueID' }, + 'imagewidth' => { 116 => 0x100, 183 => 0xe, 350 => 0x10c, 447 => 'ImageWidth', 484 => 'ImageWidth' }, + 'inclinationangle' => { 439 => 0x900f }, + 'inclinationcorrection' => { 439 => 0x900e }, + 'incrementaltemperature' => { 462 => 'IncrementalTemperature', 464 => 'IncrementalTemperature' }, + 'incrementaltint' => { 462 => 'IncrementalTint', 464 => 'IncrementalTint' }, + 'industry' => { 478 => 'industry', 479 => 'industry' }, + 'infobuttonwhenshooting' => { 81 => 0x409 }, + 'information' => { 360 => 'information', 366 => "\xa9inf" }, + 'infourl' => { 366 => 'infu' }, + 'infraredilluminator' => { 367 => 0x28 }, + 'ingredientexclusion' => { 480 => 'ingredientExclusion' }, + 'ingredients' => { 489 => 'Ingredients' }, + 'ingredientsalternatepaths' => { 489 => [\'Ingredients','IngredientsAlternatePaths'] }, + 'ingredientsdocumentid' => { 489 => [\'Ingredients','IngredientsDocumentID'] }, + 'ingredientsfilepath' => { 489 => [\'Ingredients','IngredientsFilePath'] }, + 'ingredientsfrompart' => { 489 => [\'Ingredients','IngredientsFromPart'] }, + 'ingredientsinstanceid' => { 489 => [\'Ingredients','IngredientsInstanceID'] }, + 'ingredientslastmodifydate' => { 489 => [\'Ingredients','IngredientsLastModifyDate'] }, + 'ingredientslasturl' => { 489 => [\'Ingredients','IngredientsLastURL'] }, + 'ingredientslinkcategory' => { 489 => [\'Ingredients','IngredientsLinkCategory'] }, + 'ingredientslinkform' => { 489 => [\'Ingredients','IngredientsLinkForm'] }, + 'ingredientsmanager' => { 489 => [\'Ingredients','IngredientsManager'] }, + 'ingredientsmanagervariant' => { 489 => [\'Ingredients','IngredientsManagerVariant'] }, + 'ingredientsmanageto' => { 489 => [\'Ingredients','IngredientsManageTo'] }, + 'ingredientsmanageui' => { 489 => [\'Ingredients','IngredientsManageUI'] }, + 'ingredientsmaskmarkers' => { 489 => [\'Ingredients','IngredientsMaskMarkers'] }, + 'ingredientsoriginaldocumentid' => { 489 => [\'Ingredients','IngredientsOriginalDocumentID'] }, + 'ingredientspartmapping' => { 489 => [\'Ingredients','IngredientsPartMapping'] }, + 'ingredientsplacedresolutionunit' => { 489 => [\'Ingredients','IngredientsPlacedResolutionUnit'] }, + 'ingredientsplacedxresolution' => { 489 => [\'Ingredients','IngredientsPlacedXResolution'] }, + 'ingredientsplacedyresolution' => { 489 => [\'Ingredients','IngredientsPlacedYResolution'] }, + 'ingredientsrenditionclass' => { 489 => [\'Ingredients','IngredientsRenditionClass'] }, + 'ingredientsrenditionparams' => { 489 => [\'Ingredients','IngredientsRenditionParams'] }, + 'ingredientstopart' => { 489 => [\'Ingredients','IngredientsToPart'] }, + 'ingredientsversionid' => { 489 => [\'Ingredients','IngredientsVersionID'] }, + 'initialafpointaiservoaf' => { 81 => 0x51e }, 'initialafpointinservo' => { 2 => 0x13 }, - 'initialcameradolly' => { 429 => 'InitialCameraDolly' }, - 'initialhorizontalfovdegrees' => { 429 => 'InitialHorizontalFOVDegrees' }, - 'initialviewheadingdegrees' => { 429 => 'InitialViewHeadingDegrees', 430 => 'InitialViewHeadingDegrees' }, - 'initialviewpitchdegrees' => { 429 => 'InitialViewPitchDegrees', 430 => 'InitialViewPitchDegrees' }, - 'initialviewrolldegrees' => { 429 => 'InitialViewRollDegrees', 430 => 'InitialViewRollDegrees' }, - 'initialzoomliveview' => { 257 => '4.4' }, - 'initialzoomsetting' => { 257 => '9.3', 266 => '27.3' }, - 'inkset' => { 113 => 0x14c }, - 'inputprofile' => { 131 => 0x1389 }, - 'instanceid' => { 467 => 'InstanceID' }, - 'instantplaybacksetup' => { 174 => 0x3e }, - 'instantplaybacktime' => { 174 => 0x3d }, - 'instructions' => { 454 => 'Instructions' }, - 'instrument' => { 466 => 'instrument' }, - 'integrationtime' => { 131 => 0x423 }, - 'intellectualgenre' => { 451 => 'IntellectualGenre' }, - 'intelligentauto' => { 388 => 0xb052, 413 => 0xd, 414 => 0xe, 415 => 0xd }, - 'intelligentcontrast' => { 49 => 0x4 }, - 'intelligentd-range' => { 297 => 0x79 }, - 'intelligentexposure' => { 297 => 0x5d }, - 'intelligentresolution' => { 297 => 0x70 }, - 'interchangecolorspace' => { 127 => 0x40 }, - 'internalflash' => { 171 => 0x2b, 257 => '23.1', 259 => '8.1', 262 => '22.1', 264 => '23.1', 268 => '8.1', 272 => '24.1', 277 => 0x1208 }, - 'internalflashae1' => { 279 => 0x1021 }, - 'internalflashae1_0' => { 279 => 0x101d }, - 'internalflashae2' => { 279 => 0x1022 }, - 'internalflashae2_0' => { 279 => 0x101e }, - 'internalflashmode' => { 320 => 0x1 }, - 'internalflashstrength' => { 320 => 0x3 }, - 'internalflashtable' => { 279 => 0x1024 }, - 'internallensserialnumber' => { 365 => 0xa005 }, - 'internalndfilter' => { 297 => 0x9d }, - 'internalserialnumber' => { 60 => 0x96, 71 => 0x9, 121 => 0x10, 177 => 0x49dc, 273 => 0x18, 275 => 0x102, 294 => 0x500, 297 => 0x25, 312 => 0x4, 358 => 0x5, 406 => [0x7c,0xf0], 407 => 0x88 }, - 'interopindex' => { 113 => 0x1, 447 => 'InteroperabilityIndex' }, - 'interopversion' => { 113 => 0x2 }, - 'intervallength' => { 171 => 0x10 }, - 'intervalmode' => { 171 => 0x26 }, - 'intervalnumber' => { 171 => 0x11 }, - 'intervalshooting' => { 332 => 0x92 }, - 'introtime' => { 466 => 'introTime' }, - 'introtimescale' => { 466 => [\'introTime','introTimeScale'] }, - 'introtimevalue' => { 466 => [\'introTime','introTimeValue'] }, - 'ipaversion' => { 131 => 0xdae }, - 'ipfcameramodel' => { 131 => 0xe4d }, - 'iptc' => { 114 => 'IPTC' }, - 'iptc-naa' => { 113 => 0x83bb, 302 => 0x83bb }, - 'iptcbitspersample' => { 127 => 0x56 }, - 'iptcdigest' => { 346 => 0x425 }, - 'iptcimageheight' => { 127 => 0x1e }, - 'iptcimagerotation' => { 127 => 0x66 }, - 'iptcimagewidth' => { 127 => 0x14 }, - 'iptclastedited' => { 452 => 'IptcLastEdited' }, - 'iptcpicturenumber' => { 127 => 0xa }, - 'iptcpixelheight' => { 127 => 0x32 }, - 'iptcpixelwidth' => { 127 => 0x28 }, - 'isalternativeof' => { 456 => 'isAlternativeOf' }, - 'isbn' => { 456 => 'isbn' }, - 'iscorrectionof' => { 456 => 'isCorrectionOf' }, - 'iscustompicturestyle' => { 103 => 0x3 }, - 'ismergedhdr' => { 438 => 'IsMergedHDR' }, - 'ismergedpanorama' => { 438 => 'IsMergedPanorama' }, - 'iso' => { 6 => 0x6, 8 => 0x6, 9 => 0x75, 10 => 0x6, 11 => 0x79, 12 => 0x6, 13 => 0x6, 14 => 0x6, 15 => 0x6, 16 => 0x6, 17 => 0x6, 18 => 0x6, 19 => 0x6, 20 => 0x6, 21 => 0x6, 22 => 0x6, 23 => 0x6, 24 => 0x6, 25 => 0x6, 26 => 0x6, 27 => 0x6, 28 => 0x6, 29 => 0x0, 30 => 0x1, 106 => 0x14, 107 => [0x3014,0x14], 113 => 0x8827, 130 => 0xfd06, 131 => 0x1784, 133 => 0x60, 135 => [0xfa2e,0xfa46], 136 => [0x27,0x28], 137 => 0xf105, 140 => 0x14, 142 => 0x4e, 145 => 0x34, 147 => 'ISO', 171 => 0x8, 177 => 0x49ba, 205 => 0x0, 211 => 0x2, 302 => 0x17, 332 => [0x8b,0x14], 339 => 0x14, 341 => 0x105, 365 => 0xa014, 387 => 0x6f, 393 => [0x1f,0x21,0x25], 446 => 'ISOSpeedRatings' }, - 'iso2' => { 205 => 0x6, 220 => 0x265, 221 => 0x25c, 222 => 0x265, 223 => 0x221, 224 => 0x25d, 225 => 0x256, 226 => 0x25d, 230 => 0x2b5, 233 => 0x265, 239 => 0x2b5 }, - 'isoauto' => { 313 => '14.4' }, - 'isoautohilimit' => { 228 => 0x18eb, 229 => 0xe82, 237 => 0x185d }, - 'isoautoparameters' => { 332 => 0x7a }, - 'isoautoshuttertime' => { 228 => 0x18ea, 229 => 0xe81, 237 => 0x185c }, - 'isocalibrationgain' => { 131 => 0x89f }, - 'isodisplay' => { 260 => '4.1', 261 => '4.1', 262 => '2.3', 263 => '3.3', 264 => '3.3', 267 => '3.3', 270 => '4.3', 271 => '4.1', 272 => '4.3' }, - 'isoexpansion' => { 78 => 0x103, 79 => 0x7, 80 => 0x8, 83 => 0x8, 205 => 0x4 }, - 'isoexpansion2' => { 205 => 0xa }, - 'isofloor' => { 313 => 0x6 }, - 'isoselection' => { 211 => 0xf }, - 'isosensitivitystep' => { 265 => '6.2', 267 => '6.2' }, - 'isosetting' => { 133 => 0x5e, 147 => 'ISOSetting', 171 => 0x24, 172 => 0x26, 173 => 0x1c, 174 => 0x13, 179 => 0x6, 211 => 0x13, 313 => '17.3', 357 => 0x27, 376 => 0x16, 377 => 0x14, 378 => 0x2, 387 => 0x6d }, - 'isospeed' => { 113 => 0x8833, 447 => 'ISOSpeed' }, - 'isospeedexpansion' => { 77 => 0x3 }, - 'isospeedincrements' => { 78 => 0x102 }, - 'isospeedlatitudeyyy' => { 113 => 0x8834, 447 => 'ISOSpeedLatitudeyyy' }, - 'isospeedlatitudezzz' => { 113 => 0x8835, 447 => 'ISOSpeedLatitudezzz' }, - 'isospeedrange' => { 78 => 0x103 }, - 'isostepsize' => { 257 => '6.1', 258 => '7.2', 260 => '7.2', 261 => '7.2', 266 => '4.1', 270 => '7.2', 271 => '7.2' }, - 'isovalue' => { 279 => 0x1001 }, - 'issn' => { 456 => 'issn' }, - 'issueidentifier' => { 456 => 'issueIdentifier' }, - 'issuename' => { 456 => 'issueName' }, - 'issueteaser' => { 456 => 'issueTeaser' }, - 'issuetype' => { 456 => 'issueType' }, - 'istranslationof' => { 456 => 'isTranslationOf' }, - 'itemsubtype' => { 169 => 'ItemSubType' }, - 'jobid' => { 125 => 0xb8 }, - 'jobname' => { 448 => 'JobName' }, - 'jobref' => { 465 => 'JobRef' }, - 'jobrefid' => { 465 => [\'JobRef','JobRefId'] }, - 'jobrefname' => { 465 => [\'JobRef','JobRefName'] }, - 'jobrefurl' => { 465 => [\'JobRef','JobRefUrl'] }, - 'jobstatus' => { 448 => 'JobStatus' }, - 'jpeghandling' => { 442 => 'JPEGHandling' }, - 'jpegquality' => { 9 => 0x66, 297 => 0x43, 299 => 0x3034, 388 => 0xb047 }, - 'jpegsize' => { 299 => 0x303a }, - 'jpgcompression' => { 229 => 0x7d4 }, - 'jpgfromraw' => { 91 => 0x2007, 108 => 'JpgFromRaw', 302 => 0x2e }, - 'jpgfromrawlength' => { 113 => [0x117,0x202] }, - 'jpgfromrawstart' => { 113 => [0x111,0x201] }, - 'jpgrecordedpixels' => { 313 => '14.1' }, - 'jurisdiction' => { 439 => 'jurisdiction' }, - 'kelvinwb_01' => { 321 => 0x5 }, - 'kelvinwb_02' => { 321 => 0x9 }, - 'kelvinwb_03' => { 321 => 0xd }, - 'kelvinwb_04' => { 321 => 0x11 }, - 'kelvinwb_05' => { 321 => 0x15 }, - 'kelvinwb_06' => { 321 => 0x19 }, - 'kelvinwb_07' => { 321 => 0x1d }, - 'kelvinwb_08' => { 321 => 0x21 }, - 'kelvinwb_09' => { 321 => 0x25 }, - 'kelvinwb_10' => { 321 => 0x29 }, - 'kelvinwb_11' => { 321 => 0x2d }, - 'kelvinwb_12' => { 321 => 0x31 }, - 'kelvinwb_13' => { 321 => 0x35 }, - 'kelvinwb_14' => { 321 => 0x39 }, - 'kelvinwb_15' => { 321 => 0x3d }, - 'kelvinwb_16' => { 321 => 0x41 }, - 'kelvinwb_daylight' => { 321 => 0x1 }, - 'kerneldenominators' => { 131 => 0x933 }, - 'key' => { 466 => 'key' }, - 'keystonecompensation' => { 278 => 0x1900 }, - 'keystonedirection' => { 278 => 0x1901 }, - 'keystonevalue' => { 278 => 0x1906 }, - 'keyword' => { 456 => 'keyword' }, - 'keywordinfo' => { 162 => 'Keywords' }, - 'keywords' => { 125 => 0x19, 148 => 'Keywords', 283 => 'Keywords', 348 => 'Keywords', 436 => 'keywords', 453 => 'Keywords', 464 => 'Keywords' }, - 'killdate' => { 456 => 'killDate' }, - 'killdatea-platform' => { 456 => [\'killDate','killDateA-platform'] }, - 'killdatedate' => { 456 => [\'killDate','killDateDate'] }, - 'kodakimageheight' => { 130 => 0xf908, 133 => 0xe, 135 => [0xfa1e,0xfa52], 141 => 0x70 }, - 'kodakimagewidth' => { 130 => 0xf907, 133 => 0xc, 135 => [0xfa1d,0xfa51], 141 => 0x6c }, - 'kodakinfotype' => { 130 => 0xfa00 }, - 'kodaklook' => { 131 => 0xe4c }, - 'kodaklookprofile' => { 131 => 0x138a }, - 'kodakmaker' => { 141 => 0x8 }, - 'kodakmodel' => { 133 => 0x0, 141 => 0x28 }, - 'kodaktag' => { 131 => 0x3ea }, - 'kodakversion' => { 131 => 0x0 }, - 'label' => { 287 => 'Label', 464 => 'Label' }, - 'labelname1' => { 450 => [\'TagStructure','TagStructureLabelName'] }, - 'labelname2' => { 450 => [\'TagStructure','TagStructureSubLabelsLabelName'] }, - 'labelname3' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsLabelName'] }, - 'labelname4' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsLabelName'] }, - 'labelname5' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName'] }, - 'labelname6' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName'] }, - 'landmark' => { 297 => 0x6f }, - 'landscapeoutputhighlightpoint' => { 103 => 0x26 }, - 'landscapeoutputshadowpoint' => { 103 => 0x27 }, - 'landscaperawcolortone' => { 103 => 0x1f }, - 'landscaperawcontrast' => { 103 => 0x21 }, - 'landscaperawhighlight' => { 103 => 0x77 }, - 'landscaperawhighlightpoint' => { 103 => 0x24 }, - 'landscaperawlinear' => { 103 => 0x22 }, - 'landscaperawsaturation' => { 103 => 0x20 }, - 'landscaperawshadow' => { 103 => 0x80 }, - 'landscaperawshadowpoint' => { 103 => 0x25 }, - 'landscaperawsharpness' => { 103 => 0x23 }, - 'landscapeunsharpmaskfineness' => { 103 => 0xa0 }, - 'landscapeunsharpmaskstrength' => { 103 => 0x9e }, - 'landscapeunsharpmaskthreshold' => { 103 => 0xa2 }, - 'language' => { 443 => 'language' }, - 'languageidentifier' => { 125 => 0x87 }, - 'largestvalidinteriorrectheight' => { 429 => 'LargestValidInteriorRectHeight' }, - 'largestvalidinteriorrectleft' => { 429 => 'LargestValidInteriorRectLeft' }, - 'largestvalidinteriorrecttop' => { 429 => 'LargestValidInteriorRectTop' }, - 'largestvalidinteriorrectwidth' => { 429 => 'LargestValidInteriorRectWidth' }, - 'lastfilenumber' => { 171 => 0x1b }, - 'lastkeywordiptc' => { 169 => 'LastKeywordIPTC' }, - 'lastkeywordxmp' => { 169 => 'LastKeywordXMP' }, - 'lastphotodate' => { 429 => 'LastPhotoDate' }, - 'lasturl' => { 467 => 'LastURL' }, - 'lateralchromaticaberration' => { 388 => 0x2012 }, - 'lateralchromaticaberrationcorrectionalreadyapplied' => { 438 => 'LateralChromaticAberrationCorrectionAlreadyApplied' }, - 'latestageorhigheststage' => { 112 => [\'GeologicalContext','GeologicalContextLatestAgeOrHighestStage'] }, - 'latesteonorhighesteonothem' => { 112 => [\'GeologicalContext','GeologicalContextLatestEonOrHighestEonothem'] }, - 'latestepochorhighestseries' => { 112 => [\'GeologicalContext','GeologicalContextLatestEpochOrHighestSeries'] }, - 'latesteraorhighesterathem' => { 112 => [\'GeologicalContext','GeologicalContextLatestEraOrHighestErathem'] }, - 'latestperiodorhighestsystem' => { 112 => [\'GeologicalContext','GeologicalContextLatestPeriodOrHighestSystem'] }, - 'lc1' => { 323 => 0x2 }, - 'lc10' => { 323 => 0xb }, - 'lc11' => { 323 => 0xc }, - 'lc12' => { 323 => 0xd }, - 'lc14' => { 323 => 0xf }, - 'lc15' => { 323 => 0x10 }, - 'lc3' => { 323 => 0x4 }, - 'lc4' => { 323 => 0x5 }, - 'lc5' => { 323 => 0x6 }, - 'lc6' => { 323 => 0x7 }, - 'lc7' => { 323 => 0x8 }, - 'lc8' => { 323 => 0x9 }, - 'lcddisplayatpoweron' => { 78 => 0x811, 82 => 0xa }, - 'lcddisplayreturntoshoot' => { 83 => 0x12 }, - 'lcdillumination' => { 257 => '17.5', 258 => '5.2', 260 => '5.1', 261 => '5.1', 266 => '10.3', 267 => '4.2', 270 => '5.2', 271 => '5.1', 272 => '5.4' }, - 'lcdilluminationduringbulb' => { 78 => 0x408 }, - 'lcdmatrix' => { 131 => 0xe74 }, - 'lcdmatrixchickfix' => { 131 => 0xe75 }, - 'lcdmatrixmarvin' => { 131 => 0xe76 }, - 'lcdpanels' => { 77 => 0x8 }, - 'lcheditor' => { 250 => 0x8ae85e }, - 'legacyiptcdigest' => { 454 => 'LegacyIPTCDigest' }, - 'legalcode' => { 439 => 'legalcode' }, - 'lens' => { 113 => 0xfdea, 211 => 0x84, 438 => 'Lens' }, - 'lensafstopbutton' => { 76 => 0x11, 77 => 0x13, 78 => 0x506, 79 => 0x10, 80 => 0x12, 83 => 0x13, 84 => 0x9 }, - 'lensaperturerange' => { 368 => [0x30,0x48] }, - 'lenscorrectionsettings' => { 445 => 'LensCorrectionSettings' }, - 'lensdistortinfo' => { 438 => 'LensDistortInfo' }, - 'lensdistortionparams' => { 279 => 0x206 }, - 'lensdrivenoaf' => { 78 => 0x505 }, + 'initialcameradolly' => { 450 => 'InitialCameraDolly' }, + 'initialhorizontalfovdegrees' => { 450 => 'InitialHorizontalFOVDegrees' }, + 'initialviewheadingdegrees' => { 450 => 'InitialViewHeadingDegrees', 451 => 'InitialViewHeadingDegrees' }, + 'initialviewpitchdegrees' => { 450 => 'InitialViewPitchDegrees', 451 => 'InitialViewPitchDegrees' }, + 'initialviewrolldegrees' => { 450 => 'InitialViewRollDegrees', 451 => 'InitialViewRollDegrees' }, + 'initialzoomliveview' => { 266 => '4.4' }, + 'initialzoomsetting' => { 266 => '9.3', 275 => '27.3' }, + 'inkset' => { 116 => 0x14c }, + 'inputprofile' => { 134 => 0x1389 }, + 'instanceid' => { 489 => 'InstanceID' }, + 'instantplaybacksetup' => { 179 => 0x3e }, + 'instantplaybacktime' => { 179 => 0x3d }, + 'instructions' => { 476 => 'Instructions' }, + 'instrument' => { 488 => 'instrument' }, + 'integrationtime' => { 134 => 0x423 }, + 'intellectualgenre' => { 473 => 'IntellectualGenre' }, + 'intelligentauto' => { 406 => 0xb052, 431 => 0xd, 432 => 0xe, 433 => 0xd }, + 'intelligentcontrast' => { 50 => 0x4 }, + 'intelligentd-range' => { 306 => 0x79 }, + 'intelligentexposure' => { 306 => 0x5d }, + 'intelligentresolution' => { 306 => 0x70 }, + 'interchangecolorspace' => { 130 => 0x40 }, + 'intergraphmatrix' => { 116 => 0x8480 }, + 'internalflash' => { 176 => 0x2b, 266 => '23.1', 268 => '8.1', 271 => '22.1', 273 => '23.1', 277 => '8.1', 281 => '24.1', 286 => 0x1208 }, + 'internalflashae1' => { 288 => 0x1021 }, + 'internalflashae1_0' => { 288 => 0x101d }, + 'internalflashae2' => { 288 => 0x1022 }, + 'internalflashae2_0' => { 288 => 0x101e }, + 'internalflashmode' => { 329 => 0x1 }, + 'internalflashstrength' => { 329 => 0x3 }, + 'internalflashtable' => { 288 => 0x1024 }, + 'internallensserialnumber' => { 380 => 0xa005 }, + 'internalndfilter' => { 306 => 0x9d }, + 'internalserialnumber' => { 61 => 0x96, 73 => 0x9, 124 => 0x10, 182 => 0x49dc, 282 => 0x18, 284 => 0x102, 303 => 0x500, 306 => 0x25, 321 => 0x4, 373 => 0x5, 424 => [0x7c,0xf0], 425 => 0x88 }, + 'interopindex' => { 116 => 0x1, 469 => 'InteroperabilityIndex' }, + 'interopversion' => { 116 => 0x2 }, + 'intervallength' => { 176 => 0x10 }, + 'intervalmode' => { 176 => 0x26 }, + 'intervalnumber' => { 176 => 0x11 }, + 'intervalshooting' => { 341 => 0x92 }, + 'introtime' => { 488 => 'introTime' }, + 'introtimescale' => { 488 => [\'introTime','introTimeScale'] }, + 'introtimevalue' => { 488 => [\'introTime','introTimeValue'] }, + 'ipaversion' => { 134 => 0xdae }, + 'ipfcameramodel' => { 134 => 0xe4d }, + 'iptc' => { 117 => 'IPTC' }, + 'iptc-naa' => { 116 => 0x83bb, 311 => 0x83bb }, + 'iptcbitspersample' => { 130 => 0x56 }, + 'iptcdigest' => { 355 => 0x425 }, + 'iptcimageheight' => { 130 => 0x1e }, + 'iptcimagerotation' => { 130 => 0x66 }, + 'iptcimagewidth' => { 130 => 0x14 }, + 'iptclastedited' => { 474 => 'IptcLastEdited' }, + 'iptcpicturenumber' => { 130 => 0xa }, + 'iptcpixelheight' => { 130 => 0x32 }, + 'iptcpixelwidth' => { 130 => 0x28 }, + 'isalternativeof' => { 478 => 'isAlternativeOf' }, + 'isbn' => { 478 => 'isbn' }, + 'iscorrectionof' => { 478 => 'isCorrectionOf' }, + 'iscustompicturestyle' => { 106 => 0x3 }, + 'ismergedhdr' => { 459 => 'IsMergedHDR' }, + 'ismergedpanorama' => { 459 => 'IsMergedPanorama' }, + 'iso' => { 7 => 0x6, 9 => 0x6, 10 => 0x75, 11 => 0x6, 12 => 0x79, 13 => 0x6, 14 => 0x6, 15 => 0x6, 16 => 0x6, 17 => 0x6, 18 => 0x6, 19 => 0x6, 20 => 0x6, 21 => 0x6, 22 => 0x6, 23 => 0x6, 24 => 0x6, 25 => 0x6, 26 => 0x6, 27 => 0x6, 28 => 0x6, 29 => 0x6, 30 => 0x0, 31 => 0x1, 109 => 0x14, 110 => [0x3014,0x14], 116 => 0x8827, 133 => 0xfd06, 134 => 0x1784, 136 => 0x60, 138 => [0xfa2e,0xfa46], 139 => [0x27,0x28], 140 => 0xf105, 143 => 0x14, 145 => 0x4e, 147 => 0x1e, 148 => 0x1a, 150 => 0x34, 152 => 'ISO', 176 => 0x8, 182 => 0x49ba, 210 => 0x0, 219 => 0x2, 306 => 0xd1, 311 => 0x17, 341 => [0x8b,0x14], 348 => 0x14, 350 => 0x105, 380 => 0xa014, 383 => 0x86, 404 => 0x6f, 411 => [0x1f,0x21,0x25], 468 => 'ISOSpeedRatings' }, + 'iso2' => { 210 => 0x6, 229 => 0x265, 230 => 0x25c, 231 => 0x265, 232 => 0x221, 233 => 0x25d, 234 => 0x256, 235 => 0x25d, 239 => 0x2b5, 242 => 0x265, 248 => 0x2b5 }, + 'isoauto' => { 322 => '14.4' }, + 'isoautohilimit' => { 237 => 0x18eb, 238 => 0xe82, 246 => 0x185d }, + 'isoautomax' => { 405 => 0x4 }, + 'isoautomin' => { 405 => 0x2 }, + 'isoautoparameters' => { 341 => 0x7a }, + 'isoautoshuttertime' => { 237 => 0x18ea, 238 => 0xe81, 246 => 0x185c }, + 'isocalibrationgain' => { 134 => 0x89f }, + 'isodisplay' => { 269 => '4.1', 270 => '4.1', 271 => '2.3', 272 => '3.3', 273 => '3.3', 276 => '3.3', 279 => '4.3', 280 => '4.1', 281 => '4.3' }, + 'isoexpansion' => { 81 => 0x103, 82 => 0x7, 83 => 0x8, 86 => 0x8, 210 => 0x4 }, + 'isoexpansion2' => { 210 => 0xa }, + 'isofloor' => { 322 => 0x6 }, + 'isoselected' => { 305 => 0x359 }, + 'isoselection' => { 219 => 0xf }, + 'isosensitivitystep' => { 274 => '6.2', 276 => '6.2' }, + 'isosetting' => { 136 => 0x5e, 148 => 0x14, 152 => 'ISOSetting', 176 => 0x24, 177 => 0x26, 178 => 0x1c, 179 => 0x13, 184 => 0x6, 219 => 0x13, 322 => '17.3', 372 => 0x27, 393 => 0x16, 394 => 0x14, 395 => 0x2, 404 => 0x6d, 405 => 0x0 }, + 'isospeed' => { 116 => 0x8833, 469 => 'ISOSpeed' }, + 'isospeedexpansion' => { 80 => 0x3 }, + 'isospeedincrements' => { 81 => 0x102 }, + 'isospeedlatitudeyyy' => { 116 => 0x8834, 469 => 'ISOSpeedLatitudeyyy' }, + 'isospeedlatitudezzz' => { 116 => 0x8835, 469 => 'ISOSpeedLatitudezzz' }, + 'isospeedrange' => { 81 => 0x103 }, + 'isostepsize' => { 266 => '6.1', 267 => '7.2', 269 => '7.2', 270 => '7.2', 275 => '4.1', 279 => '7.2', 280 => '7.2' }, + 'isovalue' => { 288 => 0x1001 }, + 'isrccode' => { 366 => "\xa9isr" }, + 'issn' => { 478 => 'issn' }, + 'issueidentifier' => { 478 => 'issueIdentifier' }, + 'issuename' => { 478 => 'issueName' }, + 'issueteaser' => { 478 => 'issueTeaser' }, + 'issuetype' => { 478 => 'issueType' }, + 'istranslationof' => { 478 => 'isTranslationOf' }, + 'itemsubtype' => { 174 => 'ItemSubType' }, + 'itunesu' => { 358 => 'itnu' }, + 'jobid' => { 128 => 0xb8 }, + 'jobname' => { 470 => 'JobName' }, + 'jobref' => { 487 => 'JobRef' }, + 'jobrefid' => { 487 => [\'JobRef','JobRefId'] }, + 'jobrefname' => { 487 => [\'JobRef','JobRefName'] }, + 'jobrefurl' => { 487 => [\'JobRef','JobRefUrl'] }, + 'jobstatus' => { 470 => 'JobStatus' }, + 'jpeghandling' => { 462 => 'JPEGHandling', 464 => 'JPEGHandling' }, + 'jpegquality' => { 10 => 0x66, 306 => 0x43, 308 => 0x3034, 406 => 0xb047 }, + 'jpegsize' => { 308 => 0x303a }, + 'jpgcompression' => { 238 => 0x7d4 }, + 'jpgfromraw' => { 94 => 0x2007, 111 => 'Exif::JpgFromRaw', 311 => 0x2e }, + 'jpgfromrawlength' => { 116 => [0x117,0x202] }, + 'jpgfromrawstart' => { 116 => [0x111,0x201] }, + 'jpgrecordedpixels' => { 322 => '14.1' }, + 'jurisdiction' => { 460 => 'jurisdiction' }, + 'kelvinwb_01' => { 330 => 0x5 }, + 'kelvinwb_02' => { 330 => 0x9 }, + 'kelvinwb_03' => { 330 => 0xd }, + 'kelvinwb_04' => { 330 => 0x11 }, + 'kelvinwb_05' => { 330 => 0x15 }, + 'kelvinwb_06' => { 330 => 0x19 }, + 'kelvinwb_07' => { 330 => 0x1d }, + 'kelvinwb_08' => { 330 => 0x21 }, + 'kelvinwb_09' => { 330 => 0x25 }, + 'kelvinwb_10' => { 330 => 0x29 }, + 'kelvinwb_11' => { 330 => 0x2d }, + 'kelvinwb_12' => { 330 => 0x31 }, + 'kelvinwb_13' => { 330 => 0x35 }, + 'kelvinwb_14' => { 330 => 0x39 }, + 'kelvinwb_15' => { 330 => 0x3d }, + 'kelvinwb_16' => { 330 => 0x41 }, + 'kelvinwb_daylight' => { 330 => 0x1 }, + 'kerneldenominators' => { 134 => 0x933 }, + 'key' => { 488 => 'key' }, + 'keystonecompensation' => { 287 => 0x1900 }, + 'keystonedirection' => { 287 => 0x1901 }, + 'keystonevalue' => { 287 => 0x1906 }, + 'keyword' => { 358 => 'keyw', 478 => 'keyword' }, + 'keywordinfo' => { 167 => 'Keywords' }, + 'keywords' => { 128 => 0x19, 153 => 'Keywords', 292 => 'Keywords', 357 => 'Keywords', 360 => 'keywords', 457 => 'keywords', 475 => 'Keywords', 486 => 'Keywords' }, + 'killdate' => { 478 => 'killDate' }, + 'killdatea-platform' => { 478 => [\'killDate','killDateA-platform'] }, + 'killdatedate' => { 478 => [\'killDate','killDateDate'] }, + 'kodakimageheight' => { 133 => 0xf908, 136 => 0xe, 138 => [0xfa1e,0xfa52], 144 => 0x70 }, + 'kodakimagewidth' => { 133 => 0xf907, 136 => 0xc, 138 => [0xfa1d,0xfa51], 144 => 0x6c }, + 'kodakinfotype' => { 133 => 0xfa00 }, + 'kodaklook' => { 134 => 0xe4c }, + 'kodaklookprofile' => { 134 => 0x138a }, + 'kodakmaker' => { 144 => 0x8 }, + 'kodakmodel' => { 136 => 0x0, 144 => 0x28 }, + 'kodaktag' => { 134 => 0x3ea }, + 'kodakversion' => { 134 => 0x0 }, + 'label' => { 296 => 'Label', 486 => 'Label' }, + 'labelname1' => { 472 => [\'TagStructure','TagStructureLabelName'] }, + 'labelname2' => { 472 => [\'TagStructure','TagStructureSubLabelsLabelName'] }, + 'labelname3' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsLabelName'] }, + 'labelname4' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsLabelName'] }, + 'labelname5' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName'] }, + 'labelname6' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName'] }, + 'landmark' => { 306 => 0x6f }, + 'landscapeoutputhighlightpoint' => { 106 => 0x26 }, + 'landscapeoutputshadowpoint' => { 106 => 0x27 }, + 'landscaperawcolortone' => { 106 => 0x1f }, + 'landscaperawcontrast' => { 106 => 0x21 }, + 'landscaperawhighlight' => { 106 => 0x77 }, + 'landscaperawhighlightpoint' => { 106 => 0x24 }, + 'landscaperawlinear' => { 106 => 0x22 }, + 'landscaperawsaturation' => { 106 => 0x20 }, + 'landscaperawshadow' => { 106 => 0x80 }, + 'landscaperawshadowpoint' => { 106 => 0x25 }, + 'landscaperawsharpness' => { 106 => 0x23 }, + 'landscapeunsharpmaskfineness' => { 106 => 0xa0 }, + 'landscapeunsharpmaskstrength' => { 106 => 0x9e }, + 'landscapeunsharpmaskthreshold' => { 106 => 0xa2 }, + 'language' => { 465 => 'language' }, + 'languageidentifier' => { 128 => 0x87 }, + 'largestvalidinteriorrectheight' => { 450 => 'LargestValidInteriorRectHeight' }, + 'largestvalidinteriorrectleft' => { 450 => 'LargestValidInteriorRectLeft' }, + 'largestvalidinteriorrecttop' => { 450 => 'LargestValidInteriorRectTop' }, + 'largestvalidinteriorrectwidth' => { 450 => 'LargestValidInteriorRectWidth' }, + 'lastfilenumber' => { 176 => 0x1b }, + 'lastkeywordiptc' => { 174 => 'LastKeywordIPTC' }, + 'lastkeywordxmp' => { 174 => 'LastKeywordXMP' }, + 'lastphotodate' => { 450 => 'LastPhotoDate' }, + 'lasturl' => { 489 => 'LastURL' }, + 'lateralchromaticaberration' => { 406 => 0x2012 }, + 'lateralchromaticaberrationcorrectionalreadyapplied' => { 459 => 'LateralChromaticAberrationCorrectionAlreadyApplied' }, + 'latestageorhigheststage' => { 115 => [\'GeologicalContext','GeologicalContextLatestAgeOrHighestStage'] }, + 'latesteonorhighesteonothem' => { 115 => [\'GeologicalContext','GeologicalContextLatestEonOrHighestEonothem'] }, + 'latestepochorhighestseries' => { 115 => [\'GeologicalContext','GeologicalContextLatestEpochOrHighestSeries'] }, + 'latesteraorhighesterathem' => { 115 => [\'GeologicalContext','GeologicalContextLatestEraOrHighestErathem'] }, + 'latestperiodorhighestsystem' => { 115 => [\'GeologicalContext','GeologicalContextLatestPeriodOrHighestSystem'] }, + 'latitude' => { 113 => 'Latitude' }, + 'lc1' => { 332 => 0x2 }, + 'lc10' => { 332 => 0xb }, + 'lc11' => { 332 => 0xc }, + 'lc12' => { 332 => 0xd }, + 'lc14' => { 332 => 0xf }, + 'lc15' => { 332 => 0x10 }, + 'lc3' => { 332 => 0x4 }, + 'lc4' => { 332 => 0x5 }, + 'lc5' => { 332 => 0x6 }, + 'lc6' => { 332 => 0x7 }, + 'lc7' => { 332 => 0x8 }, + 'lc8' => { 332 => 0x9 }, + 'lcddisplayatpoweron' => { 81 => 0x811, 85 => 0xa }, + 'lcddisplayreturntoshoot' => { 86 => 0x12 }, + 'lcdillumination' => { 266 => '17.5', 267 => '5.2', 269 => '5.1', 270 => '5.1', 275 => '10.3', 276 => '4.2', 279 => '5.2', 280 => '5.1', 281 => '5.4' }, + 'lcdilluminationduringbulb' => { 81 => 0x408 }, + 'lcdmatrix' => { 134 => 0xe74 }, + 'lcdmatrixchickfix' => { 134 => 0xe75 }, + 'lcdmatrixmarvin' => { 134 => 0xe76 }, + 'lcdpanels' => { 80 => 0x8 }, + 'lcheditor' => { 259 => 0x8ae85e }, + 'legacyiptcdigest' => { 476 => 'LegacyIPTCDigest' }, + 'legalcode' => { 460 => 'legalcode' }, + 'lens' => { 116 => 0xfdea, 219 => 0x84, 459 => 'Lens' }, + 'lensafstopbutton' => { 79 => 0x11, 80 => 0x13, 81 => 0x506, 82 => 0x10, 83 => 0x12, 86 => 0x13, 87 => 0x9 }, + 'lensaperturerange' => { 383 => [0x30,0x48] }, + 'lenscorrectionsettings' => { 467 => 'LensCorrectionSettings' }, + 'lensdistortinfo' => { 459 => 'LensDistortInfo' }, + 'lensdistortionparams' => { 288 => 0x206 }, + 'lensdrivenoaf' => { 81 => 0x505 }, 'lensdrivewhenafimpossible' => { 2 => 0xb }, - 'lense-mountversion' => { 378 => 0x3f0, 420 => 0xd }, - 'lensfirmware' => { 359 => 0x20, 365 => 0xa004 }, - 'lensfirmwareversion' => { 275 => 0x204, 297 => 0x60, 378 => 0x3f3, 420 => 0x14 }, - 'lensfocallength' => { 97 => 0xf0512, 323 => 0x9 }, - 'lensfocalrange' => { 368 => [0xa,0x2a] }, - 'lensfocusfunctionbuttons' => { 258 => '55.1', 260 => '52.1', 261 => '52.1', 270 => '52.1', 271 => '52.1' }, - 'lensformat' => { 400 => 0x1891, 402 => 0x18bd, 403 => 0x18ed, 404 => 0x17f1, 406 => 0x106, 407 => 0x106, 416 => 0x603, 417 => 0x5d }, - 'lensfstops' => { 206 => 0x7, 207 => 0xc, 208 => 0xd, 211 => 0x8b, 323 => '0.3' }, - 'lensid' => { 438 => 'LensID' }, - 'lensidnumber' => { 206 => 0x6, 207 => 0xb, 208 => 0xc }, - 'lensinfo' => { 113 => 0xa432, 329 => 0x2a, 438 => 'LensInfo', 447 => 'LensSpecification' }, - 'lenskind' => { 323 => 0x1 }, - 'lensmake' => { 113 => 0xa433, 154 => 'Make', 447 => 'LensMake' }, - 'lensmanualdistortionamount' => { 442 => 'LensManualDistortionAmount' }, - 'lensmanufacturer' => { 169 => 'LensManufacturer' }, - 'lensmaxaperturerange' => { 368 => 0x2b }, - 'lensmodel' => { 6 => 0x937, 13 => 0x92b, 14 => 0x933, 60 => 0x95, 113 => 0xa434, 154 => 'Model', 169 => 'LensModel', 209 => 0x18a, 275 => 0x203, 329 => 0xc, 341 => 0x412, 447 => 'LensModel' }, - 'lensmodulationoptimizer' => { 121 => 0x1045 }, - 'lensmount' => { 378 => 0x99, 400 => 0x1892, 402 => 0x18be, 403 => 0x18ee, 404 => 0x17f2, 406 => 0x105, 407 => 0x105, 416 => 0x604, 417 => 0x5e }, - 'lensmount2' => { 420 => 0x8 }, - 'lensprofilechromaticaberrationscale' => { 442 => 'LensProfileChromaticAberrationScale' }, - 'lensprofiledigest' => { 442 => 'LensProfileDigest' }, - 'lensprofiledistortionscale' => { 442 => 'LensProfileDistortionScale' }, - 'lensprofileenable' => { 442 => 'LensProfileEnable' }, - 'lensprofilefilename' => { 442 => 'LensProfileFilename' }, - 'lensprofilematchkeycameramodelname' => { 442 => 'LensProfileMatchKeyCameraModelName' }, - 'lensprofilematchkeyexifmake' => { 442 => 'LensProfileMatchKeyExifMake' }, - 'lensprofilematchkeyexifmodel' => { 442 => 'LensProfileMatchKeyExifModel' }, - 'lensprofilematchkeyisraw' => { 442 => 'LensProfileMatchKeyIsRaw' }, - 'lensprofilematchkeylensid' => { 442 => 'LensProfileMatchKeyLensID' }, - 'lensprofilematchkeylensinfo' => { 442 => 'LensProfileMatchKeyLensInfo' }, - 'lensprofilematchkeylensname' => { 442 => 'LensProfileMatchKeyLensName' }, - 'lensprofilematchkeysensorformatfactor' => { 442 => 'LensProfileMatchKeySensorFormatFactor' }, - 'lensprofilename' => { 442 => 'LensProfileName' }, - 'lensprofilesetup' => { 442 => 'LensProfileSetup' }, - 'lensprofilevignettingscale' => { 442 => 'LensProfileVignettingScale' }, - 'lensproperties' => { 275 => 0x20b }, - 'lensserialnumber' => { 20 => 0x164, 31 => 0x16b, 58 => 0x0, 113 => 0xa435, 154 => 'SerialNumber', 275 => 0x202, 295 => 0x321, 297 => 0x52, 359 => 0x30, 438 => 'LensSerialNumber', 447 => 'LensSerialNumber' }, - 'lensshutterlock' => { 174 => 0x4a }, - 'lensspec' => { 373 => 0x0, 374 => 0x0, 375 => 0x0, 388 => 0xb02a }, - 'lensspecfeatures' => { 406 => [0x115,0x116], 407 => [0x116,0x21c,0x21e] }, - 'lenstemperature' => { 279 => 0x1008 }, - 'lenstype' => { 6 => 0xe2, 7 => 0xd, 8 => 0x1a7, 9 => 0xc, 10 => 0x111, 11 => 0xc, 12 => 0x14f, 13 => 0xd6, 14 => 0xde, 15 => 0xf6, 16 => 0xea, 17 => 0xff, 18 => [0xc,0x97], 19 => 0xe6, 20 => 0x153, 21 => 0xea, 22 => 0xe8, 23 => 0x127, 24 => 0x161, 25 => 0x166, 26 => 0x184, 27 => 0x112, 28 => 0x189, 33 => 0x16, 176 => 0x10c, 177 => 0x49bd, 211 => 0x83, 275 => 0x201, 288 => 0x16, 292 => 0x310, 294 => 0x303, 295 => 0x303, 297 => 0x51, 299 => 0x3405, 324 => 0x0, 325 => 0x0, 326 => 0x1, 327 => 0x1, 328 => 0x1, 330 => 0x0, 365 => 0xa003, 368 => 0x27, 388 => 0xb027, 400 => 0x1896, 402 => 0x18c2, 403 => 0x18f2, 404 => 0x17f6, 406 => 0x109, 407 => 0x109, 416 => 0x608, 417 => 0x62 }, - 'lenstype2' => { 378 => 0x3f7, 400 => 0x1893, 402 => 0x18bf, 403 => 0x18ef, 404 => 0x17f3, 406 => 0x107, 407 => 0x107, 416 => 0x605, 417 => 0x60 }, - 'lenstype3' => { 420 => 0x9 }, - 'lenszoomposition' => { 413 => 0x19, 414 => 0x1e, 417 => [0x342,0x35a] }, - 'levelindicator' => { 305 => 0x15 }, - 'levelorientation' => { 331 => 0x0 }, - 'license' => { 439 => 'license' }, - 'licensee' => { 284 => 'Licensee' }, - 'licenseeid' => { 284 => [\'Licensee','LicenseeLicenseeID'] }, - 'licenseeimageid' => { 284 => 'LicenseeImageID' }, - 'licenseeimagenotes' => { 284 => 'LicenseeImageNotes' }, - 'licenseename' => { 284 => [\'Licensee','LicenseeLicenseeName'] }, - 'licenseenddate' => { 284 => 'LicenseEndDate' }, - 'licenseeprojectreference' => { 284 => 'LicenseeProjectReference' }, - 'licenseetransactionid' => { 284 => 'LicenseeTransactionID' }, - 'licenseid' => { 284 => 'LicenseID' }, - 'licensestartdate' => { 284 => 'LicenseStartDate' }, - 'licensetransactiondate' => { 284 => 'LicenseTransactionDate' }, - 'licensetype' => { 444 => 'licensetype' }, - 'licensor' => { 284 => 'Licensor' }, - 'licensorcity' => { 284 => [\'Licensor','LicensorLicensorCity'] }, - 'licensorcountry' => { 284 => [\'Licensor','LicensorLicensorCountry'] }, - 'licensoremail' => { 284 => [\'Licensor','LicensorLicensorEmail'] }, - 'licensorextendedaddress' => { 284 => [\'Licensor','LicensorLicensorExtendedAddress'] }, - 'licensorid' => { 284 => [\'Licensor','LicensorLicensorID'] }, - 'licensorimageid' => { 284 => 'LicensorImageID' }, - 'licensorname' => { 284 => [\'Licensor','LicensorLicensorName'] }, - 'licensornotes' => { 284 => 'LicensorNotes' }, - 'licensorpostalcode' => { 284 => [\'Licensor','LicensorLicensorPostalCode'] }, - 'licensorregion' => { 284 => [\'Licensor','LicensorLicensorRegion'] }, - 'licensorstreetaddress' => { 284 => [\'Licensor','LicensorLicensorStreetAddress'] }, - 'licensortelephone1' => { 284 => [\'Licensor','LicensorLicensorTelephone1'] }, - 'licensortelephone2' => { 284 => [\'Licensor','LicensorLicensorTelephone2'] }, - 'licensortelephonetype1' => { 284 => [\'Licensor','LicensorLicensorTelephoneType1'] }, - 'licensortelephonetype2' => { 284 => [\'Licensor','LicensorLicensorTelephoneType2'] }, - 'licensortransactionid' => { 284 => 'LicensorTransactionID' }, - 'licensorurl' => { 284 => [\'Licensor','LicensorLicensorURL'] }, - 'lightcondition' => { 279 => 0x1009 }, - 'lightingmode' => { 107 => 0x302a }, - 'lightreading' => { 332 => 0x15 }, - 'lightsource' => { 113 => 0x9208, 211 => 0x90, 282 => 0x1000, 446 => 'LightSource' }, - 'lightsourcespecial' => { 367 => 0x21d }, - 'lightswitch' => { 270 => '0.1', 272 => '0.1' }, - 'lightvaluecenter' => { 279 => 0x103d }, - 'lightvalueperiphery' => { 279 => 0x103e }, - 'limitafareamodeselection' => { 258 => '51.1', 260 => '49.1', 261 => '49.1', 270 => '49.1', 271 => '49.1' }, - 'linearitylimitblue' => { 302 => 0x10 }, - 'linearitylimitgreen' => { 302 => 0xf }, - 'linearitylimitred' => { 302 => 0xe }, - 'linearityuppermargin' => { 42 => [0x2ba,0x2d1,0x2d5], 44 => 0x1e5, 45 => [0x1fe,0x2de], 46 => [0x232,0x310], 47 => 0x31e }, - 'linearizationtable' => { 113 => 0xc618 }, - 'linearresponselimit' => { 113 => 0xc62e }, - 'link' => { 456 => 'link' }, - 'linkaetoafpoint' => { 313 => '14.2' }, - 'linkedencodedrightsexpr' => { 452 => [\'LinkedEncRightsExpr','LinkedEncRightsExprLinkedRightsExpr'] }, - 'linkedencodedrightsexprlangid' => { 452 => [\'LinkedEncRightsExpr','LinkedEncRightsExprRightsExprLangId'] }, - 'linkedencodedrightsexprtype' => { 452 => [\'LinkedEncRightsExpr','LinkedEncRightsExprRightsExprEncType'] }, - 'linkedencrightsexpr' => { 452 => 'LinkedEncRightsExpr' }, - 'linlogcoring' => { 131 => 0x904 }, - 'lithostratigraphicterms' => { 112 => [\'GeologicalContext','GeologicalContextLithostratigraphicTerms'] }, - 'liveviewaf' => { 262 => '32.1', 272 => '34.1' }, - 'liveviewafareamode' => { 267 => '34.1' }, - 'liveviewafmethod' => { 393 => 0x20 }, - 'liveviewafmode' => { 267 => '34.2' }, - 'liveviewafsetting' => { 378 => 0x36 }, - 'liveviewbuttonoptions' => { 258 => '50.2', 260 => '48.2', 261 => '48.2', 270 => '48.2', 271 => '48.2' }, - 'liveviewexposuresimulation' => { 78 => 0x810 }, - 'liveviewfocusmode' => { 378 => [0x8b,0x28b] }, - 'liveviewmetering' => { 378 => [0x84,0x284] }, - 'liveviewmonitorofftime' => { 258 => '21.2', 260 => '21.2', 261 => '21.2', 263 => '20.2', 264 => '20.2', 265 => '20.2', 267 => '20.2', 270 => '21.2', 271 => '21.2' }, - 'liveviewshooting' => { 54 => 0x13 }, - 'livingspecimen' => { 112 => 'LivingSpecimen' }, - 'livingspecimenmaterialsampleid' => { 112 => [\'LivingSpecimen','LivingSpecimenMaterialSampleID'] }, - 'localcaption' => { 125 => 0x79 }, - 'localizedcameramodel' => { 113 => 0xc615 }, - 'locallocationname' => { 365 => 0x30 }, - 'location' => { 210 => 0x9, 297 => 0x67, 434 => 'Location', 451 => 'Location', 455 => 'location', 456 => 'location' }, - 'locationareacode' => { 440 => 'lac' }, - 'locationcreated' => { 452 => 'LocationCreated' }, - 'locationcreatedcity' => { 452 => [\'LocationCreated','LocationCreatedCity'] }, - 'locationcreatedcountrycode' => { 452 => [\'LocationCreated','LocationCreatedCountryCode'] }, - 'locationcreatedcountryname' => { 452 => [\'LocationCreated','LocationCreatedCountryName'] }, - 'locationcreatedgpsaltitude' => { 452 => [\'LocationCreated','LocationCreatedGPSAltitude'] }, - 'locationcreatedgpslatitude' => { 452 => [\'LocationCreated','LocationCreatedGPSLatitude'] }, - 'locationcreatedgpslongitude' => { 452 => [\'LocationCreated','LocationCreatedGPSLongitude'] }, - 'locationcreatedidentifier' => { 452 => [\'LocationCreated','LocationCreatedIdentifier'] }, - 'locationcreatedlocationid' => { 452 => [\'LocationCreated','LocationCreatedLocationId'] }, - 'locationcreatedlocationname' => { 452 => [\'LocationCreated','LocationCreatedLocationName'] }, - 'locationcreatedprovincestate' => { 452 => [\'LocationCreated','LocationCreatedProvinceState'] }, - 'locationcreatedsublocation' => { 452 => [\'LocationCreated','LocationCreatedSublocation'] }, - 'locationcreatedworldregion' => { 452 => [\'LocationCreated','LocationCreatedWorldRegion'] }, - 'locationinfoversion' => { 210 => 0x0 }, - 'locationname' => { 365 => 0x31 }, - 'locationshown' => { 452 => 'LocationShown' }, - 'locationshowncity' => { 452 => [\'LocationShown','LocationShownCity'] }, - 'locationshowncountrycode' => { 452 => [\'LocationShown','LocationShownCountryCode'] }, - 'locationshowncountryname' => { 452 => [\'LocationShown','LocationShownCountryName'] }, - 'locationshowngpsaltitude' => { 452 => [\'LocationShown','LocationShownGPSAltitude'] }, - 'locationshowngpslatitude' => { 452 => [\'LocationShown','LocationShownGPSLatitude'] }, - 'locationshowngpslongitude' => { 452 => [\'LocationShown','LocationShownGPSLongitude'] }, - 'locationshownidentifier' => { 452 => [\'LocationShown','LocationShownIdentifier'] }, - 'locationshownlocationid' => { 452 => [\'LocationShown','LocationShownLocationId'] }, - 'locationshownlocationname' => { 452 => [\'LocationShown','LocationShownLocationName'] }, - 'locationshownprovincestate' => { 452 => [\'LocationShown','LocationShownProvinceState'] }, - 'locationshownsublocation' => { 452 => [\'LocationShown','LocationShownSublocation'] }, - 'locationshownworldregion' => { 452 => [\'LocationShown','LocationShownWorldRegion'] }, - 'lockmicrophonebutton' => { 78 => 0x709 }, - 'logcomment' => { 466 => 'logComment' }, - 'logscale' => { 131 => 0x902 }, - 'longexposurenoisereduction' => { 59 => 0x4, 78 => 0x201, 79 => 0x1, 80 => 0x2, 81 => 0x1, 82 => 0x1, 83 => 0x2, 84 => 0x1, 297 => 0x49, 376 => 0x2b, 377 => 0x25, 378 => 0x25, 388 => 0x2008, 393 => 0x11, 417 => 0x44 }, - 'longexposurenoisereduction2' => { 54 => 0x8 }, - 'loop' => { 466 => 'loop' }, - 'lowestbiostratigraphiczone' => { 112 => [\'GeologicalContext','GeologicalContextLowestBiostratigraphicZone'] }, - 'luminanceadjustmentaqua' => { 442 => 'LuminanceAdjustmentAqua' }, - 'luminanceadjustmentblue' => { 442 => 'LuminanceAdjustmentBlue' }, - 'luminanceadjustmentgreen' => { 442 => 'LuminanceAdjustmentGreen' }, - 'luminanceadjustmentmagenta' => { 442 => 'LuminanceAdjustmentMagenta' }, - 'luminanceadjustmentorange' => { 442 => 'LuminanceAdjustmentOrange' }, - 'luminanceadjustmentpurple' => { 442 => 'LuminanceAdjustmentPurple' }, - 'luminanceadjustmentred' => { 442 => 'LuminanceAdjustmentRed' }, - 'luminanceadjustmentyellow' => { 442 => 'LuminanceAdjustmentYellow' }, - 'luminancecurvelimits' => { 102 => 0x150 }, - 'luminancecurvepoints' => { 102 => 0x126 }, - 'luminancenoisereduction' => { 97 => 0x20600, 103 => 0x5f, 368 => 0x1b }, - 'luminancenoisereductioncontrast' => { 442 => 'LuminanceNoiseReductionContrast' }, - 'luminancenoisereductiondetail' => { 442 => 'LuminanceNoiseReductionDetail' }, - 'luminancenr_tiff_jpeg' => { 103 => 0x6d }, - 'luminancesmoothing' => { 442 => 'LuminanceSmoothing' }, - 'lvshootingareadisplay' => { 78 => [0x40b,0x40c] }, - 'lyrics' => { 466 => 'lyrics' }, - 'm16cversion' => { 292 => 0x333 }, - 'macatom' => { 441 => 'macAtom' }, - 'macatomapplicationcode' => { 441 => [\'macAtom','macAtomApplicationCode'] }, - 'macatominvocationappleevent' => { 441 => [\'macAtom','macAtomInvocationAppleEvent'] }, - 'macatomposixprojectpath' => { 441 => [\'macAtom','macAtomPosixProjectPath'] }, - 'machineobservation' => { 112 => 'MachineObservation' }, - 'machineobservationday' => { 112 => [\'MachineObservation','MachineObservationDay'] }, - 'machineobservationearliestdate' => { 112 => [\'MachineObservation','MachineObservationEarliestDate'] }, - 'machineobservationenddayofyear' => { 112 => [\'MachineObservation','MachineObservationEndDayOfYear'] }, - 'machineobservationeventdate' => { 112 => [\'MachineObservation','MachineObservationEventDate'] }, - 'machineobservationeventid' => { 112 => [\'MachineObservation','MachineObservationEventID'] }, - 'machineobservationeventremarks' => { 112 => [\'MachineObservation','MachineObservationEventRemarks'] }, - 'machineobservationeventtime' => { 112 => [\'MachineObservation','MachineObservationEventTime'] }, - 'machineobservationfieldnotes' => { 112 => [\'MachineObservation','MachineObservationFieldNotes'] }, - 'machineobservationfieldnumber' => { 112 => [\'MachineObservation','MachineObservationFieldNumber'] }, - 'machineobservationhabitat' => { 112 => [\'MachineObservation','MachineObservationHabitat'] }, - 'machineobservationlatestdate' => { 112 => [\'MachineObservation','MachineObservationLatestDate'] }, - 'machineobservationmonth' => { 112 => [\'MachineObservation','MachineObservationMonth'] }, - 'machineobservationparenteventid' => { 112 => [\'MachineObservation','MachineObservationParentEventID'] }, - 'machineobservationsamplesizeunit' => { 112 => [\'MachineObservation','MachineObservationSampleSizeUnit'] }, - 'machineobservationsamplesizevalue' => { 112 => [\'MachineObservation','MachineObservationSampleSizeValue'] }, - 'machineobservationsamplingeffort' => { 112 => [\'MachineObservation','MachineObservationSamplingEffort'] }, - 'machineobservationsamplingprotocol' => { 112 => [\'MachineObservation','MachineObservationSamplingProtocol'] }, - 'machineobservationstartdayofyear' => { 112 => [\'MachineObservation','MachineObservationStartDayOfYear'] }, - 'machineobservationverbatimeventdate' => { 112 => [\'MachineObservation','MachineObservationVerbatimEventDate'] }, - 'machineobservationyear' => { 112 => [\'MachineObservation','MachineObservationYear'] }, - 'macro' => { 121 => 0x1020, 123 => 0x202, 279 => 0x202, 357 => 0x21, 367 => 0x202, 388 => 0xb040 }, - 'macroled' => { 277 => 0x120a }, - 'macromagnification' => { 6 => 0x1b, 10 => 0x1b, 13 => 0x1b, 14 => 0x1b, 18 => 0x1b, 19 => 0x1b, 54 => 0x10 }, - 'macromode' => { 33 => 0x1, 171 => 0xb, 274 => 0x300, 297 => 0x1c, 358 => 0x1009 }, - 'magentahsl' => { 97 => 0x20917 }, - 'magicfilter' => { 274 => 0x52c }, - 'magnifiedview' => { 80 => 0x11, 82 => 0x9 }, - 'mainboardversion' => { 131 => 0x438 }, - 'maindialexposurecomp' => { 268 => '0.6' }, - 'mainingredient' => { 458 => 'mainIngredient' }, - 'majorversion' => { 432 => 'MajorVersion' }, - 'make' => { 92 => 0x0, 109 => 0x1, 113 => 0x10f, 147 => 'Make', 287 => 'Make', 302 => 0x10f, 455 => 'make', 462 => 'Make' }, - 'makernote' => { 446 => 'MakerNote' }, - 'makernoteapple' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotecanon' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotecasio' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotecasio2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotedji' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteflir' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotefujifilm' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotege' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotege2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotehasselblad' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotehp' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotehp2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotehp4' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotehp6' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteisl' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotejvc' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotejvctext' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak10' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak11' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak12' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak1a' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak1b' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak4' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak5' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak6a' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak6b' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak7' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak8a' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak8b' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak8c' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodak9' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekodakunknown' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotekyocera' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica4' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica5' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica6' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica7' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica8' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteleica9' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteminolta' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteminolta2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteminolta3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotemotorola' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotenikon' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotenikon2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotenikon3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotenintendo' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteoffset' => { 367 => 0xff }, - 'makernoteolympus' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteolympus2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepanasonic' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepanasonic2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepanasonic3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepentax' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepentax2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepentax3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepentax4' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepentax5' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotepentax6' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotephaseone' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotereconyx' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotereconyx2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotericoh' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotericoh2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotericohtext' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesafety' => { 113 => 0xc635 }, - 'makernotesamsung1a' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesamsung1b' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesamsung2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesanyo' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesanyoc4' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesanyopatch' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesigma' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesony' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesony2' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesony3' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesony4' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesony5' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesonyericsson' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotesonysrf' => { 111 => 'MakN', 113 => 0x927c }, - 'makernotetype' => { 358 => 0x1 }, - 'makernoteunknown' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteunknownbinary' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteunknowntext' => { 111 => 'MakN', 113 => 0x927c }, - 'makernoteversion' => { 176 => 0x0, 211 => 0x1, 279 => 0x0, 297 => 0x8000, 362 => 0x0, 365 => 0x1, 368 => [0x1d,0x1f], 379 => 0x2000 }, - 'managedfrom' => { 467 => 'ManagedFrom' }, - 'managedfromalternatepaths' => { 467 => [\'ManagedFrom','ManagedFromAlternatePaths'] }, - 'managedfromdocumentid' => { 467 => [\'ManagedFrom','ManagedFromDocumentID'] }, - 'managedfromfilepath' => { 467 => [\'ManagedFrom','ManagedFromFilePath'] }, - 'managedfromfrompart' => { 467 => [\'ManagedFrom','ManagedFromFromPart'] }, - 'managedfrominstanceid' => { 467 => [\'ManagedFrom','ManagedFromInstanceID'] }, - 'managedfromlastmodifydate' => { 467 => [\'ManagedFrom','ManagedFromLastModifyDate'] }, - 'managedfromlasturl' => { 467 => [\'ManagedFrom','ManagedFromLastURL'] }, - 'managedfromlinkcategory' => { 467 => [\'ManagedFrom','ManagedFromLinkCategory'] }, - 'managedfromlinkform' => { 467 => [\'ManagedFrom','ManagedFromLinkForm'] }, - 'managedfrommanager' => { 467 => [\'ManagedFrom','ManagedFromManager'] }, - 'managedfrommanagervariant' => { 467 => [\'ManagedFrom','ManagedFromManagerVariant'] }, - 'managedfrommanageto' => { 467 => [\'ManagedFrom','ManagedFromManageTo'] }, - 'managedfrommanageui' => { 467 => [\'ManagedFrom','ManagedFromManageUI'] }, - 'managedfrommaskmarkers' => { 467 => [\'ManagedFrom','ManagedFromMaskMarkers'] }, - 'managedfromoriginaldocumentid' => { 467 => [\'ManagedFrom','ManagedFromOriginalDocumentID'] }, - 'managedfrompartmapping' => { 467 => [\'ManagedFrom','ManagedFromPartMapping'] }, - 'managedfromplacedresolutionunit' => { 467 => [\'ManagedFrom','ManagedFromPlacedResolutionUnit'] }, - 'managedfromplacedxresolution' => { 467 => [\'ManagedFrom','ManagedFromPlacedXResolution'] }, - 'managedfromplacedyresolution' => { 467 => [\'ManagedFrom','ManagedFromPlacedYResolution'] }, - 'managedfromrenditionclass' => { 467 => [\'ManagedFrom','ManagedFromRenditionClass'] }, - 'managedfromrenditionparams' => { 467 => [\'ManagedFrom','ManagedFromRenditionParams'] }, - 'managedfromtopart' => { 467 => [\'ManagedFrom','ManagedFromToPart'] }, - 'managedfromversionid' => { 467 => [\'ManagedFrom','ManagedFromVersionID'] }, - 'manager' => { 467 => 'Manager' }, - 'managervariant' => { 467 => 'ManagerVariant' }, - 'manageto' => { 467 => 'ManageTo' }, - 'manageui' => { 467 => 'ManageUI' }, - 'manifest' => { 467 => 'Manifest' }, - 'manifestlinkform' => { 467 => [\'Manifest','ManifestLinkForm'] }, - 'manifestplacedresolutionunit' => { 467 => [\'Manifest','ManifestPlacedResolutionUnit'] }, - 'manifestplacedxresolution' => { 467 => [\'Manifest','ManifestPlacedXResolution'] }, - 'manifestplacedyresolution' => { 467 => [\'Manifest','ManifestPlacedYResolution'] }, - 'manifestreference' => { 467 => [\'Manifest','ManifestReference'] }, - 'manifestreferencealternatepaths' => { 467 => [\'Manifest','ManifestReferenceAlternatePaths'] }, - 'manifestreferencedocumentid' => { 467 => [\'Manifest','ManifestReferenceDocumentID'] }, - 'manifestreferencefilepath' => { 467 => [\'Manifest','ManifestReferenceFilePath'] }, - 'manifestreferencefrompart' => { 467 => [\'Manifest','ManifestReferenceFromPart'] }, - 'manifestreferenceinstanceid' => { 467 => [\'Manifest','ManifestReferenceInstanceID'] }, - 'manifestreferencelastmodifydate' => { 467 => [\'Manifest','ManifestReferenceLastModifyDate'] }, - 'manifestreferencelasturl' => { 467 => [\'Manifest','ManifestReferenceLastURL'] }, - 'manifestreferencelinkcategory' => { 467 => [\'Manifest','ManifestReferenceLinkCategory'] }, - 'manifestreferencelinkform' => { 467 => [\'Manifest','ManifestReferenceLinkForm'] }, - 'manifestreferencemanager' => { 467 => [\'Manifest','ManifestReferenceManager'] }, - 'manifestreferencemanagervariant' => { 467 => [\'Manifest','ManifestReferenceManagerVariant'] }, - 'manifestreferencemanageto' => { 467 => [\'Manifest','ManifestReferenceManageTo'] }, - 'manifestreferencemanageui' => { 467 => [\'Manifest','ManifestReferenceManageUI'] }, - 'manifestreferencemaskmarkers' => { 467 => [\'Manifest','ManifestReferenceMaskMarkers'] }, - 'manifestreferenceoriginaldocumentid' => { 467 => [\'Manifest','ManifestReferenceOriginalDocumentID'] }, - 'manifestreferencepartmapping' => { 467 => [\'Manifest','ManifestReferencePartMapping'] }, - 'manifestreferenceplacedresolutionunit' => { 467 => [\'Manifest','ManifestReferencePlacedResolutionUnit'] }, - 'manifestreferenceplacedxresolution' => { 467 => [\'Manifest','ManifestReferencePlacedXResolution'] }, - 'manifestreferenceplacedyresolution' => { 467 => [\'Manifest','ManifestReferencePlacedYResolution'] }, - 'manifestreferencerenditionclass' => { 467 => [\'Manifest','ManifestReferenceRenditionClass'] }, - 'manifestreferencerenditionparams' => { 467 => [\'Manifest','ManifestReferenceRenditionParams'] }, - 'manifestreferencetopart' => { 467 => [\'Manifest','ManifestReferenceToPart'] }, - 'manifestreferenceversionid' => { 467 => [\'Manifest','ManifestReferenceVersionID'] }, - 'manometerpressure' => { 274 => 0x900, 297 => 0x86 }, - 'manometerreading' => { 274 => 0x901 }, - 'manualafpointselectpattern' => { 78 => 0x513 }, + 'lense-mountversion' => { 395 => 0x3f0, 438 => 0xd }, + 'lensfirmware' => { 374 => 0x20, 380 => 0xa004 }, + 'lensfirmwareversion' => { 284 => 0x204, 306 => 0x60, 395 => 0x3f3, 438 => 0x14 }, + 'lensfocallength' => { 100 => 0xf0512, 332 => 0x9 }, + 'lensfocalrange' => { 383 => [0xa,0x2a] }, + 'lensfocusfunctionbuttons' => { 267 => '55.1', 269 => '52.1', 270 => '52.1', 279 => '52.1', 280 => '52.1' }, + 'lensformat' => { 418 => 0x1891, 420 => 0x18bd, 421 => 0x18ed, 422 => 0x17f1, 424 => 0x106, 425 => 0x106, 434 => 0x603, 435 => 0x5d }, + 'lensfstops' => { 211 => 0x7, 212 => 0xc, 213 => 0xd, 217 => 0xe, 219 => 0x8b, 332 => '0.3' }, + 'lensid' => { 217 => 0x30, 459 => 'LensID' }, + 'lensidnumber' => { 211 => 0x6, 212 => 0xb, 213 => 0xc, 217 => 0xd }, + 'lensinfo' => { 116 => 0xa432, 338 => 0x2a, 459 => 'LensInfo', 469 => 'LensSpecification' }, + 'lenskind' => { 332 => 0x1 }, + 'lensmake' => { 116 => 0xa433, 159 => 'Make', 469 => 'LensMake' }, + 'lensmanualdistortionamount' => { 462 => 'LensManualDistortionAmount', 464 => 'LensManualDistortionAmount' }, + 'lensmanufacturer' => { 174 => 'LensManufacturer' }, + 'lensmaxaperturerange' => { 383 => 0x2b }, + 'lensmodel' => { 7 => 0x937, 14 => 0x92b, 15 => 0x933, 61 => 0x95, 116 => 0xa434, 159 => 'Model', 174 => 'LensModel', 214 => 0x18a, 215 => 0x18b, 216 => 0x2ac, 284 => 0x203, 338 => 0xc, 350 => 0x412, 469 => 'LensModel' }, + 'lensmodulationoptimizer' => { 124 => 0x1045 }, + 'lensmount' => { 395 => 0x99, 418 => 0x1892, 420 => 0x18be, 421 => 0x18ee, 422 => 0x17f2, 424 => 0x105, 425 => 0x105, 434 => 0x604, 435 => 0x5e }, + 'lensmount2' => { 438 => 0x8 }, + 'lensprofilechromaticaberrationscale' => { 462 => 'LensProfileChromaticAberrationScale', 464 => 'LensProfileChromaticAberrationScale' }, + 'lensprofiledigest' => { 462 => 'LensProfileDigest', 464 => 'LensProfileDigest' }, + 'lensprofiledistortionscale' => { 462 => 'LensProfileDistortionScale', 464 => 'LensProfileDistortionScale' }, + 'lensprofileenable' => { 462 => 'LensProfileEnable', 464 => 'LensProfileEnable' }, + 'lensprofilefilename' => { 462 => 'LensProfileFilename', 464 => 'LensProfileFilename' }, + 'lensprofilematchkeycameramodelname' => { 462 => 'LensProfileMatchKeyCameraModelName', 464 => 'LensProfileMatchKeyCameraModelName' }, + 'lensprofilematchkeyexifmake' => { 462 => 'LensProfileMatchKeyExifMake', 464 => 'LensProfileMatchKeyExifMake' }, + 'lensprofilematchkeyexifmodel' => { 462 => 'LensProfileMatchKeyExifModel', 464 => 'LensProfileMatchKeyExifModel' }, + 'lensprofilematchkeyisraw' => { 462 => 'LensProfileMatchKeyIsRaw', 464 => 'LensProfileMatchKeyIsRaw' }, + 'lensprofilematchkeylensid' => { 462 => 'LensProfileMatchKeyLensID', 464 => 'LensProfileMatchKeyLensID' }, + 'lensprofilematchkeylensinfo' => { 462 => 'LensProfileMatchKeyLensInfo', 464 => 'LensProfileMatchKeyLensInfo' }, + 'lensprofilematchkeylensname' => { 462 => 'LensProfileMatchKeyLensName', 464 => 'LensProfileMatchKeyLensName' }, + 'lensprofilematchkeysensorformatfactor' => { 462 => 'LensProfileMatchKeySensorFormatFactor', 464 => 'LensProfileMatchKeySensorFormatFactor' }, + 'lensprofilename' => { 462 => 'LensProfileName', 464 => 'LensProfileName' }, + 'lensprofilesetup' => { 462 => 'LensProfileSetup', 464 => 'LensProfileSetup' }, + 'lensprofilevignettingscale' => { 462 => 'LensProfileVignettingScale', 464 => 'LensProfileVignettingScale' }, + 'lensproperties' => { 284 => 0x20b }, + 'lensserialnumber' => { 21 => 0x164, 32 => 0x16b, 59 => 0x0, 116 => 0xa435, 159 => 'SerialNumber', 284 => 0x202, 304 => 0x321, 306 => 0x52, 366 => 'LENS', 374 => 0x30, 459 => 'LensSerialNumber', 469 => 'LensSerialNumber' }, + 'lensshutterlock' => { 179 => 0x4a }, + 'lensspec' => { 390 => 0x0, 391 => 0x0, 392 => 0x0, 406 => 0xb02a }, + 'lensspecfeatures' => { 424 => [0x115,0x116], 425 => [0x116,0x1ed,0x1f0,0x21c,0x21e] }, + 'lenstemperature' => { 288 => 0x1008 }, + 'lenstype' => { 7 => 0xe2, 8 => 0xd, 9 => 0x1a7, 10 => 0xc, 11 => 0x111, 12 => 0xc, 13 => 0x14f, 14 => 0xd6, 15 => 0xde, 16 => 0xf6, 17 => 0xea, 18 => 0xff, 19 => [0xc,0x97], 20 => 0xe6, 21 => 0x153, 22 => 0xea, 23 => 0xe8, 24 => 0x127, 25 => 0x161, 26 => 0x166, 27 => 0x184, 28 => 0x112, 29 => 0x189, 34 => 0x16, 181 => 0x10c, 182 => 0x49bd, 219 => 0x83, 284 => 0x201, 297 => 0x16, 301 => 0x310, 303 => 0x303, 304 => 0x303, 306 => 0x51, 308 => 0x3405, 333 => 0x0, 334 => 0x0, 335 => 0x1, 336 => 0x1, 337 => 0x1, 339 => 0x0, 380 => 0xa003, 383 => 0x27, 406 => 0xb027, 418 => 0x1896, 420 => 0x18c2, 421 => 0x18f2, 422 => 0x17f6, 424 => 0x109, 425 => 0x109, 434 => 0x608, 435 => 0x62 }, + 'lenstype2' => { 395 => 0x3f7, 418 => 0x1893, 420 => 0x18bf, 421 => 0x18ef, 422 => 0x17f3, 424 => 0x107, 425 => 0x107, 434 => 0x605, 435 => 0x60 }, + 'lenstype3' => { 438 => 0x9 }, + 'lenstypemake' => { 306 => 0xc4 }, + 'lenstypemodel' => { 306 => 0xc5 }, + 'lenszoomposition' => { 431 => 0x19, 432 => 0x1e, 435 => [0x342,0x34e,0x35a] }, + 'levelindicator' => { 314 => 0x15 }, + 'levelmeter' => { 366 => ['Lvlm','lvlm'] }, + 'levelorientation' => { 340 => 0x0 }, + 'license' => { 460 => 'license' }, + 'licensee' => { 293 => 'Licensee' }, + 'licenseeid' => { 293 => [\'Licensee','LicenseeLicenseeID'] }, + 'licenseeimageid' => { 293 => 'LicenseeImageID' }, + 'licenseeimagenotes' => { 293 => 'LicenseeImageNotes' }, + 'licenseename' => { 293 => [\'Licensee','LicenseeLicenseeName'] }, + 'licenseenddate' => { 293 => 'LicenseEndDate' }, + 'licenseeprojectreference' => { 293 => 'LicenseeProjectReference' }, + 'licenseetransactionid' => { 293 => 'LicenseeTransactionID' }, + 'licenseid' => { 293 => 'LicenseID' }, + 'licensestartdate' => { 293 => 'LicenseStartDate' }, + 'licensetransactiondate' => { 293 => 'LicenseTransactionDate' }, + 'licensetype' => { 466 => 'licensetype' }, + 'licensor' => { 293 => 'Licensor' }, + 'licensorcity' => { 293 => [\'Licensor','LicensorLicensorCity'] }, + 'licensorcountry' => { 293 => [\'Licensor','LicensorLicensorCountry'] }, + 'licensoremail' => { 293 => [\'Licensor','LicensorLicensorEmail'] }, + 'licensorextendedaddress' => { 293 => [\'Licensor','LicensorLicensorExtendedAddress'] }, + 'licensorid' => { 293 => [\'Licensor','LicensorLicensorID'] }, + 'licensorimageid' => { 293 => 'LicensorImageID' }, + 'licensorname' => { 293 => [\'Licensor','LicensorLicensorName'] }, + 'licensornotes' => { 293 => 'LicensorNotes' }, + 'licensorpostalcode' => { 293 => [\'Licensor','LicensorLicensorPostalCode'] }, + 'licensorregion' => { 293 => [\'Licensor','LicensorLicensorRegion'] }, + 'licensorstreetaddress' => { 293 => [\'Licensor','LicensorLicensorStreetAddress'] }, + 'licensortelephone1' => { 293 => [\'Licensor','LicensorLicensorTelephone1'] }, + 'licensortelephone2' => { 293 => [\'Licensor','LicensorLicensorTelephone2'] }, + 'licensortelephonetype1' => { 293 => [\'Licensor','LicensorLicensorTelephoneType1'] }, + 'licensortelephonetype2' => { 293 => [\'Licensor','LicensorLicensorTelephoneType2'] }, + 'licensortransactionid' => { 293 => 'LicensorTransactionID' }, + 'licensorurl' => { 293 => [\'Licensor','LicensorLicensorURL'] }, + 'lightcondition' => { 288 => 0x1009 }, + 'lightingmode' => { 110 => 0x302a }, + 'lightreading' => { 341 => 0x15 }, + 'lightsource' => { 116 => 0x9208, 219 => 0x90, 291 => 0x1000, 468 => 'LightSource' }, + 'lightsourcespecial' => { 382 => 0x21d }, + 'lightswitch' => { 279 => '0.1', 281 => '0.1' }, + 'lightvaluecenter' => { 288 => 0x103d }, + 'lightvalueperiphery' => { 288 => 0x103e }, + 'limitafareamodeselection' => { 267 => '51.1', 269 => '49.1', 270 => '49.1', 279 => '49.1', 280 => '49.1' }, + 'linearitylimitblue' => { 311 => 0x10 }, + 'linearitylimitgreen' => { 311 => 0xf }, + 'linearitylimitred' => { 311 => 0xe }, + 'linearityuppermargin' => { 43 => [0x2ba,0x2d1,0x2d5], 45 => 0x1e5, 46 => [0x1fe,0x2de], 47 => [0x232,0x310], 48 => 0x31e }, + 'linearizationtable' => { 116 => 0xc618 }, + 'linearresponselimit' => { 116 => 0xc62e }, + 'link' => { 478 => 'link' }, + 'linkaetoafpoint' => { 322 => '14.2' }, + 'linkedencodedrightsexpr' => { 474 => [\'LinkedEncRightsExpr','LinkedEncRightsExprLinkedRightsExpr'] }, + 'linkedencodedrightsexprlangid' => { 474 => [\'LinkedEncRightsExpr','LinkedEncRightsExprRightsExprLangId'] }, + 'linkedencodedrightsexprtype' => { 474 => [\'LinkedEncRightsExpr','LinkedEncRightsExprRightsExprEncType'] }, + 'linkedencrightsexpr' => { 474 => 'LinkedEncRightsExpr' }, + 'linlogcoring' => { 134 => 0x904 }, + 'lithostratigraphicterms' => { 115 => [\'GeologicalContext','GeologicalContextLithostratigraphicTerms'] }, + 'liveviewaf' => { 271 => '32.1', 281 => '34.1' }, + 'liveviewafareamode' => { 276 => '34.1' }, + 'liveviewafmethod' => { 411 => 0x20 }, + 'liveviewafmode' => { 276 => '34.2' }, + 'liveviewafsetting' => { 395 => 0x36 }, + 'liveviewbuttonoptions' => { 267 => '50.2', 269 => '48.2', 270 => '48.2', 279 => '48.2', 280 => '48.2' }, + 'liveviewexposuresimulation' => { 81 => 0x810 }, + 'liveviewfocusmode' => { 395 => [0x8b,0x28b] }, + 'liveviewmetering' => { 395 => [0x84,0x284] }, + 'liveviewmonitorofftime' => { 267 => '21.2', 269 => '21.2', 270 => '21.2', 272 => '20.2', 273 => '20.2', 274 => '20.2', 276 => '20.2', 279 => '21.2', 280 => '21.2' }, + 'liveviewshooting' => { 55 => 0x13 }, + 'livingspecimen' => { 115 => 'LivingSpecimen' }, + 'livingspecimenmaterialsampleid' => { 115 => [\'LivingSpecimen','LivingSpecimenMaterialSampleID'] }, + 'localcaption' => { 128 => 0x79 }, + 'localizedcameramodel' => { 116 => 0xc615 }, + 'locallocationname' => { 380 => 0x30 }, + 'location' => { 218 => 0x9, 306 => 0x67, 455 => 'Location', 473 => 'Location', 477 => 'location', 478 => 'location' }, + 'locationareacode' => { 461 => 'lac' }, + 'locationbody' => { 360 => 'location.body' }, + 'locationcreated' => { 474 => 'LocationCreated' }, + 'locationcreatedcity' => { 474 => [\'LocationCreated','LocationCreatedCity'] }, + 'locationcreatedcountrycode' => { 474 => [\'LocationCreated','LocationCreatedCountryCode'] }, + 'locationcreatedcountryname' => { 474 => [\'LocationCreated','LocationCreatedCountryName'] }, + 'locationcreatedgpsaltitude' => { 474 => [\'LocationCreated','LocationCreatedGPSAltitude'] }, + 'locationcreatedgpslatitude' => { 474 => [\'LocationCreated','LocationCreatedGPSLatitude'] }, + 'locationcreatedgpslongitude' => { 474 => [\'LocationCreated','LocationCreatedGPSLongitude'] }, + 'locationcreatedidentifier' => { 474 => [\'LocationCreated','LocationCreatedIdentifier'] }, + 'locationcreatedlocationid' => { 474 => [\'LocationCreated','LocationCreatedLocationId'] }, + 'locationcreatedlocationname' => { 474 => [\'LocationCreated','LocationCreatedLocationName'] }, + 'locationcreatedprovincestate' => { 474 => [\'LocationCreated','LocationCreatedProvinceState'] }, + 'locationcreatedsublocation' => { 474 => [\'LocationCreated','LocationCreatedSublocation'] }, + 'locationcreatedworldregion' => { 474 => [\'LocationCreated','LocationCreatedWorldRegion'] }, + 'locationdate' => { 360 => 'location.date' }, + 'locationinfoversion' => { 218 => 0x0 }, + 'locationname' => { 360 => 'location.name', 380 => 0x31 }, + 'locationnote' => { 360 => 'location.note' }, + 'locationrole' => { 360 => 'location.role' }, + 'locationshown' => { 474 => 'LocationShown' }, + 'locationshowncity' => { 474 => [\'LocationShown','LocationShownCity'] }, + 'locationshowncountrycode' => { 474 => [\'LocationShown','LocationShownCountryCode'] }, + 'locationshowncountryname' => { 474 => [\'LocationShown','LocationShownCountryName'] }, + 'locationshowngpsaltitude' => { 474 => [\'LocationShown','LocationShownGPSAltitude'] }, + 'locationshowngpslatitude' => { 474 => [\'LocationShown','LocationShownGPSLatitude'] }, + 'locationshowngpslongitude' => { 474 => [\'LocationShown','LocationShownGPSLongitude'] }, + 'locationshownidentifier' => { 474 => [\'LocationShown','LocationShownIdentifier'] }, + 'locationshownlocationid' => { 474 => [\'LocationShown','LocationShownLocationId'] }, + 'locationshownlocationname' => { 474 => [\'LocationShown','LocationShownLocationName'] }, + 'locationshownprovincestate' => { 474 => [\'LocationShown','LocationShownProvinceState'] }, + 'locationshownsublocation' => { 474 => [\'LocationShown','LocationShownSublocation'] }, + 'locationshownworldregion' => { 474 => [\'LocationShown','LocationShownWorldRegion'] }, + 'lockmicrophonebutton' => { 81 => 0x709 }, + 'logcomment' => { 488 => 'logComment' }, + 'logscale' => { 134 => 0x902 }, + 'longdescription' => { 358 => 'ldes' }, + 'longexposurenoisereduction' => { 60 => 0x4, 81 => 0x201, 82 => 0x1, 83 => 0x2, 84 => 0x1, 85 => 0x1, 86 => 0x2, 87 => 0x1, 306 => 0x49, 393 => 0x2b, 394 => 0x25, 395 => 0x25, 406 => 0x2008, 411 => 0x11, 435 => 0x44 }, + 'longexposurenoisereduction2' => { 55 => 0x8 }, + 'longitude' => { 113 => 'Longitude' }, + 'look' => { 462 => 'Look', 464 => 'Look' }, + 'lookname' => { 462 => [\'Look','LookName'], 464 => [\'Look','LookName'] }, + 'loop' => { 488 => 'loop' }, + 'loopstyle' => { 366 => 'LOOP' }, + 'lowestbiostratigraphiczone' => { 115 => [\'GeologicalContext','GeologicalContextLowestBiostratigraphicZone'] }, + 'luminanceadjustmentaqua' => { 462 => 'LuminanceAdjustmentAqua', 464 => 'LuminanceAdjustmentAqua' }, + 'luminanceadjustmentblue' => { 462 => 'LuminanceAdjustmentBlue', 464 => 'LuminanceAdjustmentBlue' }, + 'luminanceadjustmentgreen' => { 462 => 'LuminanceAdjustmentGreen', 464 => 'LuminanceAdjustmentGreen' }, + 'luminanceadjustmentmagenta' => { 462 => 'LuminanceAdjustmentMagenta', 464 => 'LuminanceAdjustmentMagenta' }, + 'luminanceadjustmentorange' => { 462 => 'LuminanceAdjustmentOrange', 464 => 'LuminanceAdjustmentOrange' }, + 'luminanceadjustmentpurple' => { 462 => 'LuminanceAdjustmentPurple', 464 => 'LuminanceAdjustmentPurple' }, + 'luminanceadjustmentred' => { 462 => 'LuminanceAdjustmentRed', 464 => 'LuminanceAdjustmentRed' }, + 'luminanceadjustmentyellow' => { 462 => 'LuminanceAdjustmentYellow', 464 => 'LuminanceAdjustmentYellow' }, + 'luminancecurvelimits' => { 105 => 0x150 }, + 'luminancecurvepoints' => { 105 => 0x126 }, + 'luminancenoisereduction' => { 100 => 0x20600, 106 => 0x5f, 383 => 0x1b }, + 'luminancenoisereductioncontrast' => { 462 => 'LuminanceNoiseReductionContrast', 464 => 'LuminanceNoiseReductionContrast' }, + 'luminancenoisereductiondetail' => { 462 => 'LuminanceNoiseReductionDetail', 464 => 'LuminanceNoiseReductionDetail' }, + 'luminancenr_tiff_jpeg' => { 106 => 0x6d }, + 'luminancesmoothing' => { 462 => 'LuminanceSmoothing', 464 => 'LuminanceSmoothing' }, + 'lvshootingareadisplay' => { 81 => [0x40b,0x40c] }, + 'lyrics' => { 358 => "\xa9lyr", 366 => "\xa9lyr", 488 => 'lyrics' }, + 'lyricsuri' => { 366 => 'lrcu' }, + 'm16cversion' => { 301 => 0x333 }, + 'macatom' => { 463 => 'macAtom' }, + 'macatomapplicationcode' => { 463 => [\'macAtom','macAtomApplicationCode'] }, + 'macatominvocationappleevent' => { 463 => [\'macAtom','macAtomInvocationAppleEvent'] }, + 'macatomposixprojectpath' => { 463 => [\'macAtom','macAtomPosixProjectPath'] }, + 'machineobservation' => { 115 => 'MachineObservation' }, + 'machineobservationday' => { 115 => [\'MachineObservation','MachineObservationDay'] }, + 'machineobservationearliestdate' => { 115 => [\'MachineObservation','MachineObservationEarliestDate'] }, + 'machineobservationenddayofyear' => { 115 => [\'MachineObservation','MachineObservationEndDayOfYear'] }, + 'machineobservationeventdate' => { 115 => [\'MachineObservation','MachineObservationEventDate'] }, + 'machineobservationeventid' => { 115 => [\'MachineObservation','MachineObservationEventID'] }, + 'machineobservationeventremarks' => { 115 => [\'MachineObservation','MachineObservationEventRemarks'] }, + 'machineobservationeventtime' => { 115 => [\'MachineObservation','MachineObservationEventTime'] }, + 'machineobservationfieldnotes' => { 115 => [\'MachineObservation','MachineObservationFieldNotes'] }, + 'machineobservationfieldnumber' => { 115 => [\'MachineObservation','MachineObservationFieldNumber'] }, + 'machineobservationhabitat' => { 115 => [\'MachineObservation','MachineObservationHabitat'] }, + 'machineobservationlatestdate' => { 115 => [\'MachineObservation','MachineObservationLatestDate'] }, + 'machineobservationmonth' => { 115 => [\'MachineObservation','MachineObservationMonth'] }, + 'machineobservationparenteventid' => { 115 => [\'MachineObservation','MachineObservationParentEventID'] }, + 'machineobservationsamplesizeunit' => { 115 => [\'MachineObservation','MachineObservationSampleSizeUnit'] }, + 'machineobservationsamplesizevalue' => { 115 => [\'MachineObservation','MachineObservationSampleSizeValue'] }, + 'machineobservationsamplingeffort' => { 115 => [\'MachineObservation','MachineObservationSamplingEffort'] }, + 'machineobservationsamplingprotocol' => { 115 => [\'MachineObservation','MachineObservationSamplingProtocol'] }, + 'machineobservationstartdayofyear' => { 115 => [\'MachineObservation','MachineObservationStartDayOfYear'] }, + 'machineobservationverbatimeventdate' => { 115 => [\'MachineObservation','MachineObservationVerbatimEventDate'] }, + 'machineobservationyear' => { 115 => [\'MachineObservation','MachineObservationYear'] }, + 'macro' => { 124 => 0x1020, 126 => 0x202, 147 => 0x2b, 288 => 0x202, 372 => 0x21, 382 => 0x202, 406 => 0xb040 }, + 'macroled' => { 286 => 0x120a }, + 'macromagnification' => { 7 => 0x1b, 11 => 0x1b, 14 => 0x1b, 15 => 0x1b, 19 => 0x1b, 20 => 0x1b, 55 => 0x10 }, + 'macromode' => { 34 => 0x1, 176 => 0xb, 283 => 0x300, 306 => 0x1c, 373 => 0x1009 }, + 'magentahsl' => { 100 => 0x20917 }, + 'magicfilter' => { 283 => 0x52c }, + 'magnifiedview' => { 83 => 0x11, 85 => 0x9 }, + 'mainboardversion' => { 134 => 0x438 }, + 'maindialexposurecomp' => { 277 => '0.6' }, + 'mainingredient' => { 480 => 'mainIngredient' }, + 'majorversion' => { 453 => 'MajorVersion' }, + 'make' => { 95 => 0x0, 112 => 0x1, 116 => 0x10f, 152 => 'Make', 296 => 'Make', 311 => 0x10f, 360 => 'make', 366 => "\xa9mak", 477 => 'make', 484 => 'Make' }, + 'makernote' => { 468 => 'MakerNote' }, + 'makernoteapple' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotecanon' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotecasio' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotecasio2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotedji' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteflir' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotefujifilm' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotege' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotege2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotehasselblad' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotehp' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotehp2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotehp4' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotehp6' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteisl' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotejvc' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotejvctext' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak10' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak11' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak12' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak1a' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak1b' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak4' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak5' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak6a' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak6b' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak7' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak8a' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak8b' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak8c' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodak9' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekodakunknown' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotekyocera' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica10' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica4' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica5' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica6' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica7' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica8' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteleica9' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteminolta' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteminolta2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteminolta3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotemotorola' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotenikon' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotenikon2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotenikon3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotenintendo' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteoffset' => { 382 => 0xff }, + 'makernoteolympus' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteolympus2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepanasonic' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepanasonic2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepanasonic3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentax' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentax2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentax3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentax4' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentax5' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentax6' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotepentaxunknown' => { 366 => 'PXMN' }, + 'makernotephaseone' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotereconyx' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotereconyx2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotereconyx3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotericoh' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotericoh2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotericohpentax' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotericohtext' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesafety' => { 116 => 0xc635 }, + 'makernotesamsung1a' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesamsung1b' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesamsung2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesanyo' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesanyoc4' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesanyopatch' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesigma' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesony' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesony2' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesony3' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesony4' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesony5' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesonyericsson' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotesonysrf' => { 114 => 'MakN', 116 => 0x927c }, + 'makernotetype' => { 373 => 0x1 }, + 'makernoteunknown' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteunknownbinary' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteunknowntext' => { 114 => 'MakN', 116 => 0x927c }, + 'makernoteversion' => { 181 => 0x0, 219 => 0x1, 288 => 0x0, 306 => 0x8000, 377 => 0x0, 380 => 0x1, 383 => [0x1d,0x1f], 396 => 0x2000 }, + 'makerurl' => { 366 => "\xa9mal" }, + 'managedfrom' => { 489 => 'ManagedFrom' }, + 'managedfromalternatepaths' => { 489 => [\'ManagedFrom','ManagedFromAlternatePaths'] }, + 'managedfromdocumentid' => { 489 => [\'ManagedFrom','ManagedFromDocumentID'] }, + 'managedfromfilepath' => { 489 => [\'ManagedFrom','ManagedFromFilePath'] }, + 'managedfromfrompart' => { 489 => [\'ManagedFrom','ManagedFromFromPart'] }, + 'managedfrominstanceid' => { 489 => [\'ManagedFrom','ManagedFromInstanceID'] }, + 'managedfromlastmodifydate' => { 489 => [\'ManagedFrom','ManagedFromLastModifyDate'] }, + 'managedfromlasturl' => { 489 => [\'ManagedFrom','ManagedFromLastURL'] }, + 'managedfromlinkcategory' => { 489 => [\'ManagedFrom','ManagedFromLinkCategory'] }, + 'managedfromlinkform' => { 489 => [\'ManagedFrom','ManagedFromLinkForm'] }, + 'managedfrommanager' => { 489 => [\'ManagedFrom','ManagedFromManager'] }, + 'managedfrommanagervariant' => { 489 => [\'ManagedFrom','ManagedFromManagerVariant'] }, + 'managedfrommanageto' => { 489 => [\'ManagedFrom','ManagedFromManageTo'] }, + 'managedfrommanageui' => { 489 => [\'ManagedFrom','ManagedFromManageUI'] }, + 'managedfrommaskmarkers' => { 489 => [\'ManagedFrom','ManagedFromMaskMarkers'] }, + 'managedfromoriginaldocumentid' => { 489 => [\'ManagedFrom','ManagedFromOriginalDocumentID'] }, + 'managedfrompartmapping' => { 489 => [\'ManagedFrom','ManagedFromPartMapping'] }, + 'managedfromplacedresolutionunit' => { 489 => [\'ManagedFrom','ManagedFromPlacedResolutionUnit'] }, + 'managedfromplacedxresolution' => { 489 => [\'ManagedFrom','ManagedFromPlacedXResolution'] }, + 'managedfromplacedyresolution' => { 489 => [\'ManagedFrom','ManagedFromPlacedYResolution'] }, + 'managedfromrenditionclass' => { 489 => [\'ManagedFrom','ManagedFromRenditionClass'] }, + 'managedfromrenditionparams' => { 489 => [\'ManagedFrom','ManagedFromRenditionParams'] }, + 'managedfromtopart' => { 489 => [\'ManagedFrom','ManagedFromToPart'] }, + 'managedfromversionid' => { 489 => [\'ManagedFrom','ManagedFromVersionID'] }, + 'manager' => { 489 => 'Manager' }, + 'managervariant' => { 489 => 'ManagerVariant' }, + 'manageto' => { 489 => 'ManageTo' }, + 'manageui' => { 489 => 'ManageUI' }, + 'manifest' => { 489 => 'Manifest' }, + 'manifestlinkform' => { 489 => [\'Manifest','ManifestLinkForm'] }, + 'manifestplacedresolutionunit' => { 489 => [\'Manifest','ManifestPlacedResolutionUnit'] }, + 'manifestplacedxresolution' => { 489 => [\'Manifest','ManifestPlacedXResolution'] }, + 'manifestplacedyresolution' => { 489 => [\'Manifest','ManifestPlacedYResolution'] }, + 'manifestreference' => { 489 => [\'Manifest','ManifestReference'] }, + 'manifestreferencealternatepaths' => { 489 => [\'Manifest','ManifestReferenceAlternatePaths'] }, + 'manifestreferencedocumentid' => { 489 => [\'Manifest','ManifestReferenceDocumentID'] }, + 'manifestreferencefilepath' => { 489 => [\'Manifest','ManifestReferenceFilePath'] }, + 'manifestreferencefrompart' => { 489 => [\'Manifest','ManifestReferenceFromPart'] }, + 'manifestreferenceinstanceid' => { 489 => [\'Manifest','ManifestReferenceInstanceID'] }, + 'manifestreferencelastmodifydate' => { 489 => [\'Manifest','ManifestReferenceLastModifyDate'] }, + 'manifestreferencelasturl' => { 489 => [\'Manifest','ManifestReferenceLastURL'] }, + 'manifestreferencelinkcategory' => { 489 => [\'Manifest','ManifestReferenceLinkCategory'] }, + 'manifestreferencelinkform' => { 489 => [\'Manifest','ManifestReferenceLinkForm'] }, + 'manifestreferencemanager' => { 489 => [\'Manifest','ManifestReferenceManager'] }, + 'manifestreferencemanagervariant' => { 489 => [\'Manifest','ManifestReferenceManagerVariant'] }, + 'manifestreferencemanageto' => { 489 => [\'Manifest','ManifestReferenceManageTo'] }, + 'manifestreferencemanageui' => { 489 => [\'Manifest','ManifestReferenceManageUI'] }, + 'manifestreferencemaskmarkers' => { 489 => [\'Manifest','ManifestReferenceMaskMarkers'] }, + 'manifestreferenceoriginaldocumentid' => { 489 => [\'Manifest','ManifestReferenceOriginalDocumentID'] }, + 'manifestreferencepartmapping' => { 489 => [\'Manifest','ManifestReferencePartMapping'] }, + 'manifestreferenceplacedresolutionunit' => { 489 => [\'Manifest','ManifestReferencePlacedResolutionUnit'] }, + 'manifestreferenceplacedxresolution' => { 489 => [\'Manifest','ManifestReferencePlacedXResolution'] }, + 'manifestreferenceplacedyresolution' => { 489 => [\'Manifest','ManifestReferencePlacedYResolution'] }, + 'manifestreferencerenditionclass' => { 489 => [\'Manifest','ManifestReferenceRenditionClass'] }, + 'manifestreferencerenditionparams' => { 489 => [\'Manifest','ManifestReferenceRenditionParams'] }, + 'manifestreferencetopart' => { 489 => [\'Manifest','ManifestReferenceToPart'] }, + 'manifestreferenceversionid' => { 489 => [\'Manifest','ManifestReferenceVersionID'] }, + 'manometerpressure' => { 283 => 0x900, 306 => 0x86 }, + 'manometerreading' => { 283 => 0x901 }, + 'manualafpointselectpattern' => { 81 => 0x513 }, 'manualafpointselpattern' => { 2 => 0xf }, - 'manualflash' => { 277 => 0x1209 }, - 'manualflashoutput' => { 33 => 0x29, 259 => '8.2', 262 => '22.2', 263 => '23.1', 264 => '23.2', 266 => '16.2', 267 => '23.2', 268 => '8.2', 269 => '23.2', 272 => '24.2', 358 => 0x100c }, - 'manualflashstrength' => { 274 => 0x406 }, - 'manualfocusdistance' => { 211 => 0x85, 279 => 0x100c, 367 => 0x223 }, - 'manualtv' => { 77 => 0x5, 78 => 0x705 }, - 'manufacturedate' => { 181 => 0x6705, 312 => 0x1 }, - 'manufacturedate1' => { 360 => 0x4 }, - 'manufacturedate2' => { 360 => 0x5 }, - 'manufacturer' => { 426 => 'Manufacturer', 455 => 'manufacturer' }, - 'mariahchromablursize' => { 131 => 0xf0d }, - 'mariahmaphithreshold' => { 131 => 0xf0c }, - 'mariahmaplothreshold' => { 131 => 0xf0b }, - 'mariahsigmathreshold' => { 131 => 0xf0e }, - 'mariahtexturethreshold' => { 131 => 0xf0a }, - 'marked' => { 453 => 'Marked', 470 => 'Marked' }, - 'markers' => { 466 => 'markers' }, - 'markerscomment' => { 466 => [\'markers','markersComment'] }, - 'markerscuepointparams' => { 466 => [\'markers','markersCuePointParams'] }, - 'markerscuepointparamskey' => { 466 => [\'markers','markersCuePointParamsKey'] }, - 'markerscuepointparamsvalue' => { 466 => [\'markers','markersCuePointParamsValue'] }, - 'markerscuepointtype' => { 466 => [\'markers','markersCuePointType'] }, - 'markersduration' => { 466 => [\'markers','markersDuration'] }, - 'markerslocation' => { 466 => [\'markers','markersLocation'] }, - 'markersname' => { 466 => [\'markers','markersName'] }, - 'markersprobability' => { 466 => [\'markers','markersProbability'] }, - 'markersspeaker' => { 466 => [\'markers','markersSpeaker'] }, - 'markersstarttime' => { 466 => [\'markers','markersStartTime'] }, - 'markerstarget' => { 466 => [\'markers','markersTarget'] }, - 'markerstype' => { 466 => [\'markers','markersType'] }, - 'maskedareas' => { 113 => 0xc68e }, - 'masterdocumentid' => { 125 => 0xb9 }, - 'mastergain' => { 218 => 0x50 }, - 'materialsample' => { 112 => 'MaterialSample' }, - 'materialsampleid' => { 112 => [\'MaterialSample','MaterialSampleMaterialSampleID'] }, - 'matrixmetering' => { 258 => '50.1', 260 => '48.1', 261 => '48.1', 270 => '48.1', 271 => '48.1' }, - 'matrixselectk' => { 131 => 0x91b }, - 'matrixselectthreshold' => { 131 => 0x91a }, - 'matrixselectthreshold1' => { 131 => 0x91e }, - 'matrixselectthreshold2' => { 131 => 0x91f }, - 'matrixstructure' => { 352 => 0xa }, - 'maxaperture' => { 33 => 0x1a, 131 => 0x3f9, 137 => 0x6103, 154 => 'MaxAperture', 171 => 0x17, 177 => 0x49c5, 275 => 0x20a, 323 => '14.1' }, - 'maxapertureatmaxfocal' => { 121 => 0x1407, 154 => 'MaxApertureAtMaxFocal', 206 => 0xb, 207 => 0x10, 208 => 0x11, 275 => 0x206 }, - 'maxapertureatminfocal' => { 121 => 0x1406, 206 => 0xa, 207 => 0xf, 208 => 0x10, 275 => 0x205 }, - 'maxaperturevalue' => { 113 => 0x9205, 341 => 0x414, 446 => 'MaxApertureValue' }, - 'maxavailheight' => { 452 => 'MaxAvailHeight' }, - 'maxavailwidth' => { 452 => 'MaxAvailWidth' }, - 'maxcontinuousrelease' => { 257 => 0xb, 258 => 0xc, 260 => '12.1', 261 => '12.1', 266 => 0xc, 267 => 0xb, 270 => '12.1', 271 => '12.1' }, - 'maxfaces' => { 278 => 0x1202 }, - 'maxfocallength' => { 6 => 0xe6, 7 => 0x10, 8 => 0x1ab, 9 => 0x13, 10 => 0x115, 11 => 0x13, 12 => 0x153, 13 => 0xda, 15 => 0xfa, 16 => 0xee, 17 => 0x103, 18 => 0x95, 19 => 0xea, 20 => 0x157, 21 => 0xee, 22 => 0xec, 23 => 0x12b, 24 => 0x165, 25 => 0x16a, 26 => 0x188, 27 => 0x116, 28 => 0x18d, 33 => 0x17, 121 => 0x1405, 154 => 'MaxFocalLength', 206 => 0x9, 207 => 0xe, 208 => 0xf, 275 => 0x208, 400 => 0x127c, 401 => 0x1138, 402 => 0x330, 403 => 0x330, 404 => 0x30e }, - 'maximumdensityrange' => { 127 => 0x8c }, - 'maxpagesize' => { 471 => 'MaxPageSize' }, - 'maxpagesizeh' => { 471 => [\'MaxPageSize','MaxPageSizeH'] }, - 'maxpagesizeunit' => { 471 => [\'MaxPageSize','MaxPageSizeUnit'] }, - 'maxpagesizew' => { 471 => [\'MaxPageSize','MaxPageSizeW'] }, - 'maxpixelvaluethreshold' => { 131 => 0xc7d }, - 'maxsamplevalue' => { 113 => 0x119 }, - 'maxstorage' => { 461 => 'maxstorage' }, - 'mb-d10batteries' => { 257 => '12.6' }, - 'mb-d10batterytype' => { 266 => '13.3' }, - 'mb-d11batterytype' => { 267 => '2.3' }, - 'mb-d12batterytype' => { 270 => '3.2' }, - 'mb-d80batteries' => { 268 => '6.5' }, - 'mb-d80batterytype' => { 272 => '3.2' }, - 'mcuversion' => { 206 => 0xc, 207 => 0x11, 208 => 0x12 }, - 'md5digest' => { 155 => 'zmd5' }, - 'mditemfindercomment' => { 164 => 'MDItemFinderComment' }, - 'mditemfscreationdate' => { 164 => 'MDItemFSCreationDate' }, - 'mditemfslabel' => { 164 => 'MDItemFSLabel' }, - 'mditemusertags' => { 164 => 'MDItemUserTags' }, - 'meal' => { 458 => 'meal' }, - 'measuredev' => { 27 => 0x9, 72 => 0x3, 91 => 0x1814, 147 => 'MeasuredEV' }, - 'measuredev2' => { 12 => 0x8, 27 => 0x8, 72 => 0x17 }, - 'measuredev3' => { 12 => 0x9 }, - 'measuredlv' => { 177 => 0x690, 292 => 0x312, 295 => 0x312, 296 => 0x312, 299 => 0x3407 }, - 'measuredrggb' => { 61 => 0x1 }, - 'measuredrggbdata' => { 41 => 0x287 }, - 'measurementaccuracy' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementAccuracy'] }, - 'measurementdeterminedby' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementDeterminedBy'] }, - 'measurementdetermineddate' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementDeterminedDate'] }, - 'measurementid' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementID'] }, - 'measurementmethod' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementMethod'] }, - 'measurementorfact' => { 112 => 'MeasurementOrFact' }, - 'measurementremarks' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementRemarks'] }, - 'measurementtype' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementType'] }, - 'measurementunit' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementUnit'] }, - 'measurementvalue' => { 112 => [\'MeasurementOrFact','MeasurementOrFactMeasurementValue'] }, - 'measuretype' => { 426 => 'MeasureType' }, - 'mechanicalshuttercount' => { 211 => 0x37 }, - 'mediaconstraints' => { 284 => 'MediaConstraints' }, - 'mediacreatedate' => { 349 => 0x1 }, - 'mediaeventiddate' => { 431 => 'MediaEventIdDate' }, - 'mediamodifydate' => { 349 => 0x2 }, - 'mediasummarycode' => { 284 => 'MediaSummaryCode' }, - 'memoaudioquality' => { 78 => 0x812 }, - 'memorycardconfiguration' => { 382 => 0x16 }, - 'memorycardnumber' => { 197 => 0x2 }, - 'menubuttondisplayposition' => { 76 => 0xb, 79 => 0xa, 80 => 0xb, 83 => 0xb }, - 'menubuttonreturn' => { 84 => 0xb }, - 'menumonitorofftime' => { 257 => '26.1', 258 => '22.1', 260 => '22.1', 261 => '22.1', 265 => '21.1', 266 => '8.2', 267 => '21.1', 270 => '22.1', 271 => '22.1', 272 => '22.1' }, - 'metadatadate' => { 464 => 'MetadataDate' }, - 'metadatamoddate' => { 466 => 'metadataModDate' }, - 'metaversion' => { 395 => 0x34 }, - 'meterinfo1row1' => { 389 => 0x0, 390 => 0x0 }, - 'meterinfo1row2' => { 389 => 0x6c, 390 => 0x5a }, - 'meterinfo1row3' => { 389 => 0xd8, 390 => 0xb4 }, - 'meterinfo1row4' => { 389 => 0x144, 390 => 0x10e }, - 'meterinfo1row5' => { 389 => 0x1b0, 390 => 0x168 }, - 'meterinfo1row6' => { 389 => 0x21c, 390 => 0x1c2 }, - 'meterinfo1row7' => { 389 => 0x288, 390 => 0x21c }, - 'meterinfo2row1' => { 389 => 0x2f4, 390 => 0x276 }, - 'meterinfo2row2' => { 389 => 0x378, 390 => 0x2e4 }, - 'meterinfo2row3' => { 389 => 0x3fc, 390 => 0x352 }, - 'meterinfo2row4' => { 389 => 0x480, 390 => 0x3c0 }, - 'meterinfo2row5' => { 389 => 0x504, 390 => 0x42e }, - 'meterinfo2row6' => { 389 => 0x588, 390 => 0x49c }, - 'meterinfo2row7' => { 389 => 0x60c, 390 => 0x50a }, - 'meterinfo2row8' => { 389 => 0x690, 390 => 0x578 }, - 'meterinfo2row9' => { 389 => 0x714, 390 => 0x5e6 }, - 'metering' => { 259 => '6.1' }, - 'meteringmode' => { 33 => 0x11, 113 => 0x9207, 133 => 0x1c, 171 => 0x7, 172 => 0x25, 174 => 0x12, 274 => 0x202, 332 => 0x17, 368 => 0x9, 376 => 0x15, 377 => 0x13, 378 => 0x7, 393 => 0x3, 396 => 0x1174, 397 => 0x1178, 398 => 0x1154, 399 => 0x11d0, 400 => 0x11ac, 401 => 0x1064, 402 => 0x25c, 403 => 0x25c, 404 => 0x24b, 446 => 'MeteringMode' }, - 'meteringmode2' => { 313 => '2.1', 388 => 0x202c }, - 'meteringmode3' => { 313 => '16.1' }, - 'meteringoffscaleindicator' => { 174 => 0x53 }, - 'meteringtime' => { 257 => '22.2', 259 => '3.2', 262 => '17.1', 263 => '18.1', 266 => '7.3', 267 => '18.1', 268 => '3.2', 272 => '19.1' }, - 'micro1version' => { 354 => 0x1f }, - 'micro2version' => { 354 => 0x2d }, - 'mieversion' => { 155 => '0Vers' }, - 'mime' => { 426 => 'Mime' }, - 'minaperture' => { 33 => 0x1b, 131 => 0x3f8, 154 => 'MinAperture', 323 => '0.2' }, - 'minaperturevalue' => { 341 => 0x415 }, - 'minfocallength' => { 6 => 0xe4, 7 => 0xe, 8 => 0x1a9, 9 => 0x11, 10 => 0x113, 11 => 0x11, 12 => 0x151, 13 => 0xd8, 15 => 0xf8, 16 => 0xec, 17 => 0x101, 18 => 0x93, 19 => 0xe8, 20 => 0x155, 21 => 0xec, 22 => 0xea, 23 => 0x129, 24 => 0x163, 25 => 0x168, 26 => 0x186, 27 => 0x114, 28 => 0x18b, 33 => 0x18, 121 => 0x1404, 154 => 'MinFocalLength', 206 => 0x8, 207 => 0xd, 208 => 0xe, 275 => 0x207, 400 => 0x127a, 401 => 0x1136, 402 => 0x32e, 403 => 0x32e, 404 => 0x30c }, - 'minfocusdistance' => { 323 => 0x3 }, - 'minintegrationrows' => { 131 => 0x1874 }, - 'minoltadate' => { 171 => 0x15 }, - 'minoltaimagesize' => { 171 => 0x4, 172 => 0xc, 173 => 0x2, 176 => 0x103 }, - 'minoltamodelid' => { 171 => 0x25 }, - 'minoltaquality' => { 171 => 0x5, 172 => 0xd, 173 => 0x3, 176 => [0x102,0x103] }, - 'minoltatime' => { 171 => 0x16 }, - 'minormodelagedisclosure' => { 284 => 'MinorModelAgeDisclosure' }, - 'minorversion' => { 432 => 'MinorVersion' }, - 'minsamplevalue' => { 113 => 0x118 }, - 'mirrorlockup' => { 76 => 0xc, 77 => 0xc, 78 => 0x60f, 79 => 0xb, 80 => 0xc, 81 => 0x6, 82 => 0x6, 83 => 0xc, 84 => 0x3 }, - 'mobilecountrycode' => { 440 => 'mcc' }, - 'mobilenetworkcode' => { 440 => 'mnc' }, - 'moddate' => { 287 => 'modify-date', 453 => 'ModDate' }, - 'modedialposition' => { 382 => 0x14 }, - 'model' => { 92 => 0x6, 113 => 0x110, 147 => 'Model', 287 => 'Model', 302 => 0x110, 332 => 0x23f, 368 => 0x84, 426 => 'Model', 455 => 'model', 462 => 'Model' }, - 'modelage' => { 452 => 'ModelAge' }, - 'modelid' => { 273 => 0x0 }, - 'modelingflash' => { 257 => '21.4', 258 => '31.1', 260 => '31.1', 261 => '31.1', 266 => '26.4', 267 => '30.2', 268 => '7.4', 269 => '30.1', 270 => '31.1', 271 => '31.1', 272 => '31.3' }, - 'modelreleaseid' => { 284 => 'ModelReleaseID' }, - 'modelreleasestatus' => { 284 => 'ModelReleaseStatus' }, - 'modelreleaseyear' => { 408 => 0x52, 409 => 0x46, 410 => 0x53 }, - 'modelyear' => { 455 => 'modelYear' }, - 'modificationdate' => { 456 => 'modificationDate' }, - 'modifiedcolortemp' => { 62 => 0x9 }, - 'modifieddigitalgain' => { 62 => 0xb }, - 'modifiedparamflag' => { 55 => 0x1 }, - 'modifiedpicturestyle' => { 62 => 0xa }, - 'modifiedsaturation' => { 274 => 0x504 }, - 'modifiedsensorbluelevel' => { 62 => 0x5 }, - 'modifiedsensorredlevel' => { 62 => 0x4 }, - 'modifiedsharpness' => { 62 => 0x2 }, - 'modifiedsharpnessfreq' => { 62 => 0x3 }, - 'modifiedtonecurve' => { 62 => 0x1 }, - 'modifiedwhitebalance' => { 62 => 0x8 }, - 'modifiedwhitebalanceblue' => { 62 => 0x7 }, - 'modifiedwhitebalancered' => { 62 => 0x6 }, - 'modifydate' => { 113 => 0x132, 148 => 'ModifyDate', 283 => 'ModDate', 285 => 'tIME', 348 => 'ModDate', 350 => 0x2, 464 => 'ModifyDate' }, - 'moirefilter' => { 113 => 0xfe58, 442 => 'MoireFilter' }, - 'monitordisplayoff' => { 174 => 0x4c }, - 'monitormatrix' => { 131 => 0x8fc }, - 'monitorofftime' => { 257 => '18.2', 259 => '3.1', 268 => '3.1' }, - 'monochromecolor' => { 274 => 0x53b }, - 'monochromecontrast' => { 103 => 0x3c }, - 'monochromefiltereffect' => { 97 => 0x20307, 103 => 0x3a, 332 => 0x73 }, - 'monochromelinear' => { 103 => 0x3d }, - 'monochromeoutputhighlightpoint' => { 103 => 0x41 }, - 'monochromeoutputshadowpoint' => { 103 => 0x42 }, - 'monochromeprofilesettings' => { 274 => 0x537 }, - 'monochromerawhighlight' => { 103 => 0x7a }, - 'monochromerawhighlightpoint' => { 103 => 0x3f }, - 'monochromerawshadow' => { 103 => 0x83 }, - 'monochromerawshadowpoint' => { 103 => 0x40 }, - 'monochromesharpness' => { 103 => 0x3e }, - 'monochrometoning' => { 332 => 0x74 }, - 'monochrometoningeffect' => { 97 => 0x20306, 103 => 0x3b }, - 'monochromeunsharpmaskfineness' => { 103 => 0xb2 }, - 'monochromeunsharpmaskstrength' => { 103 => 0xb0 }, - 'monochromeunsharpmaskthreshold' => { 103 => 0xb4 }, - 'monochromevignetting' => { 274 => 0x53a }, - 'monthdaycreated' => { 133 => 0x12, 142 => 0xe }, - 'moonphase' => { 353 => 0x12, 354 => 0x43 }, - 'morepermissions' => { 439 => 'morePermissions' }, - 'motionsensitivity' => { 353 => 0x29 }, - 'movieaelockbuttonassignment' => { 270 => '40.1' }, - 'moviefunc1button' => { 260 => '41.1', 261 => '41.1', 271 => '41.1' }, - 'moviefunctionbutton' => { 258 => '41.1', 270 => '41.1' }, - 'moviefunctionbuttonplusdials' => { 258 => '52.1' }, - 'moviepreviewbutton' => { 258 => '41.2', 260 => '41.2', 261 => '41.2', 270 => '41.2', 271 => '41.2' }, - 'moviepreviewbuttonplusdials' => { 258 => '52.2' }, - 'movieshutterbutton' => { 258 => '38.3', 260 => '38.3', 261 => '38.3', 270 => '38.3', 271 => '38.3' }, - 'moviesubselectorassignment' => { 258 => '48.2' }, - 'moviesubselectorassignmentplusdials' => { 258 => '53.1' }, - 'multiburstimageheight' => { 388 => 0x1002 }, - 'multiburstimagewidth' => { 388 => 0x1001 }, - 'multiburstmode' => { 388 => 0x1000 }, - 'multicontrollerwhilemetering' => { 78 => 0x517 }, - 'multiexposure' => { 64 => 0x1, 297 => 0xb4 }, - 'multiexposureautogain' => { 212 => 0x3 }, - 'multiexposurecontrol' => { 64 => 0x2 }, - 'multiexposuremode' => { 212 => 0x1 }, - 'multiexposureshots' => { 64 => 0x3, 212 => 0x2 }, - 'multiframenoisereduction' => { 378 => 0x35, 388 => 0x200b, 393 => 0x15 }, - 'multiframenreffect' => { 388 => 0x2023 }, - 'multifunctionlock' => { 78 => 0x70f }, - 'multipleexposuremode' => { 278 => 0x101c }, - 'multipleexposureset' => { 313 => '10.1' }, - 'multisample' => { 218 => 0x40 }, - 'multiselector' => { 257 => '9.4', 258 => '10.3', 260 => '10.3', 261 => '10.3', 266 => '27.4', 270 => '10.3', 271 => '10.3' }, - 'multiselectorliveview' => { 257 => '4.3', 260 => '37.1', 261 => '37.1', 270 => '37.1', 271 => '37.1' }, - 'multiselectorliveviewmode' => { 228 => 0x18c2 }, - 'multiselectorplaybackmode' => { 257 => ['13.5','9.2'], 258 => '10.2', 261 => '10.2', 266 => '27.2', 270 => '10.2', 271 => '10.2' }, - 'multiselectorshootmode' => { 257 => '9.1', 258 => '10.1', 260 => '10.1', 261 => '10.1', 266 => '27.1', 270 => '10.1', 271 => '10.1' }, - 'multishot' => { 302 => 0x121 }, - 'mycolormode' => { 65 => 0x2 }, - 'nationalcatalognumber' => { 456 => 'nationalCatalogNumber' }, - 'nativedigest' => { 446 => 'NativeDigest', 462 => 'NativeDigest' }, - 'ndfilter' => { 72 => 0x1c, 274 => 0x204, 358 => 0x1019 }, - 'near' => { 426 => 'Near' }, - 'nefbitdepth' => { 211 => 0xe22 }, - 'nefcompression' => { 211 => 0x93 }, - 'neflinearizationtable' => { 211 => 0x96 }, - 'negativecachelargepreviewsize' => { 442 => 'NegativeCacheLargePreviewSize' }, - 'negativecachemaximumsize' => { 442 => 'NegativeCacheMaximumSize' }, - 'negativecachepath' => { 442 => 'NegativeCachePath' }, - 'neutraldensityfilter' => { 332 => 0x88 }, - 'neutraloutputhighlightpoint' => { 103 => 0x2f }, - 'neutraloutputshadowpoint' => { 103 => 0x30 }, - 'neutralrawcolortone' => { 103 => 0x28 }, - 'neutralrawcontrast' => { 103 => 0x2a }, - 'neutralrawhighlight' => { 103 => 0x78 }, - 'neutralrawhighlightpoint' => { 103 => 0x2d }, - 'neutralrawlinear' => { 103 => 0x2b }, - 'neutralrawsaturation' => { 103 => 0x29 }, - 'neutralrawshadow' => { 103 => 0x81 }, - 'neutralrawshadowpoint' => { 103 => 0x2e }, - 'neutralrawsharpness' => { 103 => 0x2c }, - 'neutralunsharpmaskfineness' => { 103 => 0xa6 }, - 'neutralunsharpmaskthreshold' => { 103 => 0xa8 }, - 'neutraunsharpmaskstrength' => { 103 => 0xa4 }, - 'newrawimagedigest' => { 113 => 0xc7a7 }, - 'newsphotoversion' => { 127 => 0x0 }, - 'nickname' => { 464 => 'Nickname' }, - 'nikoncapturedata' => { 211 => 0xe01 }, - 'nikoncaptureeditversions' => { 211 => 0xe13 }, - 'nikoncaptureoutput' => { 211 => 0xe1e }, - 'nikoncaptureversion' => { 211 => 0xe09 }, - 'nikoniccprofile' => { 211 => 0xe1d }, - 'nikonimagesize' => { 225 => '723.1', 226 => '732.1', 235 => 0x2c4 }, - 'noisefilter' => { 274 => 0x527 }, - 'noiseprofile' => { 113 => 0xc761 }, - 'noisereduction' => { 121 => [0x100b,0x100e], 172 => 0xb0, 173 => 0x60, 174 => 0x3f, 211 => 0x95, 250 => 0x753dcbc0, 251 => 0x17, 274 => 0x50a, 279 => 0x103a, 297 => 0x2d, 332 => 0x49, 358 => 0x100f, 360 => 0x2a }, - 'noisereduction2' => { 278 => 0x1010 }, - 'noisereductionapplied' => { 113 => 0xc6f7 }, - 'noisereductionintensity' => { 251 => 0x9 }, - 'noisereductionmethod' => { 251 => 0x11 }, - 'noisereductionmode' => { 421 => 0x801e }, - 'noisereductionparametersatcapture' => { 131 => 0xe73 }, - 'noisereductionparameterscamera' => { 131 => 0xe72 }, - 'noisereductionparametershost3mp' => { 131 => 0xe71 }, - 'noisereductionparametershost6mp' => { 131 => 0xe70 }, - 'noisereductionparametershostrgb' => { 131 => 0xe6f }, - 'noisereductionparameterskhufu3mp' => { 131 => 0xe65 }, - 'noisereductionparameterskhufu6mp' => { 131 => 0xe64 }, - 'noisereductionparameterskhufurgb' => { 131 => 0xe63 }, - 'noisereductionparams' => { 302 => 0x1b }, - 'noisereductionsharpness' => { 251 => 0xd }, - 'noisereductionvalue' => { 421 => 0x8027 }, - 'nomemorycard' => { 257 => '22.1', 258 => '4.2', 259 => '0.3', 262 => '2.4', 263 => '3.2', 264 => '3.2', 266 => '33.7', 267 => '3.2', 268 => '0.3', 270 => '4.2', 272 => '4.5' }, - 'nominalmaxaperture' => { 323 => 0xa }, - 'nominalminaperture' => { 323 => '10.1' }, - 'normallinetime' => { 131 => 0x186a }, - 'normalwhitelevel' => { 42 => [0x2b8,0x2cf,0x2d3], 44 => 0x1e3, 45 => [0x1fc,0x2dc], 46 => [0x230,0x30e], 47 => 0x31c }, - 'notes' => { 422 => 'Notes', 436 => 'notes' }, - 'npages' => { 471 => 'NPages' }, - 'nullrecord' => { 91 => 0x0 }, - 'numafpoints' => { 309 => 0x2 }, - 'number' => { 456 => 'number' }, - 'numberofbeats' => { 466 => 'numberOfBeats' }, - 'numberoffocuspoints' => { 260 => '1.2', 261 => '1.2', 264 => '0.2', 265 => '0.3', 267 => '0.3' }, - 'numfaceelements' => { 121 => 0x4200 }, - 'numfacepositions' => { 289 => 0x0 }, - 'numindexentries' => { 127 => 0x54 }, - 'numwbentries' => { 303 => 0x0, 304 => 0x0 }, - 'object' => { 456 => 'object' }, - 'objectattributereference' => { 125 => 0x4 }, - 'objectcycle' => { 125 => 0x4b, 436 => 'ObjectCycle' }, - 'objectdescription' => { 455 => 'objectDescription' }, - 'objectdistance' => { 106 => 0x6, 107 => 0x2022 }, - 'objectname' => { 125 => 0x5 }, - 'objectpreviewdata' => { 125 => 0xca }, - 'objectpreviewfileformat' => { 125 => 0xc8 }, - 'objectpreviewfileversion' => { 125 => 0xc9 }, - 'objectsubtype' => { 455 => 'objectSubtype' }, - 'objecttype' => { 455 => 'objectType' }, - 'objecttypereference' => { 125 => 0x3 }, - 'occurrence' => { 112 => 'Occurrence' }, - 'occurrenceassociatedmedia' => { 112 => [\'Occurrence','OccurrenceAssociatedMedia'] }, - 'occurrenceassociatedoccurrences' => { 112 => [\'Occurrence','OccurrenceAssociatedOccurrences'] }, - 'occurrenceassociatedreferences' => { 112 => [\'Occurrence','OccurrenceAssociatedReferences'] }, - 'occurrenceassociatedsequences' => { 112 => [\'Occurrence','OccurrenceAssociatedSequences'] }, - 'occurrenceassociatedtaxa' => { 112 => [\'Occurrence','OccurrenceAssociatedTaxa'] }, - 'occurrencebehavior' => { 112 => [\'Occurrence','OccurrenceBehavior'] }, - 'occurrencecatalognumber' => { 112 => [\'Occurrence','OccurrenceCatalogNumber'] }, - 'occurrencedetails' => { 112 => [\'Occurrence','OccurrenceOccurrenceDetails'] }, - 'occurrencedisposition' => { 112 => [\'Occurrence','OccurrenceDisposition'] }, - 'occurrenceestablishmentmeans' => { 112 => [\'Occurrence','OccurrenceEstablishmentMeans'] }, - 'occurrenceid' => { 112 => [\'Occurrence','OccurrenceOccurrenceID'] }, - 'occurrenceindividualcount' => { 112 => [\'Occurrence','OccurrenceIndividualCount'] }, - 'occurrenceindividualid' => { 112 => [\'Occurrence','OccurrenceIndividualID'] }, - 'occurrencelifestage' => { 112 => [\'Occurrence','OccurrenceLifeStage'] }, - 'occurrenceorganismquantity' => { 112 => [\'Occurrence','OccurrenceOrganismQuantity'] }, - 'occurrenceorganismquantitytype' => { 112 => [\'Occurrence','OccurrenceOrganismQuantityType'] }, - 'occurrenceothercatalognumbers' => { 112 => [\'Occurrence','OccurrenceOtherCatalogNumbers'] }, - 'occurrencepreparations' => { 112 => [\'Occurrence','OccurrencePreparations'] }, - 'occurrencepreviousidentifications' => { 112 => [\'Occurrence','OccurrencePreviousIdentifications'] }, - 'occurrencerecordedby' => { 112 => [\'Occurrence','OccurrenceRecordedBy'] }, - 'occurrencerecordnumber' => { 112 => [\'Occurrence','OccurrenceRecordNumber'] }, - 'occurrenceremarks' => { 112 => [\'Occurrence','OccurrenceOccurrenceRemarks'] }, - 'occurrencereproductivecondition' => { 112 => [\'Occurrence','OccurrenceReproductiveCondition'] }, - 'occurrencesex' => { 112 => [\'Occurrence','OccurrenceSex'] }, - 'occurrencestatus' => { 112 => [\'Occurrence','OccurrenceOccurrenceStatus'] }, - 'oecfcolumns' => { 446 => [\'OECF','OECFColumns'] }, - 'oecfnames' => { 446 => [\'OECF','OECFNames'] }, - 'oecfrows' => { 446 => [\'OECF','OECFRows'] }, - 'oecfvalues' => { 446 => [\'OECF','OECFValues'] }, - 'offsaledate' => { 456 => 'offSaleDate' }, - 'offsaledatea-platform' => { 456 => [\'offSaleDate','offSaleDateA-platform'] }, - 'offsaledatedate' => { 456 => [\'offSaleDate','offSaleDateDate'] }, - 'offsetdacvalue' => { 131 => 0x190a }, - 'offsetschema' => { 113 => 0xea1d }, - 'offsettime' => { 113 => 0x9010 }, - 'offsettimedigitized' => { 113 => 0x9012 }, - 'offsettimeoriginal' => { 113 => 0x9011 }, - 'okbutton' => { 267 => '15.1', 272 => '16.1' }, - 'oldsubfiletype' => { 113 => 0xff }, - 'olympusimageheight' => { 279 => 0x102f }, - 'olympusimagewidth' => { 279 => 0x102e }, - 'omenatcapturestrength' => { 131 => 0xa60 }, - 'omenautostrength' => { 131 => 0xa5f }, - 'omenearlystrength' => { 131 => 0xa5e }, - 'omenfocallengthlimit' => { 131 => 0xa62 }, - 'omeninitialipfstrength' => { 131 => 0xa5d }, - 'omensurfaceindex' => { 131 => 0xa64 }, + 'manualflash' => { 286 => 0x1209 }, + 'manualflashoutput' => { 34 => 0x29, 268 => '8.2', 271 => '22.2', 272 => '23.1', 273 => '23.2', 275 => '16.2', 276 => '23.2', 277 => '8.2', 278 => '23.2', 281 => '24.2', 373 => 0x100c }, + 'manualflashstrength' => { 283 => 0x406 }, + 'manualfocusdistance' => { 219 => 0x85, 288 => 0x100c, 382 => 0x223 }, + 'manualtv' => { 80 => 0x5, 81 => 0x705 }, + 'manufacturedate' => { 186 => 0x6705, 321 => 0x1 }, + 'manufacturedate1' => { 375 => 0x4 }, + 'manufacturedate2' => { 375 => 0x5 }, + 'manufacturer' => { 447 => 'Manufacturer', 477 => 'manufacturer' }, + 'mariahchromablursize' => { 134 => 0xf0d }, + 'mariahmaphithreshold' => { 134 => 0xf0c }, + 'mariahmaplothreshold' => { 134 => 0xf0b }, + 'mariahsigmathreshold' => { 134 => 0xf0e }, + 'mariahtexturethreshold' => { 134 => 0xf0a }, + 'marked' => { 475 => 'Marked', 492 => 'Marked' }, + 'markers' => { 488 => 'markers' }, + 'markerscomment' => { 488 => [\'markers','markersComment'] }, + 'markerscuepointparams' => { 488 => [\'markers','markersCuePointParams'] }, + 'markerscuepointparamskey' => { 488 => [\'markers','markersCuePointParamsKey'] }, + 'markerscuepointparamsvalue' => { 488 => [\'markers','markersCuePointParamsValue'] }, + 'markerscuepointtype' => { 488 => [\'markers','markersCuePointType'] }, + 'markersduration' => { 488 => [\'markers','markersDuration'] }, + 'markerslocation' => { 488 => [\'markers','markersLocation'] }, + 'markersname' => { 488 => [\'markers','markersName'] }, + 'markersprobability' => { 488 => [\'markers','markersProbability'] }, + 'markersspeaker' => { 488 => [\'markers','markersSpeaker'] }, + 'markersstarttime' => { 488 => [\'markers','markersStartTime'] }, + 'markerstarget' => { 488 => [\'markers','markersTarget'] }, + 'markerstype' => { 488 => [\'markers','markersType'] }, + 'maskedareas' => { 116 => 0xc68e }, + 'masterdocumentid' => { 128 => 0xb9 }, + 'mastergain' => { 227 => 0x50 }, + 'materialsample' => { 115 => 'MaterialSample' }, + 'materialsampleid' => { 115 => [\'MaterialSample','MaterialSampleMaterialSampleID'] }, + 'matrixmetering' => { 267 => '50.1', 269 => '48.1', 270 => '48.1', 279 => '48.1', 280 => '48.1' }, + 'matrixselectk' => { 134 => 0x91b }, + 'matrixselectthreshold' => { 134 => 0x91a }, + 'matrixselectthreshold1' => { 134 => 0x91e }, + 'matrixselectthreshold2' => { 134 => 0x91f }, + 'matrixstructure' => { 365 => 0xa }, + 'maxaperture' => { 34 => 0x1a, 134 => 0x3f9, 140 => 0x6103, 159 => 'MaxAperture', 176 => 0x17, 182 => 0x49c5, 217 => 0x36, 284 => 0x20a, 332 => '14.1' }, + 'maxapertureatmaxfocal' => { 124 => 0x1407, 159 => 'MaxApertureAtMaxFocal', 211 => 0xb, 212 => 0x10, 213 => 0x11, 217 => 0x12, 284 => 0x206 }, + 'maxapertureatminfocal' => { 124 => 0x1406, 211 => 0xa, 212 => 0xf, 213 => 0x10, 217 => 0x11, 284 => 0x205 }, + 'maxaperturevalue' => { 116 => 0x9205, 350 => 0x414, 468 => 'MaxApertureValue' }, + 'maxavailheight' => { 474 => 'MaxAvailHeight' }, + 'maxavailwidth' => { 474 => 'MaxAvailWidth' }, + 'maxcontinuousrelease' => { 266 => 0xb, 267 => 0xc, 269 => '12.1', 270 => '12.1', 275 => 0xc, 276 => 0xb, 279 => '12.1', 280 => '12.1' }, + 'maxfaces' => { 287 => 0x1202 }, + 'maxfocallength' => { 7 => 0xe6, 8 => 0x10, 9 => 0x1ab, 10 => 0x13, 11 => 0x115, 12 => 0x13, 13 => 0x153, 14 => 0xda, 16 => 0xfa, 17 => 0xee, 18 => 0x103, 19 => 0x95, 20 => 0xea, 21 => 0x157, 22 => 0xee, 23 => 0xec, 24 => 0x12b, 25 => 0x165, 26 => 0x16a, 27 => 0x188, 28 => 0x116, 29 => 0x18d, 34 => 0x17, 124 => 0x1405, 159 => 'MaxFocalLength', 211 => 0x9, 212 => 0xe, 213 => 0xf, 217 => 0x10, 284 => 0x208, 418 => 0x127c, 419 => 0x1138, 420 => 0x330, 421 => 0x330, 422 => 0x30e }, + 'maximumdensityrange' => { 130 => 0x8c }, + 'maxpagesize' => { 493 => 'MaxPageSize' }, + 'maxpagesizeh' => { 493 => [\'MaxPageSize','MaxPageSizeH'] }, + 'maxpagesizeunit' => { 493 => [\'MaxPageSize','MaxPageSizeUnit'] }, + 'maxpagesizew' => { 493 => [\'MaxPageSize','MaxPageSizeW'] }, + 'maxpixelvaluethreshold' => { 134 => 0xc7d }, + 'maxsamplevalue' => { 116 => 0x119 }, + 'maxstorage' => { 483 => 'maxstorage' }, + 'mb-d10batteries' => { 266 => '12.6' }, + 'mb-d10batterytype' => { 275 => '13.3' }, + 'mb-d11batterytype' => { 276 => '2.3' }, + 'mb-d12batterytype' => { 279 => '3.2' }, + 'mb-d80batteries' => { 277 => '6.5' }, + 'mb-d80batterytype' => { 281 => '3.2' }, + 'mcuversion' => { 211 => 0xc, 212 => 0x11, 213 => 0x12, 217 => 0x13 }, + 'md5digest' => { 160 => 'zmd5' }, + 'mditemfindercomment' => { 169 => 'MDItemFinderComment' }, + 'mditemfscreationdate' => { 169 => 'MDItemFSCreationDate' }, + 'mditemfslabel' => { 169 => 'MDItemFSLabel' }, + 'mditemusertags' => { 169 => 'MDItemUserTags' }, + 'meal' => { 480 => 'meal' }, + 'measuredev' => { 28 => 0x9, 74 => 0x3, 94 => 0x1814, 152 => 'MeasuredEV' }, + 'measuredev2' => { 13 => 0x8, 28 => 0x8, 74 => 0x17 }, + 'measuredev3' => { 13 => 0x9 }, + 'measuredlv' => { 182 => 0x690, 301 => 0x312, 304 => 0x312, 305 => 0x312, 308 => 0x3407 }, + 'measuredrggb' => { 62 => 0x1 }, + 'measuredrggbdata' => { 42 => 0x287 }, + 'measurementaccuracy' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementAccuracy'] }, + 'measurementdeterminedby' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementDeterminedBy'] }, + 'measurementdetermineddate' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementDeterminedDate'] }, + 'measurementid' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementID'] }, + 'measurementmethod' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementMethod'] }, + 'measurementorfact' => { 115 => 'MeasurementOrFact' }, + 'measurementremarks' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementRemarks'] }, + 'measurementtype' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementType'] }, + 'measurementunit' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementUnit'] }, + 'measurementvalue' => { 115 => [\'MeasurementOrFact','MeasurementOrFactMeasurementValue'] }, + 'measuretype' => { 447 => 'MeasureType' }, + 'mechanicalshuttercount' => { 219 => 0x37 }, + 'mediaconstraints' => { 293 => 'MediaConstraints' }, + 'mediacreatedate' => { 362 => 0x1 }, + 'mediaeventiddate' => { 452 => 'MediaEventIdDate' }, + 'mediamodifydate' => { 362 => 0x2 }, + 'mediasummarycode' => { 293 => 'MediaSummaryCode' }, + 'mediatype' => { 358 => 'stik' }, + 'memoaudioquality' => { 81 => 0x812 }, + 'memorycardconfiguration' => { 399 => 0x16 }, + 'memorycardnumber' => { 202 => 0x2 }, + 'menubuttondisplayposition' => { 79 => 0xb, 82 => 0xa, 83 => 0xb, 86 => 0xb }, + 'menubuttonreturn' => { 87 => 0xb }, + 'menumonitorofftime' => { 266 => '26.1', 267 => '22.1', 269 => '22.1', 270 => '22.1', 274 => '21.1', 275 => '8.2', 276 => '21.1', 279 => '22.1', 280 => '22.1', 281 => '22.1' }, + 'metadatadate' => { 486 => 'MetadataDate' }, + 'metadatamoddate' => { 488 => 'metadataModDate' }, + 'metaversion' => { 413 => 0x34 }, + 'meterinfo1row1' => { 407 => 0x0, 408 => 0x0 }, + 'meterinfo1row2' => { 407 => 0x6c, 408 => 0x5a }, + 'meterinfo1row3' => { 407 => 0xd8, 408 => 0xb4 }, + 'meterinfo1row4' => { 407 => 0x144, 408 => 0x10e }, + 'meterinfo1row5' => { 407 => 0x1b0, 408 => 0x168 }, + 'meterinfo1row6' => { 407 => 0x21c, 408 => 0x1c2 }, + 'meterinfo1row7' => { 407 => 0x288, 408 => 0x21c }, + 'meterinfo2row1' => { 407 => 0x2f4, 408 => 0x276 }, + 'meterinfo2row2' => { 407 => 0x378, 408 => 0x2e4 }, + 'meterinfo2row3' => { 407 => 0x3fc, 408 => 0x352 }, + 'meterinfo2row4' => { 407 => 0x480, 408 => 0x3c0 }, + 'meterinfo2row5' => { 407 => 0x504, 408 => 0x42e }, + 'meterinfo2row6' => { 407 => 0x588, 408 => 0x49c }, + 'meterinfo2row7' => { 407 => 0x60c, 408 => 0x50a }, + 'meterinfo2row8' => { 407 => 0x690, 408 => 0x578 }, + 'meterinfo2row9' => { 407 => 0x714, 408 => 0x5e6 }, + 'metering' => { 268 => '6.1' }, + 'meteringmode' => { 34 => 0x11, 116 => 0x9207, 136 => 0x1c, 176 => 0x7, 177 => 0x25, 179 => 0x12, 283 => 0x202, 341 => 0x17, 383 => 0x9, 393 => 0x15, 394 => 0x13, 395 => 0x7, 411 => 0x3, 414 => 0x1174, 415 => 0x1178, 416 => 0x1154, 417 => 0x11d0, 418 => 0x11ac, 419 => 0x1064, 420 => 0x25c, 421 => 0x25c, 422 => 0x24b, 468 => 'MeteringMode' }, + 'meteringmode2' => { 322 => '2.1', 406 => 0x202c }, + 'meteringmode3' => { 322 => '16.1' }, + 'meteringoffscaleindicator' => { 179 => 0x53 }, + 'meteringtime' => { 266 => '22.2', 268 => '3.2', 271 => '17.1', 272 => '18.1', 275 => '7.3', 276 => '18.1', 277 => '3.2', 281 => '19.1' }, + 'micro1version' => { 368 => 0x1f }, + 'micro2version' => { 368 => 0x2d }, + 'midrangesharpness' => { 223 => 0x3b }, + 'mieversion' => { 160 => '0Vers' }, + 'mime' => { 447 => 'Mime' }, + 'minaperture' => { 34 => 0x1b, 134 => 0x3f8, 159 => 'MinAperture', 332 => '0.2' }, + 'minaperturevalue' => { 350 => 0x415 }, + 'minfocallength' => { 7 => 0xe4, 8 => 0xe, 9 => 0x1a9, 10 => 0x11, 11 => 0x113, 12 => 0x11, 13 => 0x151, 14 => 0xd8, 16 => 0xf8, 17 => 0xec, 18 => 0x101, 19 => 0x93, 20 => 0xe8, 21 => 0x155, 22 => 0xec, 23 => 0xea, 24 => 0x129, 25 => 0x163, 26 => 0x168, 27 => 0x186, 28 => 0x114, 29 => 0x18b, 34 => 0x18, 124 => 0x1404, 159 => 'MinFocalLength', 211 => 0x8, 212 => 0xd, 213 => 0xe, 217 => 0xf, 284 => 0x207, 418 => 0x127a, 419 => 0x1136, 420 => 0x32e, 421 => 0x32e, 422 => 0x30c }, + 'minfocusdistance' => { 332 => 0x3 }, + 'minintegrationrows' => { 134 => 0x1874 }, + 'minoltadate' => { 176 => 0x15 }, + 'minoltaimagesize' => { 176 => 0x4, 177 => 0xc, 178 => 0x2, 181 => 0x103 }, + 'minoltamodelid' => { 176 => 0x25 }, + 'minoltaquality' => { 176 => 0x5, 177 => 0xd, 178 => 0x3, 181 => [0x102,0x103] }, + 'minoltatime' => { 176 => 0x16 }, + 'minormodelagedisclosure' => { 293 => 'MinorModelAgeDisclosure' }, + 'minorversion' => { 453 => 'MinorVersion' }, + 'minsamplevalue' => { 116 => 0x118 }, + 'mirrorlockup' => { 79 => 0xc, 80 => 0xc, 81 => 0x60f, 82 => 0xb, 83 => 0xc, 84 => 0x6, 85 => 0x6, 86 => 0xc, 87 => 0x3 }, + 'mobilecountrycode' => { 461 => 'mcc' }, + 'mobilenetworkcode' => { 461 => 'mnc' }, + 'moddate' => { 296 => 'modify-date', 475 => 'ModDate' }, + 'modedialposition' => { 399 => 0x14 }, + 'model' => { 95 => 0x6, 116 => 0x110, 152 => 'Model', 296 => 'Model', 311 => 0x110, 341 => 0x23f, 360 => 'model', 366 => ['CNMN','cmnm',"\xa9mdl","\xa9mod"], 383 => 0x84, 447 => 'Model', 477 => 'model', 484 => 'Model' }, + 'modelage' => { 474 => 'ModelAge' }, + 'modelid' => { 282 => 0x0 }, + 'modelingflash' => { 266 => '21.4', 267 => '31.1', 269 => '31.1', 270 => '31.1', 275 => '26.4', 276 => '30.2', 277 => '7.4', 278 => '30.1', 279 => '31.1', 280 => '31.1', 281 => '31.3' }, + 'modelreleaseid' => { 293 => 'ModelReleaseID' }, + 'modelreleasestatus' => { 293 => 'ModelReleaseStatus' }, + 'modelreleaseyear' => { 426 => 0x52, 427 => 0x46, 428 => 0x53 }, + 'modeltiepoint' => { 116 => 0x8482 }, + 'modeltransform' => { 116 => 0x85d8 }, + 'modelyear' => { 477 => 'modelYear' }, + 'modificationdate' => { 478 => 'modificationDate' }, + 'modifiedcolortemp' => { 63 => 0x9 }, + 'modifieddigitalgain' => { 63 => 0xb }, + 'modifiedparamflag' => { 56 => 0x1 }, + 'modifiedpicturestyle' => { 63 => 0xa }, + 'modifiedsaturation' => { 283 => 0x504 }, + 'modifiedsensorbluelevel' => { 63 => 0x5 }, + 'modifiedsensorredlevel' => { 63 => 0x4 }, + 'modifiedsharpness' => { 63 => 0x2 }, + 'modifiedsharpnessfreq' => { 63 => 0x3 }, + 'modifiedtonecurve' => { 63 => 0x1 }, + 'modifiedwhitebalance' => { 63 => 0x8 }, + 'modifiedwhitebalanceblue' => { 63 => 0x7 }, + 'modifiedwhitebalancered' => { 63 => 0x6 }, + 'modifydate' => { 116 => 0x132, 153 => 'ModifyDate', 292 => 'ModDate', 294 => 'tIME', 357 => 'ModDate', 363 => 0x2, 486 => 'ModifyDate' }, + 'moirefilter' => { 116 => 0xfe58, 462 => 'MoireFilter', 464 => 'MoireFilter' }, + 'monitordisplayoff' => { 179 => 0x4c }, + 'monitormatrix' => { 134 => 0x8fc }, + 'monitorofftime' => { 266 => '18.2', 268 => '3.1', 277 => '3.1' }, + 'monochromecolor' => { 283 => 0x53b }, + 'monochromecontrast' => { 106 => 0x3c }, + 'monochromefiltereffect' => { 100 => 0x20307, 106 => 0x3a, 341 => 0x73 }, + 'monochromelinear' => { 106 => 0x3d }, + 'monochromeoutputhighlightpoint' => { 106 => 0x41 }, + 'monochromeoutputshadowpoint' => { 106 => 0x42 }, + 'monochromeprofilesettings' => { 283 => 0x537 }, + 'monochromerawhighlight' => { 106 => 0x7a }, + 'monochromerawhighlightpoint' => { 106 => 0x3f }, + 'monochromerawshadow' => { 106 => 0x83 }, + 'monochromerawshadowpoint' => { 106 => 0x40 }, + 'monochromesharpness' => { 106 => 0x3e }, + 'monochrometoning' => { 341 => 0x74 }, + 'monochrometoningeffect' => { 100 => 0x20306, 106 => 0x3b }, + 'monochromeunsharpmaskfineness' => { 106 => 0xb2 }, + 'monochromeunsharpmaskstrength' => { 106 => 0xb0 }, + 'monochromeunsharpmaskthreshold' => { 106 => 0xb4 }, + 'monochromevignetting' => { 283 => 0x53a }, + 'monthdaycreated' => { 136 => 0x12, 145 => 0xe }, + 'moonphase' => { 367 => 0x12, 368 => 0x43, 369 => 0x4c }, + 'morepermissions' => { 460 => 'morePermissions' }, + 'motionsensitivity' => { 367 => 0x29, 369 => 0x60 }, + 'movieaelockbuttonassignment' => { 279 => '40.1' }, + 'moviefunc1button' => { 269 => '41.1', 270 => '41.1', 280 => '41.1' }, + 'moviefunctionbutton' => { 267 => '41.1', 279 => '41.1' }, + 'moviefunctionbuttonplusdials' => { 267 => '52.1' }, + 'moviepreviewbutton' => { 267 => '41.2', 269 => '41.2', 270 => '41.2', 279 => '41.2', 280 => '41.2' }, + 'moviepreviewbuttonplusdials' => { 267 => '52.2' }, + 'movieshutterbutton' => { 267 => '38.3', 269 => '38.3', 270 => '38.3', 279 => '38.3', 280 => '38.3' }, + 'moviesubselectorassignment' => { 267 => '48.2' }, + 'moviesubselectorassignmentplusdials' => { 267 => '53.1' }, + 'multiburstimageheight' => { 406 => 0x1002 }, + 'multiburstimagewidth' => { 406 => 0x1001 }, + 'multiburstmode' => { 406 => 0x1000 }, + 'multicontrollerwhilemetering' => { 81 => 0x517 }, + 'multiexposure' => { 65 => 0x1, 306 => 0xb4 }, + 'multiexposureautogain' => { 220 => 0x3 }, + 'multiexposurecontrol' => { 65 => 0x2 }, + 'multiexposuremode' => { 220 => 0x1 }, + 'multiexposureshots' => { 65 => 0x3, 220 => 0x2 }, + 'multiframenoisereduction' => { 395 => 0x35, 406 => 0x200b, 411 => 0x15 }, + 'multiframenreffect' => { 406 => 0x2023 }, + 'multifunctionlock' => { 81 => 0x70f }, + 'multipleexposuremode' => { 287 => 0x101c }, + 'multipleexposureset' => { 322 => '10.1' }, + 'multisample' => { 227 => 0x40 }, + 'multiselector' => { 266 => '9.4', 267 => '10.3', 269 => '10.3', 270 => '10.3', 275 => '27.4', 279 => '10.3', 280 => '10.3' }, + 'multiselectorliveview' => { 266 => '4.3', 269 => '37.1', 270 => '37.1', 279 => '37.1', 280 => '37.1' }, + 'multiselectorliveviewmode' => { 237 => 0x18c2 }, + 'multiselectorplaybackmode' => { 266 => ['13.5','9.2'], 267 => '10.2', 270 => '10.2', 275 => '27.2', 279 => '10.2', 280 => '10.2' }, + 'multiselectorshootmode' => { 266 => '9.1', 267 => '10.1', 269 => '10.1', 270 => '10.1', 275 => '27.1', 279 => '10.1', 280 => '10.1' }, + 'multishot' => { 311 => 0x121 }, + 'mute' => { 360 => 'player.movie.audio.mute' }, + 'mycolormode' => { 66 => 0x2 }, + 'name' => { 366 => 'name' }, + 'narrator' => { 358 => "\xa9nrt" }, + 'nationalcatalognumber' => { 478 => 'nationalCatalogNumber' }, + 'nativedigest' => { 468 => 'NativeDigest', 484 => 'NativeDigest' }, + 'ndfilter' => { 74 => 0x1c, 283 => 0x204, 373 => 0x1019 }, + 'near' => { 447 => 'Near' }, + 'nefbitdepth' => { 219 => 0xe22 }, + 'nefcompression' => { 219 => 0x93 }, + 'neflinearizationtable' => { 219 => 0x96 }, + 'negativecachelargepreviewsize' => { 462 => 'NegativeCacheLargePreviewSize', 464 => 'NegativeCacheLargePreviewSize' }, + 'negativecachemaximumsize' => { 462 => 'NegativeCacheMaximumSize', 464 => 'NegativeCacheMaximumSize' }, + 'negativecachepath' => { 462 => 'NegativeCachePath', 464 => 'NegativeCachePath' }, + 'neutraldensityfilter' => { 341 => 0x88 }, + 'neutraloutputhighlightpoint' => { 106 => 0x2f }, + 'neutraloutputshadowpoint' => { 106 => 0x30 }, + 'neutralrawcolortone' => { 106 => 0x28 }, + 'neutralrawcontrast' => { 106 => 0x2a }, + 'neutralrawhighlight' => { 106 => 0x78 }, + 'neutralrawhighlightpoint' => { 106 => 0x2d }, + 'neutralrawlinear' => { 106 => 0x2b }, + 'neutralrawsaturation' => { 106 => 0x29 }, + 'neutralrawshadow' => { 106 => 0x81 }, + 'neutralrawshadowpoint' => { 106 => 0x2e }, + 'neutralrawsharpness' => { 106 => 0x2c }, + 'neutralunsharpmaskfineness' => { 106 => 0xa6 }, + 'neutralunsharpmaskthreshold' => { 106 => 0xa8 }, + 'neutraunsharpmaskstrength' => { 106 => 0xa4 }, + 'newrawimagedigest' => { 116 => 0xc7a7 }, + 'newsphotoversion' => { 130 => 0x0 }, + 'nickname' => { 486 => 'Nickname' }, + 'nikoncapturedata' => { 219 => 0xe01 }, + 'nikoncaptureeditversions' => { 219 => 0xe13 }, + 'nikoncaptureoffsets' => { 219 => 0xe0e }, + 'nikoncaptureoutput' => { 219 => 0xe1e }, + 'nikoncaptureversion' => { 219 => 0xe09 }, + 'nikoniccprofile' => { 219 => 0xe1d }, + 'nikonimagesize' => { 234 => '723.1', 235 => '732.1', 244 => 0x2c4 }, + 'nikonmeteringmode' => { 238 => 0x2ea4, 246 => 0x175e }, + 'noisefilter' => { 283 => 0x527 }, + 'noiseprofile' => { 116 => 0xc761 }, + 'noisereduction' => { 124 => [0x100b,0x100e], 177 => 0xb0, 178 => 0x60, 179 => 0x3f, 219 => 0x95, 259 => 0x753dcbc0, 260 => 0x17, 283 => 0x50a, 288 => 0x103a, 306 => 0x2d, 341 => 0x49, 373 => 0x100f, 375 => 0x2a }, + 'noisereduction2' => { 287 => 0x1010 }, + 'noisereductionapplied' => { 116 => 0xc6f7 }, + 'noisereductionintensity' => { 260 => 0x9 }, + 'noisereductionmethod' => { 260 => 0x11 }, + 'noisereductionmode' => { 439 => 0x801e }, + 'noisereductionparametersatcapture' => { 134 => 0xe73 }, + 'noisereductionparameterscamera' => { 134 => 0xe72 }, + 'noisereductionparametershost3mp' => { 134 => 0xe71 }, + 'noisereductionparametershost6mp' => { 134 => 0xe70 }, + 'noisereductionparametershostrgb' => { 134 => 0xe6f }, + 'noisereductionparameterskhufu3mp' => { 134 => 0xe65 }, + 'noisereductionparameterskhufu6mp' => { 134 => 0xe64 }, + 'noisereductionparameterskhufurgb' => { 134 => 0xe63 }, + 'noisereductionparams' => { 311 => 0x1b }, + 'noisereductionsharpness' => { 260 => 0xd }, + 'noisereductionstrength' => { 306 => 0xd6 }, + 'noisereductionvalue' => { 439 => 0x8027 }, + 'nomemorycard' => { 266 => '22.1', 267 => '4.2', 268 => '0.3', 271 => '2.4', 272 => '3.2', 273 => '3.2', 275 => '33.7', 276 => '3.2', 277 => '0.3', 279 => '4.2', 281 => '4.5' }, + 'nominalmaxaperture' => { 332 => 0xa }, + 'nominalminaperture' => { 332 => '10.1' }, + 'normallinetime' => { 134 => 0x186a }, + 'normalwhitelevel' => { 43 => [0x2b8,0x2cf,0x2d3], 44 => 0x569, 45 => 0x1e3, 46 => [0x1fc,0x2dc], 47 => [0x230,0x30e], 48 => 0x31c }, + 'notes' => { 440 => 'Notes', 457 => 'notes' }, + 'npages' => { 493 => 'NPages' }, + 'nullrecord' => { 94 => 0x0 }, + 'numafpoints' => { 318 => 0x2 }, + 'number' => { 478 => 'number' }, + 'numberofbeats' => { 488 => 'numberOfBeats' }, + 'numberoffocuspoints' => { 269 => '1.3', 270 => '1.3', 273 => '0.2', 274 => '0.3', 276 => '0.3' }, + 'numfaceelements' => { 124 => 0x4200 }, + 'numfacepositions' => { 298 => 0x0 }, + 'numindexentries' => { 130 => 0x54 }, + 'numwbentries' => { 312 => 0x0, 313 => 0x0 }, + 'object' => { 478 => 'object' }, + 'objectattributereference' => { 128 => 0x4 }, + 'objectcycle' => { 128 => 0x4b, 457 => 'ObjectCycle' }, + 'objectdescription' => { 477 => 'objectDescription' }, + 'objectdistance' => { 109 => 0x6, 110 => 0x2022 }, + 'objectname' => { 128 => 0x5 }, + 'objectpreviewdata' => { 128 => 0xca }, + 'objectpreviewfileformat' => { 128 => 0xc8 }, + 'objectpreviewfileversion' => { 128 => 0xc9 }, + 'objectsubtype' => { 477 => 'objectSubtype' }, + 'objecttype' => { 477 => 'objectType' }, + 'objecttypereference' => { 128 => 0x3 }, + 'occurrence' => { 115 => 'Occurrence' }, + 'occurrenceassociatedmedia' => { 115 => [\'Occurrence','OccurrenceAssociatedMedia'] }, + 'occurrenceassociatedoccurrences' => { 115 => [\'Occurrence','OccurrenceAssociatedOccurrences'] }, + 'occurrenceassociatedreferences' => { 115 => [\'Occurrence','OccurrenceAssociatedReferences'] }, + 'occurrenceassociatedsequences' => { 115 => [\'Occurrence','OccurrenceAssociatedSequences'] }, + 'occurrenceassociatedtaxa' => { 115 => [\'Occurrence','OccurrenceAssociatedTaxa'] }, + 'occurrencebehavior' => { 115 => [\'Occurrence','OccurrenceBehavior'] }, + 'occurrencecatalognumber' => { 115 => [\'Occurrence','OccurrenceCatalogNumber'] }, + 'occurrencedetails' => { 115 => [\'Occurrence','OccurrenceOccurrenceDetails'] }, + 'occurrencedisposition' => { 115 => [\'Occurrence','OccurrenceDisposition'] }, + 'occurrenceestablishmentmeans' => { 115 => [\'Occurrence','OccurrenceEstablishmentMeans'] }, + 'occurrenceid' => { 115 => [\'Occurrence','OccurrenceOccurrenceID'] }, + 'occurrenceindividualcount' => { 115 => [\'Occurrence','OccurrenceIndividualCount'] }, + 'occurrenceindividualid' => { 115 => [\'Occurrence','OccurrenceIndividualID'] }, + 'occurrencelifestage' => { 115 => [\'Occurrence','OccurrenceLifeStage'] }, + 'occurrenceorganismquantity' => { 115 => [\'Occurrence','OccurrenceOrganismQuantity'] }, + 'occurrenceorganismquantitytype' => { 115 => [\'Occurrence','OccurrenceOrganismQuantityType'] }, + 'occurrenceothercatalognumbers' => { 115 => [\'Occurrence','OccurrenceOtherCatalogNumbers'] }, + 'occurrencepreparations' => { 115 => [\'Occurrence','OccurrencePreparations'] }, + 'occurrencepreviousidentifications' => { 115 => [\'Occurrence','OccurrencePreviousIdentifications'] }, + 'occurrencerecordedby' => { 115 => [\'Occurrence','OccurrenceRecordedBy'] }, + 'occurrencerecordnumber' => { 115 => [\'Occurrence','OccurrenceRecordNumber'] }, + 'occurrenceremarks' => { 115 => [\'Occurrence','OccurrenceOccurrenceRemarks'] }, + 'occurrencereproductivecondition' => { 115 => [\'Occurrence','OccurrenceReproductiveCondition'] }, + 'occurrencesex' => { 115 => [\'Occurrence','OccurrenceSex'] }, + 'occurrencestatus' => { 115 => [\'Occurrence','OccurrenceOccurrenceStatus'] }, + 'oecfcolumns' => { 468 => [\'OECF','OECFColumns'] }, + 'oecfnames' => { 468 => [\'OECF','OECFNames'] }, + 'oecfrows' => { 468 => [\'OECF','OECFRows'] }, + 'oecfvalues' => { 468 => [\'OECF','OECFValues'] }, + 'offsaledate' => { 478 => 'offSaleDate' }, + 'offsaledatea-platform' => { 478 => [\'offSaleDate','offSaleDateA-platform'] }, + 'offsaledatedate' => { 478 => [\'offSaleDate','offSaleDateDate'] }, + 'offsetdacvalue' => { 134 => 0x190a }, + 'offsetschema' => { 116 => 0xea1d }, + 'offsettime' => { 116 => 0x9010 }, + 'offsettimedigitized' => { 116 => 0x9012 }, + 'offsettimeoriginal' => { 116 => 0x9011 }, + 'okbutton' => { 276 => '15.1', 281 => '16.1' }, + 'oldsubfiletype' => { 116 => 0xff }, + 'olympusimageheight' => { 288 => 0x102f }, + 'olympusimagewidth' => { 288 => 0x102e }, + 'omenatcapturestrength' => { 134 => 0xa60 }, + 'omenautostrength' => { 134 => 0xa5f }, + 'omenearlystrength' => { 134 => 0xa5e }, + 'omenfocallengthlimit' => { 134 => 0xa62 }, + 'omeninitialipfstrength' => { 134 => 0xa5d }, + 'omensurfaceindex' => { 134 => 0xa64 }, 'oneshotafrelease' => { 2 => 0x9 }, - 'onetouchwb' => { 279 => 0x302 }, - 'onsaledate' => { 456 => 'onSaleDate' }, - 'onsaledatea-platform' => { 456 => [\'onSaleDate','onSaleDateA-platform'] }, - 'onsaledatedate' => { 456 => [\'onSaleDate','onSaleDateDate'] }, - 'onsaleday' => { 456 => 'onSaleDay' }, - 'onsaledaya-platform' => { 456 => [\'onSaleDay','onSaleDayA-platform'] }, - 'onsaledayday' => { 456 => [\'onSaleDay','onSaleDayDay'] }, - 'opcodelist1' => { 113 => 0xc740 }, - 'opcodelist2' => { 113 => 0xc741 }, - 'opcodelist3' => { 113 => 0xc74e }, - 'opticalzoom' => { 135 => 0xfa3d, 137 => [0x6006,0xf006], 138 => 0x1000, 139 => 0xf, 142 => 0x1e, 154 => 'OpticalZoom' }, - 'opticalzoomcode' => { 72 => 0xa }, - 'opticalzoommode' => { 297 => 0x34 }, - 'opticalzoomon' => { 367 => 0x219 }, - 'optionenddate' => { 459 => 'optionEndDate' }, - 'opto-electricconvfactor' => { 446 => 'OECF' }, - 'orangehsl' => { 97 => 0x20911 }, - 'ordernumber' => { 121 => 0x8002 }, - 'organisationinimagecode' => { 452 => 'OrganisationInImageCode' }, - 'organisationinimagename' => { 452 => 'OrganisationInImageName' }, - 'organism' => { 112 => 'Organism' }, - 'organismassociatedoccurrences' => { 112 => [\'Organism','OrganismAssociatedOccurrences'] }, - 'organismassociatedorganisms' => { 112 => [\'Organism','OrganismAssociatedOrganisms'] }, - 'organismid' => { 112 => [\'Organism','OrganismOrganismID'] }, - 'organismname' => { 112 => [\'Organism','OrganismOrganismName'] }, - 'organismpreviousidentifications' => { 112 => [\'Organism','OrganismPreviousIdentifications'] }, - 'organismremarks' => { 112 => [\'Organism','OrganismOrganismRemarks'] }, - 'organismscope' => { 112 => [\'Organism','OrganismOrganismScope'] }, - 'organization' => { 456 => 'organization' }, - 'orientation' => { 113 => 0x112, 302 => 0x112, 455 => 'orientation', 462 => 'Orientation' }, - 'orientation2' => { 393 => [0x28,0x2e] }, + 'onetouchwb' => { 288 => 0x302 }, + 'onsaledate' => { 478 => 'onSaleDate' }, + 'onsaledatea-platform' => { 478 => [\'onSaleDate','onSaleDateA-platform'] }, + 'onsaledatedate' => { 478 => [\'onSaleDate','onSaleDateDate'] }, + 'onsaleday' => { 478 => 'onSaleDay' }, + 'onsaledaya-platform' => { 478 => [\'onSaleDay','onSaleDayA-platform'] }, + 'onsaledayday' => { 478 => [\'onSaleDay','onSaleDayDay'] }, + 'opcodelist1' => { 116 => 0xc740 }, + 'opcodelist2' => { 116 => 0xc741 }, + 'opcodelist3' => { 116 => 0xc74e }, + 'opticalzoom' => { 138 => 0xfa3d, 140 => [0x6006,0xf006], 141 => 0x1000, 142 => 0xf, 145 => 0x1e, 147 => 0x20, 148 => 0x1c, 159 => 'OpticalZoom' }, + 'opticalzoomcode' => { 74 => 0xa }, + 'opticalzoommode' => { 306 => 0x34 }, + 'opticalzoomon' => { 382 => 0x219 }, + 'optionenddate' => { 481 => 'optionEndDate' }, + 'opto-electricconvfactor' => { 468 => 'OECF' }, + 'orangehsl' => { 100 => 0x20911 }, + 'ordernumber' => { 124 => 0x8002 }, + 'organisationinimagecode' => { 474 => 'OrganisationInImageCode' }, + 'organisationinimagename' => { 474 => 'OrganisationInImageName' }, + 'organism' => { 115 => 'Organism' }, + 'organismassociatedoccurrences' => { 115 => [\'Organism','OrganismAssociatedOccurrences'] }, + 'organismassociatedorganisms' => { 115 => [\'Organism','OrganismAssociatedOrganisms'] }, + 'organismid' => { 115 => [\'Organism','OrganismOrganismID'] }, + 'organismname' => { 115 => [\'Organism','OrganismOrganismName'] }, + 'organismpreviousidentifications' => { 115 => [\'Organism','OrganismPreviousIdentifications'] }, + 'organismremarks' => { 115 => [\'Organism','OrganismOrganismRemarks'] }, + 'organismscope' => { 115 => [\'Organism','OrganismOrganismScope'] }, + 'organization' => { 478 => 'organization' }, + 'orientation' => { 116 => 0x112, 311 => 0x112, 477 => 'orientation', 484 => 'Orientation' }, + 'orientation2' => { 411 => [0x28,0x2e] }, 'orientationlinkedaf' => { 2 => 0xe }, - 'orientationlinkedafpoint' => { 78 => 0x516 }, - 'originalbestqualitysize' => { 113 => 0xc792 }, - 'originalcreatedatetime' => { 431 => 'OriginalCreateDateTime' }, - 'originaldecisiondata' => { 108 => 'OriginalDecisionData' }, - 'originaldecisiondataoffset' => { 60 => 0x83 }, - 'originaldefaultcropsize' => { 113 => 0xc793 }, - 'originaldefaultfinalsize' => { 113 => 0xc791 }, - 'originaldirectory' => { 294 => 0x408 }, - 'originaldocumentid' => { 467 => 'OriginalDocumentID' }, - 'originalfilename' => { 91 => 0x816, 131 => 0x3e9, 143 => 0x20, 294 => 0x407, 431 => 'OriginalFilename' }, - 'originalimageheight' => { 74 => 0xc, 117 => 0x1 }, - 'originalimagewidth' => { 74 => 0xb, 117 => 0x0 }, - 'originalrawfiledata' => { 113 => 0xc68c }, - 'originalrawfiledigest' => { 113 => 0xc71d }, - 'originalrawfilename' => { 113 => 0xc68b }, - 'originaltransmissionreference' => { 125 => 0x67 }, - 'originatingprogram' => { 125 => 0x41, 436 => 'OriginatingProgram' }, - 'originplatform' => { 456 => 'originPlatform' }, - 'os' => { 444 => 'os' }, - 'otherconditions' => { 284 => 'OtherConditions' }, - 'otherconstraints' => { 284 => 'OtherConstraints' }, - 'otherimage' => { 108 => 'OtherImage' }, - 'otherimageinfo' => { 284 => 'OtherImageInfo' }, - 'otherimagelength' => { 113 => 0x202 }, - 'otherimagestart' => { 113 => 0x201 }, - 'otherlicensedocuments' => { 284 => 'OtherLicenseDocuments' }, - 'otherlicenseinfo' => { 284 => 'OtherLicenseInfo' }, - 'otherlicenserequirements' => { 284 => 'OtherLicenseRequirements' }, - 'outcue' => { 466 => 'outCue' }, - 'outcuescale' => { 466 => [\'outCue','outCueScale'] }, - 'outcuevalue' => { 466 => [\'outCue','outCueValue'] }, - 'outputimageheight' => { 186 => 0x3 }, - 'outputimagewidth' => { 186 => 0x2 }, - 'outputlut' => { 297 => 0xa7 }, - 'outputprofile' => { 131 => 0x138b }, - 'outputresolution' => { 186 => 0x4 }, - 'overclockcols' => { 131 => 0x189c }, - 'overclockrows' => { 131 => 0x18c4 }, - 'owner' => { 470 => 'Owner' }, - 'ownerid' => { 125 => 0xbc }, - 'ownername' => { 14 => 0x10f, 60 => 0x9, 91 => 0x810, 113 => [0xa430,0xfde8], 147 => 'OwnerName', 438 => 'OwnerName', 447 => 'CameraOwnerName' }, - 'padding' => { 113 => 0xea1c }, - 'pagecount' => { 456 => 'pageCount' }, - 'pageimage' => { 464 => [\'PageInfo','PageInfoImage'] }, - 'pageimageformat' => { 464 => [\'PageInfo','PageInfoFormat'] }, - 'pageimageheight' => { 464 => [\'PageInfo','PageInfoHeight'] }, - 'pageimagepagenumber' => { 464 => [\'PageInfo','PageInfoPageNumber'] }, - 'pageimagewidth' => { 464 => [\'PageInfo','PageInfoWidth'] }, - 'pageinfo' => { 464 => 'PageInfo' }, - 'pagename' => { 113 => 0x11d }, - 'pagenumber' => { 113 => 0x129 }, - 'pageprogressiondirection' => { 456 => 'pageProgressionDirection' }, - 'pagerange' => { 456 => 'pageRange' }, - 'paintbasedcorrectionmasks' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'] }, - 'paintbasedcorrections' => { 442 => 'PaintBasedCorrections' }, - 'paintcorrectionactive' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'] }, - 'paintcorrectionamount' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'] }, - 'paintcorrectionbrightness' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'] }, - 'paintcorrectionclarity' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'] }, - 'paintcorrectionclarity2012' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity2012'] }, - 'paintcorrectioncontrast' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'] }, - 'paintcorrectioncontrast2012' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast2012'] }, - 'paintcorrectiondefringe' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDefringe'] }, - 'paintcorrectionexposure' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'] }, - 'paintcorrectionexposure2012' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure2012'] }, - 'paintcorrectionhighlights2012' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHighlights2012'] }, - 'paintcorrectionhue' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalToningHue'] }, - 'paintcorrectionluminancenoise' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalLuminanceNoise'] }, - 'paintcorrectionmaskalpha' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAlpha'] }, - 'paintcorrectionmaskangle' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAngle'] }, - 'paintcorrectionmaskbottom' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksBottom'] }, - 'paintcorrectionmaskcentervalue' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterValue'] }, - 'paintcorrectionmaskcenterweight' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'] }, - 'paintcorrectionmaskdabs' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'] }, - 'paintcorrectionmaskfeather' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFeather'] }, - 'paintcorrectionmaskflipped' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlipped'] }, - 'paintcorrectionmaskflow' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'] }, - 'paintcorrectionmaskfullx' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'] }, - 'paintcorrectionmaskfully' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'] }, - 'paintcorrectionmaskleft' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksLeft'] }, - 'paintcorrectionmaskmidpoint' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMidpoint'] }, - 'paintcorrectionmaskperimetervalue' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksPerimeterValue'] }, - 'paintcorrectionmaskradius' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'] }, - 'paintcorrectionmaskright' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRight'] }, - 'paintcorrectionmaskroundness' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRoundness'] }, - 'paintcorrectionmasksizex' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeX'] }, - 'paintcorrectionmasksizey' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeY'] }, - 'paintcorrectionmasktop' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksTop'] }, - 'paintcorrectionmaskvalue' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'] }, - 'paintcorrectionmaskversion' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksVersion'] }, - 'paintcorrectionmaskwhat' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'] }, - 'paintcorrectionmaskx' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksX'] }, - 'paintcorrectionmasky' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksY'] }, - 'paintcorrectionmaskzerox' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'] }, - 'paintcorrectionmaskzeroy' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'] }, - 'paintcorrectionmoire' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalMoire'] }, - 'paintcorrectionsaturation' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'] }, - 'paintcorrectionshadows2012' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalShadows2012'] }, - 'paintcorrectionsharpness' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'] }, - 'paintcorrectiontemperature' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTemperature'] }, - 'paintcorrectiontint' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTint'] }, - 'paintcorrectionwhat' => { 442 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'] }, - 'panasonicdatetime' => { 300 => 0x0 }, - 'panasonicexifversion' => { 297 => 0x26 }, - 'panasonicimageheight' => { 297 => 0x4c }, - 'panasonicimagewidth' => { 297 => 0x4b }, - 'panasonicrawversion' => { 302 => 0x1 }, - 'panasonictitle' => { 113 => 0xc6d2 }, - 'panasonictitle2' => { 113 => 0xc6d3 }, - 'panoramaangle' => { 121 => 0x1153 }, - 'panoramacropbottom' => { 394 => 0x7 }, - 'panoramacropleft' => { 394 => 0x4 }, - 'panoramacropright' => { 394 => 0x6 }, - 'panoramacroptop' => { 394 => 0x5 }, - 'panoramadirection' => { 68 => 0x5, 121 => 0x1154, 394 => 0x3 }, - 'panoramaframeheight' => { 394 => 0x9 }, - 'panoramaframenumber' => { 68 => 0x2 }, - 'panoramaframewidth' => { 394 => 0x8 }, - 'panoramafullheight' => { 394 => 0x2 }, - 'panoramafullwidth' => { 394 => 0x1 }, - 'panoramamode' => { 133 => 0x3c, 274 => 0x601 }, - 'panoramasize3d' => { 378 => 0x38 }, - 'panoramasourceheight' => { 394 => 0xb }, - 'panoramasourcewidth' => { 394 => 0xa }, - 'panoramicstitchcameramotion' => { 167 => 'PanoramicStitchCameraMotion', 168 => 0x1 }, - 'panoramicstitchmaptype' => { 167 => 'PanoramicStitchMapType', 168 => 0x2 }, - 'panoramicstitchphi0' => { 167 => 'PanoramicStitchPhi0', 168 => 0x5 }, - 'panoramicstitchphi1' => { 167 => 'PanoramicStitchPhi1', 168 => 0x6 }, - 'panoramicstitchtheta0' => { 167 => 'PanoramicStitchTheta0', 168 => 0x3 }, - 'panoramicstitchtheta1' => { 167 => 'PanoramicStitchTheta1', 168 => 0x4 }, - 'panoramicstitchversion' => { 168 => 0x0 }, - 'pantry' => { 467 => 'Pantry' }, - 'parallax' => { 121 => 0xb211, 273 => 0x28 }, - 'parametricdarks' => { 442 => 'ParametricDarks' }, - 'parametrichighlights' => { 442 => 'ParametricHighlights' }, - 'parametrichighlightsplit' => { 442 => 'ParametricHighlightSplit' }, - 'parametriclights' => { 442 => 'ParametricLights' }, - 'parametricmidtonesplit' => { 442 => 'ParametricMidtoneSplit' }, - 'parametricshadows' => { 442 => 'ParametricShadows' }, - 'parametricshadowsplit' => { 442 => 'ParametricShadowSplit' }, - 'parentmediaeventid' => { 431 => 'ParentMediaEventID' }, - 'parentmeid' => { 431 => 'ParentMEID' }, - 'parentreference1' => { 450 => [\'TagStructure','TagStructureParentReference'] }, - 'parentreference2' => { 450 => [\'TagStructure','TagStructureSubLabelsParentReference'] }, - 'parentreference3' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsParentReference'] }, - 'parentreference4' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsParentReference'] }, - 'parentreference5' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference'] }, - 'parentreference6' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference'] }, - 'partialactivecols1' => { 131 => 0x17e8 }, - 'partialactivecols2' => { 131 => 0x17f2 }, - 'partialactiverows1' => { 131 => 0x17fc }, - 'partialactiverows2' => { 131 => 0x1806 }, - 'partofcompilation' => { 466 => 'partOfCompilation' }, - 'patientbirthdate' => { 423 => 'PatientDOB' }, - 'patientid' => { 423 => 'PatientID' }, - 'patientname' => { 423 => 'PatientName' }, - 'patientsex' => { 423 => 'PatientSex' }, - 'patternareaheight' => { 131 => 0x963 }, - 'patternareawidth' => { 131 => 0x962 }, - 'patterncorrectionfactorscale' => { 131 => 0x969 }, - 'patterncropcols1' => { 131 => 0x96c }, - 'patterncropcols2' => { 131 => 0x96d }, - 'patterncroprows1' => { 131 => 0x96a }, - 'patterncroprows2' => { 131 => 0x96b }, - 'patternimagerheight' => { 131 => 0x961 }, - 'patternimagerwidth' => { 131 => 0x960 }, - 'patternx' => { 131 => 0x966 }, - 'patterny' => { 131 => 0x967 }, - 'pdfversion' => { 453 => 'PDFVersion' }, - 'pentaximagesize' => { 332 => 0x9 }, - 'pentaxmodelid' => { 312 => 0x0, 332 => 0x5 }, - 'pentaxmodeltype' => { 332 => 0x1 }, - 'pentaxversion' => { 332 => 0x0 }, - 'people' => { 424 => 'People', 434 => 'People' }, - 'perchannelblacklevel' => { 41 => 0xc4, 42 => [0x2b4,0x2cb,0x2cf], 43 => [0x108,0x14d], 44 => 0x1df, 45 => [0x1f8,0x2d8], 46 => [0x22c,0x30a], 47 => 0x149 }, - 'peripheralillumcentralradius' => { 421 => 0x8030 }, - 'peripheralillumcentralvalue' => { 421 => 0x8031 }, - 'peripheralillumination' => { 97 => 0x20702, 103 => 0x68 }, - 'peripheralilluminationcorr' => { 59 => 0x1, 322 => 0x2 }, - 'peripheralilluminationon' => { 97 => '0x20702.0', 103 => 0x64 }, - 'peripheralillumperiphvalue' => { 421 => 0x8032 }, - 'peripherallighting' => { 74 => 0x2 }, - 'peripherallightingsetting' => { 75 => 0x5 }, - 'peripherallightingvalue' => { 74 => 0x6 }, - 'permissions' => { 459 => 'permissions' }, - 'permits' => { 439 => 'permits' }, - 'person' => { 456 => 'person' }, - 'personality' => { 431 => 'Personality' }, - 'personheard' => { 452 => 'PersonHeard' }, - 'personheardidentifier' => { 452 => [\'PersonHeard','PersonHeardIdentifier'] }, - 'personheardname' => { 452 => [\'PersonHeard','PersonHeardName'] }, - 'personinimage' => { 452 => 'PersonInImage' }, - 'personinimagecharacteristic' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristic'] }, - 'personinimagecvtermcvid' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvId'] }, - 'personinimagecvtermid' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermId'] }, - 'personinimagecvtermname' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermName'] }, - 'personinimagecvtermrefinedabout' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermRefinedAbout'] }, - 'personinimagedescription' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonDescription'] }, - 'personinimageid' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonId'] }, - 'personinimagename' => { 452 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonName'] }, - 'personinimagewdetails' => { 452 => 'PersonInImageWDetails' }, - 'perspectiveaspect' => { 442 => 'PerspectiveAspect' }, - 'perspectivehorizontal' => { 442 => 'PerspectiveHorizontal' }, - 'perspectiverotate' => { 442 => 'PerspectiveRotate' }, - 'perspectivescale' => { 442 => 'PerspectiveScale' }, - 'perspectiveupright' => { 442 => 'PerspectiveUpright' }, - 'perspectivevertical' => { 442 => 'PerspectiveVertical' }, - 'perspectivex' => { 442 => 'PerspectiveX' }, - 'perspectivey' => { 442 => 'PerspectiveY' }, - 'pf0customfuncregistration' => { 86 => 0x1 }, - 'pf10retainprogramshift' => { 86 => 0xb }, - 'pf13drivepriority' => { 86 => 0xe }, - 'pf14disablefocussearch' => { 86 => 0xf }, - 'pf15disableafassistbeam' => { 86 => 0x10 }, - 'pf16autofocuspointshoot' => { 86 => 0x11 }, - 'pf17disableafpointsel' => { 86 => 0x12 }, - 'pf18enableautoafpointsel' => { 86 => 0x13 }, - 'pf19continuousshootspeed' => { 86 => 0x14 }, - 'pf19shootingspeedhigh' => { 85 => 0xa }, - 'pf19shootingspeedlow' => { 85 => 0x9 }, - 'pf1disableshootingmodes' => { 86 => 0x2 }, - 'pf1value' => { 85 => 0x1 }, - 'pf20limitcontinousshots' => { 86 => 0x15 }, - 'pf20maxcontinousshots' => { 85 => 0xb }, - 'pf21enablequietoperation' => { 86 => 0x16 }, - 'pf23felocktime' => { 85 => 0xd }, - 'pf23postreleasetime' => { 85 => 0xe }, - 'pf23settimerlengths' => { 86 => 0x18 }, - 'pf23shutterbuttontime' => { 85 => 0xc }, - 'pf24lightlcdduringbulb' => { 86 => 0x19 }, - 'pf25aemode' => { 85 => 0xf }, - 'pf25afmode' => { 85 => 0x12 }, - 'pf25afpointsel' => { 85 => 0x13 }, - 'pf25colormatrix' => { 85 => 0x17 }, - 'pf25defaultclearsettings' => { 86 => 0x1a }, - 'pf25drivemode' => { 85 => 0x11 }, - 'pf25imagesize' => { 85 => 0x14 }, - 'pf25meteringmode' => { 85 => 0x10 }, - 'pf25parameters' => { 85 => 0x16 }, - 'pf25wbmode' => { 85 => 0x15 }, - 'pf26shortenreleaselag' => { 86 => 0x1b }, - 'pf27reversedialrotation' => { 86 => 0x1c }, - 'pf27value' => { 85 => 0x18 }, - 'pf28noquickdialexpcomp' => { 86 => 0x1d }, - 'pf29quickdialswitchoff' => { 86 => 0x1e }, - 'pf2disablemeteringmodes' => { 86 => 0x3 }, - 'pf2value' => { 85 => 0x2 }, - 'pf30enlargementmode' => { 86 => 0x1f }, - 'pf31originaldecisiondata' => { 86 => 0x20 }, - 'pf3manualexposuremetering' => { 86 => 0x4 }, - 'pf3value' => { 85 => 0x3 }, - 'pf4exposuretimelimits' => { 86 => 0x5 }, - 'pf4exposuretimemax' => { 85 => 0x5 }, - 'pf4exposuretimemin' => { 85 => 0x4 }, - 'pf5aperturelimits' => { 86 => 0x6 }, - 'pf5aperturemax' => { 85 => 0x7 }, - 'pf5aperturemin' => { 85 => 0x6 }, - 'pf6presetshootingmodes' => { 86 => 0x7 }, - 'pf7bracketcontinuousshoot' => { 86 => 0x8 }, - 'pf8bracketshots' => { 85 => 0x8 }, - 'pf8setbracketshots' => { 86 => 0x9 }, - 'pf9changebracketsequence' => { 86 => 0xa }, - 'phasedetectaf' => { 183 => 0x6 }, - 'phonenumber' => { 148 => 'Phone' }, - 'photoeffect' => { 33 => 0x28 }, - 'photoeffecthistoryxml' => { 250 => 0xe9651831 }, - 'photoeffects' => { 250 => 0xab5eca5e }, - 'photoeffectsblue' => { 252 => 0x8 }, - 'photoeffectsgreen' => { 252 => 0x6 }, - 'photoeffectsred' => { 252 => 0x4 }, - 'photoeffectstype' => { 252 => 0x0 }, - 'photographicsensitivity' => { 447 => 'PhotographicSensitivity' }, - 'photoinfoplayback' => { 257 => '17.6', 266 => '33.6' }, - 'photometricinterpretation' => { 113 => 0x106, 462 => 'PhotometricInterpretation' }, - 'photoshootingmenubank' => { 229 => 0xe7d, 238 => 0xfbd }, - 'photoshootingmenubankimagearea' => { 229 => '3716.1', 238 => 0x791 }, - 'photoshopbgrthumbnail' => { 346 => 0x409 }, - 'photoshopquality' => { 345 => 0x0 }, - 'photoshopthumbnail' => { 346 => 0x40c }, - 'photostyle' => { 297 => 0x89 }, - 'picklabel' => { 445 => 'PickLabel' }, - 'pictinfo' => { 367 => 0x208 }, - 'picturecontrol' => { 250 => 0xe2173c47 }, - 'picturecontrolactive' => { 253 => 0x0 }, - 'picturecontroladjust' => { 213 => 0x30, 214 => 0x30 }, - 'picturecontrolbase' => { 213 => 0x18, 214 => 0x18 }, - 'picturecontroldata' => { 211 => [0xbd,0x23] }, - 'picturecontrolmode' => { 253 => 0x13 }, - 'picturecontrolname' => { 213 => 0x4, 214 => 0x4 }, - 'picturecontrolquickadjust' => { 213 => 0x31, 214 => 0x31 }, - 'pictureeffect' => { 388 => 0x200e }, - 'pictureeffect2' => { 396 => 0x1163, 397 => 0x1167, 398 => 0x1143, 399 => 0x11bf, 400 => 0x119b, 401 => 0x1053, 402 => 0x24b, 403 => 0x24b, 404 => 0x23c, 417 => 0x46 }, - 'picturefinish' => { 172 => 0x71 }, - 'picturemode' => { 121 => 0x1031, 274 => 0x520, 332 => [0xb,0x33], 368 => 0x3d }, - 'picturemode2' => { 313 => 0x0 }, - 'picturemodebwfilter' => { 274 => 0x525 }, - 'picturemodecontrast' => { 274 => 0x523 }, - 'picturemodeeffect' => { 274 => 0x52d }, - 'picturemodehue' => { 274 => 0x522 }, - 'picturemodesaturation' => { 274 => 0x521 }, - 'picturemodesharpness' => { 274 => 0x524 }, - 'picturemodetone' => { 274 => 0x526 }, - 'pictureprofile' => { 396 => [0x115e,0x115f], 397 => [0x1162,0x1163], 398 => [0x113e,0x113f], 399 => [0x11ba,0x11bb], 400 => [0x1196,0x1197], 401 => [0x104e,0x104f], 402 => [0x246,0x247], 403 => [0x246,0x247], 404 => [0x237,0x238] }, - 'picturestyle' => { 7 => [0x4b,0x51], 8 => 0xf4, 9 => 0x6c, 10 => 0x86, 11 => 0x73, 15 => 0xab, 16 => 0xa7, 17 => 0xb0, 18 => 0x6c, 19 => 0xa7, 20 => 0xf4, 21 => 0xb3, 23 => 0xf4, 24 => 0xfa, 26 => 0x169, 70 => 0xa, 97 => 0x20301, 103 => 0x2 }, - 'picturewizard' => { 365 => 0x21 }, - 'picturewizardcolor' => { 364 => 0x1 }, - 'picturewizardcontrast' => { 364 => 0x4 }, - 'picturewizardmode' => { 364 => 0x0 }, - 'picturewizardsaturation' => { 364 => 0x2 }, - 'picturewizardsharpness' => { 364 => 0x3 }, - 'pipelineversion' => { 167 => 'PipelineVersion' }, - 'pitch' => { 109 => 0x6, 258 => '4.1', 270 => '4.1' }, - 'pitchangle' => { 228 => 0x350f, 229 => 0x2c28, 237 => 0x36f8, 274 => 0x904, 297 => 0x91, 331 => 0x2, 363 => 0x1 }, - 'pixelclockfrequency' => { 131 => 0x40b }, - 'pixelcorrectionoffset' => { 131 => 0x972 }, - 'pixelcorrectionscale' => { 131 => 0x971 }, - 'pixelshiftinfo' => { 388 => 0x202f }, - 'pixelshiftresolution' => { 333 => 0x0 }, - 'pixelsperunitx' => { 286 => 0x0 }, - 'pixelsperunity' => { 286 => 0x4 }, - 'pixelunits' => { 286 => 0x8 }, - 'planarconfiguration' => { 113 => 0x11c, 462 => 'PlanarConfiguration' }, - 'planningref' => { 452 => 'PlanningRef' }, - 'planningrefidentifier' => { 452 => [\'PlanningRef','PlanningRefIdentifier'] }, - 'planningrefname' => { 452 => [\'PlanningRef','PlanningRefName'] }, - 'planningrefrole' => { 452 => [\'PlanningRef','PlanningRefRole'] }, - 'platenames' => { 471 => 'PlateNames' }, - 'platform' => { 456 => 'platform' }, - 'playbackmenustime' => { 262 => '20.1', 263 => '21.1', 264 => '21.1' }, - 'playbackmonitorofftime' => { 257 => '25.2', 258 => '36.1', 260 => '36.1', 261 => '36.1', 265 => '35.1', 266 => '8.1', 267 => '35.1', 270 => '36.1', 271 => '36.1', 272 => '21.1' }, - 'playbackzoom' => { 258 => '37.1' }, - 'playdisplay' => { 174 => 0x4e }, - 'plusversion' => { 284 => 'Version' }, - 'pmversion' => { 344 => 'PMVersion' }, - 'pngwarning' => { 287 => 'Warning' }, - 'poilevel' => { 210 => 0x8 }, - 'portraitoutputhighlightpoint' => { 103 => 0x1d }, - 'portraitoutputshadowpoint' => { 103 => 0x1e }, - 'portraitrawcolortone' => { 103 => 0x16 }, - 'portraitrawcontrast' => { 103 => 0x18 }, - 'portraitrawhighlight' => { 103 => 0x76 }, - 'portraitrawhighlightpoint' => { 103 => 0x1b }, - 'portraitrawlinear' => { 103 => 0x19 }, - 'portraitrawsaturation' => { 103 => 0x17 }, - 'portraitrawshadow' => { 103 => 0x7f }, - 'portraitrawshadowpoint' => { 103 => 0x1c }, - 'portraitrawsharpness' => { 103 => 0x1a }, - 'portraitrefiner' => { 107 => 0x302b }, - 'portraitunsharpmaskfineness' => { 103 => 0x9a }, - 'portraitunsharpmaskstrength' => { 103 => 0x98 }, - 'portraitunsharpmaskthreshold' => { 103 => 0x9c }, - 'poseheadingdegrees' => { 429 => 'PoseHeadingDegrees' }, - 'posepitchdegrees' => { 429 => 'PosePitchDegrees' }, - 'poserolldegrees' => { 429 => 'PoseRollDegrees' }, - 'positiondescriptor' => { 455 => 'positionDescriptor' }, - 'postalcode' => { 152 => 'PostalCode' }, - 'postcropvignetteamount' => { 442 => 'PostCropVignetteAmount' }, - 'postcropvignettefeather' => { 442 => 'PostCropVignetteFeather' }, - 'postcropvignettehighlightcontrast' => { 442 => 'PostCropVignetteHighlightContrast' }, - 'postcropvignettemidpoint' => { 442 => 'PostCropVignetteMidpoint' }, - 'postcropvignetteroundness' => { 442 => 'PostCropVignetteRoundness' }, - 'postcropvignettestyle' => { 442 => 'PostCropVignetteStyle' }, - 'potentialface1position' => { 386 => 0xb }, - 'potentialface2position' => { 386 => 0x15 }, - 'potentialface3position' => { 386 => 0x1f }, - 'potentialface4position' => { 386 => 0x29 }, - 'potentialface5position' => { 386 => 0x33 }, - 'potentialface6position' => { 386 => 0x3d }, - 'potentialface7position' => { 386 => 0x47 }, - 'potentialface8position' => { 386 => 0x51 }, - 'powersource' => { 311 => '0.1' }, - 'poweruptime' => { 211 => 0xb6 }, - 'precaptureframes' => { 279 => 0x300 }, - 'predictor' => { 113 => 0x13d }, - 'preflashreturnstrength' => { 226 => 0x28a }, - 'prefs' => { 125 => 0xdd, 344 => 'Prefs' }, - 'prereadfastresetcount' => { 131 => 0x187e }, - 'preservedfilename' => { 467 => 'PreservedFileName' }, - 'preservedspecimen' => { 112 => 'PreservedSpecimen' }, - 'preservedspecimenmaterialsampleid' => { 112 => [\'PreservedSpecimen','PreservedSpecimenMaterialSampleID'] }, - 'presetwhitebalance' => { 174 => 0x24, 421 => 0x8002 }, - 'presetwhitebalanceadj' => { 421 => 0x8014 }, - 'pressure' => { 113 => 0x9402, 447 => 'Pressure' }, - 'previewapplicationname' => { 113 => 0xc716 }, - 'previewapplicationversion' => { 113 => 0xc717 }, - 'previewbutton' => { 257 => ['14.1','15.1'], 258 => '15.1', 260 => '15.1', 261 => '15.1', 266 => '29.1', 267 => '14.1', 270 => '15.1', 271 => '15.1' }, - 'previewbuttonplusdials' => { 257 => ['14.2','15.2'], 258 => '15.2', 260 => '43.1', 261 => '43.1', 266 => '31.2', 270 => '43.1', 271 => '43.1' }, - 'previewcolorspace' => { 113 => 0xc71a }, - 'previewcropbottom' => { 343 => 0xef }, - 'previewcropleft' => { 343 => 0xec }, - 'previewcropright' => { 343 => 0xee }, - 'previewcroptop' => { 343 => 0xed }, - 'previewdate' => { 351 => 0x0 }, - 'previewdatetime' => { 113 => 0xc71b }, - 'previewimage' => { 107 => 0x2000, 108 => 'PreviewImage', 114 => 'PreviewImage', 116 => 0x4, 157 => 'data', 176 => 0x81, 279 => 0x280, 295 => 0x300, 388 => 0x2001 }, - 'previewimageborders' => { 332 => 0x3e }, - 'previewimageheight' => { 69 => 0x4, 135 => 0xfa58 }, - 'previewimagelength' => { 69 => 0x2, 107 => 0x3, 113 => [0x117,0x202], 176 => 0x89, 215 => 0x202, 274 => 0x102, 279 => 0x1037, 332 => 0x3, 357 => 0x1e, 362 => 0x3, 368 => [0x1b,0x1d], 379 => 0x202 }, - 'previewimagename' => { 157 => '1Name' }, - 'previewimagesize' => { 107 => 0x2, 140 => 0x2, 157 => 'ImageSize', 332 => 0x2, 368 => [0x1c,0x1e], 388 => 0xb02c, 421 => 0x9012 }, - 'previewimagestart' => { 69 => 0x5, 107 => 0x4, 113 => [0x111,0x201], 176 => 0x88, 215 => 0x201, 274 => 0x101, 279 => 0x1036, 332 => 0x4, 357 => 0x1c, 362 => 0x2, 368 => [0x1a,0x1c], 379 => 0x201 }, - 'previewimagetype' => { 157 => '0Type' }, - 'previewimagevalid' => { 274 => 0x100, 279 => 0x1035 }, - 'previewimagewidth' => { 69 => 0x3, 135 => 0xfa57 }, - 'previewquality' => { 69 => 0x1 }, - 'previewsettingsdigest' => { 113 => 0xc719 }, - 'previewsettingsname' => { 113 => 0xc718 }, - 'primaryafpoint' => { 183 => [0x44,0x7] }, - 'primarychromaticities' => { 113 => 0x13f, 462 => 'PrimaryChromaticities' }, - 'primaryftp' => { 431 => 'PrimaryFTP' }, - 'primaryslot' => { 229 => 0xe7f, 238 => 0xfbf }, - 'printim' => { 113 => 0xc4a5 }, - 'prioritysetinawb' => { 388 => 0x202b }, - 'prioritysetupshutterrelease' => { 174 => 0x1d, 376 => 0x28 }, - 'privatertkinfo' => { 433 => 'privateRTKInfo' }, - 'processbordercolsleft' => { 131 => 0xc61 }, - 'processbordercolsright' => { 131 => 0xc62 }, - 'processborderrowsbottom' => { 131 => 0xc64 }, - 'processborderrowstop' => { 131 => 0xc63 }, - 'processingsoftware' => { 113 => 0xb }, - 'processversion' => { 442 => 'ProcessVersion' }, - 'producer' => { 283 => 'Producer', 453 => 'Producer' }, - 'productcode' => { 456 => 'productCode' }, - 'productid' => { 126 => 0x32, 455 => 'productID' }, - 'productidtype' => { 455 => 'productIDType' }, - 'productinimage' => { 452 => 'ProductInImage' }, - 'productinimagedescription' => { 452 => [\'ProductInImage','ProductInImageProductDescription'] }, - 'productinimagegtin' => { 452 => [\'ProductInImage','ProductInImageProductGTIN'] }, - 'productinimagename' => { 452 => [\'ProductInImage','ProductInImageProductName'] }, - 'productioncode' => { 312 => 0x2 }, - 'productorserviceconstraints' => { 284 => 'ProductOrServiceConstraints' }, - 'profession' => { 456 => 'profession' }, - 'profilecalibrationsig' => { 113 => 0xc6f4 }, - 'profilecopyright' => { 113 => 0xc6fe }, - 'profileembedpolicy' => { 113 => 0xc6fd }, - 'profilehuesatmapdata1' => { 113 => 0xc6fa }, - 'profilehuesatmapdata2' => { 113 => 0xc6fb }, - 'profilehuesatmapdims' => { 113 => 0xc6f9 }, - 'profilehuesatmapencoding' => { 113 => 0xc7a3 }, - 'profilelooktabledata' => { 113 => 0xc726 }, - 'profilelooktabledims' => { 113 => 0xc725 }, - 'profilelooktableencoding' => { 113 => 0xc7a4 }, - 'profilename' => { 113 => 0xc6f8 }, - 'profiletonecurve' => { 113 => 0xc6fc }, - 'programiso' => { 297 => 0x3c }, - 'programline' => { 313 => '1.1' }, - 'programmode' => { 179 => 0x5 }, - 'programshift' => { 211 => 0xd }, - 'programversion' => { 125 => 0x46 }, - 'prohibits' => { 439 => 'prohibits' }, - 'projectiontype' => { 429 => 'ProjectionType', 430 => 'ProjectionType' }, - 'projectname' => { 466 => 'projectName' }, - 'projectref' => { 466 => 'projectRef' }, - 'projectrefpath' => { 466 => [\'projectRef','projectRefPath'] }, - 'projectreftype' => { 466 => [\'projectRef','projectRefType'] }, - 'propertyreleaseid' => { 284 => 'PropertyReleaseID' }, - 'propertyreleasestatus' => { 284 => 'PropertyReleaseStatus' }, - 'province-state' => { 125 => 0x5f }, - 'publicationdate' => { 456 => 'publicationDate' }, - 'publicationdatea-platform' => { 456 => [\'publicationDate','publicationDateA-platform'] }, - 'publicationdatedate' => { 456 => [\'publicationDate','publicationDateDate'] }, - 'publicationdisplaydate' => { 456 => 'publicationDisplayDate' }, - 'publicationdisplaydatea-platform' => { 456 => [\'publicationDisplayDate','publicationDisplayDateA-platform'] }, - 'publicationdisplaydatedate' => { 456 => [\'publicationDisplayDate','publicationDisplayDateDate'] }, - 'publicationevent' => { 452 => 'PublicationEvent' }, - 'publicationeventdate' => { 452 => [\'PublicationEvent','PublicationEventDate'] }, - 'publicationeventidentifier' => { 452 => [\'PublicationEvent','PublicationEventIdentifier'] }, - 'publicationeventname' => { 452 => [\'PublicationEvent','PublicationEventName'] }, - 'publicationname' => { 456 => 'publicationName' }, - 'publisher' => { 443 => 'publisher' }, - 'publishingfrequency' => { 456 => 'publishingFrequency' }, - 'pulldown' => { 466 => 'pullDown' }, - 'purplehsl' => { 97 => 0x20916 }, - 'pxshiftperiphedgenr' => { 421 => 0x9013 }, - 'pxshiftperiphedgenrvalue' => { 421 => 0x9014 }, - 'quality' => { 0 => 0x1, 33 => 0x3, 106 => 0x2, 107 => 0x3002, 121 => 0x1000, 133 => 0x9, 211 => 0x4, 240 => 0x3, 279 => 0x201, 292 => 0x300, 332 => 0x8, 339 => 0x2, 368 => 0x16, 376 => 0x56, 377 => 0x56, 378 => 0xb, 388 => [0x102,0x202e] }, - 'quality2' => { 396 => 0x1170, 397 => 0x1174, 398 => 0x1150, 400 => 0x11a8, 401 => 0x1060, 402 => 0x258, 403 => 0x258, 404 => 0x247, 408 => 0x29, 409 => 0x25, 410 => 0x2a }, - 'qualitymode' => { 107 => 0x8 }, - 'quantizationmethod' => { 127 => 0x78 }, - 'quickadjust' => { 253 => 0x2a }, - 'quickcontroldialinmeter' => { 78 => 0x703 }, - 'quickfix' => { 250 => 0x416391c6 }, - 'quickshot' => { 367 => 0x213 }, - 'quiettime' => { 131 => 0x188a }, - 'rangefinder' => { 262 => '4.1', 263 => '5.1', 264 => '5.1' }, - 'rasterizedcaption' => { 125 => 0x7d }, - 'rating' => { 113 => 0x4746, 121 => 0x1431, 343 => 0xdf, 388 => 0x2002, 436 => 'rating', 444 => 'rating', 452 => 'Rating', 456 => 'rating', 464 => 'Rating' }, - 'ratingpercent' => { 113 => 0x4749, 169 => 'Rating' }, - 'ratingratingregion' => { 452 => [\'Rating','RatingRatingRegion'] }, - 'ratingregioncity' => { 452 => [\'Rating','RatingRatingRegionCity'] }, - 'ratingregioncountrycode' => { 452 => [\'Rating','RatingRatingRegionCountryCode'] }, - 'ratingregioncountryname' => { 452 => [\'Rating','RatingRatingRegionCountryName'] }, - 'ratingregiongpsaltitude' => { 452 => [\'Rating','RatingRatingRegionGPSAltitude'] }, - 'ratingregiongpslatitude' => { 452 => [\'Rating','RatingRatingRegionGPSLatitude'] }, - 'ratingregiongpslongitude' => { 452 => [\'Rating','RatingRatingRegionGPSLongitude'] }, - 'ratingregionidentifier' => { 452 => [\'Rating','RatingRatingRegionIdentifier'] }, - 'ratingregionlocationid' => { 452 => [\'Rating','RatingRatingRegionLocationId'] }, - 'ratingregionlocationname' => { 452 => [\'Rating','RatingRatingRegionLocationName'] }, - 'ratingregionprovincestate' => { 452 => [\'Rating','RatingRatingRegionProvinceState'] }, - 'ratingregionsublocation' => { 452 => [\'Rating','RatingRatingRegionSublocation'] }, - 'ratingregionworldregion' => { 452 => [\'Rating','RatingRatingRegionWorldRegion'] }, - 'ratingscalemaxvalue' => { 452 => [\'Rating','RatingRatingScaleMaxValue'] }, - 'ratingscaleminvalue' => { 452 => [\'Rating','RatingRatingScaleMinValue'] }, - 'ratingsourcelink' => { 452 => [\'Rating','RatingRatingSourceLink'] }, - 'ratingvalue' => { 452 => [\'Rating','RatingRatingValue'] }, - 'ratingvaluelogolink' => { 452 => [\'Rating','RatingRatingValueLogoLink'] }, - 'rawandjpgrecording' => { 76 => 0x8, 176 => 0x109, 313 => 0xd }, - 'rawbrightnessadj' => { 97 => 0x20001, 102 => 0x38 }, - 'rawcoloradj' => { 102 => 0x2e }, - 'rawcropbottom' => { 343 => 0xd4 }, - 'rawcropleft' => { 343 => 0xd1 }, - 'rawcropright' => { 343 => 0xd3 }, - 'rawcroptop' => { 343 => 0xd2 }, - 'rawcustomsaturation' => { 102 => 0x30 }, - 'rawcustomtone' => { 102 => 0x34 }, - 'rawdata' => { 365 => 0xa048 }, - 'rawdatabyteorder' => { 365 => 0x40 }, - 'rawdatacfapattern' => { 365 => 0x50 }, - 'rawdatauniqueid' => { 113 => 0xc65d }, - 'rawdepth' => { 178 => 0x10 }, - 'rawdevartfilter' => { 281 => 0x121 }, - 'rawdevautogradation' => { 281 => 0x119 }, - 'rawdevcolorspace' => { 280 => 0x108, 281 => 0x109 }, - 'rawdevcontrastvalue' => { 280 => 0x106, 281 => 0x105 }, - 'rawdeveditstatus' => { 280 => 0x10b }, - 'rawdevelopmentprocess' => { 332 => 0x62 }, - 'rawdevengine' => { 280 => 0x109, 281 => 0x10b }, - 'rawdevexposurebiasvalue' => { 280 => 0x100, 281 => 0x100 }, - 'rawdevgradation' => { 281 => 0x112 }, - 'rawdevgraypoint' => { 280 => 0x103, 281 => 0x104 }, - 'rawdevmemorycoloremphasis' => { 280 => 0x105, 281 => 0x108 }, - 'rawdevnoisereduction' => { 280 => 0x10a, 281 => 0x10a }, - 'rawdevpicturemode' => { 281 => 0x10c }, - 'rawdevpm_bwfilter' => { 281 => 0x110 }, - 'rawdevpmcontrast' => { 281 => 0x10e }, - 'rawdevpmnoisefilter' => { 281 => 0x120 }, - 'rawdevpmpicturetone' => { 281 => 0x111 }, - 'rawdevpmsaturation' => { 281 => 0x10d }, - 'rawdevpmsharpness' => { 281 => 0x10f }, - 'rawdevsaturation3' => { 281 => 0x113 }, - 'rawdevsaturationemphasis' => { 280 => 0x104, 281 => 0x107 }, - 'rawdevsettings' => { 280 => 0x10c }, - 'rawdevsharpnessvalue' => { 280 => 0x107, 281 => 0x106 }, - 'rawdevversion' => { 280 => 0x0, 281 => 0x0 }, - 'rawdevwbfineadjustment' => { 280 => 0x102, 281 => 0x103 }, - 'rawdevwhitebalance' => { 281 => 0x101 }, - 'rawdevwhitebalancevalue' => { 280 => 0x101, 281 => 0x102 }, - 'rawfile' => { 113 => 0xfe4c }, - 'rawfilename' => { 442 => 'RawFileName' }, - 'rawfiletype' => { 388 => 0x2029 }, - 'rawformat' => { 302 => 0x2d, 341 => 0x10e }, - 'rawimagecenter' => { 211 => 0x99 }, - 'rawimagedigest' => { 113 => 0xc71c }, - 'rawimagesize' => { 332 => 0x39 }, - 'rawinfoversion' => { 282 => 0x0 }, - 'rawjpgheight' => { 93 => 0x4 }, - 'rawjpgquality' => { 54 => 0x6, 93 => 0x1 }, - 'rawjpgsize' => { 54 => 0x7, 93 => 0x2 }, - 'rawjpgwidth' => { 93 => 0x3 }, - 'rawmeasuredrggb' => { 40 => 0x26a, 42 => 0x280, 44 => 0x194, 45 => [0x1ad,0x26b] }, - 'rawrppused' => { 436 => 'rawrppused' }, - 'rawtopreviewgain' => { 113 => 0xc7a8 }, - 'readouttypeactual' => { 131 => 0x1903 }, - 'readouttyperequested' => { 131 => 0x1902 }, - 'reardisplay' => { 257 => '12.3', 258 => '6.2' }, - 'recdevice' => { 452 => 'RecDevice' }, - 'recdeviceattlensdescription' => { 452 => [\'RecDevice','RecDeviceAttLensDescription'] }, - 'recdevicemanufacturer' => { 452 => [\'RecDevice','RecDeviceManufacturer'] }, - 'recdevicemodelname' => { 452 => [\'RecDevice','RecDeviceModelName'] }, - 'recdeviceownersdeviceid' => { 452 => [\'RecDevice','RecDeviceOwnersDeviceId'] }, - 'recdeviceserialnumber' => { 452 => [\'RecDevice','RecDeviceSerialNumber'] }, - 'recipeendingpage' => { 458 => 'recipeEndingPage' }, - 'recipepagerange' => { 458 => 'recipePageRange' }, - 'recipesource' => { 458 => 'recipeSource' }, - 'recipestartingpage' => { 458 => 'recipeStartingPage' }, - 'recipetitle' => { 458 => 'recipeTitle' }, - 'recognizedface1age' => { 290 => 0x20 }, - 'recognizedface1name' => { 290 => 0x4 }, - 'recognizedface1position' => { 290 => 0x18 }, - 'recognizedface2age' => { 290 => 0x50 }, - 'recognizedface2name' => { 290 => 0x34 }, - 'recognizedface2position' => { 290 => 0x48 }, - 'recognizedface3age' => { 290 => 0x80 }, - 'recognizedface3name' => { 290 => 0x64 }, - 'recognizedface3position' => { 290 => 0x78 }, - 'recognizedfaceflags' => { 297 => 0x63 }, - 'recommendedexposureindex' => { 113 => 0x8832, 447 => 'RecommendedExposureIndex' }, - 'record' => { 112 => 'Record' }, - 'recordbasisofrecord' => { 112 => [\'Record','RecordBasisOfRecord'] }, - 'recordcollectioncode' => { 112 => [\'Record','RecordCollectionCode'] }, - 'recordcollectionid' => { 112 => [\'Record','RecordCollectionID'] }, - 'recorddatageneralizations' => { 112 => [\'Record','RecordDataGeneralizations'] }, - 'recorddatasetid' => { 112 => [\'Record','RecordDatasetID'] }, - 'recorddatasetname' => { 112 => [\'Record','RecordDatasetName'] }, - 'recorddisplay' => { 174 => 0x4d }, - 'recorddynamicproperties' => { 112 => [\'Record','RecordDynamicProperties'] }, - 'recordid' => { 91 => 0x1804 }, - 'recordinformationwithheld' => { 112 => [\'Record','RecordInformationWithheld'] }, - 'recordingformat' => { 358 => 0x1000 }, - 'recordingmode' => { 106 => 0x1, 339 => 0x1 }, - 'recordinstitutioncode' => { 112 => [\'Record','RecordInstitutionCode'] }, - 'recordinstitutionid' => { 112 => [\'Record','RecordInstitutionID'] }, - 'recordmode' => { 33 => 0x9, 107 => 0x3000 }, - 'recordownerinstitutioncode' => { 112 => [\'Record','RecordOwnerInstitutionCode'] }, - 'recordshutterrelease' => { 367 => 0x217 }, - 'redbalance' => { 279 => 0x1017, 302 => 0x11, 332 => 0x1c }, - 'redcurvelimits' => { 102 => 0x18a }, - 'redcurvepoints' => { 101 => 0x2d, 102 => 0x160 }, - 'redeyecorrection' => { 254 => 0x0 }, - 'redeyeinfo' => { 442 => 'RedEyeInfo' }, - 'redeyereduction' => { 174 => 0x41, 376 => 0x6a, 378 => 0x28 }, - 'redeyeremoval' => { 297 => 0xb9 }, - 'redhsl' => { 97 => 0x20910 }, - 'redhue' => { 442 => 'RedHue' }, - 'redsaturation' => { 442 => 'RedSaturation' }, - 'reductionmatrix1' => { 113 => 0xc625 }, - 'reductionmatrix2' => { 113 => 0xc626 }, - 'reelname' => { 113 => 0xc789 }, - 'reference1' => { 450 => [\'TagStructure','TagStructureReference'] }, - 'reference2' => { 450 => [\'TagStructure','TagStructureSubLabelsReference'] }, - 'reference3' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsReference'] }, - 'reference4' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsReference'] }, - 'reference5' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference'] }, - 'reference6' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference'] }, - 'referenceblackwhite' => { 113 => 0x214, 462 => 'ReferenceBlackWhite' }, - 'referencedate' => { 125 => 0x2f }, - 'referencenumber' => { 125 => 0x32 }, - 'references' => { 148 => 'References' }, - 'referenceservice' => { 125 => 0x2d }, - 'regionappliedtodimensions' => { 163 => [\'Regions','RegionsAppliedToDimensions'] }, - 'regionappliedtodimensionsh' => { 163 => [\'Regions','RegionsAppliedToDimensionsH'] }, - 'regionappliedtodimensionsunit' => { 163 => [\'Regions','RegionsAppliedToDimensionsUnit'] }, - 'regionappliedtodimensionsw' => { 163 => [\'Regions','RegionsAppliedToDimensionsW'] }, - 'regionarea' => { 163 => [\'Regions','RegionsRegionListArea'] }, - 'regionaread' => { 163 => [\'Regions','RegionsRegionListAreaD'] }, - 'regionareah' => { 163 => [\'Regions','RegionsRegionListAreaH'] }, - 'regionareaunit' => { 163 => [\'Regions','RegionsRegionListAreaUnit'] }, - 'regionareaw' => { 163 => [\'Regions','RegionsRegionListAreaW'] }, - 'regionareax' => { 163 => [\'Regions','RegionsRegionListAreaX'] }, - 'regionareay' => { 163 => [\'Regions','RegionsRegionListAreaY'] }, - 'regionbarcodevalue' => { 163 => [\'Regions','RegionsRegionListBarCodeValue'] }, - 'regionconstraints' => { 284 => 'RegionConstraints' }, - 'regiondescription' => { 163 => [\'Regions','RegionsRegionListDescription'] }, - 'regionextensions' => { 163 => [\'Regions','RegionsRegionListExtensions'] }, - 'regionfocususage' => { 163 => [\'Regions','RegionsRegionListFocusUsage'] }, - 'regioninfo' => { 163 => 'Regions' }, - 'regioninfodateregionsvalid' => { 166 => [\'RegionInfo','RegionInfoDateRegionsValid'] }, - 'regioninfomp' => { 166 => 'RegionInfo' }, - 'regioninforegions' => { 166 => [\'RegionInfo','RegionInfoRegions'] }, - 'regionlist' => { 163 => [\'Regions','RegionsRegionList'] }, - 'regionname' => { 163 => [\'Regions','RegionsRegionListName'] }, - 'regionpersondisplayname' => { 166 => [\'RegionInfo','RegionInfoRegionsPersonDisplayName'] }, - 'regionpersonemaildigest' => { 166 => [\'RegionInfo','RegionInfoRegionsPersonEmailDigest'] }, - 'regionpersonliveidcid' => { 166 => [\'RegionInfo','RegionInfoRegionsPersonLiveIdCID'] }, - 'regionpersonsourceid' => { 166 => [\'RegionInfo','RegionInfoRegionsPersonSourceID'] }, - 'regionrectangle' => { 166 => [\'RegionInfo','RegionInfoRegionsRectangle'] }, - 'regionrotation' => { 163 => [\'Regions','RegionsRegionListRotation'] }, - 'regionseealso' => { 163 => [\'Regions','RegionsRegionListSeeAlso'] }, - 'regiontype' => { 163 => [\'Regions','RegionsRegionListType'] }, - 'registryentryrole' => { 452 => [\'RegistryId','RegistryIdRegEntryRole'] }, - 'registryid' => { 452 => 'RegistryId' }, - 'registryitemid' => { 452 => [\'RegistryId','RegistryIdRegItemId'] }, - 'registryorganisationid' => { 452 => [\'RegistryId','RegistryIdRegOrgId'] }, - 'relatedaudiofile' => { 146 => 'data' }, - 'relatedaudiofilename' => { 146 => '1Name' }, - 'relatedaudiofiletype' => { 146 => '0Type' }, - 'relatedimagefileformat' => { 113 => 0x1000 }, - 'relatedimageheight' => { 113 => 0x1002 }, - 'relatedimagewidth' => { 113 => 0x1001 }, - 'relatedresourceid' => { 112 => [\'ResourceRelationship','ResourceRelationshipRelatedResourceID'] }, - 'relatedsoundfile' => { 113 => 0xa004, 446 => 'RelatedSoundFile' }, - 'relatedvideofile' => { 160 => 'data' }, - 'relatedvideofilename' => { 160 => '1Name' }, - 'relatedvideofiletype' => { 160 => '0Type' }, - 'relation' => { 443 => 'relation' }, - 'relationshipaccordingto' => { 112 => [\'ResourceRelationship','ResourceRelationshipRelationshipAccordingTo'] }, - 'relationshipestablisheddate' => { 112 => [\'ResourceRelationship','ResourceRelationshipRelationshipEstablishedDate'] }, - 'relationshipofresource' => { 112 => [\'ResourceRelationship','ResourceRelationshipRelationshipOfResource'] }, - 'relationshipremarks' => { 112 => [\'ResourceRelationship','ResourceRelationshipRelationshipRemarks'] }, - 'relativealtitude' => { 110 => 'RelativeAltitude' }, - 'relativepeakaudiofilepath' => { 466 => 'relativePeakAudioFilePath' }, - 'relativetimestamp' => { 466 => 'relativeTimestamp' }, - 'relativetimestampscale' => { 466 => [\'relativeTimestamp','relativeTimestampScale'] }, - 'relativetimestampvalue' => { 466 => [\'relativeTimestamp','relativeTimestampValue'] }, - 'releasebuttontousedial' => { 257 => '17.8', 258 => '18.5', 260 => '18.4', 261 => '18.4', 266 => '33.8', 267 => '17.6', 270 => '18.5', 271 => '18.4' }, - 'releasedate' => { 125 => 0x1e, 436 => 'ReleaseDate', 466 => 'releaseDate' }, - 'releasemode' => { 107 => 0x3001, 228 => 0x184d, 388 => 0xb049 }, - 'releasemode2' => { 396 => 0x112c, 397 => [0x112c,0x8], 398 => [0x1108,0x8], 399 => [0x1184,0x8], 400 => [0x1160,0x8], 401 => [0x4,0x1018], 402 => [0x4,0x210], 403 => [0x4,0x210], 404 => [0x4,0x208], 406 => [0x67,0x3f], 407 => [0x73,0x4b], 408 => 0x10, 409 => 0x10, 410 => 0x9, 417 => 0x34 }, - 'releasemode3' => { 396 => 0x1128, 397 => 0x1128, 398 => 0x1104, 399 => 0x1180, 400 => 0x115c, 401 => 0x1014, 402 => 0x20c, 403 => 0x20c, 404 => 0x204 }, - 'releaseready' => { 452 => 'ReleaseReady' }, - 'releasesetting' => { 91 => 0x1016 }, - 'releasetime' => { 125 => 0x23, 436 => 'ReleaseTime' }, - 'remoteonduration' => { 259 => '3.4', 262 => '17.2', 263 => '18.2', 264 => '18.2', 265 => '18.2', 267 => '18.2', 268 => '4.3', 272 => '19.2' }, - 'renditionclass' => { 467 => 'RenditionClass' }, - 'renditionof' => { 467 => 'RenditionOf' }, - 'renditionofalternatepaths' => { 467 => [\'RenditionOf','RenditionOfAlternatePaths'] }, - 'renditionofdocumentid' => { 467 => [\'RenditionOf','RenditionOfDocumentID'] }, - 'renditionoffilepath' => { 467 => [\'RenditionOf','RenditionOfFilePath'] }, - 'renditionoffrompart' => { 467 => [\'RenditionOf','RenditionOfFromPart'] }, - 'renditionofinstanceid' => { 467 => [\'RenditionOf','RenditionOfInstanceID'] }, - 'renditionoflastmodifydate' => { 467 => [\'RenditionOf','RenditionOfLastModifyDate'] }, - 'renditionoflasturl' => { 467 => [\'RenditionOf','RenditionOfLastURL'] }, - 'renditionoflinkcategory' => { 467 => [\'RenditionOf','RenditionOfLinkCategory'] }, - 'renditionoflinkform' => { 467 => [\'RenditionOf','RenditionOfLinkForm'] }, - 'renditionofmanager' => { 467 => [\'RenditionOf','RenditionOfManager'] }, - 'renditionofmanagervariant' => { 467 => [\'RenditionOf','RenditionOfManagerVariant'] }, - 'renditionofmanageto' => { 467 => [\'RenditionOf','RenditionOfManageTo'] }, - 'renditionofmanageui' => { 467 => [\'RenditionOf','RenditionOfManageUI'] }, - 'renditionofmaskmarkers' => { 467 => [\'RenditionOf','RenditionOfMaskMarkers'] }, - 'renditionoforiginaldocumentid' => { 467 => [\'RenditionOf','RenditionOfOriginalDocumentID'] }, - 'renditionofpartmapping' => { 467 => [\'RenditionOf','RenditionOfPartMapping'] }, - 'renditionofplacedresolutionunit' => { 467 => [\'RenditionOf','RenditionOfPlacedResolutionUnit'] }, - 'renditionofplacedxresolution' => { 467 => [\'RenditionOf','RenditionOfPlacedXResolution'] }, - 'renditionofplacedyresolution' => { 467 => [\'RenditionOf','RenditionOfPlacedYResolution'] }, - 'renditionofrenditionclass' => { 467 => [\'RenditionOf','RenditionOfRenditionClass'] }, - 'renditionofrenditionparams' => { 467 => [\'RenditionOf','RenditionOfRenditionParams'] }, - 'renditionoftopart' => { 467 => [\'RenditionOf','RenditionOfToPart'] }, - 'renditionofversionid' => { 467 => [\'RenditionOf','RenditionOfVersionID'] }, - 'renditionparams' => { 467 => 'RenditionParams' }, - 'repeatingflashcount' => { 198 => 0xd, 199 => 0xe, 200 => 0xe, 201 => 0xe, 202 => 0xe, 266 => '17.2', 267 => '24.2', 268 => '9.2', 269 => '24.2', 272 => '25.2' }, - 'repeatingflashcountbuilt-in' => { 236 => 0x4db }, - 'repeatingflashcountexternal' => { 236 => 0x4c3 }, - 'repeatingflashoutput' => { 266 => '17.1', 267 => '24.1', 268 => '9.1', 269 => '24.1', 272 => '25.1' }, - 'repeatingflashoutputexternal' => { 236 => 0x4c0 }, - 'repeatingflashrate' => { 198 => 0xc, 199 => 0xd, 200 => 0xd, 201 => 0xd, 202 => 0xd, 266 => '18.1', 267 => '25.1', 268 => '10.1', 269 => '25.1', 272 => '26.1' }, - 'repeatingflashratebuilt-in' => { 236 => 0x4da }, - 'repeatingflashrateexternal' => { 236 => 0x4c2 }, - 'requires' => { 439 => 'requires' }, - 'resampleparams' => { 466 => 'resampleParams' }, - 'resampleparamsquality' => { 466 => [\'resampleParams','resampleParamsQuality'] }, - 'resamplingkerneldenominators050' => { 131 => 0xe50 }, - 'resamplingkerneldenominators067' => { 131 => 0xe4f }, - 'resamplingkerneldenominators100' => { 131 => 0xe51 }, - 'resaved' => { 367 => 0x21e }, - 'resetblacksegrows' => { 131 => 0x181a }, - 'resolution' => { 153 => 'Resolution' }, - 'resolutionmode' => { 368 => 0x4 }, - 'resolutionunit' => { 113 => 0x128, 128 => 0x2, 462 => 'ResolutionUnit' }, - 'resourceid' => { 112 => [\'ResourceRelationship','ResourceRelationshipResourceID'] }, - 'resourcerelationship' => { 112 => 'ResourceRelationship' }, - 'resourcerelationshipid' => { 112 => [\'ResourceRelationship','ResourceRelationshipResourceRelationshipID'] }, - 'restrictdrivemodes' => { 78 => 0x612 }, - 'restrictions' => { 459 => 'restrictions' }, - 'retouchareafeather' => { 442 => [\'RetouchAreas','RetouchAreasFeather'] }, - 'retouchareamaskalpha' => { 442 => [\'RetouchAreas','RetouchAreasMasksAlpha'] }, - 'retouchareamaskangle' => { 442 => [\'RetouchAreas','RetouchAreasMasksAngle'] }, - 'retouchareamaskbottom' => { 442 => [\'RetouchAreas','RetouchAreasMasksBottom'] }, - 'retouchareamaskcentervalue' => { 442 => [\'RetouchAreas','RetouchAreasMasksCenterValue'] }, - 'retouchareamaskcenterweight' => { 442 => [\'RetouchAreas','RetouchAreasMasksCenterWeight'] }, - 'retouchareamaskdabs' => { 442 => [\'RetouchAreas','RetouchAreasMasksDabs'] }, - 'retouchareamaskfeather' => { 442 => [\'RetouchAreas','RetouchAreasMasksFeather'] }, - 'retouchareamaskflipped' => { 442 => [\'RetouchAreas','RetouchAreasMasksFlipped'] }, - 'retouchareamaskflow' => { 442 => [\'RetouchAreas','RetouchAreasMasksFlow'] }, - 'retouchareamaskfullx' => { 442 => [\'RetouchAreas','RetouchAreasMasksFullX'] }, - 'retouchareamaskfully' => { 442 => [\'RetouchAreas','RetouchAreasMasksFullY'] }, - 'retouchareamaskleft' => { 442 => [\'RetouchAreas','RetouchAreasMasksLeft'] }, - 'retouchareamaskmidpoint' => { 442 => [\'RetouchAreas','RetouchAreasMasksMidpoint'] }, - 'retouchareamaskperimetervalue' => { 442 => [\'RetouchAreas','RetouchAreasMasksPerimeterValue'] }, - 'retouchareamaskradius' => { 442 => [\'RetouchAreas','RetouchAreasMasksRadius'] }, - 'retouchareamaskright' => { 442 => [\'RetouchAreas','RetouchAreasMasksRight'] }, - 'retouchareamaskroundness' => { 442 => [\'RetouchAreas','RetouchAreasMasksRoundness'] }, - 'retouchareamasks' => { 442 => [\'RetouchAreas','RetouchAreasMasks'] }, - 'retouchareamasksizex' => { 442 => [\'RetouchAreas','RetouchAreasMasksSizeX'] }, - 'retouchareamasksizey' => { 442 => [\'RetouchAreas','RetouchAreasMasksSizeY'] }, - 'retouchareamasktop' => { 442 => [\'RetouchAreas','RetouchAreasMasksTop'] }, - 'retouchareamaskvalue' => { 442 => [\'RetouchAreas','RetouchAreasMasksMaskValue'] }, - 'retouchareamaskversion' => { 442 => [\'RetouchAreas','RetouchAreasMasksVersion'] }, - 'retouchareamaskwhat' => { 442 => [\'RetouchAreas','RetouchAreasMasksWhat'] }, - 'retouchareamaskx' => { 442 => [\'RetouchAreas','RetouchAreasMasksX'] }, - 'retouchareamasky' => { 442 => [\'RetouchAreas','RetouchAreasMasksY'] }, - 'retouchareamaskzerox' => { 442 => [\'RetouchAreas','RetouchAreasMasksZeroX'] }, - 'retouchareamaskzeroy' => { 442 => [\'RetouchAreas','RetouchAreasMasksZeroY'] }, - 'retouchareamethod' => { 442 => [\'RetouchAreas','RetouchAreasMethod'] }, - 'retouchareaoffsety' => { 442 => [\'RetouchAreas','RetouchAreasOffsetY'] }, - 'retouchareaopacity' => { 442 => [\'RetouchAreas','RetouchAreasOpacity'] }, - 'retouchareas' => { 442 => 'RetouchAreas' }, - 'retouchareaseed' => { 442 => [\'RetouchAreas','RetouchAreasSeed'] }, - 'retouchareasourcestate' => { 442 => [\'RetouchAreas','RetouchAreasSourceState'] }, - 'retouchareasourcex' => { 442 => [\'RetouchAreas','RetouchAreasSourceX'] }, - 'retouchareaspottype' => { 442 => [\'RetouchAreas','RetouchAreasSpotType'] }, - 'retouchhistory' => { 211 => 0x9e }, - 'retouchinfo' => { 442 => 'RetouchInfo' }, - 'retouchnefprocessing' => { 217 => 0x5 }, - 'retractlensonpoweroff' => { 78 => 0x814 }, - 'reuse' => { 284 => 'Reuse' }, - 'reuseallowed' => { 469 => 'ReuseAllowed' }, - 'reuseprohibited' => { 459 => 'reuseProhibited' }, - 'reverseexposurecompdial' => { 264 => '5.2' }, - 'reverseindicators' => { 257 => '12.1', 258 => '6.1', 260 => '6.1', 261 => '6.1', 262 => '4.3', 263 => '5.2', 264 => '5.4', 266 => '33.5', 267 => '5.1', 270 => '6.1', 271 => '6.1', 272 => '6.2' }, - 'reverseshutterspeedaperture' => { 264 => '5.3' }, - 'revision' => { 444 => 'revision' }, - 'rflensmffocusringsensitivity' => { 78 => 0x714 }, - 'rgbcurvelimits' => { 102 => 0x238 }, - 'rgbcurvepoints' => { 101 => 0x7, 102 => 0x20e }, - 'richtextcomment' => { 449 => 'RichTextComment' }, - 'ricohdate' => { 357 => 0x6 }, - 'ricohimageheight' => { 357 => 0x2 }, - 'ricohimagewidth' => { 357 => 0x0 }, - 'rightalbedo' => { 432 => 'RightAlbedo' }, - 'rightascension' => { 156 => 'RightAscension' }, - 'rights' => { 443 => 'rights' }, - 'rightsagent' => { 459 => 'rightsAgent' }, - 'rightsowner' => { 459 => 'rightsOwner' }, - 'roll' => { 109 => 0x8 }, - 'rollangle' => { 228 => 0x350b, 229 => 0x2c24, 237 => 0x36f4, 274 => 0x903, 297 => 0x90, 331 => 0x1, 363 => 0x2 }, - 'romoperationmode' => { 91 => 0x80d }, - 'rotation' => { 29 => 0x17, 30 => 0x18, 90 => 0x3, 97 => 0x10002, 102 => 0x26e, 108 => 'Rotation', 117 => 0x4, 156 => 'Rotation', 172 => [0x65,0x50], 173 => 0x46, 174 => 0x5a, 177 => 0x10, 228 => 0x3693, 229 => 0xca, 235 => '590.1', 250 => 0x76a43207, 297 => 0x30, 313 => '17.2', 343 => 0xd8, 376 => 0x3f, 377 => 0x3f, 387 => 0x10 }, - 'routedto' => { 448 => 'RoutedTo' }, - 'routing' => { 348 => 'Routing' }, - 'routingdestinations' => { 431 => 'RoutingDestinations' }, - 'routingexclusions' => { 431 => 'RoutingExclusions' }, - 'routingnotes' => { 448 => 'RoutingNotes' }, - 'rowsperstrip' => { 113 => 0x116 }, - 'rpp' => { 436 => 'rpp' }, - 'safetyshift' => { 78 => 0x108 }, - 'safetyshiftinavortv' => { 76 => 0x10, 77 => 0x10, 79 => 0xf, 80 => 0x10, 83 => 0x10 }, - 'sameexposurefornewaperture' => { 78 => 0x112 }, - 'samplebits' => { 146 => 'SampleBits' }, - 'samplepagerange' => { 456 => 'samplePageRange' }, - 'samplerate' => { 146 => 'SampleRate' }, - 'samplesperpixel' => { 113 => 0x115, 302 => 0x8, 462 => 'SamplesPerPixel' }, - 'samplestructure' => { 127 => 0x5a }, - 'samsungmodelid' => { 365 => 0x3 }, - 'sanyoquality' => { 367 => 0x201 }, - 'sanyothumbnail' => { 367 => 0x100 }, - 'saturation' => { 9 => 0x6e, 11 => 0x76, 33 => 0xe, 48 => 0x1, 106 => 0xd, 107 => [0x3013,0x1f], 113 => [0xa409,0xfe55], 121 => 0x1003, 147 => 'Saturation', 171 => 0x1f, 172 => 0x32, 173 => 0x28, 174 => 0x1a, 179 => 0x1, 211 => [0x94,0xaa], 213 => 0x35, 214 => 0x3b, 297 => 0x40, 299 => 0x300d, 332 => 0x1f, 339 => 0xd, 353 => 0x27, 357 => 0x28, 358 => 0x1013, 368 => 0x10, 376 => 0x1e, 377 => 0x1b, 388 => 0x2005, 442 => 'Saturation', 446 => 'Saturation' }, - 'saturationadj' => { 97 => 0x20901, 102 => 0x116, 249 => 0x1, 253 => 0x2e, 421 => 0x8016 }, - 'saturationadjustmentaqua' => { 442 => 'SaturationAdjustmentAqua' }, - 'saturationadjustmentblue' => { 442 => 'SaturationAdjustmentBlue' }, - 'saturationadjustmentgreen' => { 442 => 'SaturationAdjustmentGreen' }, - 'saturationadjustmentmagenta' => { 442 => 'SaturationAdjustmentMagenta' }, - 'saturationadjustmentorange' => { 442 => 'SaturationAdjustmentOrange' }, - 'saturationadjustmentpurple' => { 442 => 'SaturationAdjustmentPurple' }, - 'saturationadjustmentred' => { 442 => 'SaturationAdjustmentRed' }, - 'saturationadjustmentyellow' => { 442 => 'SaturationAdjustmentYellow' }, - 'saturationauto' => { 67 => 0x98 }, - 'saturationfaithful' => { 18 => 0xfe, 66 => 0x68, 67 => 0x68 }, - 'saturationlandscape' => { 18 => 0xfc, 66 => 0x38, 67 => 0x38 }, - 'saturationmonochrome' => { 66 => 0x80, 67 => 0x80 }, - 'saturationneutral' => { 18 => 0xfd, 66 => 0x50, 67 => 0x50 }, - 'saturationportrait' => { 18 => 0xfb, 66 => 0x20, 67 => 0x20 }, - 'saturationsetting' => { 282 => 0x1010, 378 => 0x11, 393 => 0x9 }, - 'saturationstandard' => { 18 => 0xfa, 66 => 0x8, 67 => 0x8 }, - 'saturationuserdef1' => { 18 => 0x100, 66 => 0x98, 67 => 0xb0 }, - 'saturationuserdef2' => { 18 => 0x101, 66 => 0xb0, 67 => 0xc8 }, - 'saturationuserdef3' => { 18 => 0x102, 66 => 0xc8, 67 => 0xe0 }, - 'saveid' => { 467 => 'SaveID' }, - 'sbaanalysiscomplete' => { 131 => 0xc35 }, - 'sbablack' => { 131 => 0xc25 }, - 'sbagmoffset' => { 131 => 0xc4a }, - 'sbagray' => { 131 => 0xc26 }, - 'sbagreenmagentabal' => { 131 => 0xc33 }, - 'sbahighgray' => { 131 => 0xc46 }, - 'sbailloffset' => { 131 => 0xc49 }, - 'sbailluminantbal' => { 131 => 0xc34 }, - 'sbalowgray' => { 131 => 0xc47 }, - 'sbaneutralbal' => { 131 => 0xc32 }, - 'sbawhite' => { 131 => 0xc27 }, - 'scaletype' => { 466 => 'scaleType' }, - 'scanimageenhancer' => { 218 => 0x60 }, - 'scanningdirection' => { 127 => 0x64 }, - 'scene' => { 451 => 'Scene', 466 => 'scene' }, - 'scenearea' => { 277 => 0x211, 279 => 0x1031 }, - 'sceneassist' => { 211 => 0x9c }, - 'scenecapturetype' => { 113 => 0xa406, 446 => 'SceneCaptureType' }, - 'scenedetect' => { 277 => 0x210, 279 => 0x1030 }, - 'scenedetectdata' => { 277 => 0x212, 279 => 0x1033 }, - 'scenemode' => { 135 => 0xfa02, 176 => 0x100, 211 => 0x8f, 274 => 0x509, 279 => 0x403, 297 => 0x8001, 306 => 0xf, 388 => 0xb023 }, - 'scenemodeused' => { 137 => [0x6002,0xf002] }, - 'scenerecognition' => { 121 => 0x1425 }, - 'sceneselect' => { 367 => 0x21f }, - 'scenetype' => { 113 => 0xa301, 446 => 'SceneType' }, - 'screentips' => { 257 => '12.7', 258 => '5.3', 266 => '13.1', 267 => '4.4', 270 => '5.4', 272 => '5.1' }, - 'scriptversion' => { 131 => 0x1770 }, - 'season' => { 452 => 'Season', 455 => 'season' }, - 'seasonidentifier' => { 452 => [\'Season','SeasonIdentifier'] }, - 'seasonname' => { 452 => [\'Season','SeasonName'] }, - 'seasonnumber' => { 452 => [\'Season','SeasonNumber'] }, - 'secondaryftp' => { 431 => 'SecondaryFTP' }, - 'secondaryslotfunction' => { 228 => 0x1d0, 237 => 0x1d0 }, - 'section' => { 456 => 'section' }, - 'securityclassification' => { 113 => 0x9212 }, - 'selectableafpoint' => { 78 => 0x509 }, + 'orientationlinkedafpoint' => { 81 => 0x516 }, + 'originalbestqualitysize' => { 116 => 0xc792 }, + 'originalcreatedatetime' => { 452 => 'OriginalCreateDateTime' }, + 'originaldecisiondata' => { 111 => 'Canon::OriginalDecisionData' }, + 'originaldecisiondataoffset' => { 61 => 0x83 }, + 'originaldefaultcropsize' => { 116 => 0xc793 }, + 'originaldefaultfinalsize' => { 116 => 0xc791 }, + 'originaldirectory' => { 303 => 0x408 }, + 'originaldocumentid' => { 489 => 'OriginalDocumentID' }, + 'originalfilename' => { 94 => 0x816, 134 => 0x3e9, 146 => 0x20, 303 => 0x407, 452 => 'OriginalFilename' }, + 'originalimageheight' => { 76 => 0xc, 120 => 0x1 }, + 'originalimagewidth' => { 76 => 0xb, 120 => 0x0 }, + 'originalrawfiledata' => { 116 => 0xc68c }, + 'originalrawfiledigest' => { 116 => 0xc71d }, + 'originalrawfilename' => { 116 => 0xc68b }, + 'originaltransmissionreference' => { 128 => 0x67 }, + 'originatingprogram' => { 128 => 0x41, 457 => 'OriginatingProgram' }, + 'originplatform' => { 478 => 'originPlatform' }, + 'os' => { 466 => 'os' }, + 'otherconditions' => { 293 => 'OtherConditions' }, + 'otherconstraints' => { 293 => 'OtherConstraints' }, + 'otherimage' => { 111 => 'Exif::OtherImage' }, + 'otherimageinfo' => { 293 => 'OtherImageInfo' }, + 'otherimagelength' => { 116 => 0x202 }, + 'otherimagestart' => { 116 => 0x201 }, + 'otherlicensedocuments' => { 293 => 'OtherLicenseDocuments' }, + 'otherlicenseinfo' => { 293 => 'OtherLicenseInfo' }, + 'otherlicenserequirements' => { 293 => 'OtherLicenseRequirements' }, + 'outcue' => { 488 => 'outCue' }, + 'outcuescale' => { 488 => [\'outCue','outCueScale'] }, + 'outcuevalue' => { 488 => [\'outCue','outCueValue'] }, + 'outputimageheight' => { 191 => 0x3 }, + 'outputimagewidth' => { 191 => 0x2 }, + 'outputlut' => { 306 => 0xa7 }, + 'outputprofile' => { 134 => 0x138b }, + 'outputresolution' => { 191 => 0x4 }, + 'overclockcols' => { 134 => 0x189c }, + 'overclockrows' => { 134 => 0x18c4 }, + 'overridelookvignette' => { 462 => 'OverrideLookVignette', 464 => 'OverrideLookVignette' }, + 'owner' => { 492 => 'Owner' }, + 'ownerid' => { 128 => 0xbc }, + 'ownername' => { 15 => 0x10f, 61 => 0x9, 94 => 0x810, 116 => [0xa430,0xfde8], 152 => 'OwnerName', 459 => 'OwnerName', 469 => 'CameraOwnerName' }, + 'padding' => { 116 => 0xea1c }, + 'pagecount' => { 478 => 'pageCount' }, + 'pageimage' => { 486 => [\'PageInfo','PageInfoImage'] }, + 'pageimageformat' => { 486 => [\'PageInfo','PageInfoFormat'] }, + 'pageimageheight' => { 486 => [\'PageInfo','PageInfoHeight'] }, + 'pageimagepagenumber' => { 486 => [\'PageInfo','PageInfoPageNumber'] }, + 'pageimagewidth' => { 486 => [\'PageInfo','PageInfoWidth'] }, + 'pageinfo' => { 486 => 'PageInfo' }, + 'pagename' => { 116 => 0x11d }, + 'pagenumber' => { 116 => 0x129 }, + 'pageprogressiondirection' => { 478 => 'pageProgressionDirection' }, + 'pagerange' => { 478 => 'pageRange' }, + 'paintbasedcorrectionmasks' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'] }, + 'paintbasedcorrections' => { 462 => 'PaintBasedCorrections', 464 => 'PaintBasedCorrections' }, + 'paintcorrectionactive' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'] }, + 'paintcorrectionamount' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'] }, + 'paintcorrectionbrightness' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'] }, + 'paintcorrectionclarity' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'] }, + 'paintcorrectionclarity2012' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity2012'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity2012'] }, + 'paintcorrectioncontrast' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'] }, + 'paintcorrectioncontrast2012' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast2012'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast2012'] }, + 'paintcorrectiondefringe' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDefringe'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDefringe'] }, + 'paintcorrectionexposure' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'] }, + 'paintcorrectionexposure2012' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure2012'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure2012'] }, + 'paintcorrectionhighlights2012' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHighlights2012'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHighlights2012'] }, + 'paintcorrectionhue' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalToningHue'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalToningHue'] }, + 'paintcorrectionluminancenoise' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalLuminanceNoise'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalLuminanceNoise'] }, + 'paintcorrectionmaskalpha' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAlpha'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAlpha'] }, + 'paintcorrectionmaskangle' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAngle'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAngle'] }, + 'paintcorrectionmaskbottom' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksBottom'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksBottom'] }, + 'paintcorrectionmaskcentervalue' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterValue'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterValue'] }, + 'paintcorrectionmaskcenterweight' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'] }, + 'paintcorrectionmaskdabs' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'] }, + 'paintcorrectionmaskfeather' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFeather'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFeather'] }, + 'paintcorrectionmaskflipped' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlipped'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlipped'] }, + 'paintcorrectionmaskflow' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'] }, + 'paintcorrectionmaskfullx' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'] }, + 'paintcorrectionmaskfully' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'] }, + 'paintcorrectionmaskleft' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksLeft'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksLeft'] }, + 'paintcorrectionmaskmidpoint' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMidpoint'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMidpoint'] }, + 'paintcorrectionmaskperimetervalue' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksPerimeterValue'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksPerimeterValue'] }, + 'paintcorrectionmaskradius' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'] }, + 'paintcorrectionmaskright' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRight'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRight'] }, + 'paintcorrectionmaskroundness' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRoundness'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRoundness'] }, + 'paintcorrectionmasksizex' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeX'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeX'] }, + 'paintcorrectionmasksizey' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeY'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeY'] }, + 'paintcorrectionmasktop' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksTop'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksTop'] }, + 'paintcorrectionmaskvalue' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'] }, + 'paintcorrectionmaskversion' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksVersion'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksVersion'] }, + 'paintcorrectionmaskwhat' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'] }, + 'paintcorrectionmaskx' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksX'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksX'] }, + 'paintcorrectionmasky' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksY'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksY'] }, + 'paintcorrectionmaskzerox' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'] }, + 'paintcorrectionmaskzeroy' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'] }, + 'paintcorrectionmoire' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalMoire'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalMoire'] }, + 'paintcorrectionsaturation' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'] }, + 'paintcorrectionshadows2012' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalShadows2012'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalShadows2012'] }, + 'paintcorrectionsharpness' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'] }, + 'paintcorrectiontemperature' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTemperature'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTemperature'] }, + 'paintcorrectiontint' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTint'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTint'] }, + 'paintcorrectionwhat' => { 462 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'], 464 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'] }, + 'panasonicdatetime' => { 309 => 0x0 }, + 'panasonicexifversion' => { 306 => 0x26 }, + 'panasonicimageheight' => { 306 => 0x4c }, + 'panasonicimagewidth' => { 306 => 0x4b }, + 'panasonicrawversion' => { 311 => 0x1 }, + 'panasonictitle' => { 116 => 0xc6d2 }, + 'panasonictitle2' => { 116 => 0xc6d3 }, + 'panoramaangle' => { 124 => 0x1153 }, + 'panoramacropbottom' => { 412 => 0x7 }, + 'panoramacropleft' => { 412 => 0x4 }, + 'panoramacropright' => { 412 => 0x6 }, + 'panoramacroptop' => { 412 => 0x5 }, + 'panoramadirection' => { 69 => 0x5, 124 => 0x1154, 412 => 0x3 }, + 'panoramaframeheight' => { 412 => 0x9 }, + 'panoramaframenumber' => { 69 => 0x2 }, + 'panoramaframewidth' => { 412 => 0x8 }, + 'panoramafullheight' => { 412 => 0x2 }, + 'panoramafullwidth' => { 412 => 0x1 }, + 'panoramamode' => { 136 => 0x3c, 283 => 0x601 }, + 'panoramasize3d' => { 395 => 0x38 }, + 'panoramasourceheight' => { 412 => 0xb }, + 'panoramasourcewidth' => { 412 => 0xa }, + 'panoramicstitchcameramotion' => { 172 => 'PanoramicStitchCameraMotion', 173 => 0x1 }, + 'panoramicstitchmaptype' => { 172 => 'PanoramicStitchMapType', 173 => 0x2 }, + 'panoramicstitchphi0' => { 172 => 'PanoramicStitchPhi0', 173 => 0x5 }, + 'panoramicstitchphi1' => { 172 => 'PanoramicStitchPhi1', 173 => 0x6 }, + 'panoramicstitchtheta0' => { 172 => 'PanoramicStitchTheta0', 173 => 0x3 }, + 'panoramicstitchtheta1' => { 172 => 'PanoramicStitchTheta1', 173 => 0x4 }, + 'panoramicstitchversion' => { 173 => 0x0 }, + 'pantry' => { 489 => 'Pantry' }, + 'pantryinstanceid' => { 489 => [\'Pantry','PantryInstanceID'] }, + 'parallax' => { 124 => 0xb211, 282 => 0x28 }, + 'parametricdarks' => { 462 => 'ParametricDarks', 464 => 'ParametricDarks' }, + 'parametrichighlights' => { 462 => 'ParametricHighlights', 464 => 'ParametricHighlights' }, + 'parametrichighlightsplit' => { 462 => 'ParametricHighlightSplit', 464 => 'ParametricHighlightSplit' }, + 'parametriclights' => { 462 => 'ParametricLights', 464 => 'ParametricLights' }, + 'parametricmidtonesplit' => { 462 => 'ParametricMidtoneSplit', 464 => 'ParametricMidtoneSplit' }, + 'parametricshadows' => { 462 => 'ParametricShadows', 464 => 'ParametricShadows' }, + 'parametricshadowsplit' => { 462 => 'ParametricShadowSplit', 464 => 'ParametricShadowSplit' }, + 'parentmediaeventid' => { 452 => 'ParentMediaEventID' }, + 'parentmeid' => { 452 => 'ParentMEID' }, + 'parentproductid' => { 358 => '@ppi' }, + 'parentreference1' => { 472 => [\'TagStructure','TagStructureParentReference'] }, + 'parentreference2' => { 472 => [\'TagStructure','TagStructureSubLabelsParentReference'] }, + 'parentreference3' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsParentReference'] }, + 'parentreference4' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsParentReference'] }, + 'parentreference5' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference'] }, + 'parentreference6' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference'] }, + 'parentshorttitle' => { 358 => '@PST' }, + 'parenttitle' => { 358 => '@pti' }, + 'partialactivecols1' => { 134 => 0x17e8 }, + 'partialactivecols2' => { 134 => 0x17f2 }, + 'partialactiverows1' => { 134 => 0x17fc }, + 'partialactiverows2' => { 134 => 0x1806 }, + 'partofcompilation' => { 488 => 'partOfCompilation' }, + 'patientbirthdate' => { 441 => 'PatientDOB' }, + 'patientid' => { 441 => 'PatientID' }, + 'patientname' => { 441 => 'PatientName' }, + 'patientsex' => { 441 => 'PatientSex' }, + 'patternareaheight' => { 134 => 0x963 }, + 'patternareawidth' => { 134 => 0x962 }, + 'patterncorrectionfactorscale' => { 134 => 0x969 }, + 'patterncropcols1' => { 134 => 0x96c }, + 'patterncropcols2' => { 134 => 0x96d }, + 'patterncroprows1' => { 134 => 0x96a }, + 'patterncroprows2' => { 134 => 0x96b }, + 'patternimagerheight' => { 134 => 0x961 }, + 'patternimagerwidth' => { 134 => 0x960 }, + 'patternx' => { 134 => 0x966 }, + 'patterny' => { 134 => 0x967 }, + 'pdfversion' => { 475 => 'PDFVersion' }, + 'pentaximagesize' => { 341 => 0x9 }, + 'pentaxmodelid' => { 321 => 0x0, 341 => 0x5 }, + 'pentaxmodeltype' => { 341 => 0x1 }, + 'pentaxversion' => { 341 => 0x0 }, + 'people' => { 443 => 'People', 455 => 'People' }, + 'perchannelblacklevel' => { 42 => 0xc4, 43 => [0x2b4,0x2cb,0x2cf], 44 => [0x108,0x14d], 45 => 0x1df, 46 => [0x1f8,0x2d8], 47 => [0x22c,0x30a], 48 => 0x149 }, + 'performer' => { 358 => 'perf', 366 => 'perf' }, + 'performerkeywords' => { 366 => "\xa9prk" }, + 'performers' => { 366 => "\xa9prf" }, + 'performerurl' => { 366 => "\xa9prl" }, + 'peripheralillumcentralradius' => { 439 => 0x8030 }, + 'peripheralillumcentralvalue' => { 439 => 0x8031 }, + 'peripheralillumination' => { 100 => 0x20702, 106 => 0x68 }, + 'peripheralilluminationcorr' => { 60 => 0x1, 331 => 0x2 }, + 'peripheralilluminationon' => { 100 => '0x20702.0', 106 => 0x64 }, + 'peripheralillumperiphvalue' => { 439 => 0x8032 }, + 'peripherallighting' => { 76 => 0x2, 124 => 0x3804 }, + 'peripherallightingsetting' => { 77 => 0x5 }, + 'peripherallightingvalue' => { 76 => 0x6 }, + 'permissions' => { 481 => 'permissions' }, + 'permits' => { 460 => 'permits' }, + 'person' => { 478 => 'person' }, + 'personality' => { 452 => 'Personality' }, + 'personheard' => { 474 => 'PersonHeard' }, + 'personheardidentifier' => { 474 => [\'PersonHeard','PersonHeardIdentifier'] }, + 'personheardname' => { 474 => [\'PersonHeard','PersonHeardName'] }, + 'personinimage' => { 474 => 'PersonInImage' }, + 'personinimagecharacteristic' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristic'] }, + 'personinimagecvtermcvid' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvId'] }, + 'personinimagecvtermid' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermId'] }, + 'personinimagecvtermname' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermName'] }, + 'personinimagecvtermrefinedabout' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermRefinedAbout'] }, + 'personinimagedescription' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonDescription'] }, + 'personinimageid' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonId'] }, + 'personinimagename' => { 474 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonName'] }, + 'personinimagewdetails' => { 474 => 'PersonInImageWDetails' }, + 'perspectiveaspect' => { 462 => 'PerspectiveAspect', 464 => 'PerspectiveAspect' }, + 'perspectivehorizontal' => { 462 => 'PerspectiveHorizontal', 464 => 'PerspectiveHorizontal' }, + 'perspectiverotate' => { 462 => 'PerspectiveRotate', 464 => 'PerspectiveRotate' }, + 'perspectivescale' => { 462 => 'PerspectiveScale', 464 => 'PerspectiveScale' }, + 'perspectiveupright' => { 462 => 'PerspectiveUpright', 464 => 'PerspectiveUpright' }, + 'perspectivevertical' => { 462 => 'PerspectiveVertical', 464 => 'PerspectiveVertical' }, + 'perspectivex' => { 462 => 'PerspectiveX', 464 => 'PerspectiveX' }, + 'perspectivey' => { 462 => 'PerspectiveY', 464 => 'PerspectiveY' }, + 'pf0customfuncregistration' => { 89 => 0x1 }, + 'pf10retainprogramshift' => { 89 => 0xb }, + 'pf13drivepriority' => { 89 => 0xe }, + 'pf14disablefocussearch' => { 89 => 0xf }, + 'pf15disableafassistbeam' => { 89 => 0x10 }, + 'pf16autofocuspointshoot' => { 89 => 0x11 }, + 'pf17disableafpointsel' => { 89 => 0x12 }, + 'pf18enableautoafpointsel' => { 89 => 0x13 }, + 'pf19continuousshootspeed' => { 89 => 0x14 }, + 'pf19shootingspeedhigh' => { 88 => 0xa }, + 'pf19shootingspeedlow' => { 88 => 0x9 }, + 'pf1disableshootingmodes' => { 89 => 0x2 }, + 'pf1value' => { 88 => 0x1 }, + 'pf20limitcontinousshots' => { 89 => 0x15 }, + 'pf20maxcontinousshots' => { 88 => 0xb }, + 'pf21enablequietoperation' => { 89 => 0x16 }, + 'pf23felocktime' => { 88 => 0xd }, + 'pf23postreleasetime' => { 88 => 0xe }, + 'pf23settimerlengths' => { 89 => 0x18 }, + 'pf23shutterbuttontime' => { 88 => 0xc }, + 'pf24lightlcdduringbulb' => { 89 => 0x19 }, + 'pf25aemode' => { 88 => 0xf }, + 'pf25afmode' => { 88 => 0x12 }, + 'pf25afpointsel' => { 88 => 0x13 }, + 'pf25colormatrix' => { 88 => 0x17 }, + 'pf25defaultclearsettings' => { 89 => 0x1a }, + 'pf25drivemode' => { 88 => 0x11 }, + 'pf25imagesize' => { 88 => 0x14 }, + 'pf25meteringmode' => { 88 => 0x10 }, + 'pf25parameters' => { 88 => 0x16 }, + 'pf25wbmode' => { 88 => 0x15 }, + 'pf26shortenreleaselag' => { 89 => 0x1b }, + 'pf27reversedialrotation' => { 89 => 0x1c }, + 'pf27value' => { 88 => 0x18 }, + 'pf28noquickdialexpcomp' => { 89 => 0x1d }, + 'pf29quickdialswitchoff' => { 89 => 0x1e }, + 'pf2disablemeteringmodes' => { 89 => 0x3 }, + 'pf2value' => { 88 => 0x2 }, + 'pf30enlargementmode' => { 89 => 0x1f }, + 'pf31originaldecisiondata' => { 89 => 0x20 }, + 'pf3manualexposuremetering' => { 89 => 0x4 }, + 'pf3value' => { 88 => 0x3 }, + 'pf4exposuretimelimits' => { 89 => 0x5 }, + 'pf4exposuretimemax' => { 88 => 0x5 }, + 'pf4exposuretimemin' => { 88 => 0x4 }, + 'pf5aperturelimits' => { 89 => 0x6 }, + 'pf5aperturemax' => { 88 => 0x7 }, + 'pf5aperturemin' => { 88 => 0x6 }, + 'pf6presetshootingmodes' => { 89 => 0x7 }, + 'pf7bracketcontinuousshoot' => { 89 => 0x8 }, + 'pf8bracketshots' => { 88 => 0x8 }, + 'pf8setbracketshots' => { 89 => 0x9 }, + 'pf9changebracketsequence' => { 89 => 0xa }, + 'phasedetectaf' => { 188 => 0x6 }, + 'phonenumber' => { 153 => 'Phone' }, + 'photoeffect' => { 34 => 0x28 }, + 'photoeffecthistoryxml' => { 259 => 0xe9651831 }, + 'photoeffects' => { 259 => 0xab5eca5e }, + 'photoeffectsblue' => { 261 => 0x8 }, + 'photoeffectsgreen' => { 261 => 0x6 }, + 'photoeffectsred' => { 261 => 0x4 }, + 'photoeffectstype' => { 261 => 0x0 }, + 'photographicsensitivity' => { 469 => 'PhotographicSensitivity' }, + 'photoinfoplayback' => { 266 => '17.6', 275 => '33.6' }, + 'photometricinterpretation' => { 116 => 0x106, 484 => 'PhotometricInterpretation' }, + 'photoshootingmenubank' => { 238 => 0xe7d, 247 => 0xfbd }, + 'photoshootingmenubankimagearea' => { 238 => '3716.1', 247 => 0x791 }, + 'photoshopbgrthumbnail' => { 355 => 0x409 }, + 'photoshopquality' => { 354 => 0x0 }, + 'photoshopthumbnail' => { 355 => 0x40c }, + 'photostyle' => { 306 => 0x89 }, + 'picklabel' => { 467 => 'PickLabel' }, + 'pictinfo' => { 382 => 0x208 }, + 'picturecontrol' => { 259 => 0xe2173c47 }, + 'picturecontrolactive' => { 262 => 0x0 }, + 'picturecontroladjust' => { 221 => 0x30, 222 => 0x30, 223 => 0x36 }, + 'picturecontrolbase' => { 221 => 0x18, 222 => 0x18, 223 => 0x1c }, + 'picturecontroldata' => { 219 => [0xbd,0x23] }, + 'picturecontrolmode' => { 262 => 0x13 }, + 'picturecontrolname' => { 221 => 0x4, 222 => 0x4, 223 => 0x8 }, + 'picturecontrolquickadjust' => { 221 => 0x31, 222 => 0x31, 223 => 0x37 }, + 'pictureeffect' => { 406 => 0x200e }, + 'pictureeffect2' => { 414 => 0x1163, 415 => 0x1167, 416 => 0x1143, 417 => 0x11bf, 418 => 0x119b, 419 => 0x1053, 420 => 0x24b, 421 => 0x24b, 422 => 0x23c, 435 => 0x46 }, + 'picturefinish' => { 177 => 0x71 }, + 'picturemode' => { 124 => 0x1031, 283 => 0x520, 341 => [0xb,0x33], 383 => 0x3d }, + 'picturemode2' => { 322 => 0x0 }, + 'picturemodebwfilter' => { 283 => 0x525 }, + 'picturemodecontrast' => { 283 => 0x523 }, + 'picturemodeeffect' => { 283 => 0x52d }, + 'picturemodehue' => { 283 => 0x522 }, + 'picturemodesaturation' => { 283 => 0x521 }, + 'picturemodesharpness' => { 283 => 0x524 }, + 'picturemodetone' => { 283 => 0x526 }, + 'pictureprofile' => { 414 => [0x115e,0x115f], 415 => [0x1162,0x1163], 416 => [0x113e,0x113f], 417 => [0x11ba,0x11bb], 418 => [0x1196,0x1197], 419 => [0x104e,0x104f], 420 => [0x246,0x247], 421 => [0x246,0x247], 422 => [0x237,0x238] }, + 'picturestyle' => { 8 => [0x4b,0x51], 9 => 0xf4, 10 => 0x6c, 11 => 0x86, 12 => 0x73, 16 => 0xab, 17 => 0xa7, 18 => 0xb0, 19 => 0x6c, 20 => 0xa7, 21 => 0xf4, 22 => 0xb3, 24 => 0xf4, 25 => 0xfa, 27 => 0x169, 71 => 0xa, 100 => 0x20301, 106 => 0x2 }, + 'picturestylepc' => { 61 => 0x4009 }, + 'picturestyleuserdef' => { 61 => 0x4008 }, + 'picturewizard' => { 380 => 0x21 }, + 'picturewizardcolor' => { 379 => 0x1 }, + 'picturewizardcontrast' => { 379 => 0x4 }, + 'picturewizardmode' => { 379 => 0x0 }, + 'picturewizardsaturation' => { 379 => 0x2 }, + 'picturewizardsharpness' => { 379 => 0x3 }, + 'pipelineversion' => { 172 => 'PipelineVersion' }, + 'pitch' => { 112 => 0x6, 267 => '4.1', 279 => '4.1', 366 => ['ptch',"\xa9fpt"] }, + 'pitchangle' => { 237 => 0x350f, 238 => 0x2c28, 246 => 0x36f8, 283 => 0x904, 306 => 0x91, 340 => 0x2, 378 => 0x1 }, + 'pitchshift' => { 360 => 'player.movie.audio.pitchshift' }, + 'pixelaspectratio' => { 359 => 'pasp' }, + 'pixelclockfrequency' => { 134 => 0x40b }, + 'pixelcorrectionoffset' => { 134 => 0x972 }, + 'pixelcorrectionscale' => { 134 => 0x971 }, + 'pixelscale' => { 116 => 0x830e }, + 'pixelshiftinfo' => { 406 => 0x202f }, + 'pixelshiftresolution' => { 342 => 0x0 }, + 'pixelsperunitx' => { 295 => 0x0 }, + 'pixelsperunity' => { 295 => 0x4 }, + 'pixelunits' => { 295 => 0x8 }, + 'planarconfiguration' => { 116 => 0x11c, 484 => 'PlanarConfiguration' }, + 'plane' => { 442 => [\'Planes','PlanesPlane'] }, + 'planeboundary' => { 442 => [\'Planes','PlanesPlaneBoundary'] }, + 'planeboundaryvertexcount' => { 442 => [\'Planes','PlanesPlaneBoundaryVertexCount'] }, + 'planeextentx' => { 442 => [\'Planes','PlanesPlaneExtentX'] }, + 'planeextentz' => { 442 => [\'Planes','PlanesPlaneExtentZ'] }, + 'planepose' => { 442 => [\'Planes','PlanesPlanePose'] }, + 'planeposepositionx' => { 442 => [\'Planes','PlanesPlanePosePositionX'] }, + 'planeposepositiony' => { 442 => [\'Planes','PlanesPlanePosePositionY'] }, + 'planeposepositionz' => { 442 => [\'Planes','PlanesPlanePosePositionZ'] }, + 'planeposerotationw' => { 442 => [\'Planes','PlanesPlanePoseRotationW'] }, + 'planeposerotationx' => { 442 => [\'Planes','PlanesPlanePoseRotationX'] }, + 'planeposerotationy' => { 442 => [\'Planes','PlanesPlanePoseRotationY'] }, + 'planeposerotationz' => { 442 => [\'Planes','PlanesPlanePoseRotationZ'] }, + 'planeposetimestamp' => { 442 => [\'Planes','PlanesPlanePoseTimestamp'] }, + 'planes' => { 442 => 'Planes' }, + 'planningref' => { 474 => 'PlanningRef' }, + 'planningrefidentifier' => { 474 => [\'PlanningRef','PlanningRefIdentifier'] }, + 'planningrefname' => { 474 => [\'PlanningRef','PlanningRefName'] }, + 'planningrefrole' => { 474 => [\'PlanningRef','PlanningRefRole'] }, + 'platenames' => { 493 => 'PlateNames' }, + 'platform' => { 478 => 'platform' }, + 'playallframes' => { 366 => 'AllF' }, + 'playbackmenustime' => { 271 => '20.1', 272 => '21.1', 273 => '21.1' }, + 'playbackmonitorofftime' => { 266 => '25.2', 267 => '36.1', 269 => '36.1', 270 => '36.1', 274 => '35.1', 275 => '8.1', 276 => '35.1', 279 => '36.1', 280 => '36.1', 281 => '21.1' }, + 'playbackzoom' => { 267 => '37.1' }, + 'playdisplay' => { 179 => 0x4e }, + 'playerversion' => { 360 => 'player.version' }, + 'playgap' => { 358 => 'pgap' }, + 'playlistid' => { 358 => 'plID' }, + 'playmode' => { 366 => 'SDLN' }, + 'playselection' => { 366 => 'SelO' }, + 'plusversion' => { 293 => 'Version' }, + 'pmversion' => { 353 => 'PMVersion' }, + 'pngwarning' => { 296 => 'Warning' }, + 'podcast' => { 358 => 'pcst' }, + 'podcasturl' => { 358 => 'purl' }, + 'poilevel' => { 218 => 0x8 }, + 'portraitnote' => { 445 => 'PortraitNote' }, + 'portraitoutputhighlightpoint' => { 106 => 0x1d }, + 'portraitoutputshadowpoint' => { 106 => 0x1e }, + 'portraitrawcolortone' => { 106 => 0x16 }, + 'portraitrawcontrast' => { 106 => 0x18 }, + 'portraitrawhighlight' => { 106 => 0x76 }, + 'portraitrawhighlightpoint' => { 106 => 0x1b }, + 'portraitrawlinear' => { 106 => 0x19 }, + 'portraitrawsaturation' => { 106 => 0x17 }, + 'portraitrawshadow' => { 106 => 0x7f }, + 'portraitrawshadowpoint' => { 106 => 0x1c }, + 'portraitrawsharpness' => { 106 => 0x1a }, + 'portraitrefiner' => { 110 => 0x302b }, + 'portraitrequest' => { 445 => 'PortraitRequest' }, + 'portraitunsharpmaskfineness' => { 106 => 0x9a }, + 'portraitunsharpmaskstrength' => { 106 => 0x98 }, + 'portraitunsharpmaskthreshold' => { 106 => 0x9c }, + 'portraitversion' => { 445 => 'PortraitVersion' }, + 'pose' => { 442 => 'Pose' }, + 'poseheadingdegrees' => { 450 => 'PoseHeadingDegrees' }, + 'posepitchdegrees' => { 450 => 'PosePitchDegrees' }, + 'posepositionx' => { 442 => [\'Pose','PosePositionX'] }, + 'posepositiony' => { 442 => [\'Pose','PosePositionY'] }, + 'posepositionz' => { 442 => [\'Pose','PosePositionZ'] }, + 'poserolldegrees' => { 450 => 'PoseRollDegrees' }, + 'poserotationw' => { 442 => [\'Pose','PoseRotationW'] }, + 'poserotationx' => { 442 => [\'Pose','PoseRotationX'] }, + 'poserotationy' => { 442 => [\'Pose','PoseRotationY'] }, + 'poserotationz' => { 442 => [\'Pose','PoseRotationZ'] }, + 'posetimestamp' => { 442 => [\'Pose','PoseTimestamp'] }, + 'positiondescriptor' => { 477 => 'positionDescriptor' }, + 'postalcode' => { 157 => 'PostalCode' }, + 'postcropvignetteamount' => { 462 => 'PostCropVignetteAmount', 464 => 'PostCropVignetteAmount' }, + 'postcropvignettefeather' => { 462 => 'PostCropVignetteFeather', 464 => 'PostCropVignetteFeather' }, + 'postcropvignettehighlightcontrast' => { 462 => 'PostCropVignetteHighlightContrast', 464 => 'PostCropVignetteHighlightContrast' }, + 'postcropvignettemidpoint' => { 462 => 'PostCropVignetteMidpoint', 464 => 'PostCropVignetteMidpoint' }, + 'postcropvignetteroundness' => { 462 => 'PostCropVignetteRoundness', 464 => 'PostCropVignetteRoundness' }, + 'postcropvignettestyle' => { 462 => 'PostCropVignetteStyle', 464 => 'PostCropVignetteStyle' }, + 'potentialface1position' => { 403 => 0xb }, + 'potentialface2position' => { 403 => 0x15 }, + 'potentialface3position' => { 403 => 0x1f }, + 'potentialface4position' => { 403 => 0x29 }, + 'potentialface5position' => { 403 => 0x33 }, + 'potentialface6position' => { 403 => 0x3d }, + 'potentialface7position' => { 403 => 0x47 }, + 'potentialface8position' => { 403 => 0x51 }, + 'powersource' => { 320 => '0.1' }, + 'poweruptime' => { 219 => 0xb6 }, + 'precaptureframes' => { 288 => 0x300 }, + 'predictor' => { 116 => 0x13d }, + 'preflashreturnstrength' => { 235 => 0x28a }, + 'prefs' => { 128 => 0xdd, 353 => 'Prefs' }, + 'prereadfastresetcount' => { 134 => 0x187e }, + 'preservedfilename' => { 489 => 'PreservedFileName' }, + 'preservedspecimen' => { 115 => 'PreservedSpecimen' }, + 'preservedspecimenmaterialsampleid' => { 115 => [\'PreservedSpecimen','PreservedSpecimenMaterialSampleID'] }, + 'presetwhitebalance' => { 179 => 0x24, 439 => 0x8002 }, + 'presetwhitebalanceadj' => { 439 => 0x8014 }, + 'pressure' => { 116 => 0x9402, 469 => 'Pressure' }, + 'previewapplicationname' => { 116 => 0xc716 }, + 'previewapplicationversion' => { 116 => 0xc717 }, + 'previewbutton' => { 266 => ['14.1','15.1'], 267 => '15.1', 269 => '15.1', 270 => '15.1', 275 => '29.1', 276 => '14.1', 279 => '15.1', 280 => '15.1' }, + 'previewbuttonplusdials' => { 266 => ['14.2','15.2'], 267 => '15.2', 269 => '43.1', 270 => '43.1', 275 => '31.2', 279 => '43.1', 280 => '43.1' }, + 'previewcolorspace' => { 116 => 0xc71a }, + 'previewcropbottom' => { 352 => 0xef }, + 'previewcropleft' => { 352 => 0xec }, + 'previewcropright' => { 352 => 0xee }, + 'previewcroptop' => { 352 => 0xed }, + 'previewdate' => { 364 => 0x0 }, + 'previewdatetime' => { 116 => 0xc71b }, + 'previewimage' => { 110 => 0x2000, 111 => 'Exif::PreviewImage', 117 => 'PreviewImage', 119 => 0x4, 162 => 'data', 181 => 0x81, 288 => 0x280, 304 => 0x300, 406 => 0x2001 }, + 'previewimageborders' => { 341 => 0x3e }, + 'previewimageheight' => { 70 => 0x4, 138 => 0xfa58 }, + 'previewimagelength' => { 70 => 0x2, 110 => 0x3, 116 => [0x117,0x202], 181 => 0x89, 224 => 0x202, 283 => 0x102, 288 => 0x1037, 341 => 0x3, 372 => 0x1e, 377 => 0x3, 383 => [0x1b,0x1d], 396 => 0x202 }, + 'previewimagename' => { 162 => '1Name' }, + 'previewimagesize' => { 110 => 0x2, 143 => 0x2, 162 => 'ImageSize', 341 => 0x2, 383 => [0x1c,0x1e], 406 => 0xb02c, 439 => 0x9012 }, + 'previewimagestart' => { 70 => 0x5, 110 => 0x4, 116 => [0x111,0x201], 181 => 0x88, 224 => 0x201, 283 => 0x101, 288 => 0x1036, 341 => 0x4, 372 => 0x1c, 377 => 0x2, 383 => [0x1a,0x1c], 396 => 0x201 }, + 'previewimagetype' => { 162 => '0Type' }, + 'previewimagevalid' => { 283 => 0x100, 288 => 0x1035 }, + 'previewimagewidth' => { 70 => 0x3, 138 => 0xfa57 }, + 'previewquality' => { 70 => 0x1 }, + 'previewsettingsdigest' => { 116 => 0xc719 }, + 'previewsettingsname' => { 116 => 0xc718 }, + 'primaryafpoint' => { 188 => [0x44,0x7] }, + 'primarychromaticities' => { 116 => 0x13f, 484 => 'PrimaryChromaticities' }, + 'primaryftp' => { 452 => 'PrimaryFTP' }, + 'primaryslot' => { 238 => 0xe7f, 247 => 0xfbf }, + 'printim' => { 116 => 0xc4a5 }, + 'prioritysetinawb' => { 406 => 0x202b }, + 'prioritysetupshutterrelease' => { 179 => 0x1d, 393 => 0x28 }, + 'privatertkinfo' => { 454 => 'privateRTKInfo' }, + 'processbordercolsleft' => { 134 => 0xc61 }, + 'processbordercolsright' => { 134 => 0xc62 }, + 'processborderrowsbottom' => { 134 => 0xc64 }, + 'processborderrowstop' => { 134 => 0xc63 }, + 'processingsoftware' => { 116 => 0xb }, + 'processversion' => { 462 => 'ProcessVersion', 464 => 'ProcessVersion' }, + 'producer' => { 292 => 'Producer', 360 => 'producer', 366 => "\xa9prd", 475 => 'Producer' }, + 'producerkeywords' => { 366 => "\xa9pdk" }, + 'productcode' => { 478 => 'productCode' }, + 'productid' => { 129 => 0x32, 358 => 'prID', 477 => 'productID' }, + 'productidtype' => { 477 => 'productIDType' }, + 'productinimage' => { 474 => 'ProductInImage' }, + 'productinimagedescription' => { 474 => [\'ProductInImage','ProductInImageProductDescription'] }, + 'productinimagegtin' => { 474 => [\'ProductInImage','ProductInImageProductGTIN'] }, + 'productinimagename' => { 474 => [\'ProductInImage','ProductInImageProductName'] }, + 'productioncode' => { 321 => 0x2 }, + 'productorserviceconstraints' => { 293 => 'ProductOrServiceConstraints' }, + 'productversion' => { 358 => 'VERS' }, + 'profession' => { 478 => 'profession' }, + 'profile' => { 442 => [\'Profiles','ProfilesProfile'] }, + 'profilecalibrationsig' => { 116 => 0xc6f4 }, + 'profilecameraindices' => { 442 => [\'Profiles','ProfilesProfileCameraIndices'] }, + 'profilecopyright' => { 116 => 0xc6fe }, + 'profileembedpolicy' => { 116 => 0xc6fd }, + 'profilehuesatmapdata1' => { 116 => 0xc6fa }, + 'profilehuesatmapdata2' => { 116 => 0xc6fb }, + 'profilehuesatmapdims' => { 116 => 0xc6f9 }, + 'profilehuesatmapencoding' => { 116 => 0xc7a3 }, + 'profilelooktabledata' => { 116 => 0xc726 }, + 'profilelooktabledims' => { 116 => 0xc725 }, + 'profilelooktableencoding' => { 116 => 0xc7a4 }, + 'profilename' => { 116 => 0xc6f8 }, + 'profiles' => { 442 => 'Profiles' }, + 'profiletonecurve' => { 116 => 0xc6fc }, + 'profiletype' => { 442 => [\'Profiles','ProfilesProfileType'] }, + 'programiso' => { 306 => 0x3c }, + 'programline' => { 322 => '1.1' }, + 'programmode' => { 184 => 0x5 }, + 'programshift' => { 219 => 0xd }, + 'programversion' => { 128 => 0x46 }, + 'prohibits' => { 460 => 'prohibits' }, + 'projectiontype' => { 450 => 'ProjectionType', 451 => 'ProjectionType' }, + 'projectname' => { 488 => 'projectName' }, + 'projectref' => { 488 => 'projectRef' }, + 'projectrefpath' => { 488 => [\'projectRef','projectRefPath'] }, + 'projectreftype' => { 488 => [\'projectRef','projectRefType'] }, + 'propertyreleaseid' => { 293 => 'PropertyReleaseID' }, + 'propertyreleasestatus' => { 293 => 'PropertyReleaseStatus' }, + 'province-state' => { 128 => 0x5f }, + 'publicationdate' => { 478 => 'publicationDate' }, + 'publicationdatea-platform' => { 478 => [\'publicationDate','publicationDateA-platform'] }, + 'publicationdatedate' => { 478 => [\'publicationDate','publicationDateDate'] }, + 'publicationdisplaydate' => { 478 => 'publicationDisplayDate' }, + 'publicationdisplaydatea-platform' => { 478 => [\'publicationDisplayDate','publicationDisplayDateA-platform'] }, + 'publicationdisplaydatedate' => { 478 => [\'publicationDisplayDate','publicationDisplayDateDate'] }, + 'publicationevent' => { 474 => 'PublicationEvent' }, + 'publicationeventdate' => { 474 => [\'PublicationEvent','PublicationEventDate'] }, + 'publicationeventidentifier' => { 474 => [\'PublicationEvent','PublicationEventIdentifier'] }, + 'publicationeventname' => { 474 => [\'PublicationEvent','PublicationEventName'] }, + 'publicationname' => { 478 => 'publicationName' }, + 'publisher' => { 358 => "\xa9pub", 360 => 'publisher', 465 => 'publisher' }, + 'publishingfrequency' => { 478 => 'publishingFrequency' }, + 'pulldown' => { 488 => 'pullDown' }, + 'purchasedate' => { 358 => 'purd' }, + 'purplehsl' => { 100 => 0x20916 }, + 'pxshiftperiphedgenr' => { 439 => 0x9013 }, + 'pxshiftperiphedgenrvalue' => { 439 => 0x9014 }, + 'quality' => { 0 => 0x1, 34 => 0x3, 109 => 0x2, 110 => 0x3002, 124 => 0x1000, 136 => 0x9, 219 => 0x4, 249 => 0x3, 288 => 0x201, 301 => 0x300, 341 => 0x8, 348 => 0x2, 383 => 0x16, 393 => 0x56, 394 => 0x56, 395 => 0xb, 406 => [0x102,0x202e] }, + 'quality2' => { 414 => 0x1170, 415 => 0x1174, 416 => 0x1150, 418 => 0x11a8, 419 => 0x1060, 420 => 0x258, 421 => 0x258, 422 => 0x247, 426 => 0x29, 427 => 0x25, 428 => 0x2a }, + 'qualitymode' => { 110 => 0x8 }, + 'quantizationmethod' => { 130 => 0x78 }, + 'quickadjust' => { 262 => 0x2a }, + 'quickcontroldialinmeter' => { 81 => 0x703 }, + 'quickfix' => { 259 => 0x416391c6 }, + 'quickshot' => { 382 => 0x213 }, + 'quiettime' => { 134 => 0x188a }, + 'rads' => { 366 => 'rads' }, + 'rangefinder' => { 271 => '4.1', 272 => '5.1', 273 => '5.1' }, + 'rasterizedcaption' => { 128 => 0x7d }, + 'rating' => { 116 => 0x4746, 124 => 0x1431, 352 => 0xdf, 358 => 'rtng', 406 => 0x2002, 457 => 'rating', 466 => 'rating', 474 => 'Rating', 478 => 'rating', 486 => 'Rating' }, + 'ratingpercent' => { 116 => 0x4749, 174 => 'Rating', 358 => 'rate' }, + 'ratingregion' => { 474 => [\'Rating','RatingRatingRegion'] }, + 'ratingregioncity' => { 474 => [\'Rating','RatingRatingRegionCity'] }, + 'ratingregioncountrycode' => { 474 => [\'Rating','RatingRatingRegionCountryCode'] }, + 'ratingregioncountryname' => { 474 => [\'Rating','RatingRatingRegionCountryName'] }, + 'ratingregiongpsaltitude' => { 474 => [\'Rating','RatingRatingRegionGPSAltitude'] }, + 'ratingregiongpslatitude' => { 474 => [\'Rating','RatingRatingRegionGPSLatitude'] }, + 'ratingregiongpslongitude' => { 474 => [\'Rating','RatingRatingRegionGPSLongitude'] }, + 'ratingregionidentifier' => { 474 => [\'Rating','RatingRatingRegionIdentifier'] }, + 'ratingregionlocationid' => { 474 => [\'Rating','RatingRatingRegionLocationId'] }, + 'ratingregionlocationname' => { 474 => [\'Rating','RatingRatingRegionLocationName'] }, + 'ratingregionprovincestate' => { 474 => [\'Rating','RatingRatingRegionProvinceState'] }, + 'ratingregionsublocation' => { 474 => [\'Rating','RatingRatingRegionSublocation'] }, + 'ratingregionworldregion' => { 474 => [\'Rating','RatingRatingRegionWorldRegion'] }, + 'ratingscalemaxvalue' => { 474 => [\'Rating','RatingRatingScaleMaxValue'] }, + 'ratingscaleminvalue' => { 474 => [\'Rating','RatingRatingScaleMinValue'] }, + 'ratingsourcelink' => { 474 => [\'Rating','RatingRatingSourceLink'] }, + 'ratingvalue' => { 474 => [\'Rating','RatingRatingValue'] }, + 'ratingvaluelogolink' => { 474 => [\'Rating','RatingRatingValueLogoLink'] }, + 'rawandjpgrecording' => { 79 => 0x8, 181 => 0x109, 322 => 0xd }, + 'rawbrightnessadj' => { 100 => 0x20001, 105 => 0x38 }, + 'rawburstimagecount' => { 72 => 0x2 }, + 'rawburstimagenum' => { 72 => 0x1 }, + 'rawcoloradj' => { 105 => 0x2e }, + 'rawcropbottom' => { 352 => 0xd4 }, + 'rawcropleft' => { 352 => 0xd1 }, + 'rawcropright' => { 352 => 0xd3 }, + 'rawcroptop' => { 352 => 0xd2 }, + 'rawcustomsaturation' => { 105 => 0x30 }, + 'rawcustomtone' => { 105 => 0x34 }, + 'rawdata' => { 380 => 0xa048 }, + 'rawdatabyteorder' => { 380 => 0x40 }, + 'rawdatacfapattern' => { 380 => 0x50 }, + 'rawdatauniqueid' => { 116 => 0xc65d }, + 'rawdepth' => { 183 => 0x10 }, + 'rawdevartfilter' => { 290 => 0x121 }, + 'rawdevautogradation' => { 290 => 0x119 }, + 'rawdevcolorspace' => { 289 => 0x108, 290 => 0x109 }, + 'rawdevcontrastvalue' => { 289 => 0x106, 290 => 0x105 }, + 'rawdeveditstatus' => { 289 => 0x10b }, + 'rawdevelopmentprocess' => { 341 => 0x62 }, + 'rawdevengine' => { 289 => 0x109, 290 => 0x10b }, + 'rawdevexposurebiasvalue' => { 289 => 0x100, 290 => 0x100 }, + 'rawdevgradation' => { 290 => 0x112 }, + 'rawdevgraypoint' => { 289 => 0x103, 290 => 0x104 }, + 'rawdevmemorycoloremphasis' => { 289 => 0x105, 290 => 0x108 }, + 'rawdevnoisereduction' => { 289 => 0x10a, 290 => 0x10a }, + 'rawdevpicturemode' => { 290 => 0x10c }, + 'rawdevpm_bwfilter' => { 290 => 0x110 }, + 'rawdevpmcontrast' => { 290 => 0x10e }, + 'rawdevpmnoisefilter' => { 290 => 0x120 }, + 'rawdevpmpicturetone' => { 290 => 0x111 }, + 'rawdevpmsaturation' => { 290 => 0x10d }, + 'rawdevpmsharpness' => { 290 => 0x10f }, + 'rawdevsaturation3' => { 290 => 0x113 }, + 'rawdevsaturationemphasis' => { 289 => 0x104, 290 => 0x107 }, + 'rawdevsettings' => { 289 => 0x10c }, + 'rawdevsharpnessvalue' => { 289 => 0x107, 290 => 0x106 }, + 'rawdevversion' => { 289 => 0x0, 290 => 0x0 }, + 'rawdevwbfineadjustment' => { 289 => 0x102, 290 => 0x103 }, + 'rawdevwhitebalance' => { 290 => 0x101 }, + 'rawdevwhitebalancevalue' => { 289 => 0x101, 290 => 0x102 }, + 'rawfile' => { 116 => 0xfe4c }, + 'rawfilename' => { 462 => 'RawFileName', 464 => 'RawFileName' }, + 'rawfiletype' => { 406 => 0x2029 }, + 'rawformat' => { 311 => 0x2d, 350 => 0x10e }, + 'rawimagecenter' => { 219 => 0x99 }, + 'rawimagedigest' => { 116 => 0xc71c }, + 'rawimagesize' => { 341 => 0x39 }, + 'rawinfoversion' => { 291 => 0x0 }, + 'rawjpgheight' => { 96 => 0x4 }, + 'rawjpgquality' => { 55 => 0x6, 96 => 0x1 }, + 'rawjpgsize' => { 55 => 0x7, 96 => 0x2 }, + 'rawjpgwidth' => { 96 => 0x3 }, + 'rawmeasuredrggb' => { 41 => 0x26a, 43 => 0x280, 45 => 0x194, 46 => [0x1ad,0x26b] }, + 'rawrppused' => { 457 => 'rawrppused' }, + 'rawtopreviewgain' => { 116 => 0xc7a8 }, + 'readouttypeactual' => { 134 => 0x1903 }, + 'readouttyperequested' => { 134 => 0x1902 }, + 'reardisplay' => { 266 => '12.3', 267 => '6.2' }, + 'recdevice' => { 474 => 'RecDevice' }, + 'recdeviceattlensdescription' => { 474 => [\'RecDevice','RecDeviceAttLensDescription'] }, + 'recdevicemanufacturer' => { 474 => [\'RecDevice','RecDeviceManufacturer'] }, + 'recdevicemodelname' => { 474 => [\'RecDevice','RecDeviceModelName'] }, + 'recdeviceownersdeviceid' => { 474 => [\'RecDevice','RecDeviceOwnersDeviceId'] }, + 'recdeviceserialnumber' => { 474 => [\'RecDevice','RecDeviceSerialNumber'] }, + 'recipeendingpage' => { 480 => 'recipeEndingPage' }, + 'recipepagerange' => { 480 => 'recipePageRange' }, + 'recipesource' => { 480 => 'recipeSource' }, + 'recipestartingpage' => { 480 => 'recipeStartingPage' }, + 'recipetitle' => { 480 => 'recipeTitle' }, + 'recognizedface1age' => { 299 => 0x20 }, + 'recognizedface1name' => { 299 => 0x4 }, + 'recognizedface1position' => { 299 => 0x18 }, + 'recognizedface2age' => { 299 => 0x50 }, + 'recognizedface2name' => { 299 => 0x34 }, + 'recognizedface2position' => { 299 => 0x48 }, + 'recognizedface3age' => { 299 => 0x80 }, + 'recognizedface3name' => { 299 => 0x64 }, + 'recognizedface3position' => { 299 => 0x78 }, + 'recognizedfaceflags' => { 306 => 0x63 }, + 'recommendedexposureindex' => { 116 => 0x8832, 469 => 'RecommendedExposureIndex' }, + 'record' => { 115 => 'Record' }, + 'recordbasisofrecord' => { 115 => [\'Record','RecordBasisOfRecord'] }, + 'recordcollectioncode' => { 115 => [\'Record','RecordCollectionCode'] }, + 'recordcollectionid' => { 115 => [\'Record','RecordCollectionID'] }, + 'recorddatageneralizations' => { 115 => [\'Record','RecordDataGeneralizations'] }, + 'recorddatasetid' => { 115 => [\'Record','RecordDatasetID'] }, + 'recorddatasetname' => { 115 => [\'Record','RecordDatasetName'] }, + 'recorddisplay' => { 179 => 0x4d }, + 'recorddynamicproperties' => { 115 => [\'Record','RecordDynamicProperties'] }, + 'recordid' => { 94 => 0x1804 }, + 'recordinformationwithheld' => { 115 => [\'Record','RecordInformationWithheld'] }, + 'recordingcopyright' => { 366 => "\xa9phg" }, + 'recordingformat' => { 373 => 0x1000 }, + 'recordingmode' => { 109 => 0x1, 348 => 0x1 }, + 'recordinstitutioncode' => { 115 => [\'Record','RecordInstitutionCode'] }, + 'recordinstitutionid' => { 115 => [\'Record','RecordInstitutionID'] }, + 'recordlabelname' => { 366 => "\xa9lab" }, + 'recordlabelurl' => { 366 => "\xa9lal" }, + 'recordmode' => { 34 => 0x9, 110 => 0x3000 }, + 'recordownerinstitutioncode' => { 115 => [\'Record','RecordOwnerInstitutionCode'] }, + 'recordshutterrelease' => { 382 => 0x217 }, + 'redbalance' => { 288 => 0x1017, 311 => 0x11, 341 => 0x1c }, + 'redcurvelimits' => { 105 => 0x18a }, + 'redcurvepoints' => { 104 => 0x2d, 105 => 0x160 }, + 'redeyecorrection' => { 263 => 0x0 }, + 'redeyeinfo' => { 462 => 'RedEyeInfo', 464 => 'RedEyeInfo' }, + 'redeyereduction' => { 179 => 0x41, 393 => 0x6a, 395 => 0x28 }, + 'redeyeremoval' => { 306 => 0xb9 }, + 'redhsl' => { 100 => 0x20910 }, + 'redhue' => { 462 => 'RedHue', 464 => 'RedHue' }, + 'redsaturation' => { 462 => 'RedSaturation', 464 => 'RedSaturation' }, + 'reductionmatrix1' => { 116 => 0xc625 }, + 'reductionmatrix2' => { 116 => 0xc626 }, + 'reelname' => { 116 => 0xc789, 366 => 'reel' }, + 'reference1' => { 472 => [\'TagStructure','TagStructureReference'] }, + 'reference2' => { 472 => [\'TagStructure','TagStructureSubLabelsReference'] }, + 'reference3' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsReference'] }, + 'reference4' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsReference'] }, + 'reference5' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference'] }, + 'reference6' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference'] }, + 'referenceblackwhite' => { 116 => 0x214, 484 => 'ReferenceBlackWhite' }, + 'referencedate' => { 128 => 0x2f }, + 'referencenumber' => { 128 => 0x32 }, + 'references' => { 153 => 'References' }, + 'referenceservice' => { 128 => 0x2d }, + 'regionappliedtodimensions' => { 168 => [\'Regions','RegionsAppliedToDimensions'] }, + 'regionappliedtodimensionsh' => { 168 => [\'Regions','RegionsAppliedToDimensionsH'] }, + 'regionappliedtodimensionsunit' => { 168 => [\'Regions','RegionsAppliedToDimensionsUnit'] }, + 'regionappliedtodimensionsw' => { 168 => [\'Regions','RegionsAppliedToDimensionsW'] }, + 'regionarea' => { 168 => [\'Regions','RegionsRegionListArea'] }, + 'regionaread' => { 168 => [\'Regions','RegionsRegionListAreaD'] }, + 'regionareah' => { 168 => [\'Regions','RegionsRegionListAreaH'] }, + 'regionareaunit' => { 168 => [\'Regions','RegionsRegionListAreaUnit'] }, + 'regionareaw' => { 168 => [\'Regions','RegionsRegionListAreaW'] }, + 'regionareax' => { 168 => [\'Regions','RegionsRegionListAreaX'] }, + 'regionareay' => { 168 => [\'Regions','RegionsRegionListAreaY'] }, + 'regionbarcodevalue' => { 168 => [\'Regions','RegionsRegionListBarCodeValue'] }, + 'regionconstraints' => { 293 => 'RegionConstraints' }, + 'regiondescription' => { 168 => [\'Regions','RegionsRegionListDescription'] }, + 'regionextensions' => { 168 => [\'Regions','RegionsRegionListExtensions'] }, + 'regionfocususage' => { 168 => [\'Regions','RegionsRegionListFocusUsage'] }, + 'regioninfo' => { 168 => 'Regions' }, + 'regioninfodateregionsvalid' => { 171 => [\'RegionInfo','RegionInfoDateRegionsValid'] }, + 'regioninfomp' => { 171 => 'RegionInfo' }, + 'regioninforegions' => { 171 => [\'RegionInfo','RegionInfoRegions'] }, + 'regionlist' => { 168 => [\'Regions','RegionsRegionList'] }, + 'regionname' => { 168 => [\'Regions','RegionsRegionListName'] }, + 'regionpersondisplayname' => { 171 => [\'RegionInfo','RegionInfoRegionsPersonDisplayName'] }, + 'regionpersonemaildigest' => { 171 => [\'RegionInfo','RegionInfoRegionsPersonEmailDigest'] }, + 'regionpersonliveidcid' => { 171 => [\'RegionInfo','RegionInfoRegionsPersonLiveIdCID'] }, + 'regionpersonsourceid' => { 171 => [\'RegionInfo','RegionInfoRegionsPersonSourceID'] }, + 'regionrectangle' => { 171 => [\'RegionInfo','RegionInfoRegionsRectangle'] }, + 'regionrotation' => { 168 => [\'Regions','RegionsRegionListRotation'] }, + 'regionseealso' => { 168 => [\'Regions','RegionsRegionListSeeAlso'] }, + 'regiontype' => { 168 => [\'Regions','RegionsRegionListType'] }, + 'registryentryrole' => { 474 => [\'RegistryId','RegistryIdRegEntryRole'] }, + 'registryid' => { 474 => 'RegistryId' }, + 'registryitemid' => { 474 => [\'RegistryId','RegistryIdRegItemId'] }, + 'registryorganisationid' => { 474 => [\'RegistryId','RegistryIdRegOrgId'] }, + 'relatedaudiofile' => { 151 => 'data' }, + 'relatedaudiofilename' => { 151 => '1Name' }, + 'relatedaudiofiletype' => { 151 => '0Type' }, + 'relatedimagefileformat' => { 116 => 0x1000 }, + 'relatedimageheight' => { 116 => 0x1002 }, + 'relatedimagewidth' => { 116 => 0x1001 }, + 'relatedresourceid' => { 115 => [\'ResourceRelationship','ResourceRelationshipRelatedResourceID'] }, + 'relatedsoundfile' => { 116 => 0xa004, 468 => 'RelatedSoundFile' }, + 'relatedvideofile' => { 165 => 'data' }, + 'relatedvideofilename' => { 165 => '1Name' }, + 'relatedvideofiletype' => { 165 => '0Type' }, + 'relation' => { 465 => 'relation' }, + 'relationshipaccordingto' => { 115 => [\'ResourceRelationship','ResourceRelationshipRelationshipAccordingTo'] }, + 'relationshipestablisheddate' => { 115 => [\'ResourceRelationship','ResourceRelationshipRelationshipEstablishedDate'] }, + 'relationshipofresource' => { 115 => [\'ResourceRelationship','ResourceRelationshipRelationshipOfResource'] }, + 'relationshipremarks' => { 115 => [\'ResourceRelationship','ResourceRelationshipRelationshipRemarks'] }, + 'relativealtitude' => { 113 => 'RelativeAltitude' }, + 'relativepeakaudiofilepath' => { 488 => 'relativePeakAudioFilePath' }, + 'relativetimestamp' => { 488 => 'relativeTimestamp' }, + 'relativetimestampscale' => { 488 => [\'relativeTimestamp','relativeTimestampScale'] }, + 'relativetimestampvalue' => { 488 => [\'relativeTimestamp','relativeTimestampValue'] }, + 'releasebuttontousedial' => { 266 => '17.8', 267 => '18.5', 269 => '18.4', 270 => '18.4', 275 => '33.8', 276 => '17.6', 279 => '18.5', 280 => '18.4' }, + 'releasedate' => { 128 => 0x1e, 358 => 'rldt', 457 => 'ReleaseDate', 488 => 'releaseDate' }, + 'releasemode' => { 110 => 0x3001, 237 => 0x184d, 406 => 0xb049 }, + 'releasemode2' => { 414 => 0x112c, 415 => [0x112c,0x8], 416 => [0x1108,0x8], 417 => [0x1184,0x8], 418 => [0x1160,0x8], 419 => [0x4,0x1018], 420 => [0x4,0x210], 421 => [0x4,0x210], 422 => [0x4,0x208], 424 => [0x67,0x3f], 425 => [0x6b,0x6d,0x73,0x4b], 426 => 0x10, 427 => 0x10, 428 => 0x9, 435 => 0x34 }, + 'releasemode3' => { 414 => 0x1128, 415 => 0x1128, 416 => 0x1104, 417 => 0x1180, 418 => 0x115c, 419 => 0x1014, 420 => 0x20c, 421 => 0x20c, 422 => 0x204 }, + 'releaseready' => { 474 => 'ReleaseReady' }, + 'releasesetting' => { 94 => 0x1016 }, + 'releasetime' => { 128 => 0x23, 457 => 'ReleaseTime' }, + 'remoteonduration' => { 268 => '3.4', 271 => '17.2', 272 => '18.2', 273 => '18.2', 274 => '18.2', 276 => '18.2', 277 => '4.3', 281 => '19.2' }, + 'renditionclass' => { 489 => 'RenditionClass' }, + 'renditionof' => { 489 => 'RenditionOf' }, + 'renditionofalternatepaths' => { 489 => [\'RenditionOf','RenditionOfAlternatePaths'] }, + 'renditionofdocumentid' => { 489 => [\'RenditionOf','RenditionOfDocumentID'] }, + 'renditionoffilepath' => { 489 => [\'RenditionOf','RenditionOfFilePath'] }, + 'renditionoffrompart' => { 489 => [\'RenditionOf','RenditionOfFromPart'] }, + 'renditionofinstanceid' => { 489 => [\'RenditionOf','RenditionOfInstanceID'] }, + 'renditionoflastmodifydate' => { 489 => [\'RenditionOf','RenditionOfLastModifyDate'] }, + 'renditionoflasturl' => { 489 => [\'RenditionOf','RenditionOfLastURL'] }, + 'renditionoflinkcategory' => { 489 => [\'RenditionOf','RenditionOfLinkCategory'] }, + 'renditionoflinkform' => { 489 => [\'RenditionOf','RenditionOfLinkForm'] }, + 'renditionofmanager' => { 489 => [\'RenditionOf','RenditionOfManager'] }, + 'renditionofmanagervariant' => { 489 => [\'RenditionOf','RenditionOfManagerVariant'] }, + 'renditionofmanageto' => { 489 => [\'RenditionOf','RenditionOfManageTo'] }, + 'renditionofmanageui' => { 489 => [\'RenditionOf','RenditionOfManageUI'] }, + 'renditionofmaskmarkers' => { 489 => [\'RenditionOf','RenditionOfMaskMarkers'] }, + 'renditionoforiginaldocumentid' => { 489 => [\'RenditionOf','RenditionOfOriginalDocumentID'] }, + 'renditionofpartmapping' => { 489 => [\'RenditionOf','RenditionOfPartMapping'] }, + 'renditionofplacedresolutionunit' => { 489 => [\'RenditionOf','RenditionOfPlacedResolutionUnit'] }, + 'renditionofplacedxresolution' => { 489 => [\'RenditionOf','RenditionOfPlacedXResolution'] }, + 'renditionofplacedyresolution' => { 489 => [\'RenditionOf','RenditionOfPlacedYResolution'] }, + 'renditionofrenditionclass' => { 489 => [\'RenditionOf','RenditionOfRenditionClass'] }, + 'renditionofrenditionparams' => { 489 => [\'RenditionOf','RenditionOfRenditionParams'] }, + 'renditionoftopart' => { 489 => [\'RenditionOf','RenditionOfToPart'] }, + 'renditionofversionid' => { 489 => [\'RenditionOf','RenditionOfVersionID'] }, + 'renditionparams' => { 489 => 'RenditionParams' }, + 'repeatingflashcount' => { 203 => 0xd, 204 => 0xe, 205 => 0xe, 206 => 0xe, 207 => 0xe, 275 => '17.2', 276 => '24.2', 277 => '9.2', 278 => '24.2', 281 => '25.2' }, + 'repeatingflashcountbuilt-in' => { 245 => 0x4db }, + 'repeatingflashcountexternal' => { 245 => 0x4c3 }, + 'repeatingflashoutput' => { 275 => '17.1', 276 => '24.1', 277 => '9.1', 278 => '24.1', 281 => '25.1' }, + 'repeatingflashoutputexternal' => { 245 => 0x4c0 }, + 'repeatingflashrate' => { 203 => 0xc, 204 => 0xd, 205 => 0xd, 206 => 0xd, 207 => 0xd, 275 => '18.1', 276 => '25.1', 277 => '10.1', 278 => '25.1', 281 => '26.1' }, + 'repeatingflashratebuilt-in' => { 245 => 0x4da }, + 'repeatingflashrateexternal' => { 245 => 0x4c2 }, + 'requirements' => { 366 => "\xa9req" }, + 'requires' => { 460 => 'requires' }, + 'resampleparams' => { 488 => 'resampleParams' }, + 'resampleparamsquality' => { 488 => [\'resampleParams','resampleParamsQuality'] }, + 'resamplingkerneldenominators050' => { 134 => 0xe50 }, + 'resamplingkerneldenominators067' => { 134 => 0xe4f }, + 'resamplingkerneldenominators100' => { 134 => 0xe51 }, + 'resaved' => { 382 => 0x21e }, + 'resetblacksegrows' => { 134 => 0x181a }, + 'resolution' => { 158 => 'Resolution' }, + 'resolutionmode' => { 383 => [0x87,0x4] }, + 'resolutionunit' => { 116 => 0x128, 131 => 0x2, 484 => 'ResolutionUnit' }, + 'resourceid' => { 115 => [\'ResourceRelationship','ResourceRelationshipResourceID'] }, + 'resourcerelationship' => { 115 => 'ResourceRelationship' }, + 'resourcerelationshipid' => { 115 => [\'ResourceRelationship','ResourceRelationshipResourceRelationshipID'] }, + 'restrictdrivemodes' => { 81 => 0x612 }, + 'restrictions' => { 481 => 'restrictions' }, + 'retouchareafeather' => { 462 => [\'RetouchAreas','RetouchAreasFeather'], 464 => [\'RetouchAreas','RetouchAreasFeather'] }, + 'retouchareamaskalpha' => { 462 => [\'RetouchAreas','RetouchAreasMasksAlpha'], 464 => [\'RetouchAreas','RetouchAreasMasksAlpha'] }, + 'retouchareamaskangle' => { 462 => [\'RetouchAreas','RetouchAreasMasksAngle'], 464 => [\'RetouchAreas','RetouchAreasMasksAngle'] }, + 'retouchareamaskbottom' => { 462 => [\'RetouchAreas','RetouchAreasMasksBottom'], 464 => [\'RetouchAreas','RetouchAreasMasksBottom'] }, + 'retouchareamaskcentervalue' => { 462 => [\'RetouchAreas','RetouchAreasMasksCenterValue'], 464 => [\'RetouchAreas','RetouchAreasMasksCenterValue'] }, + 'retouchareamaskcenterweight' => { 462 => [\'RetouchAreas','RetouchAreasMasksCenterWeight'], 464 => [\'RetouchAreas','RetouchAreasMasksCenterWeight'] }, + 'retouchareamaskdabs' => { 462 => [\'RetouchAreas','RetouchAreasMasksDabs'], 464 => [\'RetouchAreas','RetouchAreasMasksDabs'] }, + 'retouchareamaskfeather' => { 462 => [\'RetouchAreas','RetouchAreasMasksFeather'], 464 => [\'RetouchAreas','RetouchAreasMasksFeather'] }, + 'retouchareamaskflipped' => { 462 => [\'RetouchAreas','RetouchAreasMasksFlipped'], 464 => [\'RetouchAreas','RetouchAreasMasksFlipped'] }, + 'retouchareamaskflow' => { 462 => [\'RetouchAreas','RetouchAreasMasksFlow'], 464 => [\'RetouchAreas','RetouchAreasMasksFlow'] }, + 'retouchareamaskfullx' => { 462 => [\'RetouchAreas','RetouchAreasMasksFullX'], 464 => [\'RetouchAreas','RetouchAreasMasksFullX'] }, + 'retouchareamaskfully' => { 462 => [\'RetouchAreas','RetouchAreasMasksFullY'], 464 => [\'RetouchAreas','RetouchAreasMasksFullY'] }, + 'retouchareamaskleft' => { 462 => [\'RetouchAreas','RetouchAreasMasksLeft'], 464 => [\'RetouchAreas','RetouchAreasMasksLeft'] }, + 'retouchareamaskmidpoint' => { 462 => [\'RetouchAreas','RetouchAreasMasksMidpoint'], 464 => [\'RetouchAreas','RetouchAreasMasksMidpoint'] }, + 'retouchareamaskperimetervalue' => { 462 => [\'RetouchAreas','RetouchAreasMasksPerimeterValue'], 464 => [\'RetouchAreas','RetouchAreasMasksPerimeterValue'] }, + 'retouchareamaskradius' => { 462 => [\'RetouchAreas','RetouchAreasMasksRadius'], 464 => [\'RetouchAreas','RetouchAreasMasksRadius'] }, + 'retouchareamaskright' => { 462 => [\'RetouchAreas','RetouchAreasMasksRight'], 464 => [\'RetouchAreas','RetouchAreasMasksRight'] }, + 'retouchareamaskroundness' => { 462 => [\'RetouchAreas','RetouchAreasMasksRoundness'], 464 => [\'RetouchAreas','RetouchAreasMasksRoundness'] }, + 'retouchareamasks' => { 462 => [\'RetouchAreas','RetouchAreasMasks'], 464 => [\'RetouchAreas','RetouchAreasMasks'] }, + 'retouchareamasksizex' => { 462 => [\'RetouchAreas','RetouchAreasMasksSizeX'], 464 => [\'RetouchAreas','RetouchAreasMasksSizeX'] }, + 'retouchareamasksizey' => { 462 => [\'RetouchAreas','RetouchAreasMasksSizeY'], 464 => [\'RetouchAreas','RetouchAreasMasksSizeY'] }, + 'retouchareamasktop' => { 462 => [\'RetouchAreas','RetouchAreasMasksTop'], 464 => [\'RetouchAreas','RetouchAreasMasksTop'] }, + 'retouchareamaskvalue' => { 462 => [\'RetouchAreas','RetouchAreasMasksMaskValue'], 464 => [\'RetouchAreas','RetouchAreasMasksMaskValue'] }, + 'retouchareamaskversion' => { 462 => [\'RetouchAreas','RetouchAreasMasksVersion'], 464 => [\'RetouchAreas','RetouchAreasMasksVersion'] }, + 'retouchareamaskwhat' => { 462 => [\'RetouchAreas','RetouchAreasMasksWhat'], 464 => [\'RetouchAreas','RetouchAreasMasksWhat'] }, + 'retouchareamaskx' => { 462 => [\'RetouchAreas','RetouchAreasMasksX'], 464 => [\'RetouchAreas','RetouchAreasMasksX'] }, + 'retouchareamasky' => { 462 => [\'RetouchAreas','RetouchAreasMasksY'], 464 => [\'RetouchAreas','RetouchAreasMasksY'] }, + 'retouchareamaskzerox' => { 462 => [\'RetouchAreas','RetouchAreasMasksZeroX'], 464 => [\'RetouchAreas','RetouchAreasMasksZeroX'] }, + 'retouchareamaskzeroy' => { 462 => [\'RetouchAreas','RetouchAreasMasksZeroY'], 464 => [\'RetouchAreas','RetouchAreasMasksZeroY'] }, + 'retouchareamethod' => { 462 => [\'RetouchAreas','RetouchAreasMethod'], 464 => [\'RetouchAreas','RetouchAreasMethod'] }, + 'retouchareaoffsety' => { 462 => [\'RetouchAreas','RetouchAreasOffsetY'], 464 => [\'RetouchAreas','RetouchAreasOffsetY'] }, + 'retouchareaopacity' => { 462 => [\'RetouchAreas','RetouchAreasOpacity'], 464 => [\'RetouchAreas','RetouchAreasOpacity'] }, + 'retouchareas' => { 462 => 'RetouchAreas', 464 => 'RetouchAreas' }, + 'retouchareaseed' => { 462 => [\'RetouchAreas','RetouchAreasSeed'], 464 => [\'RetouchAreas','RetouchAreasSeed'] }, + 'retouchareasourcestate' => { 462 => [\'RetouchAreas','RetouchAreasSourceState'], 464 => [\'RetouchAreas','RetouchAreasSourceState'] }, + 'retouchareasourcex' => { 462 => [\'RetouchAreas','RetouchAreasSourceX'], 464 => [\'RetouchAreas','RetouchAreasSourceX'] }, + 'retouchareaspottype' => { 462 => [\'RetouchAreas','RetouchAreasSpotType'], 464 => [\'RetouchAreas','RetouchAreasSpotType'] }, + 'retouchhistory' => { 219 => 0x9e }, + 'retouchinfo' => { 462 => 'RetouchInfo', 464 => 'RetouchInfo' }, + 'retouchnefprocessing' => { 226 => 0x5 }, + 'retractlensonpoweroff' => { 81 => 0x814 }, + 'reuse' => { 293 => 'Reuse' }, + 'reuseallowed' => { 491 => 'ReuseAllowed' }, + 'reuseprohibited' => { 481 => 'reuseProhibited' }, + 'reverseexposurecompdial' => { 273 => '5.2' }, + 'reverseindicators' => { 266 => '12.1', 267 => '6.1', 269 => '6.1', 270 => '6.1', 271 => '4.3', 272 => '5.2', 273 => '5.4', 275 => '33.5', 276 => '5.1', 279 => '6.1', 280 => '6.1', 281 => '6.2' }, + 'reverseshutterspeedaperture' => { 273 => '5.3' }, + 'revision' => { 466 => 'revision' }, + 'rflensmffocusringsensitivity' => { 81 => 0x714 }, + 'rgbcurvelimits' => { 105 => 0x238 }, + 'rgbcurvepoints' => { 104 => 0x7, 105 => 0x20e }, + 'richtextcomment' => { 471 => 'RichTextComment' }, + 'ricohdate' => { 372 => 0x6 }, + 'ricohimageheight' => { 372 => 0x2 }, + 'ricohimagewidth' => { 372 => 0x0 }, + 'rightalbedo' => { 453 => 'RightAlbedo' }, + 'rightascension' => { 161 => 'RightAscension' }, + 'rights' => { 465 => 'rights' }, + 'rightsagent' => { 481 => 'rightsAgent' }, + 'rightsowner' => { 481 => 'rightsOwner' }, + 'roll' => { 112 => 0x8, 366 => ['roll',"\xa9frl"] }, + 'rollangle' => { 237 => 0x350b, 238 => 0x2c24, 246 => 0x36f4, 283 => 0x903, 306 => 0x90, 340 => 0x1, 378 => 0x2 }, + 'romoperationmode' => { 94 => 0x80d }, + 'rotation' => { 30 => 0x17, 31 => 0x18, 93 => 0x3, 100 => 0x10002, 105 => 0x26e, 111 => 'QuickTime::Rotation', 120 => 0x4, 161 => 'Rotation', 177 => [0x65,0x50], 178 => 0x46, 179 => 0x5a, 182 => 0x10, 237 => 0x3693, 238 => 0xca, 244 => '590.1', 259 => 0x76a43207, 306 => 0x30, 322 => '17.2', 352 => 0xd8, 359 => 'irot', 393 => 0x3f, 394 => 0x3f, 404 => 0x10 }, + 'routedto' => { 470 => 'RoutedTo' }, + 'routing' => { 357 => 'Routing' }, + 'routingdestinations' => { 452 => 'RoutingDestinations' }, + 'routingexclusions' => { 452 => 'RoutingExclusions' }, + 'routingnotes' => { 470 => 'RoutingNotes' }, + 'rowsperstrip' => { 116 => 0x116 }, + 'rpp' => { 457 => 'rpp' }, + 'rtkflag' => { 113 => 'RtkFlag' }, + 'rtkstdhgt' => { 113 => 'RtkStdHgt' }, + 'rtkstdlat' => { 113 => 'RtkStdLat' }, + 'rtkstdlon' => { 113 => 'RtkStdLon' }, + 'safetyshift' => { 81 => 0x108 }, + 'safetyshiftinavortv' => { 79 => 0x10, 80 => 0x10, 82 => 0xf, 83 => 0x10, 86 => 0x10 }, + 'sameexposurefornewaperture' => { 81 => 0x112 }, + 'samplebits' => { 151 => 'SampleBits' }, + 'samplepagerange' => { 478 => 'samplePageRange' }, + 'samplerate' => { 151 => 'SampleRate' }, + 'samplesperpixel' => { 116 => 0x115, 311 => 0x8, 484 => 'SamplesPerPixel' }, + 'samplestructure' => { 130 => 0x5a }, + 'samsungmodelid' => { 380 => 0x3 }, + 'sanyoquality' => { 382 => 0x201 }, + 'sanyothumbnail' => { 382 => 0x100 }, + 'saturation' => { 10 => 0x6e, 12 => 0x76, 34 => 0xe, 49 => 0x1, 109 => 0xd, 110 => [0x3013,0x1f], 116 => [0xa409,0xfe55], 124 => 0x1003, 152 => 'Saturation', 176 => 0x1f, 177 => 0x32, 178 => 0x28, 179 => 0x1a, 184 => 0x1, 219 => 0xaa, 221 => 0x35, 222 => 0x3b, 223 => 0x43, 306 => 0x40, 308 => 0x300d, 341 => 0x1f, 348 => 0xd, 367 => 0x27, 369 => 0x58, 372 => 0x28, 373 => 0x1013, 383 => 0x10, 393 => 0x1e, 394 => 0x1b, 406 => 0x2005, 462 => 'Saturation', 464 => 'Saturation', 468 => 'Saturation' }, + 'saturationadj' => { 100 => 0x20901, 105 => 0x116, 219 => 0x94, 258 => 0x1, 262 => 0x2e, 439 => 0x8016 }, + 'saturationadjustmentaqua' => { 462 => 'SaturationAdjustmentAqua', 464 => 'SaturationAdjustmentAqua' }, + 'saturationadjustmentblue' => { 462 => 'SaturationAdjustmentBlue', 464 => 'SaturationAdjustmentBlue' }, + 'saturationadjustmentgreen' => { 462 => 'SaturationAdjustmentGreen', 464 => 'SaturationAdjustmentGreen' }, + 'saturationadjustmentmagenta' => { 462 => 'SaturationAdjustmentMagenta', 464 => 'SaturationAdjustmentMagenta' }, + 'saturationadjustmentorange' => { 462 => 'SaturationAdjustmentOrange', 464 => 'SaturationAdjustmentOrange' }, + 'saturationadjustmentpurple' => { 462 => 'SaturationAdjustmentPurple', 464 => 'SaturationAdjustmentPurple' }, + 'saturationadjustmentred' => { 462 => 'SaturationAdjustmentRed', 464 => 'SaturationAdjustmentRed' }, + 'saturationadjustmentyellow' => { 462 => 'SaturationAdjustmentYellow', 464 => 'SaturationAdjustmentYellow' }, + 'saturationauto' => { 68 => 0x98 }, + 'saturationfaithful' => { 19 => 0xfe, 67 => 0x68, 68 => 0x68 }, + 'saturationlandscape' => { 19 => 0xfc, 67 => 0x38, 68 => 0x38 }, + 'saturationmonochrome' => { 67 => 0x80, 68 => 0x80 }, + 'saturationneutral' => { 19 => 0xfd, 67 => 0x50, 68 => 0x50 }, + 'saturationportrait' => { 19 => 0xfb, 67 => 0x20, 68 => 0x20 }, + 'saturationsetting' => { 291 => 0x1010, 395 => 0x11, 411 => 0x9 }, + 'saturationstandard' => { 19 => 0xfa, 67 => 0x8, 68 => 0x8 }, + 'saturationuserdef1' => { 19 => 0x100, 67 => 0x98, 68 => 0xb0 }, + 'saturationuserdef2' => { 19 => 0x101, 67 => 0xb0, 68 => 0xc8 }, + 'saturationuserdef3' => { 19 => 0x102, 67 => 0xc8, 68 => 0xe0 }, + 'saveid' => { 489 => 'SaveID' }, + 'sbaanalysiscomplete' => { 134 => 0xc35 }, + 'sbablack' => { 134 => 0xc25 }, + 'sbagmoffset' => { 134 => 0xc4a }, + 'sbagray' => { 134 => 0xc26 }, + 'sbagreenmagentabal' => { 134 => 0xc33 }, + 'sbahighgray' => { 134 => 0xc46 }, + 'sbailloffset' => { 134 => 0xc49 }, + 'sbailluminantbal' => { 134 => 0xc34 }, + 'sbalowgray' => { 134 => 0xc47 }, + 'sbaneutralbal' => { 134 => 0xc32 }, + 'sbawhite' => { 134 => 0xc27 }, + 'scaletype' => { 488 => 'scaleType' }, + 'scanimageenhancer' => { 227 => 0x60 }, + 'scanningdirection' => { 130 => 0x64 }, + 'scene' => { 366 => 'scen', 473 => 'Scene', 488 => 'scene' }, + 'scenearea' => { 286 => 0x211, 288 => 0x1031 }, + 'sceneassist' => { 219 => 0x9c }, + 'scenecapturetype' => { 116 => 0xa406, 468 => 'SceneCaptureType' }, + 'scenedetect' => { 286 => 0x210, 288 => 0x1030 }, + 'scenedetectdata' => { 286 => 0x212, 288 => 0x1033 }, + 'scenemode' => { 138 => 0xfa02, 181 => 0x100, 219 => 0x8f, 283 => 0x509, 288 => 0x403, 306 => 0x8001, 315 => 0xf, 406 => 0xb023 }, + 'scenemodeused' => { 140 => [0x6002,0xf002] }, + 'scenerecognition' => { 124 => 0x1425 }, + 'sceneselect' => { 382 => 0x21f }, + 'scenetype' => { 116 => 0xa301, 468 => 'SceneType' }, + 'screentips' => { 266 => '12.7', 267 => '5.3', 275 => '13.1', 276 => '4.4', 279 => '5.4', 281 => '5.1' }, + 'scriptversion' => { 134 => 0x1770 }, + 'season' => { 474 => 'Season', 477 => 'season' }, + 'seasonidentifier' => { 474 => [\'Season','SeasonIdentifier'] }, + 'seasonname' => { 474 => [\'Season','SeasonName'] }, + 'seasonnumber' => { 474 => [\'Season','SeasonNumber'] }, + 'secondaryftp' => { 452 => 'SecondaryFTP' }, + 'secondaryslotfunction' => { 237 => 0x1d0, 246 => 0x1d0 }, + 'section' => { 478 => 'section' }, + 'securityclassification' => { 116 => 0x9212 }, + 'selectableafpoint' => { 81 => 0x509 }, 'selectafareaselectionmode' => { 2 => 0xc }, - 'selectafareaselectmode' => { 78 => 0x512 }, - 'selftimer' => { 33 => 0x2, 297 => 0x2e, 367 => 0x214, 396 => 0x1134, 397 => 0x1134, 398 => 0x1110, 399 => 0x118c, 400 => 0x1168, 401 => 0x1020, 402 => 0x218, 403 => 0x218, 404 => 0x210 }, - 'selftimer2' => { 72 => 0x1d }, - 'selftimerinterval' => { 267 => '19.2' }, - 'selftimermode' => { 113 => 0x882b }, - 'selftimershotcount' => { 258 => '20.2', 260 => '20.3', 261 => '20.3', 262 => '18.2', 263 => '19.2', 264 => '19.2', 265 => '19.3', 267 => '19.3', 270 => '20.3', 271 => '20.3', 272 => '20.2' }, - 'selftimershotinterval' => { 258 => '20.3', 260 => '20.2', 261 => '20.2', 265 => '19.2', 270 => '20.2', 271 => '20.2' }, - 'selftimertime' => { 91 => 0x1806, 174 => 0x1f, 257 => '18.1', 258 => '20.1', 259 => '3.3', 260 => '20.1', 261 => '20.1', 262 => '18.1', 263 => '19.1', 264 => '19.1', 265 => '19.1', 266 => '7.2', 267 => '19.1', 268 => '3.3', 270 => '20.1', 271 => '20.1', 272 => '20.1' }, - 'sellingagency' => { 456 => 'sellingAgency' }, - 'seminfo' => { 113 => 0x8546 }, - 'sensingmethod' => { 113 => 0xa217, 446 => 'SensingMethod' }, - 'sensitivityadjust' => { 332 => 0x40 }, - 'sensitivitysteps' => { 313 => ['14.3','17.4'], 315 => 0x1 }, - 'sensitivitytype' => { 113 => 0x8830, 447 => 'SensitivityType' }, - 'sensor' => { 181 => 0x665e }, - 'sensorareas' => { 365 => 0xa010 }, - 'sensorbitdepth' => { 299 => 0x312d }, - 'sensorbluelevel' => { 70 => 0x5 }, - 'sensorcalibration' => { 278 => 0x805 }, - 'sensorcleaning' => { 84 => 0xd }, - 'sensorfullheight' => { 130 => 0xf904 }, - 'sensorfullwidth' => { 130 => 0xf903 }, - 'sensorheight' => { 130 => 0xf901, 135 => 0xfa21, 178 => 0x8, 299 => 0x312c, 341 => 0x109, 358 => 0x1602 }, - 'sensorimageheight' => { 131 => 0x3ee }, - 'sensorimagewidth' => { 131 => 0x3ed }, - 'sensorleftborder' => { 131 => 0x3eb }, - 'sensorleftmargin' => { 341 => 0x10a }, - 'sensorpixelsize' => { 211 => 0x9a }, - 'sensorredlevel' => { 70 => 0x4 }, - 'sensorserialnumber' => { 131 => 0x9ce }, - 'sensorsize' => { 147 => 'SensorSize', 332 => 0x35 }, - 'sensortemperature' => { 277 => 0x1500, 279 => 0x1007, 337 => 0xc, 341 => 0x210, 368 => [0x39,0x55] }, - 'sensortemperature2' => { 337 => 0xe, 341 => 0x211 }, - 'sensortopborder' => { 131 => 0x3ec }, - 'sensortopmargin' => { 341 => 0x10b }, - 'sensorwidth' => { 130 => 0xf900, 135 => 0xfa20, 178 => 0xa, 299 => 0x312b, 341 => 0x108, 358 => 0x1601 }, - 'sequence' => { 353 => 0x7, 354 => 0x35 }, - 'sequencefilenumber' => { 397 => 0x4, 398 => 0x4, 399 => 0x4, 400 => 0x4, 408 => 0xc, 409 => 0xc, 410 => 0x1a }, - 'sequenceimagenumber' => { 397 => 0x0, 398 => 0x0, 399 => 0x0, 400 => 0x0, 408 => 0x8, 409 => 0x8, 410 => 0x12, 417 => 0x24 }, - 'sequencelength' => { 408 => 0x22, 409 => 0x1e, 410 => [0x16,0x1e] }, - 'sequencename' => { 455 => 'sequenceName' }, - 'sequencenumber' => { 72 => 0x9, 107 => 0x301c, 121 => 0x1101, 133 => 0x1d, 236 => 0x51c, 297 => 0x2b, 378 => [0x10c,0x30c], 388 => 0xb04a, 455 => 'sequenceNumber' }, - 'sequenceshotinterval' => { 367 => 0x224 }, - 'sequencetotalnumber' => { 455 => 'sequenceTotalNumber' }, - 'sequentialshot' => { 367 => 0x20e }, - 'serialnumber' => { 60 => 0xc, 91 => 0x180b, 113 => [0xa431,0xfde9], 130 => 0xfa04, 132 => 0xfa00, 134 => 0xc354, 135 => 0xfa19, 144 => 0x0, 147 => 'SerialNumber', 211 => [0xa0,0x1d], 275 => 0x101, 279 => [0x404,0x101a], 292 => 0x303, 294 => 0x305, 299 => 0x3103, 332 => 0x229, 341 => 0x102, 342 => 0x407, 353 => 0x15, 354 => 0x4b, 358 => 0x5, 365 => 0xa002, 368 => 0x2, 388 => 0x2031, 438 => 'SerialNumber', 447 => 'BodySerialNumber' }, - 'serialnumberformat' => { 60 => 0x15, 91 => 0x183b }, - 'series' => { 452 => 'Series' }, - 'seriesdatetime' => { 423 => 'SeriesDateTime' }, - 'seriesdescription' => { 423 => 'SeriesDescription' }, - 'seriesidentifier' => { 452 => [\'Series','SeriesIdentifier'] }, - 'seriesmodality' => { 423 => 'SeriesModality' }, - 'seriesname' => { 452 => [\'Series','SeriesName'] }, - 'seriesnumber' => { 423 => 'SeriesNumber', 456 => 'seriesNumber' }, - 'seriestitle' => { 456 => 'seriesTitle' }, - 'serviceidentifier' => { 126 => 0x1e }, - 'servingsize' => { 458 => 'servingSize' }, - 'setbuttoncrosskeysfunc' => { 81 => 0x0, 82 => 0x0 }, - 'setbuttonwhenshooting' => { 76 => 0x1, 78 => 0x704, 84 => 0xc }, - 'setfunctionwhenshooting' => { 79 => 0x0, 80 => 0x1, 83 => 0x1 }, - 'setting' => { 455 => 'setting' }, - 'shadingcompensation' => { 274 => 0x50c, 297 => 0x8a }, - 'shadingcompensation2' => { 278 => 0x1012 }, - 'shadow' => { 368 => 0xe }, - 'shadowadj' => { 97 => 0x2030b }, - 'shadowcorrection' => { 332 => 0x79 }, - 'shadowprotection' => { 249 => 0x0 }, - 'shadows' => { 113 => 0xfe52, 435 => 'Shadows', 442 => 'Shadows' }, - 'shadows2012' => { 442 => 'Shadows2012' }, - 'shadowsadj' => { 421 => 0x901a }, - 'shadowscale' => { 113 => 0xc633 }, - 'shadowtint' => { 442 => 'ShadowTint' }, - 'shadowtone' => { 121 => 0x1040 }, - 'shakereduction' => { 334 => 0x1, 335 => 0x1 }, - 'sharpendetail' => { 442 => 'SharpenDetail' }, - 'sharpenedgemasking' => { 442 => 'SharpenEdgeMasking' }, - 'sharpening' => { 299 => 0x300b }, - 'sharpeningadj' => { 253 => 0x2b }, - 'sharpeningkernel' => { 131 => 0x92f }, - 'sharpenradius' => { 442 => 'SharpenRadius' }, - 'sharpness' => { 7 => [0x42,0x48], 9 => 0x72, 11 => 0x74, 33 => 0xf, 70 => 0x2, 106 => 0xb, 107 => [0x3011,0x21], 113 => [0xa40a,0xfe56], 121 => 0x1001, 133 => 0x6b, 142 => 0x37, 147 => 'Sharpness', 171 => 0x21, 172 => 0x30, 173 => 0x26, 174 => 0x18, 179 => 0x3, 211 => 0x6, 213 => 0x32, 214 => 0x33, 279 => 0x100f, 297 => 0x41, 332 => 0x21, 339 => 0xb, 353 => 0x26, 357 => 0x22, 358 => [0x1003,0x1014], 368 => 0x11, 376 => 0x1c, 377 => 0x19, 388 => 0x2006, 417 => 0x52, 442 => 'Sharpness', 446 => 'Sharpness' }, - 'sharpnessadj' => { 97 => 0x20310, 102 => 0x25a, 421 => 0x801a }, - 'sharpnessadjon' => { 97 => '0x20310.0' }, - 'sharpnessauto' => { 67 => 0x94 }, - 'sharpnessfactor' => { 279 => 0x102a }, - 'sharpnessfaithful' => { 18 => 0xf5, 66 => 0x64, 67 => 0x64 }, - 'sharpnessfrequency' => { 7 => [0x41,0x47], 70 => 0x3 }, - 'sharpnesslandscape' => { 18 => 0xf3, 66 => 0x34, 67 => 0x34 }, - 'sharpnessmonochrome' => { 18 => 0xf6, 66 => 0x7c, 67 => 0x7c }, - 'sharpnessneutral' => { 18 => 0xf4, 66 => 0x4c, 67 => 0x4c }, - 'sharpnessovershoot' => { 421 => 0x801b }, - 'sharpnessportrait' => { 18 => 0xf2, 66 => 0x1c, 67 => 0x1c }, - 'sharpnesssetting' => { 274 => 0x506, 282 => 0x1013, 378 => 0x12, 393 => 0xa }, - 'sharpnessstandard' => { 18 => 0xf1, 66 => 0x4, 67 => 0x4 }, - 'sharpnessstrength' => { 97 => 0x20311 }, - 'sharpnessthreshold' => { 421 => 0x801d }, - 'sharpnessundershoot' => { 421 => 0x801c }, - 'sharpnessuserdef1' => { 18 => 0xf7, 66 => 0x94, 67 => 0xac }, - 'sharpnessuserdef2' => { 18 => 0xf8, 66 => 0xac, 67 => 0xc4 }, - 'sharpnessuserdef3' => { 18 => 0xf9, 66 => 0xc4, 67 => 0xdc }, - 'shiftcols' => { 131 => 0xc70 }, - 'shootid' => { 455 => 'shootID' }, - 'shootingdistance' => { 97 => 0x20701 }, - 'shootinginfodisplay' => { 257 => '13.2', 258 => '5.1', 266 => '10.2', 267 => '4.1', 270 => '5.1', 272 => '5.3' }, - 'shootinginfomonitorofftime' => { 257 => '26.2', 258 => '22.2', 260 => '22.2', 261 => '22.2', 265 => '21.2', 266 => '9.1', 267 => '21.2', 270 => '22.2', 271 => '22.2', 272 => '22.2' }, - 'shootingmode' => { 147 => 'ShootingMode', 211 => 0x89, 297 => 0x1f }, - 'shootingmodesetting' => { 259 => '5.1' }, - 'shortdescription' => { 444 => 'shortdescription' }, - 'shortdocumentid' => { 125 => 0xba }, - 'shortownername' => { 18 => 0xac }, - 'shortreleasetimelag' => { 78 => 0x80d }, - 'shotdate' => { 466 => 'shotDate' }, - 'shotday' => { 466 => 'shotDay' }, - 'shotlocation' => { 466 => 'shotLocation' }, - 'shotname' => { 466 => 'shotName' }, - 'shotnumber' => { 466 => 'shotNumber' }, - 'shotnumbersincepowerup' => { 392 => 0x44e, 408 => 0x1a, 409 => 0x16, 410 => 0xa }, - 'shotnumbersincepowerup2' => { 378 => 0x200 }, - 'shotsize' => { 466 => 'shotSize' }, - 'shownevent' => { 452 => 'EventExt' }, - 'showneventidentifier' => { 452 => [\'EventExt','EventExtIdentifier'] }, - 'showneventname' => { 452 => [\'EventExt','EventExtName'] }, - 'shutter-aelock' => { 76 => 0x4, 78 => 0x701, 79 => 0x3, 80 => 0x4, 81 => 0x3, 82 => 0x3, 83 => 0x4, 84 => 0x2 }, - 'shutteraelbutton' => { 77 => 0x4 }, - 'shutterbuttonafonbutton' => { 78 => 0x701 }, - 'shuttercount' => { 10 => 0x176, 54 => 0x1, 211 => 0xa7, 219 => [0x6a,0x157,0x24d], 220 => 0x286, 221 => 0x279, 222 => 0x284, 223 => 0x242, 224 => 0x280, 225 => 0x276, 226 => [0x27d,0x27f], 227 => 0x246, 230 => 0x2d6, 231 => 0x321, 232 => 0xbd8, 233 => 0x287, 234 => 0x320, 235 => 0x24a, 236 => 0x5fb, 239 => 0x2d5, 332 => 0x5d, 387 => 0x846, 391 => [0x125,0x14a] }, - 'shuttercurtainsync' => { 76 => 0xf, 77 => 0xf, 78 => 0x305, 79 => 0xe, 80 => 0xf, 81 => 0x8, 82 => 0x8, 83 => 0xf, 84 => 0x8 }, - 'shuttermode' => { 133 => 0x1b }, - 'shutterreleasebuttonae-l' => { 257 => '17.7', 258 => '18.4', 260 => '78.4', 261 => '78.4', 262 => '16.1', 263 => '17.1', 264 => '17.1', 265 => '17.1', 266 => '7.1', 267 => '17.5', 270 => '18.4', 271 => '78.4', 272 => '18.2' }, - 'shutterreleasemethod' => { 91 => 0x1010 }, - 'shutterreleasenocfcard' => { 76 => 0x2, 77 => 0x2, 84 => 0xf }, - 'shutterreleasetiming' => { 91 => 0x1011 }, - 'shutterreleasewithoutlens' => { 78 => 0x711 }, - 'shutterspeedlock' => { 258 => '38.1', 260 => '38.1', 261 => '38.1', 270 => '38.1', 271 => '38.1' }, - 'shutterspeedrange' => { 78 => 0x10c }, - 'shutterspeedsetting' => { 174 => 0x6, 376 => 0x2f, 377 => 0x28, 378 => 0x0 }, - 'shutterspeedvalue' => { 87 => 0x1, 113 => 0x9201, 279 => 0x1000, 341 => 0x400, 446 => 'ShutterSpeedValue' }, - 'shuttertype' => { 121 => 0x1050, 297 => 0x9f }, - 'sidecarforextension' => { 454 => 'SidecarForExtension' }, - 'sigmaimpulseparameters' => { 131 => 0xe0d }, - 'sigmascalingfactorcamera' => { 131 => 0xe0c }, - 'sigmascalingfactorlowres' => { 131 => 0xe0b }, - 'sigmasizetable' => { 131 => 0xe0f }, - 'similarityindex' => { 125 => 0xe4 }, - 'singleframebracketing' => { 174 => 0x21 }, - 'skilllevel' => { 458 => 'skillLevel' }, - 'skintonecorrection' => { 332 => 0x95 }, - 'skiplinetime' => { 131 => 0x184e }, - 'slaveflashmeteringsegments' => { 332 => 0x20b }, - 'slideshowname' => { 455 => 'slideshowName' }, - 'slideshownumber' => { 455 => 'slideshowNumber' }, - 'slideshowtotalnumber' => { 455 => 'slideshowTotalNumber' }, - 'slowshutter' => { 72 => 0x8 }, - 'slowsync' => { 121 => 0x1030 }, - 'smartalbumcolor' => { 365 => 0x20 }, - 'smartrange' => { 365 => 0xa012 }, - 'smileshutter' => { 378 => 0x31 }, - 'smileshuttermode' => { 378 => 0x27 }, - 'smoothness' => { 113 => 0xfe57, 442 => 'Smoothness' }, - 'snapshot' => { 452 => 'SnapshotLink' }, - 'snapshotformat' => { 452 => [\'SnapshotLink','SnapshotLinkFormat'] }, - 'snapshotheightpixels' => { 452 => [\'SnapshotLink','SnapshotLinkHeightPixels'] }, - 'snapshotimagerole' => { 452 => [\'SnapshotLink','SnapshotLinkImageRole'] }, - 'snapshotlink' => { 452 => [\'SnapshotLink','SnapshotLinkLink'] }, - 'snapshotlinkqualifier' => { 452 => [\'SnapshotLink','SnapshotLinkLinkQualifier'] }, - 'snapshots' => { 436 => 'Snapshots' }, - 'snapshotusedvideoframe' => { 452 => [\'SnapshotLink','SnapshotLinkUsedVideoFrame'] }, - 'snapshotusedvideoframetimeformat' => { 452 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameTimeFormat'] }, - 'snapshotusedvideoframetimevalue' => { 452 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameTimeValue'] }, - 'snapshotusedvideoframevalue' => { 452 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameValue'] }, - 'snapshotwidthpixels' => { 452 => [\'SnapshotLink','SnapshotLinkWidthPixels'] }, - 'softskineffect' => { 388 => 0x200f }, - 'software' => { 113 => 0x131, 148 => 'Software', 287 => 'Software', 341 => 0x203, 368 => 0x18, 426 => 'Software', 462 => 'Software' }, - 'softwareversion' => { 367 => 0x207 }, - 'sonydatetime' => { 395 => 0x6, 397 => 0x1b6, 398 => 0x210, 399 => 0x1fe, 400 => 0x22c }, - 'sonydatetime2' => { 406 => 0x51 }, - 'sonyexposuretime' => { 406 => 0x3a, 407 => 0x46 }, - 'sonyexposuretime2' => { 417 => 0xe }, - 'sonyfnumber' => { 406 => 0x3c, 407 => 0x48, 417 => 0x14 }, - 'sonyimageheight' => { 395 => 0x1a, 408 => 0x44, 409 => 0x3f, 410 => 0x47 }, - 'sonyimageheightmax' => { 417 => 0x40 }, - 'sonyimagesize' => { 174 => 0x3b, 376 => 0x54, 377 => 0x54, 378 => 0x9 }, - 'sonyimagewidth' => { 395 => 0x1c }, - 'sonyimagewidthmax' => { 417 => 0x3e }, - 'sonyiso' => { 397 => 0x1218, 398 => 0x11f4, 399 => 0x1270, 400 => [0x1254,0x1258,0x1280], 401 => 0x113c, 402 => 0x344, 403 => 0x346, 404 => 0x320, 417 => 0x4 }, - 'sonymaxaperture' => { 406 => 0x0, 407 => 0x0 }, - 'sonymaxaperturevalue' => { 417 => 0x16 }, - 'sonyminaperture' => { 406 => 0x1, 407 => 0x1 }, - 'sonymodelid' => { 388 => 0xb001 }, - 'sonyquality' => { 174 => 0x3c }, - 'sonytimeminsec' => { 407 => 0x61 }, - 'source' => { 125 => 0x73, 287 => 'Source', 443 => 'source', 444 => 'source', 454 => 'Source' }, - 'sourcecount' => { 430 => 'SourceCount' }, - 'sourcedirectoryindex' => { 319 => 0x0 }, - 'sourcefileindex' => { 319 => 0x2 }, - 'sourcephotoscount' => { 429 => 'SourcePhotosCount' }, - 'sourceprofileprefix' => { 131 => 0x1390 }, - 'spatialfrequencyresponse' => { 446 => 'SpatialFrequencyResponse' }, - 'spatialfrequencyresponsecolumns' => { 446 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseColumns'] }, - 'spatialfrequencyresponsenames' => { 446 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseNames'] }, - 'spatialfrequencyresponserows' => { 446 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseRows'] }, - 'spatialfrequencyresponsevalues' => { 446 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseValues'] }, - 'speakerplacement' => { 466 => 'speakerPlacement' }, - 'specialeffectlevel' => { 107 => 0x3030 }, - 'specialeffectmode' => { 107 => 0x2076 }, - 'specialeffectsetting' => { 107 => 0x3031 }, - 'specialinstructions' => { 125 => 0x28 }, - 'specialmode' => { 279 => 0x200, 367 => 0x200 }, - 'specialoccasion' => { 458 => 'specialOccasion' }, - 'spectralsensitivity' => { 113 => 0x8824, 446 => 'SpectralSensitivity' }, - 'specularwhitelevel' => { 42 => [0x2b9,0x2d0,0x2d4], 44 => 0x1e4, 45 => [0x1fd,0x2dd], 46 => [0x231,0x30f], 47 => 0x31d }, - 'speedx' => { 109 => 0x3 }, - 'speedy' => { 109 => 0x4 }, - 'speedz' => { 109 => 0x5 }, - 'spherical' => { 430 => 'Spherical' }, - 'splitcolumn' => { 341 => 0x222 }, - 'splittoningbalance' => { 442 => 'SplitToningBalance' }, - 'splittoninghighlighthue' => { 442 => 'SplitToningHighlightHue' }, - 'splittoninghighlightsaturation' => { 442 => 'SplitToningHighlightSaturation' }, - 'splittoningshadowhue' => { 442 => 'SplitToningShadowHue' }, - 'splittoningshadowsaturation' => { 442 => 'SplitToningShadowSaturation' }, - 'sport' => { 456 => 'sport' }, - 'spotfocuspointx' => { 171 => 0x2d }, - 'spotfocuspointy' => { 171 => 0x2e }, - 'spotmeteringmode' => { 33 => 0x27 }, - 'spotmeterlinktoafpoint' => { 78 => 0x107 }, - 'sractive' => { 313 => '17.1' }, - 'srawquality' => { 33 => 0x2e }, - 'srfocallength' => { 334 => 0x3 }, - 'srhalfpresstime' => { 334 => 0x2 }, - 'srresult' => { 334 => 0x0, 335 => 0x0 }, - 'stackedimage' => { 274 => 0x804 }, - 'standardmatrixcustom' => { 131 => 0x7d4 }, - 'standardmatrixdaylight' => { 131 => 0x7d0 }, - 'standardmatrixflash' => { 131 => 0x7d3 }, - 'standardmatrixfluorescent' => { 131 => 0x7d2 }, - 'standardmatrixtungsten' => { 131 => 0x7d1 }, - 'standardoutputhighlightpoint' => { 103 => 0x14 }, - 'standardoutputsensitivity' => { 113 => 0x8831, 447 => 'StandardOutputSensitivity' }, - 'standardoutputshadowpoint' => { 103 => 0x15 }, - 'standardrawcolortone' => { 103 => 0xd }, - 'standardrawcontrast' => { 103 => 0xf }, - 'standardrawhighlight' => { 103 => 0x75 }, - 'standardrawhighlightpoint' => { 103 => 0x12 }, - 'standardrawlinear' => { 103 => 0x10 }, - 'standardrawsaturation' => { 103 => 0xe }, - 'standardrawshadow' => { 103 => 0x7e }, - 'standardrawshadowpoint' => { 103 => 0x13 }, - 'standardrawsharpness' => { 103 => 0x11 }, - 'standardunsharpmaskfineness' => { 103 => 0x94 }, - 'standardunsharpmaskstrength' => { 103 => 0x92 }, - 'standardunsharpmaskthreshold' => { 103 => 0x96 }, - 'standardwhitecustom' => { 131 => 0x838 }, - 'standardwhitedaylight' => { 131 => 0x834 }, - 'standardwhiteflash' => { 131 => 0x837 }, - 'standardwhitefluorescent' => { 131 => 0x836 }, - 'standardwhitetungsten' => { 131 => 0x835 }, - 'standbytimer' => { 258 => '19.1', 260 => '19.1', 261 => '19.1', 264 => '18.1', 265 => '18.1', 270 => '19.1', 271 => '19.1' }, - 'startingpage' => { 456 => 'startingPage' }, - 'startmovieshooting' => { 78 => 0x70d }, - 'starttimecode' => { 466 => 'startTimecode' }, - 'starttimecodetimeformat' => { 466 => [\'startTimecode','startTimecodeTimeFormat'] }, - 'starttimecodetimevalue' => { 466 => [\'startTimecode','startTimecodeTimeValue'] }, - 'starttimecodevalue' => { 466 => [\'startTimecode','startTimecodeValue'] }, - 'starttimesamplesize' => { 466 => 'startTimeSampleSize' }, - 'starttimescale' => { 466 => 'startTimeScale' }, - 'state' => { 152 => 'State', 297 => 0x6b, 454 => 'State' }, - 'status' => { 424 => 'Status', 434 => 'Status' }, - 'stereomode' => { 430 => 'StereoMode' }, - 'stitched' => { 430 => 'Stitched' }, - 'stitchingsoftware' => { 429 => 'StitchingSoftware', 430 => 'StitchingSoftware' }, - 'stopsabovebaseiso' => { 396 => 0x113e, 397 => 0x113e, 398 => 0x111a, 399 => 0x1196, 400 => 0x1172, 401 => 0x102a, 402 => 0x222, 403 => 0x222, 404 => 0x217, 417 => 0xa }, - 'storagemethod' => { 178 => 0x12 }, - 'storebyorientation' => { 258 => '46.3', 260 => '47.3', 261 => '47.3', 270 => '47.3', 271 => '47.3' }, - 'storylineidentifier' => { 452 => 'StorylineIdentifier' }, - 'straightenangle' => { 250 => 0x2fc08431 }, - 'streamready' => { 452 => 'StreamReady' }, - 'streamtype' => { 167 => 'StreamType' }, - 'stretchmode' => { 466 => 'stretchMode' }, - 'studydatetime' => { 423 => 'StudyDateTime' }, - 'studydescription' => { 423 => 'StudyDescription' }, - 'studyid' => { 423 => 'StudyID' }, - 'studyphysician' => { 423 => 'StudyPhysician' }, - 'styleperiod' => { 452 => 'StylePeriod' }, - 'sub-location' => { 125 => 0x5c }, - 'subfiledata' => { 155 => 'data' }, - 'subfiledirectory' => { 155 => '1Directory' }, - 'subfilemimetype' => { 155 => '2MIME' }, - 'subfilename' => { 155 => '1Name' }, - 'subfileresource' => { 155 => 'rsrc' }, - 'subfiletype' => { 113 => 0xfe, 155 => '0Type' }, - 'subject' => { 283 => 'Subject', 348 => 'Subject', 443 => 'subject', 453 => 'Subject', 467 => 'subject' }, - 'subjectarea' => { 113 => 0x9214, 446 => 'SubjectArea' }, - 'subjectcode' => { 451 => 'SubjectCode' }, - 'subjectdistance' => { 113 => 0x9206, 133 => 0x3e, 446 => 'SubjectDistance' }, - 'subjectdistancerange' => { 113 => 0xa40c, 446 => 'SubjectDistanceRange' }, - 'subjectlocation' => { 113 => 0xa214, 446 => 'SubjectLocation' }, - 'subjectmotion' => { 260 => '78.2', 261 => '78.2', 271 => '78.2' }, - 'subjectprogram' => { 171 => 0x22 }, - 'subjectreference' => { 125 => 0xc }, - 'sublabels4' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabels'] }, - 'sublabels5' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels'] }, - 'sublables1' => { 450 => [\'TagStructure','TagStructureSubLabels'] }, - 'sublables2' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabels'] }, - 'sublables3' => { 450 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabels'] }, - 'subseccreatedate' => { 108 => 'SubSecCreateDate' }, - 'subsecdatetimeoriginal' => { 108 => 'SubSecDateTimeOriginal' }, - 'subsecmodifydate' => { 108 => 'SubSecModifyDate' }, - 'subsectime' => { 113 => 0x9290 }, - 'subsectimedigitized' => { 113 => 0x9292 }, - 'subsectimeoriginal' => { 113 => 0x9291 }, - 'subsection1' => { 456 => 'subsection1' }, - 'subsection2' => { 456 => 'subsection2' }, - 'subsection3' => { 456 => 'subsection3' }, - 'subsection4' => { 456 => 'subsection4' }, - 'subselector' => { 258 => '49.1', 260 => '71.1', 261 => '71.1', 271 => '71.1' }, - 'subselectorassignment' => { 258 => '48.1' }, - 'subselectorcenter' => { 260 => '72.1', 261 => '72.1', 271 => '72.1' }, - 'subselectorplusdials' => { 258 => '49.2', 260 => '73.1', 261 => '73.1', 271 => '73.1' }, - 'subtitle' => { 456 => 'subtitle' }, - 'subversionfilename' => { 450 => [\'SubVersions','SubVersionsFileName'] }, - 'subversionreference' => { 450 => [\'SubVersions','SubVersionsVersRef'] }, - 'subversions' => { 450 => 'SubVersions' }, - 'superimposeddisplay' => { 76 => 0xa, 78 => 0x510, 79 => 0x9, 80 => 0xa, 83 => 0xa, 84 => 0xe }, - 'supermacro' => { 60 => 0x1a }, - 'supplementalcategories' => { 125 => 0x14, 454 => 'SupplementalCategories' }, - 'supplementaltype' => { 127 => 0x37 }, - 'supplementdisplayid' => { 456 => 'supplementDisplayID' }, - 'supplementstartingpage' => { 456 => 'supplementStartingPage' }, - 'supplementtitle' => { 456 => 'supplementTitle' }, - 'supplychainsource' => { 452 => 'SupplyChainSource' }, - 'supplychainsourceidentifier' => { 452 => [\'SupplyChainSource','SupplyChainSourceIdentifier'] }, - 'supplychainsourcename' => { 452 => [\'SupplyChainSource','SupplyChainSourceName'] }, - 'svisosetting' => { 313 => 0x14 }, - 'swatchcoloranta' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsA'] }, - 'swatchcolorantb' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsB'] }, - 'swatchcolorantblack' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsBlack'] }, - 'swatchcolorantblue' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsBlue'] }, - 'swatchcolorantcyan' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsCyan'] }, - 'swatchcolorantgray' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsGray'] }, - 'swatchcolorantgreen' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsGreen'] }, - 'swatchcolorantl' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsL'] }, - 'swatchcolorantmagenta' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsMagenta'] }, - 'swatchcolorantmode' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsMode'] }, - 'swatchcolorantred' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsRed'] }, - 'swatchcolorantswatchname' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsSwatchName'] }, - 'swatchcoloranttint' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsTint'] }, - 'swatchcoloranttype' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsType'] }, - 'swatchcolorantyellow' => { 471 => [\'SwatchGroups','SwatchGroupsColorantsYellow'] }, - 'swatchgroupname' => { 471 => [\'SwatchGroups','SwatchGroupsGroupName'] }, - 'swatchgroups' => { 471 => 'SwatchGroups' }, - 'swatchgroupscolorants' => { 471 => [\'SwatchGroups','SwatchGroupsColorants'] }, - 'swatchgrouptype' => { 471 => [\'SwatchGroups','SwatchGroupsGroupType'] }, - 'sweeppanoramadirection' => { 297 => 0x93, 378 => 0x33 }, - 'sweeppanoramafieldofview' => { 297 => 0x94 }, - 'sweeppanoramasize' => { 378 => 0x32 }, - 'switchtoregisteredafpoint' => { 77 => 0x12, 78 => 0x50a }, - 'syncreleasemode' => { 260 => '77.1', 261 => '77.1', 271 => '77.1' }, - 'system' => { 341 => 0x204 }, - 'tagged' => { 343 => 0xdd, 344 => 'Tagged', 436 => 'tagged' }, - 'tagslist' => { 445 => 'TagsList' }, - 'tagstructure' => { 450 => 'TagStructure' }, - 'takenumber' => { 466 => 'takeNumber' }, - 'tapename' => { 466 => 'tapeName' }, - 'targetaperture' => { 72 => 0x4 }, - 'targetcompressionratio' => { 89 => 0x1 }, - 'targetdistancesetting' => { 91 => 0x1807 }, - 'targetexposuretime' => { 72 => 0x5 }, - 'targetimagetype' => { 91 => 0x100a }, - 'targetprinter' => { 113 => 0x151 }, - 'taxon' => { 112 => 'Taxon' }, - 'taxonacceptednameusage' => { 112 => [\'Taxon','TaxonAcceptedNameUsage'] }, - 'taxonacceptednameusageid' => { 112 => [\'Taxon','TaxonAcceptedNameUsageID'] }, - 'taxonclass' => { 112 => [\'Taxon','TaxonClass'] }, - 'taxonconceptid' => { 112 => [\'Taxon','TaxonTaxonConceptID'] }, - 'taxonfamily' => { 112 => [\'Taxon','TaxonFamily'] }, - 'taxongenus' => { 112 => [\'Taxon','TaxonGenus'] }, - 'taxonhigherclassification' => { 112 => [\'Taxon','TaxonHigherClassification'] }, - 'taxonid' => { 112 => [\'Taxon','TaxonTaxonID'] }, - 'taxoninfraspecificepithet' => { 112 => [\'Taxon','TaxonInfraspecificEpithet'] }, - 'taxonkingdom' => { 112 => [\'Taxon','TaxonKingdom'] }, - 'taxonnameaccordingto' => { 112 => [\'Taxon','TaxonNameAccordingTo'] }, - 'taxonnameaccordingtoid' => { 112 => [\'Taxon','TaxonNameAccordingToID'] }, - 'taxonnamepublishedin' => { 112 => [\'Taxon','TaxonNamePublishedIn'] }, - 'taxonnamepublishedinid' => { 112 => [\'Taxon','TaxonNamePublishedInID'] }, - 'taxonnamepublishedinyear' => { 112 => [\'Taxon','TaxonNamePublishedInYear'] }, - 'taxonnomenclaturalcode' => { 112 => [\'Taxon','TaxonNomenclaturalCode'] }, - 'taxonnomenclaturalstatus' => { 112 => [\'Taxon','TaxonNomenclaturalStatus'] }, - 'taxonorder' => { 112 => [\'Taxon','TaxonOrder'] }, - 'taxonoriginalnameusage' => { 112 => [\'Taxon','TaxonOriginalNameUsage'] }, - 'taxonoriginalnameusageid' => { 112 => [\'Taxon','TaxonOriginalNameUsageID'] }, - 'taxonparentnameusage' => { 112 => [\'Taxon','TaxonParentNameUsage'] }, - 'taxonparentnameusageid' => { 112 => [\'Taxon','TaxonParentNameUsageID'] }, - 'taxonphylum' => { 112 => [\'Taxon','TaxonPhylum'] }, - 'taxonrank' => { 112 => [\'Taxon','TaxonTaxonRank'] }, - 'taxonremarks' => { 112 => [\'Taxon','TaxonTaxonRemarks'] }, - 'taxonscientificname' => { 112 => [\'Taxon','TaxonScientificName'] }, - 'taxonscientificnameauthorship' => { 112 => [\'Taxon','TaxonScientificNameAuthorship'] }, - 'taxonscientificnameid' => { 112 => [\'Taxon','TaxonScientificNameID'] }, - 'taxonspecificepithet' => { 112 => [\'Taxon','TaxonSpecificEpithet'] }, - 'taxonsubgenus' => { 112 => [\'Taxon','TaxonSubgenus'] }, - 'taxontaxonomicstatus' => { 112 => [\'Taxon','TaxonTaxonomicStatus'] }, - 'taxonverbatimtaxonrank' => { 112 => [\'Taxon','TaxonVerbatimTaxonRank'] }, - 'taxonvernacularname' => { 112 => [\'Taxon','TaxonVernacularName'] }, - 'tda1bandwidth' => { 131 => 0x196f }, - 'tda1edgepolarity' => { 131 => 0x1971 }, - 'tda1gain' => { 131 => 0x1970 }, - 'tda1offset' => { 131 => 0x196e }, - 'tda2bandwidth' => { 131 => 0x1979 }, - 'tda2edgepolarity' => { 131 => 0x197b }, - 'tda2gain' => { 131 => 0x197a }, - 'tda2offset' => { 131 => 0x1978 }, - 'tda3bandwidth' => { 131 => 0x1983 }, - 'tda3edgepolarity' => { 131 => 0x1985 }, - 'tda3gain' => { 131 => 0x1984 }, - 'tda3offset' => { 131 => 0x1982 }, - 'tda4bandwidth' => { 131 => 0x198d }, - 'tda4edgepolarity' => { 131 => 0x198f }, - 'tda4gain' => { 131 => 0x198e }, - 'tda4offset' => { 131 => 0x198c }, - 'teaser' => { 456 => 'teaser' }, - 'teleconverter' => { 176 => 0x105, 388 => 0x105 }, - 'tempampgainx100' => { 131 => 0x1914 }, - 'tempo' => { 466 => 'tempo' }, - 'temporalcoverage' => { 452 => 'TemporalCoverage' }, - 'temporalcoveragefrom' => { 452 => [\'TemporalCoverage','TemporalCoverageTempCoverageFrom'] }, - 'temporalcoverageto' => { 452 => [\'TemporalCoverage','TemporalCoverageTempCoverageTo'] }, - 'termsandconditionstext' => { 284 => 'TermsAndConditionsText' }, - 'termsandconditionsurl' => { 284 => 'TermsAndConditionsURL' }, - 'testname' => { 114 => 'TestName' }, - 'textencoding' => { 210 => 0x4 }, - 'textlayername' => { 454 => [\'TextLayers','TextLayersLayerName'] }, - 'textlayers' => { 454 => 'TextLayers' }, - 'textlayertext' => { 454 => [\'TextLayers','TextLayersLayerText'] }, - 'textstamp' => { 297 => [0x8008,0x8009,0x3b,0x3e] }, - 'three-dtrackingfacedetection' => { 260 => '1.3', 261 => '1.3', 271 => '1.4' }, - 'three-dtrackingwatcharea' => { 260 => '78.1', 261 => '78.1', 271 => '78.1' }, - 'thresholding' => { 113 => 0x107 }, - 'thumbnailfilename' => { 91 => 0x817 }, - 'thumbnailformat' => { 464 => [\'Thumbnails','ThumbnailsFormat'] }, - 'thumbnailheight' => { 135 => 0xfa55, 464 => [\'Thumbnails','ThumbnailsHeight'] }, - 'thumbnailimage' => { 91 => 0x2008, 108 => 'ThumbnailImage', 116 => 0x3, 158 => 'data', 279 => 0x100, 464 => [\'Thumbnails','ThumbnailsImage'] }, - 'thumbnailimagename' => { 158 => '1Name' }, - 'thumbnailimagesize' => { 158 => 'ImageSize' }, - 'thumbnailimagetype' => { 158 => '0Type' }, - 'thumbnailimagevalidarea' => { 60 => 0x13 }, - 'thumbnaillength' => { 113 => 0x202 }, - 'thumbnailoffset' => { 113 => 0x201 }, - 'thumbnails' => { 464 => 'Thumbnails' }, - 'thumbnailwidth' => { 135 => 0xfa54, 464 => [\'Thumbnails','ThumbnailsWidth'] }, - 'ticker' => { 456 => 'ticker' }, - 'tiffhandling' => { 442 => 'TIFFHandling' }, - 'tiffmeteringimage' => { 177 => 0x104c, 387 => 0x1110 }, - 'tilelength' => { 113 => 0x143 }, - 'tilewidth' => { 113 => 0x142 }, - 'time' => { 131 => 0x401, 332 => 0x7 }, - 'timecodes' => { 113 => 0xc763 }, - 'timecreated' => { 125 => 0x3c, 133 => 0x14, 142 => 0x10, 344 => 'TimeCreated' }, - 'timelapseshotnumber' => { 300 => 0x10 }, - 'timeperiod' => { 456 => 'timePeriod' }, - 'timerfunctionbutton' => { 259 => '5.2', 262 => '12.1', 263 => '13.1' }, - 'timerlength' => { 78 => 0x80c }, - 'timerrecording' => { 297 => 0x96 }, - 'timescaleparams' => { 466 => 'timeScaleParams' }, - 'timescaleparamsframeoverlappingpercentage' => { 466 => [\'timeScaleParams','timeScaleParamsFrameOverlappingPercentage'] }, - 'timescaleparamsframesize' => { 466 => [\'timeScaleParams','timeScaleParamsFrameSize'] }, - 'timescaleparamsquality' => { 466 => [\'timeScaleParams','timeScaleParamsQuality'] }, - 'timesent' => { 126 => 0x50 }, - 'timeshot' => { 431 => 'TimeShot' }, - 'timesignature' => { 466 => 'timeSignature' }, - 'timesincepoweron' => { 297 => 0x29 }, - 'timestamp' => { 10 => 0x45e, 18 => 0x11c, 273 => 0x8, 287 => 'TimeStamp', 297 => 0xaf, 430 => 'Timestamp', 437 => 'Timestamp', 450 => 'TimeStamp' }, - 'timestamp1' => { 10 => 0x45a }, - 'timezone' => { 73 => 0x1, 242 => 0x0, 361 => 0xa }, - 'timezonecity' => { 73 => 0x2 }, - 'timezonecode' => { 94 => 0x1 }, - 'timezoneinfo' => { 94 => 0x2 }, - 'timezoneoffset' => { 113 => 0x882a }, - 'tint' => { 442 => 'Tint' }, - 'title' => { 148 => 'Title', 283 => 'Title', 287 => 'Title', 297 => 0x65, 348 => 'Title', 443 => 'title', 453 => 'Title', 464 => 'Title' }, - 'tonecomp' => { 211 => 0x81 }, - 'tonecurve' => { 70 => 0x1, 332 => 0x402, 442 => 'ToneCurve' }, - 'tonecurveactive' => { 102 => 0x110 }, - 'tonecurveadobergb' => { 365 => 0xa043 }, - 'tonecurveadobergbdefault' => { 365 => 0xa041 }, - 'tonecurveblue' => { 442 => 'ToneCurveBlue' }, - 'tonecurvebluex' => { 421 => 0x9003 }, - 'tonecurvebluey' => { 421 => 0x9007 }, - 'tonecurvebrightness' => { 97 => 0x20410 }, - 'tonecurvebrightnessx' => { 421 => 0x9000 }, - 'tonecurvebrightnessy' => { 421 => 0x9004 }, - 'tonecurvecolorspace' => { 101 => 0x0 }, - 'tonecurvecontrast' => { 97 => 0x20411 }, - 'tonecurvegreen' => { 442 => 'ToneCurveGreen' }, - 'tonecurvegreenx' => { 421 => 0x9002 }, - 'tonecurvegreeny' => { 421 => 0x9006 }, - 'tonecurveinputrange' => { 101 => 0x3 }, - 'tonecurveinterpolation' => { 102 => 0x159 }, - 'tonecurvemode' => { 102 => 0x113 }, - 'tonecurvename' => { 442 => 'ToneCurveName' }, - 'tonecurvename2012' => { 442 => 'ToneCurveName2012' }, - 'tonecurveoriginal' => { 97 => '0x20400.1' }, - 'tonecurveoutputrange' => { 101 => 0x5 }, - 'tonecurveprofilename' => { 131 => 0x1391 }, - 'tonecurveproperty' => { 102 => 0x3c }, - 'tonecurvepv2012' => { 442 => 'ToneCurvePV2012' }, - 'tonecurvepv2012blue' => { 442 => 'ToneCurvePV2012Blue' }, - 'tonecurvepv2012green' => { 442 => 'ToneCurvePV2012Green' }, - 'tonecurvepv2012red' => { 442 => 'ToneCurvePV2012Red' }, - 'tonecurvered' => { 442 => 'ToneCurveRed' }, - 'tonecurveredx' => { 421 => 0x9001 }, - 'tonecurveredy' => { 421 => 0x9005 }, - 'tonecurves' => { 332 => 0x403 }, - 'tonecurveshape' => { 101 => 0x1 }, - 'tonecurvesrgb' => { 365 => 0xa042 }, - 'tonecurvesrgbdefault' => { 365 => 0xa040 }, - 'tonecurvex' => { 101 => 0xa }, - 'tonecurvey' => { 101 => 0xb }, - 'tonelevel' => { 274 => 0x52e }, - 'tonemapstrength' => { 442 => 'ToneMapStrength' }, - 'toningeffect' => { 54 => 0xf, 211 => 0xb3, 213 => 0x38, 214 => 0x40, 358 => 0x1015 }, - 'toningeffectauto' => { 67 => 0xa4 }, - 'toningeffectfaithful' => { 66 => 0x74, 67 => 0x74 }, - 'toningeffectlandscape' => { 66 => 0x44, 67 => 0x44 }, - 'toningeffectmonochrome' => { 18 => 0x108, 66 => 0x8c, 67 => 0x8c }, - 'toningeffectneutral' => { 66 => 0x5c, 67 => 0x5c }, - 'toningeffectportrait' => { 66 => 0x2c, 67 => 0x2c }, - 'toningeffectstandard' => { 66 => 0x14, 67 => 0x14 }, - 'toningeffectuserdef1' => { 66 => 0xa4, 67 => 0xbc }, - 'toningeffectuserdef2' => { 66 => 0xbc, 67 => 0xd4 }, - 'toningeffectuserdef3' => { 66 => 0xd4, 67 => 0xec }, - 'toningsaturation' => { 213 => 0x39, 214 => 0x41 }, - 'totalzoom' => { 133 => 0x62 }, - 'touchae' => { 297 => 0xab }, - 'trackcreatedate' => { 352 => 0x1 }, - 'trackmodifydate' => { 352 => 0x2 }, - 'tracknumber' => { 466 => 'trackNumber' }, - 'tracks' => { 466 => 'Tracks' }, - 'tracksframerate' => { 466 => [\'Tracks','TracksFrameRate'] }, - 'tracksmarkers' => { 466 => [\'Tracks','TracksMarkers'] }, - 'tracksmarkerscomment' => { 466 => [\'Tracks','TracksMarkersComment'] }, - 'tracksmarkerscuepointparams' => { 466 => [\'Tracks','TracksMarkersCuePointParams'] }, - 'tracksmarkerscuepointparamskey' => { 466 => [\'Tracks','TracksMarkersCuePointParamsKey'] }, - 'tracksmarkerscuepointparamsvalue' => { 466 => [\'Tracks','TracksMarkersCuePointParamsValue'] }, - 'tracksmarkerscuepointtype' => { 466 => [\'Tracks','TracksMarkersCuePointType'] }, - 'tracksmarkersduration' => { 466 => [\'Tracks','TracksMarkersDuration'] }, - 'tracksmarkerslocation' => { 466 => [\'Tracks','TracksMarkersLocation'] }, - 'tracksmarkersname' => { 466 => [\'Tracks','TracksMarkersName'] }, - 'tracksmarkersprobability' => { 466 => [\'Tracks','TracksMarkersProbability'] }, - 'tracksmarkersspeaker' => { 466 => [\'Tracks','TracksMarkersSpeaker'] }, - 'tracksmarkersstarttime' => { 466 => [\'Tracks','TracksMarkersStartTime'] }, - 'tracksmarkerstarget' => { 466 => [\'Tracks','TracksMarkersTarget'] }, - 'tracksmarkerstype' => { 466 => [\'Tracks','TracksMarkersType'] }, - 'trackstrackname' => { 466 => [\'Tracks','TracksTrackName'] }, - 'trackstracktype' => { 466 => [\'Tracks','TracksTrackType'] }, - 'trailersignature' => { 155 => 'zmie' }, - 'transcript' => { 452 => 'Transcript' }, - 'transcriptlink' => { 452 => 'TranscriptLink' }, - 'transcriptlinklink' => { 452 => [\'TranscriptLink','TranscriptLinkLink'] }, - 'transcriptlinklinkqualifier' => { 452 => [\'TranscriptLink','TranscriptLinkLinkQualifier'] }, - 'transferfunction' => { 113 => 0x12d, 462 => 'TransferFunction' }, - 'transfertimenormal' => { 131 => 0x1888 }, - 'transfertimetest' => { 131 => 0x1889 }, - 'transform' => { 297 => [0x8012,0x59] }, - 'transmissionreference' => { 454 => 'TransmissionReference' }, - 'trapped' => { 283 => 'Trapped', 453 => 'Trapped' }, - 'trashbuttonfunction' => { 78 => 0x710 }, - 'travelday' => { 297 => 0x36 }, - 'triggermode' => { 353 => 0x6, 354 => 0x34 }, - 'tstop' => { 113 => 0xc772 }, - 'ttl_da_adown' => { 320 => 0x5 }, - 'ttl_da_aup' => { 320 => 0x4 }, - 'ttl_da_bdown' => { 320 => 0x7 }, - 'ttl_da_bup' => { 320 => 0x6 }, - 'tungstenawb' => { 310 => 0x1 }, - 'tvexposuretimesetting' => { 313 => 0x12 }, - 'type' => { 443 => 'type', 461 => 'type' }, - 'typestatus' => { 112 => [\'Identification','IdentificationTypeStatus'] }, - 'uniquecameramodel' => { 113 => 0xc614 }, - 'uniquedocumentid' => { 125 => 0xbb }, - 'uniquematrixauto' => { 131 => 0x7e9 }, - 'uniquematrixcustom' => { 131 => 0x7e8 }, - 'uniquematrixdaylight' => { 131 => 0x7e4 }, - 'uniquematrixflash' => { 131 => 0x7e7 }, - 'uniquematrixfluorescent' => { 131 => 0x7e6 }, - 'uniquematrixtungsten' => { 131 => 0x7e5 }, - 'uniqueobjectname' => { 126 => 0x64 }, - 'units' => { 426 => 'Units' }, - 'unknownblock' => { 332 => 0x405 }, - 'unknownblock1' => { 278 => 0x635 }, - 'unknownblock2' => { 278 => 0x636 }, - 'unknownblock3' => { 278 => 0x1103 }, - 'unknownblock4' => { 278 => 0x1104 }, - 'unknowncontrast' => { 103 => 0x45 }, - 'unknowndate' => { 341 => 0x212 }, - 'unknownev' => { 131 => 0x1 }, - 'unknownlinear' => { 103 => 0x46 }, - 'unknownnumber' => { 91 => 0x180b }, - 'unknownoutputhighlightpoint' => { 103 => 0x4a }, - 'unknownoutputshadowpoint' => { 103 => 0x4b }, - 'unknownrawhighlight' => { 103 => 0x7b }, - 'unknownrawhighlightpoint' => { 103 => 0x48 }, - 'unknownrawshadow' => { 103 => 0x84 }, - 'unknownrawshadowpoint' => { 103 => 0x49 }, - 'unknownsharpness' => { 103 => 0x47 }, - 'unknowntemperature' => { 115 => 0x4 }, - 'unsharp1color' => { 255 => 0x13 }, - 'unsharp1halowidth' => { 255 => 0x19 }, - 'unsharp1intensity' => { 255 => 0x17 }, - 'unsharp1threshold' => { 255 => 0x1b }, - 'unsharp2color' => { 255 => 0x2e }, - 'unsharp2halowidth' => { 255 => 0x34 }, - 'unsharp2intensity' => { 255 => 0x32 }, - 'unsharp2threshold' => { 255 => 0x36 }, - 'unsharp3color' => { 255 => 0x49 }, - 'unsharp3halowidth' => { 255 => 0x4f }, - 'unsharp3intensity' => { 255 => 0x4d }, - 'unsharp3threshold' => { 255 => 0x51 }, - 'unsharp4color' => { 255 => 0x64 }, - 'unsharp4halowidth' => { 255 => 0x6a }, - 'unsharp4intensity' => { 255 => 0x68 }, - 'unsharp4threshold' => { 255 => 0x6c }, - 'unsharpcount' => { 255 => 0x0 }, - 'unsharpmask' => { 103 => 0x90, 250 => 0x76a43200 }, - 'unsharpmaskfineness' => { 97 => 0x20309 }, - 'unsharpmaskstrength' => { 97 => 0x20308 }, - 'unsharpmaskthreshold' => { 97 => 0x2030a }, - 'uprightcentermode' => { 442 => 'UprightCenterMode' }, - 'uprightcenternormx' => { 442 => 'UprightCenterNormX' }, - 'uprightcenternormy' => { 442 => 'UprightCenterNormY' }, - 'uprightdependentdigest' => { 442 => 'UprightDependentDigest' }, - 'uprightfocallength35mm' => { 442 => 'UprightFocalLength35mm' }, - 'uprightfocalmode' => { 442 => 'UprightFocalMode' }, - 'uprightfoursegmentscount' => { 442 => 'UprightFourSegmentsCount' }, - 'uprightpreview' => { 442 => 'UprightPreview' }, - 'uprighttransform_0' => { 442 => 'UprightTransform_0' }, - 'uprighttransform_1' => { 442 => 'UprightTransform_1' }, - 'uprighttransform_2' => { 442 => 'UprightTransform_2' }, - 'uprighttransform_3' => { 442 => 'UprightTransform_3' }, - 'uprighttransform_4' => { 442 => 'UprightTransform_4' }, - 'uprighttransform_5' => { 442 => 'UprightTransform_5' }, - 'uprighttransformcount' => { 442 => 'UprightTransformCount' }, - 'uprightversion' => { 442 => 'UprightVersion' }, - 'urgency' => { 125 => 0xa, 454 => 'Urgency' }, - 'url' => { 148 => 'URL', 287 => 'URL', 346 => 0x40b, 456 => 'url' }, - 'url_list' => { 346 => 0x41e }, - 'urla-platform' => { 456 => [\'url','urlA-platform'] }, - 'urlurl' => { 456 => [\'url','urlUrl'] }, - 'usablemeteringmodes' => { 78 => 0x10a }, - 'usableshootingmodes' => { 78 => 0x109 }, - 'usage' => { 457 => 'usage' }, - 'usageterms' => { 470 => 'UsageTerms' }, - 'useguidelines' => { 439 => 'useGuidelines' }, - 'usepanoramaviewer' => { 429 => 'UsePanoramaViewer' }, - 'usercomment' => { 91 => 0x805, 113 => 0x9286, 446 => 'UserComment' }, - 'userdef1picturestyle' => { 18 => 0x10c, 66 => 0xd8, 67 => 0xf0 }, - 'userdef2picturestyle' => { 18 => 0x10e, 66 => 0xda, 67 => 0xf2 }, - 'userdef3picturestyle' => { 18 => 0x110, 66 => 0xdc, 67 => 0xf4 }, - 'userfields' => { 434 => 'UserFields' }, - 'userlabel' => { 353 => 0x2b, 354 => 0x5a }, - 'userprofile' => { 292 => 0x302, 299 => 0x3038 }, - 'usmlenselectronicmf' => { 2 => 0x7, 77 => 0x7, 78 => 0x501 }, - 'uspsnumber' => { 456 => 'uspsNumber' }, - 'utmeasting' => { 159 => 'Easting' }, - 'utmmapdatum' => { 159 => 'Datum' }, - 'utmnorthing' => { 159 => 'Northing' }, - 'utmzone' => { 159 => 'Zone' }, - 'uv-irfiltercorrection' => { 292 => 0x325 }, - 'validbits' => { 278 => 0x611, 279 => 0x102c }, - 'validpixeldepth' => { 282 => 0x611 }, - 'variablelowpassfilter' => { 388 => 0x2028 }, - 'variousmodes' => { 133 => 0x26 }, - 'variousmodes2' => { 133 => 0x3a }, - 'variprogram' => { 211 => 0xab }, - 'varraydacnominalvalues' => { 131 => 0x191e }, - 'version' => { 121 => 0x0, 348 => 'Version', 442 => 'Version' }, - 'versioncreatedate' => { 421 => 0xd100 }, - 'versionid' => { 467 => 'VersionID' }, - 'versionidentifier' => { 456 => 'versionIdentifier' }, - 'versionmodifydate' => { 421 => 0xd101 }, - 'versions' => { 467 => 'Versions' }, - 'versionscomments' => { 467 => [\'Versions','VersionsComments'] }, - 'versionsevent' => { 467 => [\'Versions','VersionsEvent'] }, - 'versionseventaction' => { 467 => [\'Versions','VersionsEventAction'] }, - 'versionseventchanged' => { 467 => [\'Versions','VersionsEventChanged'] }, - 'versionseventinstanceid' => { 467 => [\'Versions','VersionsEventInstanceID'] }, - 'versionseventparameters' => { 467 => [\'Versions','VersionsEventParameters'] }, - 'versionseventsoftwareagent' => { 467 => [\'Versions','VersionsEventSoftwareAgent'] }, - 'versionseventwhen' => { 467 => [\'Versions','VersionsEventWhen'] }, - 'versionsmodifier' => { 467 => [\'Versions','VersionsModifier'] }, - 'versionsmodifydate' => { 467 => [\'Versions','VersionsModifyDate'] }, - 'versionsversion' => { 467 => [\'Versions','VersionsVersion'] }, - 'verticalafonbutton' => { 257 => '3.2', 258 => '47.2', 260 => '79.1' }, - 'verticalclockoverlaps' => { 131 => 0x412 }, - 'verticalfuncbutton' => { 258 => '42.2', 260 => '67.1' }, - 'verticalfuncbuttonplusdials' => { 258 => '43.1' }, - 'verticalfuncplusdials' => { 260 => '68.1' }, - 'verticalmultiselector' => { 258 => '42.1', 260 => '66.1', 261 => '66.1', 271 => '66.1' }, - 'vfdisplayillumination' => { 2 => 0x11, 78 => [0x510,0x51d] }, - 'vibrance' => { 435 => 'Vibrance', 442 => 'Vibrance' }, - 'vibrationreduction' => { 219 => [0x75,0x82,0x1ae], 227 => '586.1', 235 => '590.2', 241 => 0x4 }, - 'videoalphamode' => { 466 => 'videoAlphaMode' }, - 'videoalphapremultiplecolor' => { 466 => 'videoAlphaPremultipleColor' }, - 'videoalphapremultiplecolora' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorA'] }, - 'videoalphapremultiplecolorb' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorB'] }, - 'videoalphapremultiplecolorblack' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlack'] }, - 'videoalphapremultiplecolorblue' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlue'] }, - 'videoalphapremultiplecolorcyan' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorCyan'] }, - 'videoalphapremultiplecolorgray' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGray'] }, - 'videoalphapremultiplecolorgreen' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGreen'] }, - 'videoalphapremultiplecolorl' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorL'] }, - 'videoalphapremultiplecolormagenta' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMagenta'] }, - 'videoalphapremultiplecolormode' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMode'] }, - 'videoalphapremultiplecolorred' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorRed'] }, - 'videoalphapremultiplecolorswatchname' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorSwatchName'] }, - 'videoalphapremultiplecolortint' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorTint'] }, - 'videoalphapremultiplecolortype' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorType'] }, - 'videoalphapremultiplecoloryellow' => { 466 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorYellow'] }, - 'videoalphaunityistransparent' => { 466 => 'videoAlphaUnityIsTransparent' }, - 'videobitrate' => { 452 => 'videoBitRate' }, - 'videobitratemode' => { 452 => 'videoBitRateMode' }, - 'videoburstmode' => { 297 => 0xbb }, - 'videocodec' => { 63 => 0x74 }, - 'videocolorspace' => { 466 => 'videoColorSpace' }, - 'videocompressor' => { 466 => 'videoCompressor' }, - 'videodisplayaspectratio' => { 452 => 'videoDisplayAspectRatio' }, - 'videoencodingprofile' => { 452 => 'videoEncodingProfile' }, - 'videofieldorder' => { 466 => 'videoFieldOrder' }, - 'videoframerate' => { 466 => 'videoFrameRate' }, - 'videoframesize' => { 466 => 'videoFrameSize' }, - 'videoframesizeh' => { 466 => [\'videoFrameSize','videoFrameSizeH'] }, - 'videoframesizeunit' => { 466 => [\'videoFrameSize','videoFrameSizeUnit'] }, - 'videoframesizew' => { 466 => [\'videoFrameSize','videoFrameSizeW'] }, - 'videomoddate' => { 466 => 'videoModDate' }, - 'videopixelaspectratio' => { 466 => 'videoPixelAspectRatio' }, - 'videopixeldepth' => { 466 => 'videoPixelDepth' }, - 'videoquality' => { 107 => 0x4003 }, - 'videoshottype' => { 452 => 'VideoShotType' }, - 'videoshottypeidentifier' => { 452 => [\'VideoShotType','VideoShotTypeIdentifier'] }, - 'videoshottypename' => { 452 => [\'VideoShotType','VideoShotTypeName'] }, - 'videostreamscount' => { 452 => 'videoStreamsCount' }, - 'viewfinder' => { 341 => 0x455 }, - 'viewfinderdisplay' => { 257 => '12.4', 258 => '6.3' }, - 'viewfinderwarning' => { 257 => '13.4', 267 => '3.5', 268 => '6.2', 272 => '4.4' }, - 'viewfinderwarnings' => { 78 => 0x40a }, - 'viewinfoduringexposure' => { 78 => 0x407 }, - 'viewingmode' => { 378 => 0x2f, 393 => 0x18 }, - 'viewingmode2' => { 378 => [0x85,0x285] }, - 'viewpoint' => { 455 => 'viewpoint' }, - 'vignetteamount' => { 442 => 'VignetteAmount' }, - 'vignettecontrol' => { 211 => 0x2a, 250 => 0x76a43205 }, - 'vignettecontrolintensity' => { 250 => 0xac6bd5c0 }, - 'vignettecorrectionalreadyapplied' => { 438 => 'VignetteCorrectionAlreadyApplied' }, - 'vignettemidpoint' => { 442 => 'VignetteMidpoint' }, - 'vignetting' => { 358 => 0x1011, 365 => 0xa052 }, - 'vignettingcorrection' => { 113 => 0x7031, 365 => 0xa053, 388 => 0x2011 }, - 'vignettingcorrparams' => { 113 => 0x7032, 416 => 0x64a, 417 => [0x34a,0x350,0x35c,0x368] }, - 'vignettingsetting' => { 365 => 0xa054 }, - 'visualcolor' => { 452 => 'VisualColour' }, - 'visualtechnique' => { 455 => 'visualTechnique' }, - 'voicememo' => { 367 => 0x216 }, - 'volume' => { 456 => 'volume' }, - 'vr_0x66' => { 219 => 0x66 }, - 'vrdoffset' => { 60 => 0xd0 }, - 'vrmode' => { 241 => 0x6 }, - 'waterdepth' => { 113 => 0x9403, 447 => 'WaterDepth' }, - 'wb_bluelevel3500k' => { 177 => 0x19a }, - 'wb_bluelevel6500k' => { 177 => 0x18a }, - 'wb_bluelevelcustom' => { 177 => 0x18e }, - 'wb_bluelevelscloudy' => { 177 => 0x106 }, - 'wb_bluelevelsdaylight' => { 177 => 0xea }, - 'wb_bluelevelsflash' => { 177 => 0x122 }, - 'wb_bluelevelsfluorescent' => { 177 => [0x40a,0x15a] }, - 'wb_bluelevelskelvin' => { 177 => 0x254 }, - 'wb_bluelevelsshade' => { 177 => 0x176 }, - 'wb_bluelevelstungsten' => { 177 => 0xce }, - 'wb_gbrglevels' => { 177 => 0xae, 180 => 0x4 }, - 'wb_glevel' => { 278 => 0x11f }, - 'wb_glevel3000k' => { 278 => 0x113 }, - 'wb_glevel3300k' => { 278 => 0x114 }, - 'wb_glevel3600k' => { 278 => 0x115 }, - 'wb_glevel3900k' => { 278 => 0x116 }, - 'wb_glevel4000k' => { 278 => 0x117 }, - 'wb_glevel4300k' => { 278 => 0x118 }, - 'wb_glevel4500k' => { 278 => 0x119 }, - 'wb_glevel4800k' => { 278 => 0x11a }, - 'wb_glevel5300k' => { 278 => 0x11b }, - 'wb_glevel6000k' => { 278 => 0x11c }, - 'wb_glevel6600k' => { 278 => 0x11d }, - 'wb_glevel7500k' => { 278 => 0x11e }, - 'wb_grbglevels' => { 190 => 0x0 }, - 'wb_rbgglevels' => { 187 => 0x0 }, - 'wb_rblevels' => { 191 => 0x270, 211 => 0xc, 278 => 0x100 }, - 'wb_rblevels1' => { 303 => 0x2 }, - 'wb_rblevels2' => { 303 => 0x5 }, - 'wb_rblevels3' => { 303 => 0x8 }, - 'wb_rblevels3000k' => { 278 => 0x102 }, - 'wb_rblevels3300k' => { 278 => 0x103 }, - 'wb_rblevels3500k' => { 177 => 0x430 }, - 'wb_rblevels3600k' => { 278 => 0x104 }, - 'wb_rblevels3900k' => { 278 => 0x105 }, - 'wb_rblevels4' => { 303 => 0xb }, - 'wb_rblevels4000k' => { 278 => 0x106 }, - 'wb_rblevels4300k' => { 278 => 0x107 }, - 'wb_rblevels4500k' => { 278 => 0x108 }, - 'wb_rblevels4800k' => { 278 => 0x109 }, - 'wb_rblevels5' => { 303 => 0xe }, - 'wb_rblevels5300k' => { 278 => 0x10a }, - 'wb_rblevels6' => { 303 => 0x11 }, - 'wb_rblevels6000k' => { 278 => 0x10b }, - 'wb_rblevels6500k' => { 177 => 0x420 }, - 'wb_rblevels6600k' => { 278 => 0x10c }, - 'wb_rblevels7' => { 303 => 0x14 }, - 'wb_rblevels7500k' => { 278 => 0x10d }, - 'wb_rblevelsauto' => { 191 => 0x272, 282 => 0x110 }, - 'wb_rblevelscloudy' => { 177 => 0x3f0, 179 => 0x10, 191 => 0x296, 282 => 0x121 }, - 'wb_rblevelscoolwhitef' => { 177 => 0x308, 179 => 0x14 }, - 'wb_rblevelscoolwhitefluor' => { 282 => 0x132 }, - 'wb_rblevelscustom' => { 177 => 0x424 }, - 'wb_rblevelscwb1' => { 278 => 0x10e }, - 'wb_rblevelscwb2' => { 278 => 0x10f }, - 'wb_rblevelscwb3' => { 278 => 0x110 }, - 'wb_rblevelscwb4' => { 278 => 0x111 }, - 'wb_rblevelsdaylight' => { 177 => [0x3ec,0x528], 179 => 0xc, 191 => 0x274 }, - 'wb_rblevelsdaylightf' => { 179 => 0x24 }, - 'wb_rblevelsdaylightfluor' => { 282 => 0x130 }, - 'wb_rblevelsdaywhitef' => { 179 => 0x28 }, - 'wb_rblevelsdaywhitefluor' => { 282 => 0x131 }, - 'wb_rblevelseveningsunlight' => { 282 => 0x124 }, - 'wb_rblevelsfineweather' => { 282 => 0x122 }, - 'wb_rblevelsflash' => { 177 => [0x3f4,0x304], 179 => 0x18, 191 => 0x2a4 }, - 'wb_rblevelsfluorescent' => { 191 => 0x290 }, - 'wb_rblevelsincandescent' => { 191 => 0x282 }, - 'wb_rblevelsshade' => { 177 => 0x418, 179 => 0x20, 191 => 0x2b2, 282 => 0x120 }, - 'wb_rblevelstungsten' => { 177 => 0x3e8, 179 => 0x8, 282 => 0x123 }, - 'wb_rblevelsunknown' => { 179 => 0x1c }, - 'wb_rblevelsused' => { 282 => 0x100 }, - 'wb_rblevelswhitef' => { 179 => 0x2c }, - 'wb_rblevelswhitefluorescent' => { 282 => 0x133 }, - 'wb_redlevel3500k' => { 177 => 0x198 }, - 'wb_redlevel6500k' => { 177 => 0x188 }, - 'wb_redlevelcustom' => { 177 => 0x18c }, - 'wb_redlevelscloudy' => { 177 => 0xf8 }, - 'wb_redlevelsdaylight' => { 177 => 0xdc }, - 'wb_redlevelsflash' => { 177 => 0x114 }, - 'wb_redlevelsfluorescent' => { 177 => [0x3fc,0x14c] }, - 'wb_redlevelskelvin' => { 177 => 0x1be }, - 'wb_redlevelsshade' => { 177 => 0x168 }, - 'wb_redlevelstungsten' => { 177 => 0xc0 }, - 'wb_rgbglevels' => { 189 => 0x0 }, - 'wb_rgblevels' => { 177 => [0x546,0x96], 293 => 0xd, 294 => 0x413, 299 => 0x3036, 341 => 0x107, 396 => 0x117c, 397 => 0x1180, 398 => 0x115c, 399 => 0x11d8, 400 => 0x11b4, 401 => 0x106c, 402 => 0x264, 403 => 0x264, 404 => 0x252 }, - 'wb_rgblevels1' => { 304 => 0x2 }, - 'wb_rgblevels2' => { 304 => 0x6 }, - 'wb_rgblevels3' => { 304 => 0xa }, - 'wb_rgblevels4' => { 304 => 0xe }, - 'wb_rgblevels5' => { 304 => 0x12 }, - 'wb_rgblevels6' => { 304 => 0x16 }, - 'wb_rgblevels7' => { 304 => 0x1a }, - 'wb_rgbmuldaylight' => { 131 => 0x852 }, - 'wb_rgbmulflash' => { 131 => 0x855 }, - 'wb_rgbmulfluorescent' => { 131 => 0x854 }, - 'wb_rgbmultungsten' => { 131 => 0x853 }, - 'wb_rggbblacklevels' => { 34 => 0x25 }, - 'wb_rggblevels' => { 180 => 0x4, 188 => 0x0, 192 => 0x13e8, 193 => 0x38 }, - 'wb_rggblevelsasshot' => { 37 => 0x0, 38 => 0x0, 39 => 0x19, 40 => 0x22, 41 => 0x3f, 44 => 0x3f, 45 => 0x3f, 46 => 0x3f, 47 => 0x47 }, - 'wb_rggblevelsauto' => { 34 => 0x1, 37 => 0x5, 38 => 0x8, 39 => 0x1e, 40 => 0x18, 41 => 0x44, 44 => 0x44, 45 => 0x44, 46 => 0x44, 47 => 0x4c, 192 => 0x1478, 193 => 0x114, 365 => 0xa022 }, - 'wb_rggblevelsblack' => { 365 => 0xa028 }, - 'wb_rggblevelscloudy' => { 34 => 0xd, 37 => 0x1e, 38 => 0x30, 39 => 0x2d, 40 => 0x31, 41 => 0x58, 44 => 0x71, 45 => 0x8a, 46 => 0x8f, 47 => 0x92, 192 => 0x1408, 193 => 0x60, 332 => 0x20f, 340 => 0x14 }, - 'wb_rggblevelscustom' => { 34 => 0x1d, 41 => 0x80, 192 => 0x1468, 193 => 0x100 }, - 'wb_rggblevelscustom1' => { 39 => 0x41 }, - 'wb_rggblevelscustom2' => { 39 => 0x46 }, - 'wb_rggblevelsdaylight' => { 34 => 0x5, 37 => 0x14, 38 => 0x20, 39 => 0x23, 40 => 0x27, 41 => 0x4e, 44 => 0x67, 45 => 0x80, 46 => 0x85, 47 => 0x88, 192 => 0x13f8, 193 => 0x4c, 332 => 0x20d, 340 => 0x2 }, - 'wb_rggblevelsflash' => { 34 => 0x19, 37 => 0x32, 38 => 0x50, 39 => 0x3c, 40 => 0x45, 41 => 0x6c, 44 => 0x85, 45 => 0x9e, 46 => 0xa3, 47 => 0xa6, 192 => 0x1448, 332 => 0x214, 340 => 0x41 }, - 'wb_rggblevelsfluorescent' => { 34 => 0x15, 37 => 0x28, 38 => 0x40, 39 => 0x37, 40 => 0x3b, 41 => 0x62, 44 => 0x7b, 45 => 0x94, 46 => 0x99, 47 => 0x9c }, - 'wb_rggblevelsfluorescentd' => { 193 => 0xc4, 332 => 0x211, 340 => 0x26 }, - 'wb_rggblevelsfluorescentl' => { 340 => 0x4a }, - 'wb_rggblevelsfluorescentn' => { 193 => 0xb0, 332 => 0x212, 340 => 0x2f }, - 'wb_rggblevelsfluorescentw' => { 192 => 0x1438, 193 => 0x9c, 332 => 0x213, 340 => 0x38 }, - 'wb_rggblevelshtmercury' => { 193 => 0xd8 }, - 'wb_rggblevelsilluminator1' => { 365 => 0xa023 }, - 'wb_rggblevelsilluminator2' => { 365 => 0xa024 }, - 'wb_rggblevelskelvin' => { 34 => 0x21, 37 => 0x2d, 38 => 0x48, 40 => 0x40, 41 => 0x67, 44 => 0x80, 45 => 0x99, 46 => 0x9e, 47 => 0xa1 }, - 'wb_rggblevelsmeasured' => { 37 => 0xa, 38 => 0x10, 41 => 0x49, 44 => 0x49, 45 => 0x49, 46 => 0x49, 47 => 0x51 }, - 'wb_rggblevelspc1' => { 40 => 0x90, 41 => 0x71 }, - 'wb_rggblevelspc2' => { 40 => 0x95, 41 => 0x76 }, - 'wb_rggblevelspc3' => { 40 => 0x9a, 41 => 0x7b }, - 'wb_rggblevelsshade' => { 34 => 0x9, 37 => 0x19, 38 => 0x28, 39 => 0x28, 40 => 0x2c, 41 => 0x53, 44 => 0x6c, 45 => 0x85, 46 => 0x8a, 47 => 0x8d, 193 => 0x74, 332 => 0x20e, 340 => 0xb }, - 'wb_rggblevelstungsten' => { 34 => 0x11, 37 => 0x23, 38 => 0x38, 39 => 0x32, 40 => 0x36, 41 => 0x5d, 44 => 0x76, 45 => 0x8f, 46 => 0x94, 47 => 0x97, 192 => 0x1428, 193 => 0x88, 332 => 0x210, 340 => 0x1d }, - 'wb_rggblevelsuncorrected' => { 365 => 0xa021 }, - 'wb_rggblevelsunknown' => { 37 => 0xf, 38 => 0x18, 40 => 0x1d, 44 => 0x4e, 45 => 0x4e, 46 => 0x4e, 47 => 0x56, 340 => 0x53 }, - 'wb_rggblevelsunknown10' => { 37 => 0x5f, 38 => 0x98, 40 => 0x72, 44 => 0x9e, 45 => 0x7b, 46 => 0x7b, 47 => 0x83 }, - 'wb_rggblevelsunknown11' => { 37 => 0x64, 38 => 0xa0, 40 => 0x77, 44 => 0xa3, 45 => 0xa3, 46 => 0x80, 47 => 0xab }, - 'wb_rggblevelsunknown12' => { 37 => 0x69, 38 => 0xa8, 40 => 0x7c, 44 => 0xa8, 45 => 0xa8, 46 => 0xa8, 47 => 0xb0 }, - 'wb_rggblevelsunknown13' => { 37 => 0x6e, 38 => 0xb0, 40 => 0x81, 44 => 0xad, 45 => 0xad, 46 => 0xad, 47 => 0xb5 }, - 'wb_rggblevelsunknown14' => { 40 => 0x86, 44 => 0xb2, 45 => 0xb2, 46 => 0xb2, 47 => 0xba }, - 'wb_rggblevelsunknown15' => { 40 => 0x8b, 44 => 0xb7, 45 => 0xb7, 46 => 0xb7, 47 => 0xbf }, - 'wb_rggblevelsunknown16' => { 40 => 0x9f, 45 => 0xbc, 46 => 0xbc, 47 => 0xc4 }, - 'wb_rggblevelsunknown17' => { 45 => 0xc1, 46 => 0xc1, 47 => 0xc9 }, - 'wb_rggblevelsunknown18' => { 45 => 0xc6, 46 => 0xc6, 47 => 0xce }, - 'wb_rggblevelsunknown19' => { 45 => 0xcb, 46 => 0xcb, 47 => 0xd3 }, - 'wb_rggblevelsunknown2' => { 37 => 0x37, 38 => 0x58, 40 => 0x4a, 44 => 0x53, 45 => 0x53, 46 => 0x53, 47 => 0x5b }, - 'wb_rggblevelsunknown20' => { 45 => 0xd0, 46 => 0xd0, 47 => 0xd8 }, - 'wb_rggblevelsunknown21' => { 46 => 0xd5, 47 => 0xdd }, - 'wb_rggblevelsunknown22' => { 46 => 0xda, 47 => 0xe2 }, - 'wb_rggblevelsunknown23' => { 46 => 0xdf, 47 => 0xe7 }, - 'wb_rggblevelsunknown24' => { 46 => 0xe4, 47 => 0xec }, - 'wb_rggblevelsunknown25' => { 46 => 0xe9, 47 => 0xf1 }, - 'wb_rggblevelsunknown26' => { 46 => 0xee, 47 => 0xf6 }, - 'wb_rggblevelsunknown27' => { 46 => 0xf3, 47 => 0xfb }, - 'wb_rggblevelsunknown28' => { 46 => 0xf8, 47 => 0x100 }, - 'wb_rggblevelsunknown29' => { 46 => 0xfd, 47 => 0x105 }, - 'wb_rggblevelsunknown3' => { 37 => 0x3c, 38 => 0x60, 40 => 0x4f, 44 => 0x58, 45 => 0x58, 46 => 0x58, 47 => 0x60 }, - 'wb_rggblevelsunknown30' => { 46 => 0x102 }, - 'wb_rggblevelsunknown4' => { 37 => 0x41, 38 => 0x68, 40 => 0x54, 44 => 0x5d, 45 => 0x5d, 46 => 0x5d, 47 => 0x65 }, - 'wb_rggblevelsunknown5' => { 37 => 0x46, 38 => 0x70, 40 => 0x59, 44 => 0x62, 45 => 0x62, 46 => 0x62, 47 => 0x6a }, - 'wb_rggblevelsunknown6' => { 37 => 0x4b, 38 => 0x78, 40 => 0x5e, 44 => 0x8a, 45 => 0x67, 46 => 0x67, 47 => 0x6f }, - 'wb_rggblevelsunknown7' => { 37 => 0x50, 38 => 0x80, 40 => 0x63, 44 => 0x8f, 45 => 0x6c, 46 => 0x6c, 47 => 0x74 }, - 'wb_rggblevelsunknown8' => { 37 => 0x55, 38 => 0x88, 40 => 0x68, 44 => 0x94, 45 => 0x71, 46 => 0x71, 47 => 0x79 }, - 'wb_rggblevelsunknown9' => { 37 => 0x5a, 38 => 0x90, 40 => 0x6d, 44 => 0x99, 45 => 0x76, 46 => 0x76, 47 => 0x7e }, - 'wb_rggblevelsuserselected' => { 340 => 0x5c }, - 'wbadjblueamber' => { 97 => 0x20106 }, - 'wbadjbluebalance' => { 256 => 0x8 }, - 'wbadjcolortemp' => { 97 => 0x20102, 102 => 0x1a }, - 'wbadjlighting' => { 256 => 0x14 }, - 'wbadjmagentagreen' => { 97 => 0x20105 }, - 'wbadjmode' => { 256 => 0x10 }, - 'wbadjredbalance' => { 256 => 0x0 }, - 'wbadjrggblevels' => { 97 => 0x20125, 102 => 0x6 }, - 'wbadjtemperature' => { 256 => 0x18 }, - 'wbadjtint' => { 256 => 0x25 }, - 'wbbluelevel' => { 292 => 0x324, 297 => 0x8006, 302 => 0x26 }, - 'wbbracketingsteps' => { 228 => 0x174d, 229 => 0x87c, 237 => 0x1757 }, - 'wbbracketmode' => { 54 => 0x9 }, - 'wbbracketshotnumber' => { 177 => 0x2b, 358 => 0x101a }, - 'wbbracketvalueab' => { 54 => 0xc }, - 'wbbracketvaluegm' => { 54 => 0xd }, - 'wbfinetuneactive' => { 102 => 0x24 }, - 'wbfinetunesaturation' => { 102 => 0x28 }, - 'wbfinetunetone' => { 102 => 0x2c }, - 'wbgreenlevel' => { 292 => 0x323, 297 => 0x8005, 302 => 0x25 }, - 'wbmediaimagesizesetting' => { 78 => 0x708 }, - 'wbmode' => { 179 => 0x4, 279 => 0x1015 }, - 'wbredlevel' => { 292 => 0x322, 297 => 0x8004, 302 => 0x24 }, - 'wbscale' => { 180 => 0x0 }, - 'wbshiftab' => { 70 => 0xc, 297 => 0x46, 314 => 0x10 }, - 'wbshiftab_gm' => { 388 => 0x2014 }, - 'wbshiftab_gm_precise' => { 388 => 0x2026 }, - 'wbshiftcreativecontrol' => { 297 => 0x92 }, - 'wbshiftgm' => { 70 => 0xd, 297 => 0x47, 314 => 0x11 }, - 'wbshiftintelligentauto' => { 297 => 0x8b }, - 'wbtype1' => { 303 => 0x1, 304 => 0x1 }, - 'wbtype2' => { 303 => 0x4, 304 => 0x5 }, - 'wbtype3' => { 303 => 0x7, 304 => 0x9 }, - 'wbtype4' => { 303 => 0xa, 304 => 0xd }, - 'wbtype5' => { 303 => 0xd, 304 => 0x11 }, - 'wbtype6' => { 303 => 0x10, 304 => 0x15 }, - 'wbtype7' => { 303 => 0x13, 304 => 0x19 }, - 'webstatement' => { 470 => 'WebStatement' }, - 'what' => { 442 => 'What' }, - 'whitebalance' => { 6 => 0x6f, 7 => [0x44,0x4a], 8 => 0xbc, 9 => 0x36, 10 => 0x5e, 11 => 0x36, 12 => 0x78, 13 => 0x6f, 14 => 0x6f, 15 => 0x73, 16 => 0x6f, 17 => 0x78, 18 => 0x54, 19 => 0x6f, 20 => 0xbc, 21 => 0x7b, 23 => 0xbc, 24 => 0xc2, 26 => 0x131, 27 => 0x77, 70 => 0x8, 72 => 0x7, 106 => 0x7, 107 => [0x19,0x2012], 113 => [0xa403,0xfe4e], 121 => 0x1002, 131 => 0x3fc, 132 => 0xfa0d, 133 => 0x40, 171 => 0x3, 172 => 0xe, 173 => 0x4, 174 => 0xb, 176 => 0x115, 211 => 0x5, 240 => 0x7, 292 => 0x304, 297 => 0x3, 299 => 0x3033, 332 => 0x19, 339 => 0x7, 357 => 0x26, 358 => 0x1003, 368 => [0x3c,0x7,0x58], 376 => 0xf, 377 => 0xe, 388 => [0x115,0xb054], 442 => 'WhiteBalance', 446 => 'WhiteBalance' }, - 'whitebalance0' => { 167 => 'WhiteBalance0' }, - 'whitebalance1' => { 167 => 'WhiteBalance1' }, - 'whitebalance2' => { 167 => 'WhiteBalance2', 274 => 0x500 }, - 'whitebalanceadj' => { 97 => 0x20101, 102 => 0x18, 250 => 0x76a43204 }, - 'whitebalanceautoadjustment' => { 310 => 0x0 }, - 'whitebalancebias' => { 107 => 0x2011, 279 => 0x304, 297 => 0x23 }, - 'whitebalanceblue' => { 70 => 0x7 }, - 'whitebalancebracket' => { 274 => 0x502, 279 => 0x303 }, - 'whitebalancebracketing' => { 174 => 0x22, 177 => 0x2c, 387 => 0x2c }, - 'whitebalancecomp' => { 282 => 0x1001 }, - 'whitebalancedetected' => { 131 => 0x3fb }, - 'whitebalancefinetune' => { 121 => 0x100a, 174 => 0x38, 176 => 0x112, 211 => 0xb, 358 => 0x1004, 376 => 0x6, 377 => 0x5, 388 => 0x112 }, - 'whitebalancemode' => { 131 => 0x3fa, 332 => 0x1a }, - 'whitebalancered' => { 70 => 0x6 }, - 'whitebalanceset' => { 313 => 0xa }, - 'whitebalancesetting' => { 174 => 0x23, 376 => 0x5, 377 => 0x4, 378 => 0x16, 393 => 0xd }, - 'whitebalancesetup' => { 365 => 0x41 }, - 'whitebalancetemperature' => { 274 => 0x501 }, - 'whiteboard' => { 279 => 0x301 }, - 'whitelevel' => { 113 => 0xc61d, 332 => 0x7e }, - 'whitepoint' => { 113 => 0x13e, 332 => 0x201, 462 => 'WhitePoint' }, - 'whites2012' => { 442 => 'Whites2012' }, - 'whitesadj' => { 421 => 0x9017 }, - 'wideadapter' => { 358 => 0x1017 }, - 'widefocuszone' => { 171 => 0x2f }, - 'widerange' => { 367 => 0x20f }, - 'windmode' => { 131 => 0x3f4 }, - 'windowsatom' => { 441 => 'windowsAtom' }, - 'windowsatomextension' => { 441 => [\'windowsAtom','windowsAtomExtension'] }, - 'windowsatominvocationflags' => { 441 => [\'windowsAtom','windowsAtomInvocationFlags'] }, - 'windowsatomuncprojectpath' => { 441 => [\'windowsAtom','windowsAtomUncProjectPath'] }, - 'wordcount' => { 456 => 'wordCount' }, - 'workcolorspace' => { 97 => 0x10200, 102 => 0x270 }, - 'workflowtag' => { 452 => 'WorkflowTag' }, - 'workflowtagcvid' => { 452 => [\'WorkflowTag','WorkflowTagCvId'] }, - 'workflowtagcvtermid' => { 452 => [\'WorkflowTag','WorkflowTagCvTermId'] }, - 'workflowtagcvtermname' => { 452 => [\'WorkflowTag','WorkflowTagCvTermName'] }, - 'workflowtagcvtermrefinedabout' => { 452 => [\'WorkflowTag','WorkflowTagCvTermRefinedAbout'] }, - 'worktodo' => { 448 => 'WorkToDo' }, - 'worldtimelocation' => { 297 => 0x3a, 332 => 0x22, 338 => '0.1' }, - 'writer-editor' => { 125 => 0x7a }, - 'x3filllight' => { 368 => 0x12 }, - 'xattrquarantine' => { 165 => 'com.apple.quarantine' }, - 'xilinxversion' => { 131 => 0x414 }, - 'xml' => { 129 => 'xml ' }, - 'xmp' => { 100 => 0xffff00f6, 114 => 'XMP' }, - 'xmptoolkit' => { 463 => 'xmptk' }, - 'xpauthor' => { 113 => 0x9c9d }, - 'xpcomment' => { 113 => 0x9c9c }, - 'xpkeywords' => { 113 => 0x9c9e }, - 'xposition' => { 113 => 0x11e }, - 'xpsubject' => { 113 => 0x9c9f }, - 'xptitle' => { 113 => 0x9c9b }, - 'xresolution' => { 113 => 0x11a, 128 => 0x3, 347 => 0x0, 462 => 'XResolution' }, - 'xyresolution' => { 117 => 0x3 }, - 'yaw' => { 109 => 0x7 }, - 'yawangle' => { 228 => 0x3513, 229 => 0x2c2c, 237 => 0x36fc, 363 => 0x0 }, - 'ycbcrcoefficients' => { 113 => 0x211, 462 => 'YCbCrCoefficients' }, - 'ycbcrpositioning' => { 113 => 0x213, 462 => 'YCbCrPositioning' }, - 'ycbcrsubsampling' => { 113 => 0x212, 462 => 'YCbCrSubSampling' }, - 'yearcreated' => { 133 => 0x10, 142 => 0xc }, - 'yellowhsl' => { 97 => 0x20912 }, - 'yield' => { 458 => 'yield' }, - 'yposition' => { 113 => 0x11f }, - 'yresolution' => { 113 => 0x11b, 128 => 0x5, 347 => 0x4, 462 => 'YResolution' }, - 'zonematching' => { 176 => 0x10a, 179 => [0x3a,0x4a], 388 => 0xb024 }, - 'zonematchingmode' => { 174 => 0x14 }, - 'zonematchingon' => { 173 => 0x75 }, - 'zonematchingvalue' => { 376 => 0x1f }, - 'zoomedpreviewlength' => { 279 => 0xf05 }, - 'zoomedpreviewsize' => { 279 => 0xf06 }, - 'zoomedpreviewstart' => { 279 => 0xf04 }, - 'zoomsourcewidth' => { 33 => 0x24 }, - 'zoomstepcount' => { 277 => 0x300, 279 => 0x100d }, - 'zoomtargetwidth' => { 33 => 0x25 }, + 'selectafareaselectmode' => { 81 => 0x512 }, + 'selfdata' => { 113 => 'SelfData' }, + 'selftimer' => { 34 => 0x2, 306 => 0x2e, 382 => 0x214, 414 => 0x1134, 415 => 0x1134, 416 => 0x1110, 417 => 0x118c, 418 => 0x1168, 419 => 0x1020, 420 => 0x218, 421 => 0x218, 422 => 0x210 }, + 'selftimer2' => { 74 => 0x1d }, + 'selftimerinterval' => { 276 => '19.2' }, + 'selftimermode' => { 116 => 0x882b }, + 'selftimershotcount' => { 267 => '20.2', 269 => '20.3', 270 => '20.3', 271 => '18.2', 272 => '19.2', 273 => '19.2', 274 => '19.3', 276 => '19.3', 279 => '20.3', 280 => '20.3', 281 => '20.2' }, + 'selftimershotinterval' => { 267 => '20.3', 269 => '20.2', 270 => '20.2', 274 => '19.2', 279 => '20.2', 280 => '20.2' }, + 'selftimertime' => { 94 => 0x1806, 179 => 0x1f, 266 => '18.1', 267 => '20.1', 268 => '3.3', 269 => '20.1', 270 => '20.1', 271 => '18.1', 272 => '19.1', 273 => '19.1', 274 => '19.1', 275 => '7.2', 276 => '19.1', 277 => '3.3', 279 => '20.1', 280 => '20.1', 281 => '20.1' }, + 'sellingagency' => { 478 => 'sellingAgency' }, + 'seminfo' => { 116 => 0x8546 }, + 'sensingmethod' => { 116 => 0xa217, 468 => 'SensingMethod' }, + 'sensitivityadjust' => { 341 => 0x40 }, + 'sensitivitysteps' => { 322 => ['14.3','17.4'], 324 => 0x1 }, + 'sensitivitytype' => { 116 => 0x8830, 469 => 'SensitivityType' }, + 'sensor' => { 186 => 0x665e }, + 'sensorarea' => { 288 => 0x400 }, + 'sensorareas' => { 380 => 0xa010 }, + 'sensorbitdepth' => { 308 => 0x312d }, + 'sensorbluelevel' => { 71 => 0x5 }, + 'sensorcalibration' => { 287 => 0x805 }, + 'sensorcleaning' => { 87 => 0xd }, + 'sensorfullheight' => { 133 => 0xf904 }, + 'sensorfullwidth' => { 133 => 0xf903 }, + 'sensorheight' => { 133 => 0xf901, 138 => 0xfa21, 183 => 0x8, 308 => 0x312c, 350 => 0x109, 373 => 0x1602 }, + 'sensorimageheight' => { 134 => 0x3ee }, + 'sensorimagewidth' => { 134 => 0x3ed }, + 'sensorleftborder' => { 134 => 0x3eb }, + 'sensorleftmargin' => { 350 => 0x10a }, + 'sensorpixelsize' => { 219 => 0x9a }, + 'sensorredlevel' => { 71 => 0x4 }, + 'sensorserialnumber' => { 134 => 0x9ce }, + 'sensorsize' => { 152 => 'SensorSize', 341 => 0x35 }, + 'sensortemperature' => { 286 => 0x1500, 288 => 0x1007, 346 => 0xc, 350 => 0x210, 383 => [0x39,0x55] }, + 'sensortemperature2' => { 346 => 0xe, 350 => 0x211 }, + 'sensortopborder' => { 134 => 0x3ec }, + 'sensortopmargin' => { 350 => 0x10b }, + 'sensorwidth' => { 133 => 0xf900, 138 => 0xfa20, 183 => 0xa, 308 => 0x312b, 350 => 0x108, 373 => 0x1601 }, + 'sequence' => { 367 => 0x7, 368 => 0x35, 369 => 0x36 }, + 'sequencefilenumber' => { 415 => 0x4, 416 => 0x4, 417 => 0x4, 418 => 0x4, 426 => 0xc, 427 => 0xc, 428 => 0x1a }, + 'sequenceimagenumber' => { 415 => 0x0, 416 => 0x0, 417 => 0x0, 418 => 0x0, 426 => 0x8, 427 => 0x8, 428 => 0x12, 435 => 0x24 }, + 'sequencelength' => { 426 => 0x22, 427 => 0x1e, 428 => [0x16,0x1e] }, + 'sequencename' => { 477 => 'sequenceName' }, + 'sequencenumber' => { 74 => 0x9, 110 => 0x301c, 124 => 0x1101, 136 => 0x1d, 245 => 0x51c, 306 => 0x2b, 395 => [0x10c,0x30c], 406 => 0xb04a, 477 => 'sequenceNumber' }, + 'sequenceshotinterval' => { 382 => 0x224 }, + 'sequencetotalnumber' => { 477 => 'sequenceTotalNumber' }, + 'sequentialshot' => { 382 => 0x20e }, + 'serialnumber' => { 61 => 0xc, 94 => 0x180b, 116 => [0xa431,0xfde9], 133 => 0xfa04, 135 => 0xfa00, 137 => 0xc354, 138 => 0xfa19, 149 => 0x0, 152 => 'SerialNumber', 186 => 0x5501, 219 => [0xa0,0x1d], 284 => 0x101, 288 => [0x404,0x101a], 301 => 0x303, 303 => 0x305, 308 => 0x3103, 341 => 0x229, 350 => 0x102, 351 => 0x407, 366 => ['SNum','slno'], 367 => 0x15, 368 => 0x4b, 369 => 0x7e, 373 => 0x5, 380 => 0xa002, 383 => 0x2, 406 => 0x2031, 459 => 'SerialNumber', 469 => 'BodySerialNumber' }, + 'serialnumberformat' => { 61 => 0x15, 94 => 0x183b }, + 'serialnumberhash' => { 366 => 'CAME' }, + 'series' => { 474 => 'Series' }, + 'seriesdatetime' => { 441 => 'SeriesDateTime' }, + 'seriesdescription' => { 441 => 'SeriesDescription' }, + 'seriesidentifier' => { 474 => [\'Series','SeriesIdentifier'] }, + 'seriesmodality' => { 441 => 'SeriesModality' }, + 'seriesname' => { 474 => [\'Series','SeriesName'] }, + 'seriesnumber' => { 441 => 'SeriesNumber', 478 => 'seriesNumber' }, + 'seriestitle' => { 478 => 'seriesTitle' }, + 'serviceidentifier' => { 129 => 0x1e }, + 'servingsize' => { 480 => 'servingSize' }, + 'setbuttoncrosskeysfunc' => { 84 => 0x0, 85 => 0x0 }, + 'setbuttonwhenshooting' => { 79 => 0x1, 81 => 0x704, 87 => 0xc }, + 'setfunctionwhenshooting' => { 82 => 0x0, 83 => 0x1, 86 => 0x1 }, + 'setting' => { 477 => 'setting' }, + 'shadingcompensation' => { 283 => 0x50c, 306 => 0x8a }, + 'shadingcompensation2' => { 287 => 0x1012 }, + 'shadow' => { 383 => 0xe }, + 'shadowadj' => { 100 => 0x2030b }, + 'shadowcorrection' => { 341 => 0x79 }, + 'shadowprotection' => { 258 => 0x0 }, + 'shadows' => { 116 => 0xfe52, 456 => 'Shadows', 462 => 'Shadows', 464 => 'Shadows' }, + 'shadows2012' => { 462 => 'Shadows2012', 464 => 'Shadows2012' }, + 'shadowsadj' => { 439 => 0x901a }, + 'shadowscale' => { 116 => 0xc633 }, + 'shadowtint' => { 462 => 'ShadowTint', 464 => 'ShadowTint' }, + 'shadowtone' => { 124 => 0x1040 }, + 'shakereduction' => { 343 => 0x1, 344 => 0x1 }, + 'sharpendetail' => { 462 => 'SharpenDetail', 464 => 'SharpenDetail' }, + 'sharpenedgemasking' => { 462 => 'SharpenEdgeMasking', 464 => 'SharpenEdgeMasking' }, + 'sharpening' => { 308 => 0x300b }, + 'sharpeningadj' => { 262 => 0x2b }, + 'sharpeningkernel' => { 134 => 0x92f }, + 'sharpenradius' => { 462 => 'SharpenRadius', 464 => 'SharpenRadius' }, + 'sharpness' => { 8 => [0x42,0x48], 10 => 0x72, 12 => 0x74, 34 => 0xf, 71 => 0x2, 109 => 0xb, 110 => [0x3011,0x21], 116 => [0xa40a,0xfe56], 124 => 0x1001, 136 => 0x6b, 145 => 0x37, 152 => 'Sharpness', 176 => 0x21, 177 => 0x30, 178 => 0x26, 179 => 0x18, 184 => 0x3, 219 => 0x6, 221 => 0x32, 222 => 0x33, 223 => 0x39, 288 => 0x100f, 306 => 0x41, 341 => 0x21, 348 => 0xb, 367 => 0x26, 369 => 0x56, 372 => 0x22, 373 => [0x1003,0x1014], 383 => 0x11, 393 => 0x1c, 394 => 0x19, 406 => 0x2006, 435 => 0x52, 462 => 'Sharpness', 464 => 'Sharpness', 468 => 'Sharpness' }, + 'sharpnessadj' => { 100 => 0x20310, 105 => 0x25a, 439 => 0x801a }, + 'sharpnessadjon' => { 100 => '0x20310.0' }, + 'sharpnessauto' => { 68 => 0x94 }, + 'sharpnessfactor' => { 288 => 0x102a }, + 'sharpnessfaithful' => { 19 => 0xf5, 67 => 0x64, 68 => 0x64 }, + 'sharpnessfrequency' => { 8 => [0x41,0x47], 71 => 0x3 }, + 'sharpnesslandscape' => { 19 => 0xf3, 67 => 0x34, 68 => 0x34 }, + 'sharpnessmonochrome' => { 19 => 0xf6, 67 => 0x7c, 68 => 0x7c }, + 'sharpnessneutral' => { 19 => 0xf4, 67 => 0x4c, 68 => 0x4c }, + 'sharpnessovershoot' => { 439 => 0x801b }, + 'sharpnessportrait' => { 19 => 0xf2, 67 => 0x1c, 68 => 0x1c }, + 'sharpnesssetting' => { 283 => 0x506, 291 => 0x1013, 395 => 0x12, 411 => 0xa }, + 'sharpnessstandard' => { 19 => 0xf1, 67 => 0x4, 68 => 0x4 }, + 'sharpnessstrength' => { 100 => 0x20311 }, + 'sharpnessthreshold' => { 439 => 0x801d }, + 'sharpnessundershoot' => { 439 => 0x801c }, + 'sharpnessuserdef1' => { 19 => 0xf7, 67 => 0x94, 68 => 0xac }, + 'sharpnessuserdef2' => { 19 => 0xf8, 67 => 0xac, 68 => 0xc4 }, + 'sharpnessuserdef3' => { 19 => 0xf9, 67 => 0xc4, 68 => 0xdc }, + 'shiftcols' => { 134 => 0xc70 }, + 'shootid' => { 477 => 'shootID' }, + 'shootingdistance' => { 100 => 0x20701 }, + 'shootinginfodisplay' => { 266 => '13.2', 267 => '5.1', 275 => '10.2', 276 => '4.1', 279 => '5.1', 281 => '5.3' }, + 'shootinginfomonitorofftime' => { 266 => '26.2', 267 => '22.2', 269 => '22.2', 270 => '22.2', 274 => '21.2', 275 => '9.1', 276 => '21.2', 279 => '22.2', 280 => '22.2', 281 => '22.2' }, + 'shootingmode' => { 152 => 'ShootingMode', 219 => 0x89, 306 => 0x1f }, + 'shootingmodesetting' => { 268 => '5.1' }, + 'shortdescription' => { 466 => 'shortdescription' }, + 'shortdocumentid' => { 128 => 0xba }, + 'shortownername' => { 19 => 0xac }, + 'shortreleasetimelag' => { 81 => 0x80d }, + 'shorttitle' => { 358 => '@sti' }, + 'shotdate' => { 488 => 'shotDate' }, + 'shotday' => { 488 => 'shotDay' }, + 'shotlocation' => { 488 => 'shotLocation' }, + 'shotname' => { 366 => 'shot', 488 => 'shotName' }, + 'shotnumber' => { 488 => 'shotNumber' }, + 'shotnumbersincepowerup' => { 410 => 0x44e, 426 => 0x1a, 427 => 0x16, 428 => 0xa }, + 'shotnumbersincepowerup2' => { 395 => 0x200 }, + 'shotsize' => { 488 => 'shotSize' }, + 'shownevent' => { 474 => 'EventExt' }, + 'showneventidentifier' => { 474 => [\'EventExt','EventExtIdentifier'] }, + 'showneventname' => { 474 => [\'EventExt','EventExtName'] }, + 'shutter' => { 424 => 0x20, 425 => 0x26 }, + 'shutter-aelock' => { 79 => 0x4, 81 => 0x701, 82 => 0x3, 83 => 0x4, 84 => 0x3, 85 => 0x3, 86 => 0x4, 87 => 0x2 }, + 'shutteraelbutton' => { 80 => 0x4 }, + 'shutterbuttonafonbutton' => { 81 => 0x701 }, + 'shuttercount' => { 11 => 0x176, 55 => 0x1, 219 => 0xa7, 228 => [0x6a,0x157,0x24d], 229 => 0x286, 230 => 0x279, 231 => 0x284, 232 => 0x242, 233 => 0x280, 234 => 0x276, 235 => [0x27d,0x27f], 236 => 0x246, 239 => 0x2d6, 240 => 0x321, 241 => 0xbd8, 242 => 0x287, 243 => 0x320, 244 => 0x24a, 245 => 0x5fb, 248 => 0x2d5, 341 => 0x5d, 404 => 0x846, 409 => [0x125,0x14a], 424 => 0x32, 425 => 0x3a }, + 'shuttercount2' => { 424 => 0x4c, 425 => [0x50,0x52,0x58] }, + 'shuttercount3' => { 424 => [0x1a0,0x1aa,0x1bd], 425 => [0x19f,0x1cb,0x1cd] }, + 'shuttercurtainsync' => { 79 => 0xf, 80 => 0xf, 81 => 0x305, 82 => 0xe, 83 => 0xf, 84 => 0x8, 85 => 0x8, 86 => 0xf, 87 => 0x8 }, + 'shuttermode' => { 136 => 0x1b, 219 => 0x34 }, + 'shutterreleasebuttonae-l' => { 266 => '17.7', 267 => '18.4', 269 => '78.4', 270 => '78.4', 271 => '16.1', 272 => '17.1', 273 => '17.1', 274 => '17.1', 275 => '7.1', 276 => '17.5', 279 => '18.4', 280 => '78.4', 281 => '18.2' }, + 'shutterreleasemethod' => { 94 => 0x1010 }, + 'shutterreleasenocfcard' => { 79 => 0x2, 80 => 0x2, 87 => 0xf }, + 'shutterreleasetiming' => { 94 => 0x1011 }, + 'shutterreleasewithoutlens' => { 81 => 0x711 }, + 'shutterspeedlock' => { 267 => '38.1', 269 => '38.1', 270 => '38.1', 279 => '38.1', 280 => '38.1' }, + 'shutterspeedrange' => { 81 => 0x10c }, + 'shutterspeedsetting' => { 179 => 0x6, 393 => 0x2f, 394 => 0x28, 395 => 0x0 }, + 'shutterspeedvalue' => { 90 => 0x1, 116 => 0x9201, 288 => 0x1000, 350 => 0x400, 468 => 'ShutterSpeedValue' }, + 'shuttertype' => { 124 => 0x1050, 306 => 0x9f }, + 'sidecarforextension' => { 476 => 'SidecarForExtension' }, + 'sigmaimpulseparameters' => { 134 => 0xe0d }, + 'sigmascalingfactorcamera' => { 134 => 0xe0c }, + 'sigmascalingfactorlowres' => { 134 => 0xe0b }, + 'sigmasizetable' => { 134 => 0xe0f }, + 'similarityindex' => { 128 => 0xe4 }, + 'singleframebracketing' => { 179 => 0x21 }, + 'skilllevel' => { 480 => 'skillLevel' }, + 'skintonecorrection' => { 341 => 0x95 }, + 'skiplinetime' => { 134 => 0x184e }, + 'slaveflashmeteringsegments' => { 341 => 0x20b }, + 'slideshowname' => { 477 => 'slideshowName' }, + 'slideshownumber' => { 477 => 'slideshowNumber' }, + 'slideshowtotalnumber' => { 477 => 'slideshowTotalNumber' }, + 'slowshutter' => { 74 => 0x8 }, + 'slowsync' => { 124 => 0x1030 }, + 'smartalbumcolor' => { 380 => 0x20 }, + 'smartrange' => { 380 => 0xa012 }, + 'smileshutter' => { 395 => 0x31 }, + 'smileshuttermode' => { 395 => 0x27 }, + 'smoothness' => { 116 => 0xfe57, 462 => 'Smoothness', 464 => 'Smoothness' }, + 'snapshot' => { 474 => 'SnapshotLink' }, + 'snapshotformat' => { 474 => [\'SnapshotLink','SnapshotLinkFormat'] }, + 'snapshotheightpixels' => { 474 => [\'SnapshotLink','SnapshotLinkHeightPixels'] }, + 'snapshotimagerole' => { 474 => [\'SnapshotLink','SnapshotLinkImageRole'] }, + 'snapshotlink' => { 474 => [\'SnapshotLink','SnapshotLinkLink'] }, + 'snapshotlinkqualifier' => { 474 => [\'SnapshotLink','SnapshotLinkLinkQualifier'] }, + 'snapshots' => { 457 => 'Snapshots' }, + 'snapshotusedvideoframe' => { 474 => [\'SnapshotLink','SnapshotLinkUsedVideoFrame'] }, + 'snapshotusedvideoframetimeformat' => { 474 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameTimeFormat'] }, + 'snapshotusedvideoframetimevalue' => { 474 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameTimeValue'] }, + 'snapshotusedvideoframevalue' => { 474 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameValue'] }, + 'snapshotwidthpixels' => { 474 => [\'SnapshotLink','SnapshotLinkWidthPixels'] }, + 'softskineffect' => { 406 => 0x200f }, + 'software' => { 116 => 0x131, 153 => 'Software', 296 => 'Software', 350 => 0x203, 360 => 'software', 383 => 0x18, 447 => 'Software', 484 => 'Software' }, + 'softwareversion' => { 366 => "\xa9swr", 382 => 0x207 }, + 'songwriter' => { 366 => "\xa9swf" }, + 'songwriterkeywords' => { 366 => "\xa9swk" }, + 'sonycropsize' => { 116 => 0x74c8 }, + 'sonycroptopleft' => { 116 => 0x74c7 }, + 'sonydatetime' => { 413 => 0x6, 415 => 0x1b6, 416 => 0x210, 417 => 0x1fe, 418 => 0x22c }, + 'sonydatetime2' => { 424 => 0x51 }, + 'sonyexposuretime' => { 424 => 0x3a, 425 => 0x46 }, + 'sonyexposuretime2' => { 435 => 0xe }, + 'sonyfnumber' => { 424 => 0x3c, 425 => 0x48, 435 => 0x14 }, + 'sonyimageheight' => { 413 => 0x1a, 426 => 0x44, 427 => 0x3f, 428 => 0x47 }, + 'sonyimageheightmax' => { 435 => 0x40 }, + 'sonyimagesize' => { 179 => 0x3b, 393 => 0x54, 394 => 0x54, 395 => 0x9 }, + 'sonyimagewidth' => { 413 => 0x1c }, + 'sonyimagewidthmax' => { 435 => 0x3e }, + 'sonyiso' => { 415 => 0x1218, 416 => 0x11f4, 417 => 0x1270, 418 => [0x1254,0x1258,0x1280], 419 => 0x113c, 420 => 0x344, 421 => 0x346, 422 => 0x320, 435 => 0x4 }, + 'sonymaxaperture' => { 424 => 0x0, 425 => 0x0 }, + 'sonymaxaperturevalue' => { 435 => 0x16 }, + 'sonyminaperture' => { 424 => 0x1, 425 => 0x1 }, + 'sonymodelid' => { 406 => 0xb001 }, + 'sonyquality' => { 179 => 0x3c }, + 'sonytimeminsec' => { 425 => 0x61 }, + 'sortalbum' => { 358 => 'soal' }, + 'sortalbumartist' => { 358 => 'soaa' }, + 'sortartist' => { 358 => 'soar' }, + 'sortcomposer' => { 358 => 'soco' }, + 'sortname' => { 358 => 'sonm' }, + 'sortshow' => { 358 => 'sosn' }, + 'source' => { 128 => 0x73, 296 => 'Source', 465 => 'source', 466 => 'source', 476 => 'Source' }, + 'sourcecount' => { 451 => 'SourceCount' }, + 'sourcecredits' => { 366 => "\xa9src" }, + 'sourcedirectoryindex' => { 328 => 0x0 }, + 'sourcefileindex' => { 328 => 0x2 }, + 'sourcephotoscount' => { 450 => 'SourcePhotosCount' }, + 'sourceprofileprefix' => { 134 => 0x1390 }, + 'spatialfrequencyresponse' => { 468 => 'SpatialFrequencyResponse' }, + 'spatialfrequencyresponsecolumns' => { 468 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseColumns'] }, + 'spatialfrequencyresponsenames' => { 468 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseNames'] }, + 'spatialfrequencyresponserows' => { 468 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseRows'] }, + 'spatialfrequencyresponsevalues' => { 468 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseValues'] }, + 'speakerplacement' => { 488 => 'speakerPlacement' }, + 'specialeffectlevel' => { 110 => 0x3030 }, + 'specialeffectmode' => { 110 => 0x2076 }, + 'specialeffectsetting' => { 110 => 0x3031 }, + 'specialinstructions' => { 128 => 0x28 }, + 'specialmode' => { 288 => 0x200, 382 => 0x200 }, + 'specialoccasion' => { 480 => 'specialOccasion' }, + 'specialtypeid' => { 445 => 'SpecialTypeID' }, + 'spectralsensitivity' => { 116 => 0x8824, 468 => 'SpectralSensitivity' }, + 'specularwhitelevel' => { 43 => [0x2b9,0x2d0,0x2d4], 44 => 0x56a, 45 => 0x1e4, 46 => [0x1fd,0x2dd], 47 => [0x231,0x30f], 48 => 0x31d }, + 'speedx' => { 112 => 0x3, 366 => "\xa9xsp" }, + 'speedy' => { 112 => 0x4, 366 => "\xa9ysp" }, + 'speedz' => { 112 => 0x5, 366 => "\xa9zsp" }, + 'spherical' => { 451 => 'Spherical' }, + 'splitcolumn' => { 350 => 0x222 }, + 'splittoningbalance' => { 462 => 'SplitToningBalance', 464 => 'SplitToningBalance' }, + 'splittoninghighlighthue' => { 462 => 'SplitToningHighlightHue', 464 => 'SplitToningHighlightHue' }, + 'splittoninghighlightsaturation' => { 462 => 'SplitToningHighlightSaturation', 464 => 'SplitToningHighlightSaturation' }, + 'splittoningshadowhue' => { 462 => 'SplitToningShadowHue', 464 => 'SplitToningShadowHue' }, + 'splittoningshadowsaturation' => { 462 => 'SplitToningShadowSaturation', 464 => 'SplitToningShadowSaturation' }, + 'sport' => { 478 => 'sport' }, + 'spotfocuspointx' => { 176 => 0x2d }, + 'spotfocuspointy' => { 176 => 0x2e }, + 'spotmeteringmode' => { 34 => 0x27 }, + 'spotmeterlinktoafpoint' => { 81 => 0x107 }, + 'sractive' => { 322 => '17.1' }, + 'srawquality' => { 34 => 0x2e }, + 'srfocallength' => { 343 => 0x3 }, + 'srhalfpresstime' => { 343 => 0x2 }, + 'srresult' => { 343 => 0x0, 344 => 0x0 }, + 'stackedimage' => { 283 => 0x804 }, + 'standardmatrixcustom' => { 134 => 0x7d4 }, + 'standardmatrixdaylight' => { 134 => 0x7d0 }, + 'standardmatrixflash' => { 134 => 0x7d3 }, + 'standardmatrixfluorescent' => { 134 => 0x7d2 }, + 'standardmatrixtungsten' => { 134 => 0x7d1 }, + 'standardoutputhighlightpoint' => { 106 => 0x14 }, + 'standardoutputsensitivity' => { 116 => 0x8831, 469 => 'StandardOutputSensitivity' }, + 'standardoutputshadowpoint' => { 106 => 0x15 }, + 'standardrawcolortone' => { 106 => 0xd }, + 'standardrawcontrast' => { 106 => 0xf }, + 'standardrawhighlight' => { 106 => 0x75 }, + 'standardrawhighlightpoint' => { 106 => 0x12 }, + 'standardrawlinear' => { 106 => 0x10 }, + 'standardrawsaturation' => { 106 => 0xe }, + 'standardrawshadow' => { 106 => 0x7e }, + 'standardrawshadowpoint' => { 106 => 0x13 }, + 'standardrawsharpness' => { 106 => 0x11 }, + 'standardunsharpmaskfineness' => { 106 => 0x94 }, + 'standardunsharpmaskstrength' => { 106 => 0x92 }, + 'standardunsharpmaskthreshold' => { 106 => 0x96 }, + 'standardwhitecustom' => { 134 => 0x838 }, + 'standardwhitedaylight' => { 134 => 0x834 }, + 'standardwhiteflash' => { 134 => 0x837 }, + 'standardwhitefluorescent' => { 134 => 0x836 }, + 'standardwhitetungsten' => { 134 => 0x835 }, + 'standbytimer' => { 267 => '19.1', 269 => '19.1', 270 => '19.1', 273 => '18.1', 274 => '18.1', 279 => '19.1', 280 => '19.1' }, + 'startingpage' => { 478 => 'startingPage' }, + 'startmovieshooting' => { 81 => 0x70d }, + 'starttimecode' => { 366 => "\xa9TIM", 488 => 'startTimecode' }, + 'starttimecodetimeformat' => { 488 => [\'startTimecode','startTimecodeTimeFormat'] }, + 'starttimecodetimevalue' => { 488 => [\'startTimecode','startTimecodeTimeValue'] }, + 'starttimecodevalue' => { 488 => [\'startTimecode','startTimecodeValue'] }, + 'starttimesamplesize' => { 366 => "\xa9TSZ", 488 => 'startTimeSampleSize' }, + 'starttimescale' => { 366 => "\xa9TSC", 488 => 'startTimeScale' }, + 'state' => { 157 => 'State', 306 => 0x6b, 476 => 'State' }, + 'status' => { 443 => 'Status', 455 => 'Status' }, + 'stereomode' => { 451 => 'StereoMode' }, + 'stitched' => { 451 => 'Stitched' }, + 'stitchingsoftware' => { 450 => 'StitchingSoftware', 451 => 'StitchingSoftware' }, + 'stopsabovebaseiso' => { 414 => 0x113e, 415 => 0x113e, 416 => 0x111a, 417 => 0x1196, 418 => 0x1172, 419 => 0x102a, 420 => 0x222, 421 => 0x222, 422 => 0x217, 435 => 0xa }, + 'storagemethod' => { 183 => 0x12 }, + 'storebyorientation' => { 267 => '46.3', 269 => '47.3', 270 => '47.3', 279 => '47.3', 280 => '47.3' }, + 'storylineidentifier' => { 474 => 'StorylineIdentifier' }, + 'straightenangle' => { 259 => 0x2fc08431 }, + 'streamready' => { 474 => 'StreamReady' }, + 'streamtype' => { 172 => 'StreamType' }, + 'stretchmode' => { 488 => 'stretchMode' }, + 'studydatetime' => { 441 => 'StudyDateTime' }, + 'studydescription' => { 441 => 'StudyDescription' }, + 'studyid' => { 441 => 'StudyID' }, + 'studyphysician' => { 441 => 'StudyPhysician' }, + 'styleperiod' => { 474 => 'StylePeriod' }, + 'sub-location' => { 128 => 0x5c }, + 'subfiledata' => { 160 => 'data' }, + 'subfiledirectory' => { 160 => '1Directory' }, + 'subfilemimetype' => { 160 => '2MIME' }, + 'subfilename' => { 160 => '1Name' }, + 'subfileresource' => { 160 => 'rsrc' }, + 'subfiletype' => { 116 => 0xfe, 160 => '0Type' }, + 'subject' => { 292 => 'Subject', 357 => 'Subject', 465 => 'subject', 475 => 'Subject', 489 => 'subject' }, + 'subjectarea' => { 116 => 0x9214, 468 => 'SubjectArea' }, + 'subjectcode' => { 473 => 'SubjectCode' }, + 'subjectdistance' => { 116 => 0x9206, 136 => 0x3e, 468 => 'SubjectDistance' }, + 'subjectdistancerange' => { 116 => 0xa40c, 468 => 'SubjectDistanceRange' }, + 'subjectlocation' => { 116 => 0xa214, 468 => 'SubjectLocation' }, + 'subjectmotion' => { 269 => '78.2', 270 => '78.2', 280 => '78.2' }, + 'subjectprogram' => { 176 => 0x22 }, + 'subjectreference' => { 128 => 0xc }, + 'sublabels1' => { 472 => [\'TagStructure','TagStructureSubLabels'] }, + 'sublabels2' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabels'] }, + 'sublabels3' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabels'] }, + 'sublabels4' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabels'] }, + 'sublabels5' => { 472 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels'] }, + 'subseccreatedate' => { 111 => 'Exif::SubSecCreateDate' }, + 'subsecdatetimeoriginal' => { 111 => 'Exif::SubSecDateTimeOriginal' }, + 'subsecmodifydate' => { 111 => 'Exif::SubSecModifyDate' }, + 'subsectime' => { 116 => 0x9290 }, + 'subsectimedigitized' => { 116 => 0x9292 }, + 'subsectimeoriginal' => { 116 => 0x9291 }, + 'subsection1' => { 478 => 'subsection1' }, + 'subsection2' => { 478 => 'subsection2' }, + 'subsection3' => { 478 => 'subsection3' }, + 'subsection4' => { 478 => 'subsection4' }, + 'subselector' => { 267 => '49.1', 269 => '71.1', 270 => '71.1', 280 => '71.1' }, + 'subselectorassignment' => { 267 => '48.1' }, + 'subselectorcenter' => { 269 => '72.1', 270 => '72.1', 280 => '72.1' }, + 'subselectorplusdials' => { 267 => '49.2', 269 => '73.1', 270 => '73.1', 280 => '73.1' }, + 'subtitle' => { 366 => "\xa9snm", 478 => 'subtitle' }, + 'subtitlekeywords' => { 366 => "\xa9snk" }, + 'subversionfilename' => { 472 => [\'SubVersions','SubVersionsFileName'] }, + 'subversionreference' => { 472 => [\'SubVersions','SubVersionsVersRef'] }, + 'subversions' => { 472 => 'SubVersions' }, + 'superimposeddisplay' => { 79 => 0xa, 81 => 0x510, 82 => 0x9, 83 => 0xa, 86 => 0xa, 87 => 0xe }, + 'supermacro' => { 61 => 0x1a }, + 'supplementalcategories' => { 128 => 0x14, 476 => 'SupplementalCategories' }, + 'supplementaltype' => { 130 => 0x37 }, + 'supplementdisplayid' => { 478 => 'supplementDisplayID' }, + 'supplementstartingpage' => { 478 => 'supplementStartingPage' }, + 'supplementtitle' => { 478 => 'supplementTitle' }, + 'supplychainsource' => { 474 => 'SupplyChainSource' }, + 'supplychainsourceidentifier' => { 474 => [\'SupplyChainSource','SupplyChainSourceIdentifier'] }, + 'supplychainsourcename' => { 474 => [\'SupplyChainSource','SupplyChainSourceName'] }, + 'svisosetting' => { 322 => 0x14 }, + 'swatchcoloranta' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsA'] }, + 'swatchcolorantb' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsB'] }, + 'swatchcolorantblack' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsBlack'] }, + 'swatchcolorantblue' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsBlue'] }, + 'swatchcolorantcyan' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsCyan'] }, + 'swatchcolorantgray' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsGray'] }, + 'swatchcolorantgreen' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsGreen'] }, + 'swatchcolorantl' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsL'] }, + 'swatchcolorantmagenta' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsMagenta'] }, + 'swatchcolorantmode' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsMode'] }, + 'swatchcolorantred' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsRed'] }, + 'swatchcolorantswatchname' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsSwatchName'] }, + 'swatchcoloranttint' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsTint'] }, + 'swatchcoloranttype' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsType'] }, + 'swatchcolorantyellow' => { 493 => [\'SwatchGroups','SwatchGroupsColorantsYellow'] }, + 'swatchgroupname' => { 493 => [\'SwatchGroups','SwatchGroupsGroupName'] }, + 'swatchgroups' => { 493 => 'SwatchGroups' }, + 'swatchgroupscolorants' => { 493 => [\'SwatchGroups','SwatchGroupsColorants'] }, + 'swatchgrouptype' => { 493 => [\'SwatchGroups','SwatchGroupsGroupType'] }, + 'sweeppanoramadirection' => { 306 => 0x93, 395 => 0x33 }, + 'sweeppanoramafieldofview' => { 306 => 0x94 }, + 'sweeppanoramasize' => { 395 => 0x32 }, + 'switchtoregisteredafpoint' => { 80 => 0x12, 81 => 0x50a }, + 'symlink' => { 117 => 'SymLink' }, + 'syncreleasemode' => { 269 => '77.1', 270 => '77.1', 280 => '77.1' }, + 'system' => { 350 => 0x204 }, + 'tagged' => { 352 => 0xdd, 353 => 'Tagged', 457 => 'tagged' }, + 'tagslist' => { 467 => 'TagsList' }, + 'tagstructure' => { 472 => 'TagStructure' }, + 'takenumber' => { 488 => 'takeNumber' }, + 'tapename' => { 488 => 'tapeName' }, + 'targetaperture' => { 74 => 0x4 }, + 'targetcompressionratio' => { 92 => 0x1 }, + 'targetdistancesetting' => { 94 => 0x1807 }, + 'targetexposuretime' => { 74 => 0x5 }, + 'targetimagetype' => { 94 => 0x100a }, + 'targetprinter' => { 116 => 0x151 }, + 'taxon' => { 115 => 'Taxon' }, + 'taxonacceptednameusage' => { 115 => [\'Taxon','TaxonAcceptedNameUsage'] }, + 'taxonacceptednameusageid' => { 115 => [\'Taxon','TaxonAcceptedNameUsageID'] }, + 'taxonclass' => { 115 => [\'Taxon','TaxonClass'] }, + 'taxonconceptid' => { 115 => [\'Taxon','TaxonTaxonConceptID'] }, + 'taxonfamily' => { 115 => [\'Taxon','TaxonFamily'] }, + 'taxongenus' => { 115 => [\'Taxon','TaxonGenus'] }, + 'taxonhigherclassification' => { 115 => [\'Taxon','TaxonHigherClassification'] }, + 'taxonid' => { 115 => [\'Taxon','TaxonTaxonID'] }, + 'taxoninfraspecificepithet' => { 115 => [\'Taxon','TaxonInfraspecificEpithet'] }, + 'taxonkingdom' => { 115 => [\'Taxon','TaxonKingdom'] }, + 'taxonnameaccordingto' => { 115 => [\'Taxon','TaxonNameAccordingTo'] }, + 'taxonnameaccordingtoid' => { 115 => [\'Taxon','TaxonNameAccordingToID'] }, + 'taxonnamepublishedin' => { 115 => [\'Taxon','TaxonNamePublishedIn'] }, + 'taxonnamepublishedinid' => { 115 => [\'Taxon','TaxonNamePublishedInID'] }, + 'taxonnamepublishedinyear' => { 115 => [\'Taxon','TaxonNamePublishedInYear'] }, + 'taxonnomenclaturalcode' => { 115 => [\'Taxon','TaxonNomenclaturalCode'] }, + 'taxonnomenclaturalstatus' => { 115 => [\'Taxon','TaxonNomenclaturalStatus'] }, + 'taxonorder' => { 115 => [\'Taxon','TaxonOrder'] }, + 'taxonoriginalnameusage' => { 115 => [\'Taxon','TaxonOriginalNameUsage'] }, + 'taxonoriginalnameusageid' => { 115 => [\'Taxon','TaxonOriginalNameUsageID'] }, + 'taxonparentnameusage' => { 115 => [\'Taxon','TaxonParentNameUsage'] }, + 'taxonparentnameusageid' => { 115 => [\'Taxon','TaxonParentNameUsageID'] }, + 'taxonphylum' => { 115 => [\'Taxon','TaxonPhylum'] }, + 'taxonrank' => { 115 => [\'Taxon','TaxonTaxonRank'] }, + 'taxonremarks' => { 115 => [\'Taxon','TaxonTaxonRemarks'] }, + 'taxonscientificname' => { 115 => [\'Taxon','TaxonScientificName'] }, + 'taxonscientificnameauthorship' => { 115 => [\'Taxon','TaxonScientificNameAuthorship'] }, + 'taxonscientificnameid' => { 115 => [\'Taxon','TaxonScientificNameID'] }, + 'taxonspecificepithet' => { 115 => [\'Taxon','TaxonSpecificEpithet'] }, + 'taxonsubgenus' => { 115 => [\'Taxon','TaxonSubgenus'] }, + 'taxontaxonomicstatus' => { 115 => [\'Taxon','TaxonTaxonomicStatus'] }, + 'taxonverbatimtaxonrank' => { 115 => [\'Taxon','TaxonVerbatimTaxonRank'] }, + 'taxonvernacularname' => { 115 => [\'Taxon','TaxonVernacularName'] }, + 'tda1bandwidth' => { 134 => 0x196f }, + 'tda1edgepolarity' => { 134 => 0x1971 }, + 'tda1gain' => { 134 => 0x1970 }, + 'tda1offset' => { 134 => 0x196e }, + 'tda2bandwidth' => { 134 => 0x1979 }, + 'tda2edgepolarity' => { 134 => 0x197b }, + 'tda2gain' => { 134 => 0x197a }, + 'tda2offset' => { 134 => 0x1978 }, + 'tda3bandwidth' => { 134 => 0x1983 }, + 'tda3edgepolarity' => { 134 => 0x1985 }, + 'tda3gain' => { 134 => 0x1984 }, + 'tda3offset' => { 134 => 0x1982 }, + 'tda4bandwidth' => { 134 => 0x198d }, + 'tda4edgepolarity' => { 134 => 0x198f }, + 'tda4gain' => { 134 => 0x198e }, + 'tda4offset' => { 134 => 0x198c }, + 'teaser' => { 478 => 'teaser' }, + 'teleconverter' => { 181 => 0x105, 406 => 0x105 }, + 'tempampgainx100' => { 134 => 0x1914 }, + 'tempo' => { 488 => 'tempo' }, + 'temporalcoverage' => { 474 => 'TemporalCoverage' }, + 'temporalcoveragefrom' => { 474 => [\'TemporalCoverage','TemporalCoverageTempCoverageFrom'] }, + 'temporalcoverageto' => { 474 => [\'TemporalCoverage','TemporalCoverageTempCoverageTo'] }, + 'termsandconditionstext' => { 293 => 'TermsAndConditionsText' }, + 'termsandconditionsurl' => { 293 => 'TermsAndConditionsURL' }, + 'testname' => { 117 => 'TestName' }, + 'textencoding' => { 218 => 0x4 }, + 'textlayername' => { 476 => [\'TextLayers','TextLayersLayerName'] }, + 'textlayers' => { 476 => 'TextLayers' }, + 'textlayertext' => { 476 => [\'TextLayers','TextLayersLayerText'] }, + 'textstamp' => { 306 => [0x8008,0x8009,0x3b,0x3e] }, + 'texture' => { 462 => 'Texture', 464 => 'Texture' }, + 'three-dtrackingfacedetection' => { 269 => '1.4', 270 => '1.4', 280 => '1.4' }, + 'three-dtrackingwatcharea' => { 269 => '78.1', 270 => '78.1', 280 => '78.1' }, + 'thresholding' => { 116 => 0x107 }, + 'thumbnailfilename' => { 94 => 0x817 }, + 'thumbnailformat' => { 486 => [\'Thumbnails','ThumbnailsFormat'] }, + 'thumbnailheight' => { 138 => 0xfa55, 486 => [\'Thumbnails','ThumbnailsHeight'] }, + 'thumbnailimage' => { 6 => 'CNDA', 94 => 0x2008, 111 => 'Exif::ThumbnailImage', 119 => 0x3, 163 => 'data', 288 => 0x100, 366 => 'thmb', 486 => [\'Thumbnails','ThumbnailsImage'] }, + 'thumbnailimagename' => { 163 => '1Name' }, + 'thumbnailimagesize' => { 163 => 'ImageSize' }, + 'thumbnailimagetype' => { 163 => '0Type' }, + 'thumbnailimagevalidarea' => { 61 => 0x13 }, + 'thumbnaillength' => { 116 => 0x202 }, + 'thumbnailoffset' => { 116 => 0x201 }, + 'thumbnailpng' => { 366 => 'thmb' }, + 'thumbnails' => { 486 => 'Thumbnails' }, + 'thumbnailwidth' => { 138 => 0xfa54, 486 => [\'Thumbnails','ThumbnailsWidth'] }, + 'ticker' => { 478 => 'ticker' }, + 'tiffhandling' => { 462 => 'TIFFHandling', 464 => 'TIFFHandling' }, + 'tiffmeteringimage' => { 182 => 0x104c, 404 => 0x1110 }, + 'tilelength' => { 116 => 0x143 }, + 'tilewidth' => { 116 => 0x142 }, + 'time' => { 134 => 0x401, 341 => 0x7 }, + 'timecodes' => { 116 => 0xc763 }, + 'timecreated' => { 128 => 0x3c, 136 => 0x14, 145 => 0x10, 353 => 'TimeCreated' }, + 'timelapseshotnumber' => { 309 => 0x10 }, + 'timeperiod' => { 478 => 'timePeriod' }, + 'timerfunctionbutton' => { 268 => '5.2', 271 => '12.1', 272 => '13.1' }, + 'timerlength' => { 81 => 0x80c }, + 'timerrecording' => { 306 => 0x96 }, + 'timescaleparams' => { 488 => 'timeScaleParams' }, + 'timescaleparamsframeoverlappingpercentage' => { 488 => [\'timeScaleParams','timeScaleParamsFrameOverlappingPercentage'] }, + 'timescaleparamsframesize' => { 488 => [\'timeScaleParams','timeScaleParamsFrameSize'] }, + 'timescaleparamsquality' => { 488 => [\'timeScaleParams','timeScaleParamsQuality'] }, + 'timesent' => { 129 => 0x50 }, + 'timeshot' => { 452 => 'TimeShot' }, + 'timesignature' => { 488 => 'timeSignature' }, + 'timesincepoweron' => { 306 => 0x29 }, + 'timestamp' => { 11 => 0x45e, 19 => 0x11c, 282 => 0x8, 296 => 'TimeStamp', 306 => 0xaf, 451 => 'Timestamp', 458 => 'Timestamp', 472 => 'TimeStamp' }, + 'timestamp1' => { 11 => 0x45a }, + 'timezone' => { 75 => 0x1, 251 => 0x0, 376 => 0xa }, + 'timezonecity' => { 75 => 0x2 }, + 'timezonecode' => { 97 => 0x1 }, + 'timezoneinfo' => { 97 => 0x2 }, + 'timezoneoffset' => { 116 => 0x882a }, + 'tint' => { 360 => 'player.movie.visual.tint', 462 => 'Tint', 464 => 'Tint' }, + 'title' => { 153 => 'Title', 292 => 'Title', 296 => 'Title', 306 => 0x65, 357 => 'Title', 358 => ['titl',"\xa9nam"], 360 => 'title', 366 => ['titl',"\xa9nam"], 465 => 'title', 475 => 'Title', 486 => 'Title' }, + 'tonecomp' => { 219 => 0x81 }, + 'tonecurve' => { 71 => 0x1, 341 => 0x402, 462 => 'ToneCurve', 464 => 'ToneCurve' }, + 'tonecurveactive' => { 105 => 0x110 }, + 'tonecurveadobergb' => { 380 => 0xa043 }, + 'tonecurveadobergbdefault' => { 380 => 0xa041 }, + 'tonecurveblue' => { 462 => 'ToneCurveBlue', 464 => 'ToneCurveBlue' }, + 'tonecurvebluex' => { 439 => 0x9003 }, + 'tonecurvebluey' => { 439 => 0x9007 }, + 'tonecurvebrightness' => { 100 => 0x20410 }, + 'tonecurvebrightnessx' => { 439 => 0x9000 }, + 'tonecurvebrightnessy' => { 439 => 0x9004 }, + 'tonecurvecolorspace' => { 104 => 0x0 }, + 'tonecurvecontrast' => { 100 => 0x20411 }, + 'tonecurvegreen' => { 462 => 'ToneCurveGreen', 464 => 'ToneCurveGreen' }, + 'tonecurvegreenx' => { 439 => 0x9002 }, + 'tonecurvegreeny' => { 439 => 0x9006 }, + 'tonecurveinputrange' => { 104 => 0x3 }, + 'tonecurveinterpolation' => { 105 => 0x159 }, + 'tonecurvemode' => { 105 => 0x113 }, + 'tonecurvename' => { 462 => 'ToneCurveName', 464 => 'ToneCurveName' }, + 'tonecurvename2012' => { 462 => 'ToneCurveName2012', 464 => 'ToneCurveName2012' }, + 'tonecurveoriginal' => { 100 => '0x20400.1' }, + 'tonecurveoutputrange' => { 104 => 0x5 }, + 'tonecurveprofilename' => { 134 => 0x1391 }, + 'tonecurveproperty' => { 105 => 0x3c }, + 'tonecurvepv2012' => { 462 => 'ToneCurvePV2012', 464 => 'ToneCurvePV2012' }, + 'tonecurvepv2012blue' => { 462 => 'ToneCurvePV2012Blue', 464 => 'ToneCurvePV2012Blue' }, + 'tonecurvepv2012green' => { 462 => 'ToneCurvePV2012Green', 464 => 'ToneCurvePV2012Green' }, + 'tonecurvepv2012red' => { 462 => 'ToneCurvePV2012Red', 464 => 'ToneCurvePV2012Red' }, + 'tonecurvered' => { 462 => 'ToneCurveRed', 464 => 'ToneCurveRed' }, + 'tonecurveredx' => { 439 => 0x9001 }, + 'tonecurveredy' => { 439 => 0x9005 }, + 'tonecurves' => { 341 => 0x403 }, + 'tonecurveshape' => { 104 => 0x1 }, + 'tonecurvesrgb' => { 380 => 0xa042 }, + 'tonecurvesrgbdefault' => { 380 => 0xa040 }, + 'tonecurvex' => { 104 => 0xa }, + 'tonecurvey' => { 104 => 0xb }, + 'tonelevel' => { 283 => 0x52e }, + 'tonemapstrength' => { 462 => 'ToneMapStrength', 464 => 'ToneMapStrength' }, + 'toningeffect' => { 55 => 0xf, 219 => 0xb3, 221 => 0x38, 222 => 0x40, 223 => 0x48, 373 => 0x1015 }, + 'toningeffectauto' => { 68 => 0xa4 }, + 'toningeffectfaithful' => { 67 => 0x74, 68 => 0x74 }, + 'toningeffectlandscape' => { 67 => 0x44, 68 => 0x44 }, + 'toningeffectmonochrome' => { 19 => 0x108, 67 => 0x8c, 68 => 0x8c }, + 'toningeffectneutral' => { 67 => 0x5c, 68 => 0x5c }, + 'toningeffectportrait' => { 67 => 0x2c, 68 => 0x2c }, + 'toningeffectstandard' => { 67 => 0x14, 68 => 0x14 }, + 'toningeffectuserdef1' => { 67 => 0xa4, 68 => 0xbc }, + 'toningeffectuserdef2' => { 67 => 0xbc, 68 => 0xd4 }, + 'toningeffectuserdef3' => { 67 => 0xd4, 68 => 0xec }, + 'toningsaturation' => { 221 => 0x39, 222 => 0x41, 223 => 0x49 }, + 'totalzoom' => { 136 => 0x62 }, + 'touchae' => { 306 => 0xab }, + 'track' => { 358 => "\xa9trk", 366 => "\xa9trk" }, + 'trackcreatedate' => { 365 => 0x1 }, + 'trackmodifydate' => { 365 => 0x2 }, + 'tracknumber' => { 358 => 'trkn', 488 => 'trackNumber' }, + 'tracks' => { 488 => 'Tracks' }, + 'tracksframerate' => { 488 => [\'Tracks','TracksFrameRate'] }, + 'tracksmarkers' => { 488 => [\'Tracks','TracksMarkers'] }, + 'tracksmarkerscomment' => { 488 => [\'Tracks','TracksMarkersComment'] }, + 'tracksmarkerscuepointparams' => { 488 => [\'Tracks','TracksMarkersCuePointParams'] }, + 'tracksmarkerscuepointparamskey' => { 488 => [\'Tracks','TracksMarkersCuePointParamsKey'] }, + 'tracksmarkerscuepointparamsvalue' => { 488 => [\'Tracks','TracksMarkersCuePointParamsValue'] }, + 'tracksmarkerscuepointtype' => { 488 => [\'Tracks','TracksMarkersCuePointType'] }, + 'tracksmarkersduration' => { 488 => [\'Tracks','TracksMarkersDuration'] }, + 'tracksmarkerslocation' => { 488 => [\'Tracks','TracksMarkersLocation'] }, + 'tracksmarkersname' => { 488 => [\'Tracks','TracksMarkersName'] }, + 'tracksmarkersprobability' => { 488 => [\'Tracks','TracksMarkersProbability'] }, + 'tracksmarkersspeaker' => { 488 => [\'Tracks','TracksMarkersSpeaker'] }, + 'tracksmarkersstarttime' => { 488 => [\'Tracks','TracksMarkersStartTime'] }, + 'tracksmarkerstarget' => { 488 => [\'Tracks','TracksMarkersTarget'] }, + 'tracksmarkerstype' => { 488 => [\'Tracks','TracksMarkersType'] }, + 'trackstrackname' => { 488 => [\'Tracks','TracksTrackName'] }, + 'trackstracktype' => { 488 => [\'Tracks','TracksTrackType'] }, + 'tracktype' => { 366 => 'kgtt' }, + 'trailer' => { 117 => 'Trailer' }, + 'trailersignature' => { 160 => 'zmie' }, + 'transcript' => { 474 => 'Transcript' }, + 'transcriptlink' => { 474 => 'TranscriptLink' }, + 'transcriptlinklink' => { 474 => [\'TranscriptLink','TranscriptLinkLink'] }, + 'transcriptlinklinkqualifier' => { 474 => [\'TranscriptLink','TranscriptLinkLinkQualifier'] }, + 'transferfunction' => { 116 => 0x12d, 484 => 'TransferFunction' }, + 'transfertimenormal' => { 134 => 0x1888 }, + 'transfertimetest' => { 134 => 0x1889 }, + 'transform' => { 306 => [0x8012,0x59] }, + 'transmissionreference' => { 476 => 'TransmissionReference' }, + 'trapped' => { 292 => 'Trapped', 475 => 'Trapped' }, + 'trashbuttonfunction' => { 81 => 0x710 }, + 'travelday' => { 306 => 0x36 }, + 'trebel' => { 360 => 'player.movie.audio.treble' }, + 'triggermode' => { 367 => 0x6, 368 => 0x34, 369 => 0x34 }, + 'tstop' => { 116 => 0xc772 }, + 'ttl_da_adown' => { 329 => 0x5 }, + 'ttl_da_aup' => { 329 => 0x4 }, + 'ttl_da_bdown' => { 329 => 0x7 }, + 'ttl_da_bup' => { 329 => 0x6 }, + 'tungstenawb' => { 319 => 0x1 }, + 'tvepisode' => { 358 => 'tves' }, + 'tvepisodeid' => { 358 => 'tven' }, + 'tvexposuretimesetting' => { 322 => 0x12 }, + 'tvnetworkname' => { 358 => 'tvnn' }, + 'tvseason' => { 358 => 'tvsn' }, + 'tvshow' => { 358 => 'tvsh' }, + 'type' => { 465 => 'type', 483 => 'type' }, + 'typestatus' => { 115 => [\'Identification','IdentificationTypeStatus'] }, + 'uniquecameramodel' => { 116 => 0xc614 }, + 'uniquedocumentid' => { 128 => 0xbb }, + 'uniquematrixauto' => { 134 => 0x7e9 }, + 'uniquematrixcustom' => { 134 => 0x7e8 }, + 'uniquematrixdaylight' => { 134 => 0x7e4 }, + 'uniquematrixflash' => { 134 => 0x7e7 }, + 'uniquematrixfluorescent' => { 134 => 0x7e6 }, + 'uniquematrixtungsten' => { 134 => 0x7e5 }, + 'uniqueobjectname' => { 129 => 0x64 }, + 'units' => { 447 => 'Units' }, + 'unknown_aacr' => { 358 => 'AACR' }, + 'unknown_cdek' => { 358 => 'CDEK' }, + 'unknown_cdet' => { 358 => 'CDET' }, + 'unknownblock' => { 341 => 0x405 }, + 'unknownblock1' => { 287 => 0x635 }, + 'unknownblock2' => { 287 => 0x636 }, + 'unknownblock3' => { 287 => 0x1103 }, + 'unknownblock4' => { 287 => 0x1104 }, + 'unknowncontrast' => { 106 => 0x45 }, + 'unknowndate' => { 350 => 0x212 }, + 'unknownev' => { 134 => 0x1 }, + 'unknownlinear' => { 106 => 0x46 }, + 'unknownnumber' => { 94 => 0x180b }, + 'unknownoutputhighlightpoint' => { 106 => 0x4a }, + 'unknownoutputshadowpoint' => { 106 => 0x4b }, + 'unknownrawhighlight' => { 106 => 0x7b }, + 'unknownrawhighlightpoint' => { 106 => 0x48 }, + 'unknownrawshadow' => { 106 => 0x84 }, + 'unknownrawshadowpoint' => { 106 => 0x49 }, + 'unknownsharpness' => { 106 => 0x47 }, + 'unknowntags' => { 366 => 'TAGS' }, + 'unknowntemperature' => { 118 => 0x4 }, + 'unknownthumbnail' => { 366 => 'thmb' }, + 'unsharp1color' => { 264 => 0x13 }, + 'unsharp1halowidth' => { 264 => 0x19 }, + 'unsharp1intensity' => { 264 => 0x17 }, + 'unsharp1threshold' => { 264 => 0x1b }, + 'unsharp2color' => { 264 => 0x2e }, + 'unsharp2halowidth' => { 264 => 0x34 }, + 'unsharp2intensity' => { 264 => 0x32 }, + 'unsharp2threshold' => { 264 => 0x36 }, + 'unsharp3color' => { 264 => 0x49 }, + 'unsharp3halowidth' => { 264 => 0x4f }, + 'unsharp3intensity' => { 264 => 0x4d }, + 'unsharp3threshold' => { 264 => 0x51 }, + 'unsharp4color' => { 264 => 0x64 }, + 'unsharp4halowidth' => { 264 => 0x6a }, + 'unsharp4intensity' => { 264 => 0x68 }, + 'unsharp4threshold' => { 264 => 0x6c }, + 'unsharpcount' => { 264 => 0x0 }, + 'unsharpmask' => { 106 => 0x90, 259 => 0x76a43200 }, + 'unsharpmaskfineness' => { 100 => 0x20309 }, + 'unsharpmaskstrength' => { 100 => 0x20308 }, + 'unsharpmaskthreshold' => { 100 => 0x2030a }, + 'uprightcentermode' => { 462 => 'UprightCenterMode', 464 => 'UprightCenterMode' }, + 'uprightcenternormx' => { 462 => 'UprightCenterNormX', 464 => 'UprightCenterNormX' }, + 'uprightcenternormy' => { 462 => 'UprightCenterNormY', 464 => 'UprightCenterNormY' }, + 'uprightdependentdigest' => { 462 => 'UprightDependentDigest', 464 => 'UprightDependentDigest' }, + 'uprightfocallength35mm' => { 462 => 'UprightFocalLength35mm', 464 => 'UprightFocalLength35mm' }, + 'uprightfocalmode' => { 462 => 'UprightFocalMode', 464 => 'UprightFocalMode' }, + 'uprightfoursegmentscount' => { 462 => 'UprightFourSegmentsCount', 464 => 'UprightFourSegmentsCount' }, + 'uprightpreview' => { 462 => 'UprightPreview', 464 => 'UprightPreview' }, + 'uprighttransform_0' => { 462 => 'UprightTransform_0', 464 => 'UprightTransform_0' }, + 'uprighttransform_1' => { 462 => 'UprightTransform_1', 464 => 'UprightTransform_1' }, + 'uprighttransform_2' => { 462 => 'UprightTransform_2', 464 => 'UprightTransform_2' }, + 'uprighttransform_3' => { 462 => 'UprightTransform_3', 464 => 'UprightTransform_3' }, + 'uprighttransform_4' => { 462 => 'UprightTransform_4', 464 => 'UprightTransform_4' }, + 'uprighttransform_5' => { 462 => 'UprightTransform_5', 464 => 'UprightTransform_5' }, + 'uprighttransformcount' => { 462 => 'UprightTransformCount', 464 => 'UprightTransformCount' }, + 'uprightversion' => { 462 => 'UprightVersion', 464 => 'UprightVersion' }, + 'urgency' => { 128 => 0xa, 476 => 'Urgency' }, + 'url' => { 153 => 'URL', 296 => 'URL', 355 => 0x40b, 478 => 'url' }, + 'url_list' => { 355 => 0x41e }, + 'urla-platform' => { 478 => [\'url','urlA-platform'] }, + 'urlurl' => { 478 => [\'url','urlUrl'] }, + 'usablemeteringmodes' => { 81 => 0x10a }, + 'usableshootingmodes' => { 81 => 0x109 }, + 'usage' => { 479 => 'usage' }, + 'usageterms' => { 492 => 'UsageTerms' }, + 'useguidelines' => { 460 => 'useGuidelines' }, + 'usepanoramaviewer' => { 450 => 'UsePanoramaViewer' }, + 'usercollection' => { 360 => 'collection.user' }, + 'usercomment' => { 94 => 0x805, 116 => 0x9286, 468 => 'UserComment' }, + 'userdef1picturestyle' => { 19 => 0x10c, 67 => 0xd8, 68 => 0xf0 }, + 'userdef2picturestyle' => { 19 => 0x10e, 67 => 0xda, 68 => 0xf2 }, + 'userdef3picturestyle' => { 19 => 0x110, 67 => 0xdc, 68 => 0xf4 }, + 'userfields' => { 455 => 'UserFields' }, + 'userlabel' => { 367 => 0x2b, 368 => 0x5a, 369 => 0x68 }, + 'userprofile' => { 301 => 0x302, 305 => 0x34c, 308 => 0x3038 }, + 'userrating' => { 360 => 'rating.user' }, + 'usmlenselectronicmf' => { 2 => 0x7, 80 => 0x7, 81 => 0x501 }, + 'uspsnumber' => { 478 => 'uspsNumber' }, + 'utmeasting' => { 164 => 'Easting' }, + 'utmmapdatum' => { 164 => 'Datum' }, + 'utmnorthing' => { 164 => 'Northing' }, + 'utmzone' => { 164 => 'Zone' }, + 'uv-irfiltercorrection' => { 301 => 0x325 }, + 'validbits' => { 287 => 0x611, 288 => 0x102c }, + 'validpixeldepth' => { 291 => 0x611 }, + 'variablelowpassfilter' => { 406 => 0x2028 }, + 'variousmodes' => { 136 => 0x26 }, + 'variousmodes2' => { 136 => 0x3a }, + 'variprogram' => { 219 => 0xab }, + 'varraydacnominalvalues' => { 134 => 0x191e }, + 'vendor' => { 366 => 'vndr' }, + 'vendorinfo' => { 442 => 'VendorInfo' }, + 'vendorinfomanufacturer' => { 442 => [\'VendorInfo','VendorInfoManufacturer'] }, + 'vendorinfomodel' => { 442 => [\'VendorInfo','VendorInfoModel'] }, + 'vendorinfonotes' => { 442 => [\'VendorInfo','VendorInfoNotes'] }, + 'version' => { 124 => 0x0, 357 => 'Version', 360 => 'version', 462 => 'Version', 464 => 'Version' }, + 'versioncreatedate' => { 439 => 0xd100 }, + 'versionid' => { 489 => 'VersionID' }, + 'versionidentifier' => { 478 => 'versionIdentifier' }, + 'versionmodifydate' => { 439 => 0xd101 }, + 'versions' => { 489 => 'Versions' }, + 'versionscomments' => { 489 => [\'Versions','VersionsComments'] }, + 'versionsevent' => { 489 => [\'Versions','VersionsEvent'] }, + 'versionseventaction' => { 489 => [\'Versions','VersionsEventAction'] }, + 'versionseventchanged' => { 489 => [\'Versions','VersionsEventChanged'] }, + 'versionseventinstanceid' => { 489 => [\'Versions','VersionsEventInstanceID'] }, + 'versionseventparameters' => { 489 => [\'Versions','VersionsEventParameters'] }, + 'versionseventsoftwareagent' => { 489 => [\'Versions','VersionsEventSoftwareAgent'] }, + 'versionseventwhen' => { 489 => [\'Versions','VersionsEventWhen'] }, + 'versionsmodifier' => { 489 => [\'Versions','VersionsModifier'] }, + 'versionsmodifydate' => { 489 => [\'Versions','VersionsModifyDate'] }, + 'versionsversion' => { 489 => [\'Versions','VersionsVersion'] }, + 'verticalafonbutton' => { 266 => '3.2', 267 => '47.2', 269 => '79.1' }, + 'verticalclockoverlaps' => { 134 => 0x412 }, + 'verticalfuncbutton' => { 267 => '42.2', 269 => '67.1' }, + 'verticalfuncbuttonplusdials' => { 267 => '43.1' }, + 'verticalfuncplusdials' => { 269 => '68.1' }, + 'verticalmultiselector' => { 267 => '42.1', 269 => '66.1', 270 => '66.1', 280 => '66.1' }, + 'vfdisplayillumination' => { 2 => 0x11, 81 => [0x510,0x51d] }, + 'vibrance' => { 456 => 'Vibrance', 462 => 'Vibrance', 464 => 'Vibrance' }, + 'vibrationreduction' => { 228 => [0x75,0x82,0x1ae], 236 => '586.1', 244 => '590.2', 250 => 0x4 }, + 'videoalphamode' => { 488 => 'videoAlphaMode' }, + 'videoalphapremultiplecolor' => { 488 => 'videoAlphaPremultipleColor' }, + 'videoalphapremultiplecolora' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorA'] }, + 'videoalphapremultiplecolorb' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorB'] }, + 'videoalphapremultiplecolorblack' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlack'] }, + 'videoalphapremultiplecolorblue' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlue'] }, + 'videoalphapremultiplecolorcyan' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorCyan'] }, + 'videoalphapremultiplecolorgray' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGray'] }, + 'videoalphapremultiplecolorgreen' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGreen'] }, + 'videoalphapremultiplecolorl' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorL'] }, + 'videoalphapremultiplecolormagenta' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMagenta'] }, + 'videoalphapremultiplecolormode' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMode'] }, + 'videoalphapremultiplecolorred' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorRed'] }, + 'videoalphapremultiplecolorswatchname' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorSwatchName'] }, + 'videoalphapremultiplecolortint' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorTint'] }, + 'videoalphapremultiplecolortype' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorType'] }, + 'videoalphapremultiplecoloryellow' => { 488 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorYellow'] }, + 'videoalphaunityistransparent' => { 488 => 'videoAlphaUnityIsTransparent' }, + 'videobitrate' => { 474 => 'videoBitRate' }, + 'videobitratemode' => { 474 => 'videoBitRateMode' }, + 'videoburstmode' => { 306 => 0xbb }, + 'videocodec' => { 64 => 0x74 }, + 'videocolorspace' => { 488 => 'videoColorSpace' }, + 'videocompression' => { 124 => 0x3806 }, + 'videocompressor' => { 488 => 'videoCompressor' }, + 'videodisplayaspectratio' => { 474 => 'videoDisplayAspectRatio' }, + 'videoencodingprofile' => { 474 => 'videoEncodingProfile' }, + 'videofieldorder' => { 488 => 'videoFieldOrder' }, + 'videoframerate' => { 488 => 'videoFrameRate' }, + 'videoframesize' => { 488 => 'videoFrameSize' }, + 'videoframesizeh' => { 488 => [\'videoFrameSize','videoFrameSizeH'] }, + 'videoframesizeunit' => { 488 => [\'videoFrameSize','videoFrameSizeUnit'] }, + 'videoframesizew' => { 488 => [\'videoFrameSize','videoFrameSizeW'] }, + 'videomoddate' => { 488 => 'videoModDate' }, + 'videopixelaspectratio' => { 488 => 'videoPixelAspectRatio' }, + 'videopixeldepth' => { 488 => 'videoPixelDepth' }, + 'videoquality' => { 110 => 0x4003 }, + 'videorecordingmode' => { 124 => 0x3803 }, + 'videoshottype' => { 474 => 'VideoShotType' }, + 'videoshottypeidentifier' => { 474 => [\'VideoShotType','VideoShotTypeIdentifier'] }, + 'videoshottypename' => { 474 => [\'VideoShotType','VideoShotTypeName'] }, + 'videostreamscount' => { 474 => 'videoStreamsCount' }, + 'viewfinder' => { 350 => 0x455 }, + 'viewfinderdisplay' => { 266 => '12.4', 267 => '6.3' }, + 'viewfinderwarning' => { 266 => '13.4', 276 => '3.5', 277 => '6.2', 281 => '4.4' }, + 'viewfinderwarnings' => { 81 => 0x40a }, + 'viewinfoduringexposure' => { 81 => 0x407 }, + 'viewingmode' => { 395 => 0x2f, 411 => 0x18 }, + 'viewingmode2' => { 395 => [0x85,0x285] }, + 'viewpoint' => { 477 => 'viewpoint' }, + 'vignetteamount' => { 462 => 'VignetteAmount', 464 => 'VignetteAmount' }, + 'vignettecontrol' => { 219 => 0x2a, 259 => 0x76a43205 }, + 'vignettecontrolintensity' => { 259 => 0xac6bd5c0 }, + 'vignettecorrectionalreadyapplied' => { 459 => 'VignetteCorrectionAlreadyApplied' }, + 'vignettemidpoint' => { 462 => 'VignetteMidpoint', 464 => 'VignetteMidpoint' }, + 'vignetting' => { 373 => 0x1011, 380 => 0xa052 }, + 'vignettingcorrection' => { 116 => 0x7031, 380 => 0xa053, 406 => 0x2011 }, + 'vignettingcorrparams' => { 116 => 0x7032, 434 => 0x64a, 435 => [0x34a,0x350,0x35c,0x368] }, + 'vignettingsetting' => { 380 => 0xa054 }, + 'visualcolor' => { 474 => 'VisualColour' }, + 'visualtechnique' => { 477 => 'visualTechnique' }, + 'voicememo' => { 382 => 0x216 }, + 'volume' => { 478 => 'volume' }, + 'vr_0x66' => { 228 => 0x66 }, + 'vrdoffset' => { 61 => 0xd0 }, + 'vrmode' => { 250 => 0x6 }, + 'waterdepth' => { 116 => 0x9403, 469 => 'WaterDepth' }, + 'wb_bluelevel3500k' => { 182 => 0x19a }, + 'wb_bluelevel6500k' => { 182 => 0x18a }, + 'wb_bluelevelcustom' => { 182 => 0x18e }, + 'wb_bluelevelscloudy' => { 182 => 0x106 }, + 'wb_bluelevelsdaylight' => { 182 => 0xea }, + 'wb_bluelevelsflash' => { 182 => 0x122 }, + 'wb_bluelevelsfluorescent' => { 182 => [0x40a,0x15a] }, + 'wb_bluelevelskelvin' => { 182 => 0x254 }, + 'wb_bluelevelsshade' => { 182 => 0x176 }, + 'wb_bluelevelstungsten' => { 182 => 0xce }, + 'wb_gbrglevels' => { 182 => 0xae, 185 => 0x4 }, + 'wb_glevel' => { 287 => 0x11f }, + 'wb_glevel3000k' => { 287 => 0x113 }, + 'wb_glevel3300k' => { 287 => 0x114 }, + 'wb_glevel3600k' => { 287 => 0x115 }, + 'wb_glevel3900k' => { 287 => 0x116 }, + 'wb_glevel4000k' => { 287 => 0x117 }, + 'wb_glevel4300k' => { 287 => 0x118 }, + 'wb_glevel4500k' => { 287 => 0x119 }, + 'wb_glevel4800k' => { 287 => 0x11a }, + 'wb_glevel5300k' => { 287 => 0x11b }, + 'wb_glevel6000k' => { 287 => 0x11c }, + 'wb_glevel6600k' => { 287 => 0x11d }, + 'wb_glevel7500k' => { 287 => 0x11e }, + 'wb_grbglevels' => { 195 => 0x0 }, + 'wb_grgblevelsauto' => { 78 => 0x2 }, + 'wb_grgblevelscloudy' => { 78 => 0x12 }, + 'wb_grgblevelscustom1' => { 78 => 0x42 }, + 'wb_grgblevelscustom2' => { 78 => 0x4a }, + 'wb_grgblevelsdaylight' => { 78 => 0xa }, + 'wb_grgblevelsflash' => { 78 => 0x32 }, + 'wb_grgblevelsfluorescent' => { 78 => 0x22 }, + 'wb_grgblevelsfluorhigh' => { 78 => 0x2a }, + 'wb_grgblevelstungsten' => { 78 => 0x1a }, + 'wb_grgblevelsunderwater' => { 78 => 0x3a }, + 'wb_rbgglevels' => { 192 => 0x0 }, + 'wb_rblevels' => { 196 => 0x270, 219 => 0xc, 287 => 0x100 }, + 'wb_rblevels1' => { 312 => 0x2 }, + 'wb_rblevels2' => { 312 => 0x5 }, + 'wb_rblevels3' => { 312 => 0x8 }, + 'wb_rblevels3000k' => { 287 => 0x102 }, + 'wb_rblevels3300k' => { 287 => 0x103 }, + 'wb_rblevels3500k' => { 182 => 0x430 }, + 'wb_rblevels3600k' => { 287 => 0x104 }, + 'wb_rblevels3900k' => { 287 => 0x105 }, + 'wb_rblevels4' => { 312 => 0xb }, + 'wb_rblevels4000k' => { 287 => 0x106 }, + 'wb_rblevels4300k' => { 287 => 0x107 }, + 'wb_rblevels4500k' => { 287 => 0x108 }, + 'wb_rblevels4800k' => { 287 => 0x109 }, + 'wb_rblevels5' => { 312 => 0xe }, + 'wb_rblevels5300k' => { 287 => 0x10a }, + 'wb_rblevels6' => { 312 => 0x11 }, + 'wb_rblevels6000k' => { 287 => 0x10b }, + 'wb_rblevels6500k' => { 182 => 0x420 }, + 'wb_rblevels6600k' => { 287 => 0x10c }, + 'wb_rblevels7' => { 312 => 0x14 }, + 'wb_rblevels7500k' => { 287 => 0x10d }, + 'wb_rblevelsauto' => { 196 => 0x272, 291 => 0x110 }, + 'wb_rblevelscloudy' => { 182 => 0x3f0, 184 => 0x10, 196 => 0x296, 291 => 0x121 }, + 'wb_rblevelscoolwhitef' => { 182 => 0x308, 184 => 0x14 }, + 'wb_rblevelscoolwhitefluor' => { 291 => 0x132 }, + 'wb_rblevelscustom' => { 182 => 0x424 }, + 'wb_rblevelscwb1' => { 287 => 0x10e }, + 'wb_rblevelscwb2' => { 287 => 0x10f }, + 'wb_rblevelscwb3' => { 287 => 0x110 }, + 'wb_rblevelscwb4' => { 287 => 0x111 }, + 'wb_rblevelsdaylight' => { 182 => [0x3ec,0x528], 184 => 0xc, 196 => 0x274 }, + 'wb_rblevelsdaylightf' => { 184 => 0x24 }, + 'wb_rblevelsdaylightfluor' => { 291 => 0x130 }, + 'wb_rblevelsdaywhitef' => { 184 => 0x28 }, + 'wb_rblevelsdaywhitefluor' => { 291 => 0x131 }, + 'wb_rblevelseveningsunlight' => { 291 => 0x124 }, + 'wb_rblevelsfineweather' => { 291 => 0x122 }, + 'wb_rblevelsflash' => { 182 => [0x3f4,0x304], 184 => 0x18, 196 => 0x2a4 }, + 'wb_rblevelsfluorescent' => { 196 => 0x290 }, + 'wb_rblevelsincandescent' => { 196 => 0x282 }, + 'wb_rblevelsshade' => { 182 => 0x418, 184 => 0x20, 196 => 0x2b2, 291 => 0x120 }, + 'wb_rblevelstungsten' => { 182 => 0x3e8, 184 => 0x8, 291 => 0x123 }, + 'wb_rblevelsunknown' => { 184 => 0x1c }, + 'wb_rblevelsused' => { 291 => 0x100 }, + 'wb_rblevelswhitef' => { 184 => 0x2c }, + 'wb_rblevelswhitefluorescent' => { 291 => 0x133 }, + 'wb_redlevel3500k' => { 182 => 0x198 }, + 'wb_redlevel6500k' => { 182 => 0x188 }, + 'wb_redlevelcustom' => { 182 => 0x18c }, + 'wb_redlevelscloudy' => { 182 => 0xf8 }, + 'wb_redlevelsdaylight' => { 182 => 0xdc }, + 'wb_redlevelsflash' => { 182 => 0x114 }, + 'wb_redlevelsfluorescent' => { 182 => [0x3fc,0x14c] }, + 'wb_redlevelskelvin' => { 182 => 0x1be }, + 'wb_redlevelsshade' => { 182 => 0x168 }, + 'wb_redlevelstungsten' => { 182 => 0xc0 }, + 'wb_rgbglevels' => { 194 => 0x0 }, + 'wb_rgblevels' => { 182 => [0x546,0x96], 302 => 0xd, 303 => 0x413, 308 => 0x3036, 350 => 0x107, 414 => 0x117c, 415 => 0x1180, 416 => 0x115c, 417 => 0x11d8, 418 => 0x11b4, 419 => 0x106c, 420 => 0x264, 421 => 0x264, 422 => 0x252 }, + 'wb_rgblevels1' => { 313 => 0x2 }, + 'wb_rgblevels2' => { 313 => 0x6 }, + 'wb_rgblevels3' => { 313 => 0xa }, + 'wb_rgblevels4' => { 313 => 0xe }, + 'wb_rgblevels5' => { 313 => 0x12 }, + 'wb_rgblevels6' => { 313 => 0x16 }, + 'wb_rgblevels7' => { 313 => 0x1a }, + 'wb_rgblevelsauto' => { 384 => 0x0 }, + 'wb_rgblevelscustom1' => { 384 => 0x15 }, + 'wb_rgblevelscustom2' => { 384 => 0x18 }, + 'wb_rgblevelscustom3' => { 384 => 0x1b }, + 'wb_rgblevelsdaylight' => { 384 => 0x3 }, + 'wb_rgblevelsflash' => { 384 => 0x12 }, + 'wb_rgblevelsfluorescent' => { 384 => 0xf }, + 'wb_rgblevelsincandescent' => { 384 => 0xc }, + 'wb_rgblevelsovercast' => { 384 => 0x9 }, + 'wb_rgblevelsshade' => { 384 => 0x6 }, + 'wb_rgblevelsunknown0' => { 385 => 0x0 }, + 'wb_rgblevelsunknown1' => { 385 => 0x3 }, + 'wb_rgblevelsunknown2' => { 385 => 0x6 }, + 'wb_rgblevelsunknown3' => { 385 => 0x9 }, + 'wb_rgblevelsunknown4' => { 385 => 0xc }, + 'wb_rgblevelsunknown5' => { 385 => 0xf }, + 'wb_rgblevelsunknown6' => { 385 => 0x12 }, + 'wb_rgblevelsunknown7' => { 385 => 0x15 }, + 'wb_rgblevelsunknown8' => { 385 => 0x18 }, + 'wb_rgblevelsunknown9' => { 385 => 0x1b }, + 'wb_rgbmuldaylight' => { 134 => 0x852 }, + 'wb_rgbmulflash' => { 134 => 0x855 }, + 'wb_rgbmulfluorescent' => { 134 => 0x854 }, + 'wb_rgbmultungsten' => { 134 => 0x853 }, + 'wb_rggbblacklevels' => { 35 => 0x25 }, + 'wb_rggblevels' => { 185 => 0x4, 193 => 0x0, 197 => 0x13e8, 198 => 0x38 }, + 'wb_rggblevelsasshot' => { 38 => 0x0, 39 => 0x0, 40 => 0x19, 41 => 0x22, 42 => 0x3f, 45 => 0x3f, 46 => 0x3f, 47 => 0x3f, 48 => 0x47 }, + 'wb_rggblevelsauto' => { 35 => 0x1, 38 => 0x5, 39 => 0x8, 40 => 0x1e, 41 => 0x18, 42 => 0x44, 45 => 0x44, 46 => 0x44, 47 => 0x44, 48 => 0x4c, 197 => 0x1478, 198 => 0x114, 380 => 0xa022 }, + 'wb_rggblevelsblack' => { 380 => 0xa028 }, + 'wb_rggblevelscloudy' => { 35 => 0xd, 38 => 0x1e, 39 => 0x30, 40 => 0x2d, 41 => 0x31, 42 => 0x58, 45 => 0x71, 46 => 0x8a, 47 => 0x8f, 48 => 0x92, 197 => 0x1408, 198 => 0x60, 341 => 0x20f, 349 => 0x14 }, + 'wb_rggblevelscustom' => { 35 => 0x1d, 42 => 0x80, 197 => 0x1468, 198 => 0x100 }, + 'wb_rggblevelscustom1' => { 40 => 0x41 }, + 'wb_rggblevelscustom2' => { 40 => 0x46 }, + 'wb_rggblevelsdaylight' => { 35 => 0x5, 38 => 0x14, 39 => 0x20, 40 => 0x23, 41 => 0x27, 42 => 0x4e, 45 => 0x67, 46 => 0x80, 47 => 0x85, 48 => 0x88, 197 => 0x13f8, 198 => 0x4c, 341 => 0x20d, 349 => 0x2 }, + 'wb_rggblevelsflash' => { 35 => 0x19, 38 => 0x32, 39 => 0x50, 40 => 0x3c, 41 => 0x45, 42 => 0x6c, 45 => 0x85, 46 => 0x9e, 47 => 0xa3, 48 => 0xa6, 197 => 0x1448, 341 => 0x214, 349 => 0x41 }, + 'wb_rggblevelsfluorescent' => { 35 => 0x15, 38 => 0x28, 39 => 0x40, 40 => 0x37, 41 => 0x3b, 42 => 0x62, 45 => 0x7b, 46 => 0x94, 47 => 0x99, 48 => 0x9c }, + 'wb_rggblevelsfluorescentd' => { 198 => 0xc4, 341 => 0x211, 349 => 0x26 }, + 'wb_rggblevelsfluorescentl' => { 349 => 0x4a }, + 'wb_rggblevelsfluorescentn' => { 198 => 0xb0, 341 => 0x212, 349 => 0x2f }, + 'wb_rggblevelsfluorescentw' => { 197 => 0x1438, 198 => 0x9c, 341 => 0x213, 349 => 0x38 }, + 'wb_rggblevelshtmercury' => { 198 => 0xd8 }, + 'wb_rggblevelsilluminator1' => { 380 => 0xa023 }, + 'wb_rggblevelsilluminator2' => { 380 => 0xa024 }, + 'wb_rggblevelskelvin' => { 35 => 0x21, 38 => 0x2d, 39 => 0x48, 41 => 0x40, 42 => 0x67, 45 => 0x80, 46 => 0x99, 47 => 0x9e, 48 => 0xa1 }, + 'wb_rggblevelsmeasured' => { 38 => 0xa, 39 => 0x10, 42 => 0x49, 45 => 0x49, 46 => 0x49, 47 => 0x49, 48 => 0x51 }, + 'wb_rggblevelspc1' => { 41 => 0x90, 42 => 0x71 }, + 'wb_rggblevelspc2' => { 41 => 0x95, 42 => 0x76 }, + 'wb_rggblevelspc3' => { 41 => 0x9a, 42 => 0x7b }, + 'wb_rggblevelsshade' => { 35 => 0x9, 38 => 0x19, 39 => 0x28, 40 => 0x28, 41 => 0x2c, 42 => 0x53, 45 => 0x6c, 46 => 0x85, 47 => 0x8a, 48 => 0x8d, 198 => 0x74, 341 => 0x20e, 349 => 0xb }, + 'wb_rggblevelstungsten' => { 35 => 0x11, 38 => 0x23, 39 => 0x38, 40 => 0x32, 41 => 0x36, 42 => 0x5d, 45 => 0x76, 46 => 0x8f, 47 => 0x94, 48 => 0x97, 197 => 0x1428, 198 => 0x88, 341 => 0x210, 349 => 0x1d }, + 'wb_rggblevelsuncorrected' => { 380 => 0xa021 }, + 'wb_rggblevelsunknown' => { 38 => 0xf, 39 => 0x18, 41 => 0x1d, 45 => 0x4e, 46 => 0x4e, 47 => 0x4e, 48 => 0x56, 349 => 0x53 }, + 'wb_rggblevelsunknown10' => { 38 => 0x5f, 39 => 0x98, 41 => 0x72, 45 => 0x9e, 46 => 0x7b, 47 => 0x7b, 48 => 0x83 }, + 'wb_rggblevelsunknown11' => { 38 => 0x64, 39 => 0xa0, 41 => 0x77, 45 => 0xa3, 46 => 0xa3, 47 => 0x80, 48 => 0xab }, + 'wb_rggblevelsunknown12' => { 38 => 0x69, 39 => 0xa8, 41 => 0x7c, 45 => 0xa8, 46 => 0xa8, 47 => 0xa8, 48 => 0xb0 }, + 'wb_rggblevelsunknown13' => { 38 => 0x6e, 39 => 0xb0, 41 => 0x81, 45 => 0xad, 46 => 0xad, 47 => 0xad, 48 => 0xb5 }, + 'wb_rggblevelsunknown14' => { 41 => 0x86, 45 => 0xb2, 46 => 0xb2, 47 => 0xb2, 48 => 0xba }, + 'wb_rggblevelsunknown15' => { 41 => 0x8b, 45 => 0xb7, 46 => 0xb7, 47 => 0xb7, 48 => 0xbf }, + 'wb_rggblevelsunknown16' => { 41 => 0x9f, 46 => 0xbc, 47 => 0xbc, 48 => 0xc4 }, + 'wb_rggblevelsunknown17' => { 46 => 0xc1, 47 => 0xc1, 48 => 0xc9 }, + 'wb_rggblevelsunknown18' => { 46 => 0xc6, 47 => 0xc6, 48 => 0xce }, + 'wb_rggblevelsunknown19' => { 46 => 0xcb, 47 => 0xcb, 48 => 0xd3 }, + 'wb_rggblevelsunknown2' => { 38 => 0x37, 39 => 0x58, 41 => 0x4a, 45 => 0x53, 46 => 0x53, 47 => 0x53, 48 => 0x5b }, + 'wb_rggblevelsunknown20' => { 46 => 0xd0, 47 => 0xd0, 48 => 0xd8 }, + 'wb_rggblevelsunknown21' => { 47 => 0xd5, 48 => 0xdd }, + 'wb_rggblevelsunknown22' => { 47 => 0xda, 48 => 0xe2 }, + 'wb_rggblevelsunknown23' => { 47 => 0xdf, 48 => 0xe7 }, + 'wb_rggblevelsunknown24' => { 47 => 0xe4, 48 => 0xec }, + 'wb_rggblevelsunknown25' => { 47 => 0xe9, 48 => 0xf1 }, + 'wb_rggblevelsunknown26' => { 47 => 0xee, 48 => 0xf6 }, + 'wb_rggblevelsunknown27' => { 47 => 0xf3, 48 => 0xfb }, + 'wb_rggblevelsunknown28' => { 47 => 0xf8, 48 => 0x100 }, + 'wb_rggblevelsunknown29' => { 47 => 0xfd, 48 => 0x105 }, + 'wb_rggblevelsunknown3' => { 38 => 0x3c, 39 => 0x60, 41 => 0x4f, 45 => 0x58, 46 => 0x58, 47 => 0x58, 48 => 0x60 }, + 'wb_rggblevelsunknown30' => { 47 => 0x102 }, + 'wb_rggblevelsunknown4' => { 38 => 0x41, 39 => 0x68, 41 => 0x54, 45 => 0x5d, 46 => 0x5d, 47 => 0x5d, 48 => 0x65 }, + 'wb_rggblevelsunknown5' => { 38 => 0x46, 39 => 0x70, 41 => 0x59, 45 => 0x62, 46 => 0x62, 47 => 0x62, 48 => 0x6a }, + 'wb_rggblevelsunknown6' => { 38 => 0x4b, 39 => 0x78, 41 => 0x5e, 45 => 0x8a, 46 => 0x67, 47 => 0x67, 48 => 0x6f }, + 'wb_rggblevelsunknown7' => { 38 => 0x50, 39 => 0x80, 41 => 0x63, 45 => 0x8f, 46 => 0x6c, 47 => 0x6c, 48 => 0x74 }, + 'wb_rggblevelsunknown8' => { 38 => 0x55, 39 => 0x88, 41 => 0x68, 45 => 0x94, 46 => 0x71, 47 => 0x71, 48 => 0x79 }, + 'wb_rggblevelsunknown9' => { 38 => 0x5a, 39 => 0x90, 41 => 0x6d, 45 => 0x99, 46 => 0x76, 47 => 0x76, 48 => 0x7e }, + 'wb_rggblevelsuserselected' => { 349 => 0x5c }, + 'wbadjblueamber' => { 100 => 0x20106 }, + 'wbadjbluebalance' => { 265 => 0x8 }, + 'wbadjcolortemp' => { 100 => 0x20102, 105 => 0x1a }, + 'wbadjlighting' => { 265 => 0x14 }, + 'wbadjmagentagreen' => { 100 => 0x20105 }, + 'wbadjmode' => { 265 => 0x10 }, + 'wbadjredbalance' => { 265 => 0x0 }, + 'wbadjrggblevels' => { 100 => 0x20125, 105 => 0x6 }, + 'wbadjtemperature' => { 265 => 0x18 }, + 'wbadjtint' => { 265 => 0x25 }, + 'wbbluelevel' => { 301 => 0x324, 306 => 0x8006, 311 => 0x26 }, + 'wbbracketingsteps' => { 237 => 0x174d, 238 => 0x87c, 246 => 0x1757 }, + 'wbbracketmode' => { 55 => 0x9 }, + 'wbbracketshotnumber' => { 182 => 0x2b, 373 => 0x101a }, + 'wbbracketvalueab' => { 55 => 0xc }, + 'wbbracketvaluegm' => { 55 => 0xd }, + 'wbfinetuneactive' => { 105 => 0x24 }, + 'wbfinetunesaturation' => { 105 => 0x28 }, + 'wbfinetunetone' => { 105 => 0x2c }, + 'wbgreenlevel' => { 301 => 0x323, 306 => 0x8005, 311 => 0x25 }, + 'wbmediaimagesizesetting' => { 81 => 0x708 }, + 'wbmode' => { 184 => 0x4, 288 => 0x1015 }, + 'wbredlevel' => { 301 => 0x322, 306 => 0x8004, 311 => 0x24 }, + 'wbscale' => { 185 => 0x0 }, + 'wbshiftab' => { 71 => 0xc, 306 => 0x46, 323 => 0x10 }, + 'wbshiftab_gm' => { 406 => 0x2014 }, + 'wbshiftab_gm_precise' => { 406 => 0x2026 }, + 'wbshiftcreativecontrol' => { 306 => 0x92 }, + 'wbshiftgm' => { 71 => 0xd, 306 => 0x47, 323 => 0x11 }, + 'wbshiftintelligentauto' => { 306 => 0x8b }, + 'wbtype1' => { 312 => 0x1, 313 => 0x1 }, + 'wbtype2' => { 312 => 0x4, 313 => 0x5 }, + 'wbtype3' => { 312 => 0x7, 313 => 0x9 }, + 'wbtype4' => { 312 => 0xa, 313 => 0xd }, + 'wbtype5' => { 312 => 0xd, 313 => 0x11 }, + 'wbtype6' => { 312 => 0x10, 313 => 0x15 }, + 'wbtype7' => { 312 => 0x13, 313 => 0x19 }, + 'webstatement' => { 492 => 'WebStatement' }, + 'what' => { 462 => 'What', 464 => 'What' }, + 'whitebalance' => { 7 => 0x6f, 8 => [0x44,0x4a], 9 => 0xbc, 10 => 0x36, 11 => 0x5e, 12 => 0x36, 13 => 0x78, 14 => 0x6f, 15 => 0x6f, 16 => 0x73, 17 => 0x6f, 18 => 0x78, 19 => 0x54, 20 => 0x6f, 21 => 0xbc, 22 => 0x7b, 24 => 0xbc, 25 => 0xc2, 27 => 0x131, 28 => 0x77, 71 => 0x8, 74 => 0x7, 109 => 0x7, 110 => [0x19,0x2012], 116 => [0xa403,0xfe4e], 124 => 0x1002, 134 => 0x3fc, 135 => 0xfa0d, 136 => 0x40, 147 => 0x1a, 176 => 0x3, 177 => 0xe, 178 => 0x4, 179 => 0xb, 181 => 0x115, 219 => 0x5, 249 => 0x7, 301 => 0x304, 306 => 0x3, 308 => 0x3033, 341 => 0x19, 348 => 0x7, 372 => 0x26, 373 => 0x1003, 383 => [0x88,0x3c,0x7,0x58], 393 => 0xf, 394 => 0xe, 406 => [0x115,0xb054], 462 => 'WhiteBalance', 464 => 'WhiteBalance', 468 => 'WhiteBalance' }, + 'whitebalance0' => { 172 => 'WhiteBalance0' }, + 'whitebalance1' => { 172 => 'WhiteBalance1' }, + 'whitebalance2' => { 172 => 'WhiteBalance2', 283 => 0x500 }, + 'whitebalanceadj' => { 100 => 0x20101, 105 => 0x18, 259 => 0x76a43204 }, + 'whitebalanceautoadjustment' => { 319 => 0x0 }, + 'whitebalancebias' => { 110 => 0x2011, 288 => 0x304, 306 => 0x23 }, + 'whitebalanceblue' => { 71 => 0x7 }, + 'whitebalancebracket' => { 283 => 0x502, 288 => 0x303 }, + 'whitebalancebracketing' => { 179 => 0x22, 182 => 0x2c, 404 => 0x2c }, + 'whitebalancecomp' => { 291 => 0x1001 }, + 'whitebalancedetected' => { 134 => 0x3fb }, + 'whitebalancefinetune' => { 124 => 0x100a, 179 => 0x38, 181 => 0x112, 219 => 0xb, 373 => 0x1004, 393 => 0x6, 394 => 0x5, 406 => 0x112 }, + 'whitebalancemode' => { 134 => 0x3fa, 341 => 0x1a }, + 'whitebalancered' => { 71 => 0x6 }, + 'whitebalanceset' => { 322 => 0xa }, + 'whitebalancesetting' => { 179 => 0x23, 393 => 0x5, 394 => 0x4, 395 => 0x16, 411 => 0xd }, + 'whitebalancesetup' => { 380 => 0x41 }, + 'whitebalancetemperature' => { 283 => 0x501 }, + 'whiteboard' => { 288 => 0x301 }, + 'whitelevel' => { 116 => 0xc61d, 341 => 0x7e }, + 'whitepoint' => { 116 => 0x13e, 341 => 0x201, 484 => 'WhitePoint' }, + 'whites2012' => { 462 => 'Whites2012', 464 => 'Whites2012' }, + 'whitesadj' => { 439 => 0x9017 }, + 'wideadapter' => { 373 => 0x1017 }, + 'widefocuszone' => { 176 => 0x2f }, + 'widerange' => { 382 => 0x20f }, + 'windmode' => { 134 => 0x3f4 }, + 'windowlocation' => { 366 => 'WLOC' }, + 'windowsatom' => { 463 => 'windowsAtom' }, + 'windowsatomextension' => { 463 => [\'windowsAtom','windowsAtomExtension'] }, + 'windowsatominvocationflags' => { 463 => [\'windowsAtom','windowsAtomInvocationFlags'] }, + 'windowsatomuncprojectpath' => { 463 => [\'windowsAtom','windowsAtomUncProjectPath'] }, + 'wordcount' => { 478 => 'wordCount' }, + 'workcolorspace' => { 100 => 0x10200, 105 => 0x270 }, + 'workflowtag' => { 474 => 'WorkflowTag' }, + 'workflowtagcvid' => { 474 => [\'WorkflowTag','WorkflowTagCvId'] }, + 'workflowtagcvtermid' => { 474 => [\'WorkflowTag','WorkflowTagCvTermId'] }, + 'workflowtagcvtermname' => { 474 => [\'WorkflowTag','WorkflowTagCvTermName'] }, + 'workflowtagcvtermrefinedabout' => { 474 => [\'WorkflowTag','WorkflowTagCvTermRefinedAbout'] }, + 'worktodo' => { 470 => 'WorkToDo' }, + 'worldtimelocation' => { 306 => 0x3a, 341 => 0x22, 347 => '0.1' }, + 'writer-editor' => { 128 => 0x7a }, + 'x3filllight' => { 383 => 0x12 }, + 'xattrquarantine' => { 170 => 'com.apple.quarantine' }, + 'xilinxversion' => { 134 => 0x414 }, + 'xml' => { 132 => 'xml ' }, + 'xmp' => { 103 => 0xffff00f6, 117 => 'XMP' }, + 'xmptoolkit' => { 485 => 'xmptk' }, + 'xpauthor' => { 116 => 0x9c9d }, + 'xpcomment' => { 116 => 0x9c9c }, + 'xpkeywords' => { 116 => 0x9c9e }, + 'xposition' => { 116 => 0x11e }, + 'xpsubject' => { 116 => 0x9c9f }, + 'xptitle' => { 116 => 0x9c9b }, + 'xresolution' => { 116 => 0x11a, 131 => 0x3, 356 => 0x0, 484 => 'XResolution' }, + 'xyresolution' => { 120 => 0x3 }, + 'yaw' => { 112 => 0x7, 366 => ['_yaw',"\xa9fyw"] }, + 'yawangle' => { 237 => 0x3513, 238 => 0x2c2c, 246 => 0x36fc, 378 => 0x0 }, + 'ycbcrcoefficients' => { 116 => 0x211, 484 => 'YCbCrCoefficients' }, + 'ycbcrpositioning' => { 116 => 0x213, 484 => 'YCbCrPositioning' }, + 'ycbcrsubsampling' => { 116 => 0x212, 484 => 'YCbCrSubSampling' }, + 'year' => { 358 => 'yrrc', 360 => 'year' }, + 'yearcreated' => { 136 => 0x10, 145 => 0xc }, + 'yellowhsl' => { 100 => 0x20912 }, + 'yield' => { 480 => 'yield' }, + 'yposition' => { 116 => 0x11f }, + 'yresolution' => { 116 => 0x11b, 131 => 0x5, 356 => 0x4, 484 => 'YResolution' }, + 'zonematching' => { 181 => 0x10a, 184 => [0x3a,0x4a], 406 => 0xb024 }, + 'zonematchingmode' => { 179 => 0x14 }, + 'zonematchingon' => { 178 => 0x75 }, + 'zonematchingvalue' => { 393 => 0x1f }, + 'zoomedpreviewlength' => { 288 => 0xf05 }, + 'zoomedpreviewsize' => { 288 => 0xf06 }, + 'zoomedpreviewstart' => { 288 => 0xf04 }, + 'zoomsourcewidth' => { 34 => 0x24 }, + 'zoomstepcount' => { 286 => 0x300, 288 => 0x100d }, + 'zoomtargetwidth' => { 34 => 0x25 }, ); # lookup for non-writable tags to check if the name exists @@ -5864,6 +6277,7 @@ my %tagExists = ( 'abovecolor' => 1, 'abstract' => 1, 'abstractfilename' => 1, + 'acceldata' => 1, 'accelerometertime' => 1, 'accessdate' => 1, 'accountname' => 1, @@ -5950,10 +6364,10 @@ my %tagExists = ( 'ainumlayers' => 1, 'aipdfprivatedata' => 1, 'aiprivatedata' => 1, + 'airspeed' => 1, 'airulerunits' => 1, 'aitargetresolution' => 1, 'album2' => 1, - 'albumartist' => 1, 'albumartistsortorder' => 1, 'albumcoverurl' => 1, 'albumid' => 1, @@ -5961,7 +6375,6 @@ my %tagExists = ( 'albumname' => 1, 'albumsortorder' => 1, 'albumtitle' => 1, - 'albumtitleid' => 1, 'albumtitlesortorder' => 1, 'aliaslayermetadata' => 1, 'alignment' => 1, @@ -5986,6 +6399,7 @@ my %tagExists = ( 'alternateduotonecolors' => 1, 'alternatesourceurl' => 1, 'alternatespotcolors' => 1, + 'altitudefromtakeoff' => 1, 'ambienceinfo' => 1, 'angleaxis' => 1, 'angularvelocity' => 1, @@ -6007,22 +6421,19 @@ my %tagExists = ( 'anta' => 1, 'aperture' => 1, 'aperturedisplayed' => 1, - 'aperturemode' => 1, 'apeversion' => 1, 'app14flags0' => 1, 'app14flags1' => 1, 'app1_profile' => 1, 'apple-fi' => 1, 'applemaildatereceived' => 1, + 'applemaildatesent' => 1, 'applemailflagged' => 1, + 'applemailisremoteattachment' => 1, 'applemailmessageid' => 1, 'applemailpriority' => 1, 'applemailread' => 1, 'applemailrepliedto' => 1, - 'applestoreaccount' => 1, - 'applestoreaccounttype' => 1, - 'applestorecatalogid' => 1, - 'applestorecountry' => 1, 'application' => 1, 'applicationdata' => 1, 'applicationmissingmsg' => 1, @@ -6031,12 +6442,9 @@ my %tagExists = ( 'archivedfilename' => 1, 'ardronefile' => 1, 'ardronetelemetry' => 1, - 'arranger' => 1, - 'arrangerkeywords' => 1, 'artist2' => 1, 'artistlen' => 1, 'artisturl' => 1, - 'artwork' => 1, 'ascender' => 1, 'ascent' => 1, 'asfleakybucketpairs' => 1, @@ -6097,7 +6505,6 @@ my %tagExists = ( 'audiofileurl' => 1, 'audioformat' => 1, 'audioframesize' => 1, - 'audiogain' => 1, 'audiohasvariablepacketbytesizes' => 1, 'audioheader' => 1, 'audioinfo' => 1, @@ -6139,14 +6546,19 @@ my %tagExists = ( 'authorurl' => 1, 'autoisomin' => 1, 'autolowlightduration' => 1, + 'automationanimation' => 1, + 'automationflags' => 1, 'autorotation' => 1, 'autosavefilepath' => 1, 'autosaveformat' => 1, 'autosummary' => 1, 'aux' => 1, 'auxiliaryimagetype' => 1, + 'av1configuration' => 1, + 'av1configurationversion' => 1, 'avcconfiguration' => 1, 'averagebitrate' => 1, + 'averageframerate' => 1, 'averagelevel' => 1, 'avgbitrate' => 1, 'avgbytespersec' => 1, @@ -6160,6 +6572,7 @@ my %tagExists = ( 'axisdistancex' => 1, 'axisdistancey' => 1, 'axisdistancez' => 1, + 'axml' => 1, 'background' => 1, 'backgroundcolor' => 1, 'backgroundcolorindicator' => 1, @@ -6171,7 +6584,6 @@ my %tagExists = ( 'backuptime' => 1, 'badfaxlines' => 1, 'bahpver' => 1, - 'balance' => 1, 'balpver' => 1, 'band' => 1, 'bandwidthsharing' => 1, @@ -6185,7 +6597,6 @@ my %tagExists = ( 'baselinelength' => 1, 'baseviewpointnum' => 1, 'basisobject' => 1, - 'bass' => 1, 'battery' => 1, 'batterycapacity' => 1, 'batterycurrent' => 1, @@ -6198,7 +6609,8 @@ my %tagExists = ( 'bccaddresses' => 1, 'bccnames' => 1, 'beats-per-minute' => 1, - 'beatsperminute' => 1, + 'beautycolorlevel' => 1, + 'beautyretouchlevel' => 1, 'belowcolor' => 1, 'beta' => 1, 'bibligraphicfilename' => 1, @@ -6207,7 +6619,10 @@ my %tagExists = ( 'billinginformation' => 1, 'binaryfilter' => 1, 'binaryxml' => 1, + 'binning' => 1, 'birthday' => 1, + 'bitdepthchroma' => 1, + 'bitdepthluma' => 1, 'bitrate' => 1, 'bitrateinfo' => 1, 'bitratemutualexclusion' => 1, @@ -6248,8 +6663,10 @@ my %tagExists = ( 'bluetrc' => 1, 'bluex' => 1, 'bluey' => 1, + 'blurstrength' => 1, 'bmpversion' => 1, 'boardtemperature' => 1, + 'bokehshape' => 1, 'bookname' => 1, 'booktitle' => 1, 'booktype' => 1, @@ -6270,9 +6687,7 @@ my %tagExists = ( 'boundaryorigin' => 1, 'boundingbox' => 1, 'bracketingcounter' => 1, - 'bracketinginfooffset' => 1, 'bracketingmode' => 1, - 'bracketingoffset' => 1, 'bracketingstep' => 1, 'bracketshot' => 1, 'brain' => 1, @@ -6312,10 +6727,13 @@ my %tagExists = ( 'buytickets' => 1, 'bw_halftoninginfo' => 1, 'bw_transferfunc' => 1, + 'bwf_umid' => 1, 'bwfversion' => 1, 'bytelength' => 1, 'byteorder' => 1, + 'byteordermark' => 1, 'bytes' => 1, + 'bytesperline' => 1, 'bytesperminute' => 1, 'cachecontrol' => 1, 'cachedimageheight' => 1, @@ -6327,7 +6745,6 @@ my %tagExists = ( 'callbacknumber' => 1, 'callletters' => 1, 'camcore' => 1, - 'camera' => 1, 'camera1' => 1, 'camera2' => 1, 'cameraarrangementinterval' => 1, @@ -6335,8 +6752,6 @@ my %tagExists = ( 'camerabody' => 1, 'camerabyteorder' => 1, 'cameradatetime' => 1, - 'cameradirection' => 1, - 'cameraidentifier' => 1, 'cameraifd' => 1, 'camerainfo' => 1, 'camerainfo2' => 1, @@ -6345,7 +6760,6 @@ my %tagExists = ( 'camerainfounknown' => 1, 'cameramaker' => 1, 'cameramanufacturer' => 1, - 'cameramotion' => 1, 'cameraname' => 1, 'cameraobjbacktype' => 1, 'cameraobject' => 1, @@ -6353,6 +6767,7 @@ my %tagExists = ( 'cameraobjtype' => 1, 'cameraobjversion' => 1, 'cameraoperator' => 1, + 'camerapan' => 1, 'camerapartnumber' => 1, 'cameraprofileversion' => 1, 'camerascalemax' => 1, @@ -6372,6 +6787,7 @@ my %tagExists = ( 'cameratemperatureminclip' => 1, 'cameratemperatureminsaturated' => 1, 'cameratemperatureminwarn' => 1, + 'cameratilt' => 1, 'camm0' => 1, 'camm1' => 1, 'camm2' => 1, @@ -6461,6 +6877,7 @@ my %tagExists = ( 'capturexresolutionunit' => 1, 'captureyresolution' => 1, 'captureyresolutionunit' => 1, + 'car' => 1, 'carphone' => 1, 'casio' => 1, 'casiodata' => 1, @@ -6522,7 +6939,6 @@ my %tagExists = ( 'channelusage' => 1, 'chapter' => 1, 'chaptercount' => 1, - 'chapterlist' => 1, 'chapterlisttrackid' => 1, 'chaptername' => 1, 'chapternum' => 1, @@ -6550,6 +6966,8 @@ my %tagExists = ( 'checkedby' => 1, 'children' => 1, 'chmversion' => 1, + 'chromaformat' => 1, + 'chromasampleposition' => 1, 'chromaticaberrationparams' => 1, 'chromaticadaptation' => 1, 'chromaticities' => 1, @@ -6579,8 +6997,6 @@ my %tagExists = ( 'cleanfaxdata' => 1, 'clientid' => 1, 'clipboundary' => 1, - 'clipfilename' => 1, - 'clipid' => 1, 'clipobjects' => 1, 'clippath' => 1, 'clippingboundary' => 1, @@ -6591,6 +7007,7 @@ my %tagExists = ( 'clonetype' => 1, 'closedcaptioning' => 1, 'cmmflags' => 1, + 'cmp1' => 1, 'cmykequivalent' => 1, 'coarsedata' => 1, 'coarsemapimage' => 1, @@ -6604,7 +7021,6 @@ my %tagExists = ( 'codesize' => 1, 'codestreamheader' => 1, 'codestreamregistration' => 1, - 'codeversion' => 1, 'codinghistory' => 1, 'codingmethods' => 1, 'codirectors' => 1, @@ -6664,6 +7080,7 @@ my %tagExists = ( 'colorobjtype' => 1, 'colorobjversion' => 1, 'colorpalette' => 1, + 'colorpopstrength' => 1, 'colorprimaries' => 1, 'colorresolutiondepth' => 1, 'colorresponseunit' => 1, @@ -6683,6 +7100,7 @@ my %tagExists = ( 'colortransform' => 1, 'colortwistmatrix' => 1, 'colortype' => 1, + 'columncount' => 1, 'columngainfactors' => 1, 'columnresetoffsets' => 1, 'command' => 1, @@ -6703,7 +7121,6 @@ my %tagExists = ( 'compatibility' => 1, 'compatiblebrands' => 1, 'compatiblefontname' => 1, - 'compilation' => 1, 'complete' => 1, 'compobj' => 1, 'compobjusertype' => 1, @@ -6712,7 +7129,6 @@ my %tagExists = ( 'componentdefinition' => 1, 'componentmapping' => 1, 'componenttable' => 1, - 'composerkeywords' => 1, 'composers' => 1, 'composersortorder' => 1, 'compositinglayerheader' => 1, @@ -6732,7 +7148,6 @@ my %tagExists = ( 'compressiontype' => 1, 'compressorid' => 1, 'compressorname' => 1, - 'compressorversion' => 1, 'computedatmospherictrans' => 1, 'computer' => 1, 'concreteflag' => 1, @@ -6745,23 +7160,22 @@ my %tagExists = ( 'consecutivebadfaxlines' => 1, 'consoledata' => 1, 'consolefedata' => 1, + 'constantframerate' => 1, + 'constraintindicatorflags' => 1, 'cont' => 1, 'contactnames' => 1, 'containerversion' => 1, 'contake' => 1, 'contentbranding' => 1, - 'contentcreatedate' => 1, 'contentdescribes' => 1, 'contentdescription' => 1, 'contentdescriptionnotes' => 1, 'contentdisposition' => 1, 'contentdistributor' => 1, 'contentdistributorduration' => 1, - 'contentdistributorid' => 1, 'contentdistributortype' => 1, 'contentencryption' => 1, 'contentgroupdescription' => 1, - 'contentid' => 1, 'contentlanguage' => 1, 'contentprotected' => 1, 'contentprotectedpercent' => 1, @@ -6788,10 +7202,8 @@ my %tagExists = ( 'count' => 1, 'countinfo' => 1, 'country-region' => 1, - 'coverart' => 1, 'coverartmimetype' => 1, 'coverarttype' => 1, - 'coveruri' => 1, 'coyotesense' => 1, 'coyotestatus' => 1, 'cpuarchitecture' => 1, @@ -6802,6 +7214,7 @@ my %tagExists = ( 'cpuversions' => 1, 'cr2cfapattern' => 1, 'crcdevelparams' => 1, + 'crd' => 1, 'crdinfo' => 1, 'createdby' => 1, 'creatingapplication' => 1, @@ -6890,9 +7303,6 @@ my %tagExists = ( 'customsettingsd810' => 1, 'customsettingsd850' => 1, 'customsettingsd90' => 1, - 'customsettingsoffset' => 1, - 'cx' => 1, - 'cy' => 1, 'd-lightinghqdata' => 1, 'd-lightinghsdata' => 1, 'daccountspervolt' => 1, @@ -6907,6 +7317,7 @@ my %tagExists = ( 'darkrefoffsettest' => 1, 'darkthreshold' => 1, 'darwindata' => 1, + 'data' => 1, 'data1' => 1, 'data2' => 1, 'databasename' => 1, @@ -6914,7 +7325,6 @@ my %tagExists = ( 'datadump' => 1, 'datadump2' => 1, 'datainfo' => 1, - 'datainformation' => 1, 'datakey' => 1, 'datalen' => 1, 'datalength' => 1, @@ -6979,6 +7389,7 @@ my %tagExists = ( 'decoderversion' => 1, 'defaultaudiostream' => 1, 'defaultchar' => 1, + 'defaultcmyk' => 1, 'defaultdisplayheight' => 1, 'defaultdisplaywidth' => 1, 'defaultimagecolor' => 1, @@ -6994,6 +7405,7 @@ my %tagExists = ( 'delay' => 1, 'delaycols' => 1, 'delaytime' => 1, + 'delimiter' => 1, 'delta12to8spline' => 1, 'delta8to12spline' => 1, 'deltapngheader' => 1, @@ -7003,11 +7415,15 @@ my %tagExists = ( 'dependentimage1entrynumber' => 1, 'dependentimage2entrynumber' => 1, 'depth' => 1, + 'depthhwheight' => 1, + 'depthhwwidth' => 1, 'depthmapdata' => 1, 'depthmapheight' => 1, 'depthmapname' => 1, 'depthmaptiff' => 1, 'depthmapwidth' => 1, + 'depthswheight' => 1, + 'depthswwidth' => 1, 'descender' => 1, 'designer' => 1, 'designerurl' => 1, @@ -7027,6 +7443,7 @@ my %tagExists = ( 'devicemodel' => 1, 'devicemodeldesc' => 1, 'devicename' => 1, + 'deviceorientation' => 1, 'devicesettings' => 1, 'dex' => 1, 'dialect' => 1, @@ -7048,7 +7465,6 @@ my %tagExists = ( 'directors' => 1, 'disableflagspresent' => 1, 'discardobjects' => 1, - 'disknumber' => 1, 'displayartist' => 1, 'displayinfo' => 1, 'displayresolution' => 1, @@ -7061,6 +7477,8 @@ my %tagExists = ( 'displayyresolutionunit' => 1, 'dispose' => 1, 'disposition' => 1, + 'distance' => 1, + 'distancefromhome' => 1, 'distortinfo' => 1, 'distortioninfo' => 1, 'distortionversion' => 1, @@ -7135,6 +7553,10 @@ my %tagExists = ( 'drmkeyid' => 1, 'drmserverid' => 1, 'drone-dji' => 1, + 'dronepitch' => 1, + 'dronequaternion' => 1, + 'droneroll' => 1, + 'droneyaw' => 1, 'dropbykeyword' => 1, 'dropchunks' => 1, 'dtcpiphost' => 1, @@ -7146,7 +7568,7 @@ my %tagExists = ( 'dtvcontent' => 1, 'dualcameraimage' => 1, 'dualcameraimagename' => 1, - 'dualshotinfo' => 1, + 'dualshotextra' => 1, 'ducky' => 1, 'duedate' => 1, 'dummycolsleft' => 1, @@ -7167,25 +7589,19 @@ my %tagExists = ( 'edgesplinehigh' => 1, 'edgesplinelow' => 1, 'edgesplinemed' => 1, - 'edit1' => 1, - 'edit2' => 1, - 'edit3' => 1, - 'edit4' => 1, 'edit4data' => 1, - 'edit5' => 1, - 'edit6' => 1, - 'edit7' => 1, - 'edit8' => 1, - 'edit9' => 1, 'editdata' => 1, 'editedby' => 1, 'editor' => 1, 'edittagarray' => 1, 'effect' => 1, 'effectivebw' => 1, + 'effectstrength' => 1, 'effectsvisible' => 1, + 'effecttype' => 1, 'eighteenpercentpoint' => 1, 'eighthlanguage' => 1, + 'electronicimagestabilization' => 1, 'electronicvr' => 1, 'elementarystreamtrack' => 1, 'embeddedaudiofile' => 1, @@ -7202,16 +7618,13 @@ my %tagExists = ( 'embeddedimagewidth' => 1, 'embeddedjpg' => 1, 'embeddedpng' => 1, + 'embeddedvideo' => 1, 'embeddedvideofile' => 1, 'embeddedvideotype' => 1, 'emphasis' => 1, 'empty' => 1, - 'encodedby' => 1, 'encodedpixelsdimensions' => 1, 'encodedusing' => 1, - 'encodedwith' => 1, - 'encoder' => 1, - 'encoderid' => 1, 'encoderoptions' => 1, 'encodersettings' => 1, 'encodervendor' => 1, @@ -7233,7 +7646,6 @@ my %tagExists = ( 'entrytype' => 1, 'environmentmap' => 1, 'envvardata' => 1, - 'episodeglobaluniqueid' => 1, 'eppim' => 1, 'eprint' => 1, 'epsoptions' => 1, @@ -7379,7 +7791,6 @@ my %tagExists = ( 'fedexedr' => 1, 'fffheader' => 1, 'fieldmdp' => 1, - 'fieldofview' => 1, 'fieldpermissions' => 1, 'fifthlanguage' => 1, 'file1duration' => 1, @@ -7487,6 +7898,7 @@ my %tagExists = ( 'flashused' => 1, 'flashversion' => 1, 'flavor' => 1, + 'flipstatus' => 1, 'flir' => 1, 'flir_gps' => 1, 'flir_moreinfo' => 1, @@ -7506,6 +7918,7 @@ my %tagExists = ( 'fluormat8' => 1, 'fluormat9' => 1, 'flushtiming' => 1, + 'flyingstate' => 1, 'focalinfo' => 1, 'focallength35efl' => 1, 'focallength35mm' => 1, @@ -7519,6 +7932,8 @@ my %tagExists = ( 'focussettings' => 1, 'folder' => 1, 'folderpath' => 1, + 'follow-meanimation' => 1, + 'follow-memode' => 1, 'font' => 1, 'fontsize' => 1, 'fontsubfamily' => 1, @@ -7553,15 +7968,16 @@ my %tagExists = ( 'fragmentlist' => 1, 'fragmenttable' => 1, 'frame' => 1, + 'framebaseview' => 1, 'frameexposuretime' => 1, 'frameid' => 1, 'frameinfo' => 1, 'framepriority' => 1, - 'framereadouttime' => 1, 'framesize' => 1, 'framesizemax' => 1, 'framesizemin' => 1, 'framespersecond' => 1, + 'frameview' => 1, 'free' => 1, 'free-busystatus' => 1, 'freebytecounts' => 1, @@ -7593,12 +8009,16 @@ my %tagExists = ( 'gapless' => 1, 'gaudio' => 1, 'gaussianweights' => 1, - 'gdalmetadata' => 1, - 'gdalnodata' => 1, + 'gcamera' => 1, + 'gcreations' => 1, 'gdepth' => 1, 'geminfo' => 1, 'genbalance' => 1, 'gender' => 1, + 'generallevelidc' => 1, + 'generalprofileidc' => 1, + 'generalprofilespace' => 1, + 'generaltierflag' => 1, 'generator' => 1, 'generatorversion' => 1, 'genflags' => 1, @@ -7607,8 +8027,8 @@ my %tagExists = ( 'genmediainfo' => 1, 'genmediaversion' => 1, 'genopcolor' => 1, + 'genprofilecompatibilityflags' => 1, 'genr' => 1, - 'genreid' => 1, 'geo' => 1, 'geogangularunits' => 1, 'geogangularunitsize' => 1, @@ -7647,22 +8067,18 @@ my %tagExists = ( 'globalparametersifd' => 1, 'globalpixelsize' => 1, 'googlebot' => 1, - 'googlehostheader' => 1, - 'googlepingmessage' => 1, - 'googlepingurl' => 1, - 'googlesourcedata' => 1, - 'googlestarttime' => 1, - 'googletrackduration' => 1, 'gopro' => 1, 'goprogpmf' => 1, - 'goprotype' => 1, 'gpano' => 1, 'gpmd' => 1, 'gps' => 1, 'gpsaltituderaw' => 1, - 'gpscoordinates' => 1, 'gpsdatalist' => 1, 'gpsdatetimeraw' => 1, + 'gpsdestaltitude' => 1, + 'gpsframingaltitude' => 1, + 'gpsframinglatitude' => 1, + 'gpsframinglongitude' => 1, 'gpshorizontalaccuracy' => 1, 'gpsinfo' => 1, 'gpslatituderaw' => 1, @@ -7677,8 +8093,12 @@ my %tagExists = ( 'gpsspeedx' => 1, 'gpsspeedy' => 1, 'gpsspeedz' => 1, + 'gpstargetaltitude' => 1, + 'gpstargetlatitude' => 1, + 'gpstargetlongitude' => 1, 'gpstrackraw' => 1, 'gpsvalid' => 1, + 'gpsvelocitydown' => 1, 'gpsvelocityeast' => 1, 'gpsvelocitynorth' => 1, 'gpsvelocityup' => 1, @@ -7702,14 +8122,13 @@ my %tagExists = ( 'gridguidesinfo' => 1, 'group' => 1, 'groupcaption' => 1, - 'grouping' => 1, 'groupmutualexclusion' => 1, + 'groups' => 1, 'gsensor' => 1, 'gspherical' => 1, 'gtcitation' => 1, 'gtmodeltype' => 1, 'gtrastertype' => 1, - 'guid' => 1, 'gyroscope' => 1, 'handler' => 1, 'handlerclass' => 1, @@ -7732,6 +8151,8 @@ my %tagExists = ( 'hasmetadata' => 1, 'hasrealmergeddata' => 1, 'hasscript' => 1, + 'hasselbladexif' => 1, + 'hasselbladrawimage' => 1, 'hasvideo' => 1, 'hasxfa' => 1, 'hcusage' => 1, @@ -7739,7 +8160,6 @@ my %tagExists = ( 'hdrinfo' => 1, 'hdrl' => 1, 'hdrtoninginfo' => 1, - 'hdvideo' => 1, 'header' => 1, 'header4' => 1, 'headerext' => 1, @@ -7749,7 +8169,9 @@ my %tagExists = ( 'headingpairs' => 1, 'heightresolution' => 1, 'hevcconfiguration' => 1, + 'hevcconfigurationversion' => 1, 'hiddenslides' => 1, + 'highbitdepth' => 1, 'highisomode' => 1, 'highlightdata' => 1, 'highlightendpoints' => 1, @@ -7759,7 +8181,6 @@ my %tagExists = ( 'hintsampledesc' => 1, 'hinttrackinfo' => 1, 'hinttrackversion' => 1, - 'hintversion' => 1, 'histogram' => 1, 'historybuffersize' => 1, 'hmaphandling' => 1, @@ -7789,6 +8210,7 @@ my %tagExists = ( 'htctrack' => 1, 'http-equiv' => 1, 'httphostheader' => 1, + 'huawei' => 1, 'huffmantable' => 1, 'huffmantablelength' => 1, 'huffmantablevalue' => 1, @@ -7796,12 +8218,12 @@ my %tagExists = ( 'hyperlinkbase' => 1, 'hyperlinks' => 1, 'hyperlinkschanged' => 1, + 'iad1' => 1, 'icc_untagged' => 1, 'iccbased' => 1, 'iconenvdata' => 1, 'iconfilename' => 1, 'iconindex' => 1, - 'iconuri' => 1, 'ics' => 1, 'id' => 1, 'id3' => 1, @@ -7878,7 +8300,6 @@ my %tagExists = ( 'imageresources' => 1, 'imagerinitialtimingcode' => 1, 'imagerlogicprogram' => 1, - 'imagerotated' => 1, 'imagerotation' => 1, 'imagerotationstatus' => 1, 'imagertimingdata' => 1, @@ -7925,9 +8346,8 @@ my %tagExists = ( 'indexoffset' => 1, 'indexparameters' => 1, 'info' => 1, - 'information' => 1, - 'infourl' => 1, 'ingrreserved' => 1, + 'initialdelaysamples' => 1, 'initialdisplayeffect' => 1, 'initializationvector' => 1, 'initializeddatasize' => 1, @@ -7938,17 +8358,20 @@ my %tagExists = ( 'inputdataobjectlist' => 1, 'inputdevicename' => 1, 'inputdeviceserialnumber' => 1, + 'inputheight' => 1, + 'inputwidth' => 1, 'insertmode' => 1, 'insetnwpixelx' => 1, 'insetnwpixely' => 1, + 'insta360' => 1, 'institution' => 1, 'instructionset' => 1, + 'insv' => 1, 'integratetiming' => 1, 'intellectualproperty' => 1, 'intellectualpropertynotes' => 1, 'intensitystereo' => 1, 'intergraphflagregisters' => 1, - 'intergraphmatrix' => 1, 'intergraphpacketdata' => 1, 'interlace' => 1, 'interleavedfield' => 1, @@ -7987,6 +8410,7 @@ my %tagExists = ( 'irwindowtransmission' => 1, 'is_protected' => 1, 'is_trusted' => 1, + 'isartbokeh' => 1, 'isattachment' => 1, 'isbasefont' => 1, 'iscompleted' => 1, @@ -8003,7 +8427,6 @@ my %tagExists = ( 'isotherm2color' => 1, 'isprotected' => 1, 'isrc' => 1, - 'isrccode' => 1, 'isrcnumber' => 1, 'isrecurring' => 1, 'isvbr' => 1, @@ -8032,10 +8455,10 @@ my %tagExists = ( 'iterations' => 1, 'itunesinfo' => 1, 'itunesmediatype' => 1, - 'itunesu' => 1, 'itunmovi' => 1, 'itunsmpb' => 1, 'ituntool' => 1, + 'ixml' => 1, 'jbigoptions' => 1, 'jfif' => 1, 'jfifversion' => 1, @@ -8053,6 +8476,7 @@ my %tagExists = ( 'jpegdctables' => 1, 'jpegdigest' => 1, 'jpegexifdata' => 1, + 'jpegimagelength' => 1, 'jpeginfo' => 1, 'jpeglosslesspredictors' => 1, 'jpegpointtransforms' => 1, @@ -8065,7 +8489,6 @@ my %tagExists = ( 'jpegqualityestimate' => 1, 'jpegrestartinterval' => 1, 'jpegtables' => 1, - 'jpginfooffset' => 1, 'jplcartoifd' => 1, 'jsonmetadata' => 1, 'jumptoxpep' => 1, @@ -8196,6 +8619,7 @@ my %tagExists = ( 'leftdarkcol2' => 1, 'leftdarkrect' => 1, 'leftmag' => 1, + 'leftmargin' => 1, 'legalcopyright' => 1, 'legaltrademarks' => 1, 'leicaleic' => 1, @@ -8209,8 +8633,12 @@ my %tagExists = ( 'lensdata0201' => 1, 'lensdata0204' => 1, 'lensdata0400' => 1, + 'lensdata0402' => 1, + 'lensdata0403' => 1, + 'lensdata0800' => 1, 'lensdataunknown' => 1, 'lensdataversion' => 1, + 'lensfacing' => 1, 'lensinfoq' => 1, 'lensmaker' => 1, 'lensnumber' => 1, @@ -8219,7 +8647,6 @@ my %tagExists = ( 'lensshading' => 1, 'lenstableindex' => 1, 'levelinfo' => 1, - 'levelmeter' => 1, 'libraryid' => 1, 'libraryname' => 1, 'licenseinfourl' => 1, @@ -8235,35 +8662,34 @@ my %tagExists = ( 'linearizationcoefficients1' => 1, 'linearizationcoefficients2' => 1, 'linearized' => 1, + 'linecount' => 1, 'lineorder' => 1, 'lines' => 1, 'linkedprofilename' => 1, 'linkerversion' => 1, + 'linkgoodput' => 1, 'linkinfo' => 1, + 'linkquality' => 1, 'linkstatus' => 1, 'linksuptodate' => 1, 'linktarget' => 1, 'linlogtable' => 1, 'listtype' => 1, 'lit' => 1, + 'livephotoinfo' => 1, 'ln0' => 1, 'ln1' => 1, 'localbasepath' => 1, 'localdeltatype' => 1, 'localeindicator' => 1, 'localpositionned' => 1, - 'locationbody' => 1, - 'locationdate' => 1, 'locationinfo' => 1, 'locationinformation' => 1, - 'locationnote' => 1, - 'locationrole' => 1, 'lockedpropertylist' => 1, 'locks' => 1, 'loglintable' => 1, 'logoiconurl' => 1, 'logourl' => 1, - 'longdescription' => 1, 'lookheadbacktype' => 1, 'lookheader' => 1, 'lookheadname' => 1, @@ -8281,7 +8707,6 @@ my %tagExists = ( 'lookmat9' => 1, 'lookmodtransform' => 1, 'lookuptable' => 1, - 'loopstyle' => 1, 'lotus' => 1, 'lr' => 1, 'lslv' => 1, @@ -8289,7 +8714,6 @@ my %tagExists = ( 'luminanceconsts' => 1, 'lyricist' => 1, 'lyrics_synchronised' => 1, - 'lyricsuri' => 1, 'machineid' => 1, 'machinetype' => 1, 'macintoshnsprintinfo' => 1, @@ -8309,9 +8733,7 @@ my %tagExists = ( 'makernotepentax5a' => 1, 'makernotepentax5b' => 1, 'makernotepentax5c' => 1, - 'makernotepentaxunknown' => 1, 'makernotes' => 1, - 'makerurl' => 1, 'mandatorybackground' => 1, 'manufacturecode' => 1, 'manufactureindex' => 1, @@ -8361,15 +8783,19 @@ my %tagExists = ( 'mditemacquisitionmodel' => 1, 'mditemaltitude' => 1, 'mditemaperture' => 1, + 'mditemaudiobitrate' => 1, + 'mditemaudiochannelcount' => 1, 'mditemauthoremailaddresses' => 1, 'mditemauthors' => 1, 'mditembitspersample' => 1, 'mditembundleidentifier' => 1, 'mditemcity' => 1, + 'mditemcodecs' => 1, 'mditemcolorspace' => 1, 'mditemcomment' => 1, 'mditemcontentcreationdate' => 1, 'mditemcontentcreationdate_ranking' => 1, + 'mditemcontentcreationdateranking' => 1, 'mditemcontentmodificationdate' => 1, 'mditemcontenttype' => 1, 'mditemcontenttypetree' => 1, @@ -8382,6 +8808,7 @@ my %tagExists = ( 'mditemdescription' => 1, 'mditemdisplayname' => 1, 'mditemdownloadeddate' => 1, + 'mditemdurationseconds' => 1, 'mditememailconversationid' => 1, 'mditemencodingapplications' => 1, 'mditemexifgpsversion' => 1, @@ -8412,6 +8839,7 @@ my %tagExists = ( 'mditemidentifier' => 1, 'mditemimagedirection' => 1, 'mditeminterestingdate_ranking' => 1, + 'mditeminterestingdateranking' => 1, 'mditemisapplicationmanaged' => 1, 'mditemisexistingthread' => 1, 'mditemislikelyjunk' => 1, @@ -8419,11 +8847,14 @@ my %tagExists = ( 'mditemkeywords' => 1, 'mditemkind' => 1, 'mditemlastuseddate' => 1, + 'mditemlastuseddate_ranking' => 1, 'mditemlatitude' => 1, + 'mditemlensmodel' => 1, 'mditemlogicalsize' => 1, 'mditemlongitude' => 1, 'mditemmailboxes' => 1, 'mditemmaildatereceived_ranking' => 1, + 'mditemmediatypes' => 1, 'mditemnumberofpages' => 1, 'mditemorientation' => 1, 'mditemoriginapplicationidentifier' => 1, @@ -8446,12 +8877,23 @@ my %tagExists = ( 'mditemsecuritymethod' => 1, 'mditemspeed' => 1, 'mditemstateorprovince' => 1, + 'mditemstreamable' => 1, 'mditemsubject' => 1, 'mditemtimestamp' => 1, 'mditemtitle' => 1, + 'mditemtotalbitrate' => 1, 'mditemusecount' => 1, 'mditemuseddates' => 1, + 'mditemuserdownloadeddate' => 1, + 'mditemuserdownloadeduserhandle' => 1, + 'mditemusersharedreceiveddate' => 1, + 'mditemusersharedreceivedrecipient' => 1, + 'mditemusersharedreceivedrecipienthandle' => 1, + 'mditemusersharedreceivedsender' => 1, + 'mditemusersharedreceivedsenderhandle' => 1, + 'mditemusersharedreceivedtransport' => 1, 'mditemversion' => 1, + 'mditemvideobitrate' => 1, 'mditemwherefroms' => 1, 'mditemwhitebalance' => 1, 'mdlabname' => 1, @@ -8484,6 +8926,8 @@ my %tagExists = ( 'mediacreated' => 1, 'mediacredits' => 1, 'mediadata' => 1, + 'mediadataoffset' => 1, + 'mediadatasize' => 1, 'mediaduration' => 1, 'mediaflags' => 1, 'mediaheader' => 1, @@ -8523,7 +8967,6 @@ my %tagExists = ( 'mediathumbwidth' => 1, 'mediatimescale' => 1, 'mediatrackbytes' => 1, - 'mediatype' => 1, 'mediaweight' => 1, 'mediawhitepoint' => 1, 'medium' => 1, @@ -8538,11 +8981,13 @@ my %tagExists = ( 'metadatanumber' => 1, 'metadatasource' => 1, 'metaformat' => 1, + 'metarelation' => 1, 'metasampledesc' => 1, 'metdata' => 1, 'meterinfo' => 1, 'meterlink' => 1, 'metermode' => 1, + 'mett' => 1, 'microsoft' => 1, 'microsoftxtra' => 1, 'middlename' => 1, @@ -8551,6 +8996,7 @@ my %tagExists = ( 'midisong' => 1, 'mie' => 1, 'mileage' => 1, + 'mimeencoding' => 1, 'mimetype' => 1, 'miniaturefilter' => 1, 'miniaturefilterorientation' => 1, @@ -8573,6 +9019,7 @@ my %tagExists = ( 'minoltattw' => 1, 'minoltawbg' => 1, 'minpacketsize' => 1, + 'minspatialsegmentationidc' => 1, 'mintransmissiontime' => 1, 'mmclips' => 1, 'mngheader' => 1, @@ -8582,8 +9029,6 @@ my %tagExists = ( 'modeflags' => 1, 'model2' => 1, 'modelandversion' => 1, - 'modeltiepoint' => 1, - 'modeltransform' => 1, 'modeltype' => 1, 'modenumber' => 1, 'modificationnumber' => 1, @@ -8592,6 +9037,7 @@ my %tagExists = ( 'modifiedinfo' => 1, 'moiversion' => 1, 'monomonitormatrix' => 1, + 'monostrength' => 1, 'monotonescaletable' => 1, 'monouniquematrix' => 1, 'montage' => 1, @@ -8609,10 +9055,9 @@ my %tagExists = ( 'movableinfo' => 1, 'moveobjects' => 1, 'movie' => 1, - 'moviedata' => 1, - 'moviedataoffset' => 1, - 'moviedatasize' => 1, 'moviefragment' => 1, + 'moviefragmentheader' => 1, + 'moviefragmentsequence' => 1, 'movieheader' => 1, 'movieheaderversion' => 1, 'movieinfo' => 1, @@ -8646,18 +9091,15 @@ my %tagExists = ( 'musicby' => 1, 'musiccdidentifier' => 1, 'musiciancredits' => 1, - 'mute' => 1, 'mwg-coll' => 1, 'mwg-kw' => 1, 'mwg-rs' => 1, 'mxfversion' => 1, 'mycolors' => 1, - 'name' => 1, 'namedcolor' => 1, 'namedcolor2' => 1, 'nametableversion' => 1, 'nameutf-8' => 1, - 'narrator' => 1, 'nativedisplayinfo' => 1, 'nativeresolutionunit' => 1, 'nativexresolution' => 1, @@ -8682,6 +9124,7 @@ my %tagExists = ( 'newbitdepth' => 1, 'newcolortype' => 1, 'newguid' => 1, + 'newlines' => 1, 'nexttrackid' => 1, 'nifnonlinearity' => 1, 'nifnonlinearity12bit' => 1, @@ -8689,11 +9132,11 @@ my %tagExists = ( 'nifnonlinearity16bit' => 1, 'nifnonlinearityext' => 1, 'nikon' => 1, - 'nikoncaptureoffsets' => 1, 'nikondata' => 1, 'nikondatetime' => 1, 'nikonncdb' => 1, 'nikonncdt' => 1, + 'nikonnefinfo' => 1, 'nikonscanifd' => 1, 'nikontags' => 1, 'nikonvers' => 1, @@ -8746,10 +9189,17 @@ my %tagExists = ( 'numsampleframes' => 1, 'numslices' => 1, 'numstreams' => 1, + 'numtemporallayers' => 1, 'objectfiletype' => 1, 'objectflags' => 1, 'objectid' => 1, + 'objectorientation' => 1, 'objectsizeannounced' => 1, + 'observationdate' => 1, + 'observationdateend' => 1, + 'observationtime' => 1, + 'observationtimeend' => 1, + 'observer' => 1, 'obsoletephotoshoptag1' => 1, 'obsoletephotoshoptag2' => 1, 'obsoletephotoshoptag3' => 1, @@ -8843,7 +9293,6 @@ my %tagExists = ( 'organizeraddress' => 1, 'organizername' => 1, 'orientationinfo' => 1, - 'orientationoffset' => 1, 'originalalbum' => 1, 'originalalbumtitle' => 1, 'originalartist' => 1, @@ -8884,6 +9333,8 @@ my %tagExists = ( 'otherfirmware' => 1, 'otherformat' => 1, 'otherinfo' => 1, + 'othermeta' => 1, + 'othername' => 1, 'otherpobox' => 1, 'otherpostalcode' => 1, 'othersampledesc' => 1, @@ -8892,7 +9343,9 @@ my %tagExists = ( 'otherstreet' => 1, 'outputdataobjectlist' => 1, 'outputgain' => 1, + 'outputheight' => 1, 'outputresponse' => 1, + 'outputwidth' => 1, 'overclockcolsright' => 1, 'overclockrowsbottom' => 1, 'overflowcolor' => 1, @@ -8931,18 +9384,23 @@ my %tagExists = ( 'panoverlaph' => 1, 'panoverlapv' => 1, 'paragraphs' => 1, + 'parallelismtype' => 1, 'param0' => 1, 'param1' => 1, 'param2' => 1, 'param3' => 1, 'parameter' => 1, 'parameterinfo' => 1, + 'parameters' => 1, 'parasites' => 1, 'parentalrating' => 1, 'parentalratingreason' => 1, - 'parentproductid' => 1, - 'parentshorttitle' => 1, - 'parenttitle' => 1, + 'parrotautomation' => 1, + 'parrotfollowme' => 1, + 'parrottimestamp' => 1, + 'parrotv1' => 1, + 'parrotv2' => 1, + 'parrotv3' => 1, 'part' => 1, 'partialactivecolsleft' => 1, 'partialactivecolsright' => 1, @@ -8985,11 +9443,8 @@ my %tagExists = ( 'perceivedtype' => 1, 'perceptualrenderingintentgamut' => 1, 'percussivepolyphony' => 1, - 'performer' => 1, - 'performerkeywords' => 1, - 'performers' => 1, + 'perfmode' => 1, 'performersortorder' => 1, - 'performerurl' => 1, 'period' => 1, 'perms' => 1, 'perpicturenotes' => 1, @@ -9031,21 +9486,19 @@ my %tagExists = ( 'picturelength' => 1, 'picturemimetype' => 1, 'picturestyleinfo' => 1, - 'picturestylepc' => 1, - 'picturestyleuserdef' => 1, 'picturetype' => 1, 'picturewidth' => 1, 'pieceinfo' => 1, 'piecelength' => 1, 'pieces' => 1, + 'pilotingmode' => 1, 'pip' => 1, 'pipx1' => 1, 'pipx2' => 1, 'pipy1' => 1, 'pipy2' => 1, 'pitchandfamily' => 1, - 'pitchshift' => 1, - 'pixelaspectratio' => 1, + 'pittasoft' => 1, 'pixelaspectratiox' => 1, 'pixelaspectratioy' => 1, 'pixelcalibration' => 1, @@ -9056,7 +9509,6 @@ my %tagExists = ( 'pixelintensityrange' => 1, 'pixellive' => 1, 'pixelmagicjbigoptions' => 1, - 'pixelscale' => 1, 'pixelspermeterx' => 1, 'pixelspermetery' => 1, 'pixheight' => 1, @@ -9067,32 +9519,22 @@ my %tagExists = ( 'plancko' => 1, 'planckr1' => 1, 'planckr2' => 1, - 'planes' => 1, - 'playallframes' => 1, 'playcounter' => 1, - 'playerversion' => 1, - 'playgap' => 1, 'playlistdelay' => 1, - 'playlistid' => 1, 'playlistindex' => 1, - 'playmode' => 1, - 'playselection' => 1, 'plus' => 1, 'pmi' => 1, 'pobox' => 1, - 'podcast' => 1, 'podcastcategory' => 1, 'podcastdescription' => 1, 'podcastid' => 1, 'podcastkeywords' => 1, - 'podcasturl' => 1, 'pointsize' => 1, 'popularimeter' => 1, 'popupfillattributes' => 1, 'popupflash' => 1, 'portraitmatrix' => 1, 'portraittonescaletable' => 1, - 'pose' => 1, 'poseyawdegrees' => 1, 'position' => 1, 'postertime' => 1, @@ -9165,7 +9607,6 @@ my %tagExists = ( 'producedby' => 1, 'produceddate' => 1, 'producednotice' => 1, - 'producerkeywords' => 1, 'producers' => 1, 'product' => 1, 'productionaperturedimensions' => 1, @@ -9174,9 +9615,7 @@ my %tagExists = ( 'productionstudio' => 1, 'productname' => 1, 'producttype' => 1, - 'productversion' => 1, 'productversionnumber' => 1, - 'profile' => 1, 'profile1audiocodec' => 1, 'profile1height' => 1, 'profile1videocodec' => 1, @@ -9193,11 +9632,9 @@ my %tagExists = ( 'profileheader' => 1, 'profileid' => 1, 'profileifd' => 1, - 'profiles' => 1, 'profilesequencedesc' => 1, 'profilesequenceidentifier' => 1, 'profilesize' => 1, - 'profiletype' => 1, 'profileversion' => 1, 'progid' => 1, 'programdescription' => 1, @@ -9258,12 +9695,12 @@ my %tagExists = ( 'ps2renderingintent' => 1, 'psfontinfo' => 1, 'pstringcaption' => 1, + 'ptrh' => 1, 'publishdate' => 1, 'publishdatestart' => 1, 'publisherlimit' => 1, 'publisherurl' => 1, 'pur' => 1, - 'purchasedate' => 1, 'purchasefileformat' => 1, 'purchaseinfo' => 1, 'purpose' => 1, @@ -9283,6 +9720,7 @@ my %tagExists = ( 'qualcomm' => 1, 'quickedit' => 1, 'quickmaskinfo' => 1, + 'quoting' => 1, 'qvci' => 1, 'ra3' => 1, 'ra4' => 1, @@ -9291,7 +9729,6 @@ my %tagExists = ( 'radioformat' => 1, 'radiostationname' => 1, 'radiostationowner' => 1, - 'rads' => 1, 'rafdata' => 1, 'rafversion' => 1, 'rasterpadding' => 1, @@ -9299,6 +9736,7 @@ my %tagExists = ( 'rated' => 1, 'ratingorg' => 1, 'ratioimage' => 1, + 'rawburstmoderoll' => 1, 'rawcfacomponentaverages' => 1, 'rawcodecversion' => 1, 'rawdatalength' => 1, @@ -9311,6 +9749,9 @@ my %tagExists = ( 'rawexposurebias' => 1, 'rawgsensor' => 1, 'rawhistogram' => 1, + 'rawimageaspectratio' => 1, + 'rawimagecroppedsize' => 1, + 'rawimagecroptopleft' => 1, 'rawimagefullheight' => 1, 'rawimagefullsize' => 1, 'rawimagefullwidth' => 1, @@ -9327,6 +9768,8 @@ my %tagExists = ( 'rawthermalimagewidth' => 1, 'rawvaluemedian' => 1, 'rawvaluerange' => 1, + 'rawvaluerangemax' => 1, + 'rawvaluerangemin' => 1, 'rawzorcreatorversion' => 1, 'rawzorrequiredversion' => 1, 'rdf' => 1, @@ -9358,7 +9801,6 @@ my %tagExists = ( 'reconstructiontype' => 1, 'recordedby' => 1, 'recordeddate' => 1, - 'recordingcopyright' => 1, 'recordingdates' => 1, 'recordingtime' => 1, 'recordingtimeday' => 1, @@ -9366,8 +9808,6 @@ my %tagExists = ( 'recordingtimeyear' => 1, 'recordingtimeyearmonth' => 1, 'recordingtimeyearmonthday' => 1, - 'recordlabelname' => 1, - 'recordlabelurl' => 1, 'rect' => 1, 'rectangleofinterest' => 1, 'red1header' => 1, @@ -9428,7 +9868,6 @@ my %tagExists = ( 'requeststate' => 1, 'requiredattendeeaddresses' => 1, 'requiredattendees' => 1, - 'requirements' => 1, 'rerun' => 1, 'reserved1' => 1, 'reserved5' => 1, @@ -9509,8 +9948,8 @@ my %tagExists = ( 'root' => 1, 'rootdirectorycreatedate' => 1, 'rotationangle' => 1, - 'rotationinfooffset' => 1, 'roundtripversion' => 1, + 'rowcount' => 1, 'rowinterleavefactor' => 1, 'rtmd' => 1, 'rtptimescale' => 1, @@ -9550,6 +9989,7 @@ my %tagExists = ( 'samsungsmta' => 1, 'samsungsvss' => 1, 'samsungtags' => 1, + 'samsunguniqueid' => 1, 'sanyomov' => 1, 'sanyomp4' => 1, 'sap' => 1, @@ -9607,9 +10047,11 @@ my %tagExists = ( 'school' => 1, 'screenbuffersize' => 1, 'screendescriptor' => 1, + 'screenheight' => 1, 'screening' => 1, 'screeningdesc' => 1, 'screennail' => 1, + 'screenwidth' => 1, 'screenwindowcenter' => 1, 'screenwindowwidth' => 1, 'screenwriters' => 1, @@ -9621,6 +10063,8 @@ my %tagExists = ( 'seekable' => 1, 'seekpoint' => 1, 'seektable' => 1, + 'segheight' => 1, + 'segwidth' => 1, 'selection' => 1, 'selectionduration' => 1, 'selectiontime' => 1, @@ -9637,10 +10081,12 @@ my %tagExists = ( 'sensorid' => 1, 'sensorinfo' => 1, 'sensorrightborder' => 1, + 'seqlevelidx0' => 1, + 'seqprofile' => 1, + 'seqtier0' => 1, 'sequenceframenumber' => 1, 'sequencenumberrandomoffset' => 1, 'serialinfo' => 1, - 'serialnumberhash' => 1, 'seriesuid' => 1, 'serviceid' => 1, 'serviceorganizationname' => 1, @@ -9676,14 +10122,12 @@ my %tagExists = ( 'shifttiming' => 1, 'shimdata' => 1, 'shootingcount' => 1, - 'shootingmenuoffset' => 1, 'shootingrecord' => 1, 'shootobjbacktype' => 1, 'shootobjname' => 1, 'shootobjtype' => 1, 'shootobjversion' => 1, 'shootsetup' => 1, - 'shorttitle' => 1, 'shotinfo' => 1, 'shotinfo02xx' => 1, 'shotinfod300a' => 1, @@ -9713,11 +10157,11 @@ my %tagExists = ( 'shotinfoversion' => 1, 'showmode' => 1, 'showobjects' => 1, - 'shutter' => 1, 'shuttercurtainhack' => 1, 'shutterspeed' => 1, 'shutterspeeddisplayed' => 1, 'sidebars' => 1, + 'sidelightstrength' => 1, 'sigma' => 1, 'sigmanoisefiltercaltablev1' => 1, 'sigmanoisefiltertablev1' => 1, @@ -9737,6 +10181,9 @@ my %tagExists = ( 'simpleindex' => 1, 'simplicityprofile' => 1, 'singlequality' => 1, + 'singleshotdepthmap' => 1, + 'singleshotdepthmaptiff' => 1, + 'singleshotmeta' => 1, 'site' => 1, 'siteenter' => 1, 'siteexit' => 1, @@ -9759,21 +10206,12 @@ my %tagExists = ( 'softfocusfilter' => 1, 'softwarecomponents' => 1, 'softwarerelease' => 1, - 'songwriter' => 1, - 'songwriterkeywords' => 1, 'sony' => 1, 'sonyrawfiletype' => 1, 'sonytonecurve' => 1, - 'sortalbum' => 1, - 'sortalbumartist' => 1, - 'sortartist' => 1, - 'sortcomposer' => 1, - 'sortname' => 1, - 'sortshow' => 1, 'soundfile' => 1, 'soundschemetitle' => 1, 'sourcecreatedate' => 1, - 'sourcecredits' => 1, 'sourcedata' => 1, 'sourcedate' => 1, 'sourceedition' => 1, @@ -9802,6 +10240,7 @@ my %tagExists = ( 'sphericalvideoxml' => 1, 'spiff' => 1, 'spiffversion' => 1, + 'spinstrength' => 1, 'spothalftone' => 1, 'spouse' => 1, 'sr2dataifd' => 1, @@ -9840,6 +10279,7 @@ my %tagExists = ( 'stereo' => 1, 'stereoimage' => 1, 'stereoscopic3d' => 1, + 'stillimagetime' => 1, 'stim' => 1, 'stimversion' => 1, 'stitchcolumns' => 1, @@ -9926,7 +10366,6 @@ my %tagExists = ( 'subsystemversion' => 1, 'subtileblocksize' => 1, 'subtitledescription' => 1, - 'subtitlekeywords' => 1, 'suffix' => 1, 'suggestedpalette' => 1, 'summary' => 1, @@ -9980,6 +10419,7 @@ my %tagExists = ( 'tag9400a' => 1, 'tag9400b' => 1, 'tag9400c' => 1, + 'tag9401' => 1, 'tag9402' => 1, 'tag9403' => 1, 'tag9404a' => 1, @@ -10009,10 +10449,12 @@ my %tagExists = ( 'technician' => 1, 'technology' => 1, 'telephonenumber' => 1, + 'telescope' => 1, 'telex' => 1, 'temperature' => 1, 'tempinfo' => 1, 'template' => 1, + 'temporalidnested' => 1, 'temporary' => 1, 'terminationaction' => 1, 'terminationcondition' => 1, @@ -10043,7 +10485,6 @@ my %tagExists = ( 'thumbnailclip' => 1, 'thumbnailcompressiontable' => 1, 'thumbnailexpansiontable' => 1, - 'thumbnailpng' => 1, 'thumbnailresizeratio' => 1, 'thumbnailtiff' => 1, 'tickspersecond' => 1, @@ -10077,6 +10518,12 @@ my %tagExists = ( 'toaddresses' => 1, 'tocitems' => 1, 'todotitle' => 1, + 'tomtomad' => 1, + 'tomtomhl' => 1, + 'tomtomid' => 1, + 'tomtommetadata' => 1, + 'tomtomvd' => 1, + 'tomtomvi' => 1, 'tonames' => 1, 'tonecurvematching' => 1, 'tonecurvetable' => 1, @@ -10115,6 +10562,7 @@ my %tagExists = ( 'topdarkrow1' => 1, 'topdarkrow2' => 1, 'topmag' => 1, + 'topmargin' => 1, 'totalbitrate' => 1, 'totalbytes' => 1, 'totalbytesnortpheaders' => 1, @@ -10128,7 +10576,6 @@ my %tagExists = ( 'totalsamples' => 1, 'totalsize' => 1, 'toycamerafilter' => 1, - 'track' => 1, 'trackaperture' => 1, 'trackcategory' => 1, 'trackcomments' => 1, @@ -10143,7 +10590,6 @@ my %tagExists = ( 'tracklyrics' => 1, 'trackproperty' => 1, 'trackref' => 1, - 'tracktype' => 1, 'trackvolume' => 1, 'trademark' => 1, 'transactionid' => 1, @@ -10162,7 +10608,6 @@ my %tagExists = ( 'trapindicator' => 1, 'trashcolsright' => 1, 'trashrowsbottom' => 1, - 'trebel' => 1, 'tty-ttdphone' => 1, 'tungmat0' => 1, 'tungmat1' => 1, @@ -10174,11 +10619,7 @@ my %tagExists = ( 'tungmat7' => 1, 'tungmat8' => 1, 'tungmat9' => 1, - 'tvepisode' => 1, - 'tvepisodeid' => 1, - 'tvnetworkname' => 1, - 'tvseason' => 1, - 'tvshow' => 1, + 'twelvebit' => 1, 'tx3g' => 1, 'typeoforiginal' => 1, 'typist' => 1, @@ -10197,10 +10638,12 @@ my %tagExists = ( 'unicodealphanames' => 1, 'uninitializeddatasize' => 1, 'uniquefileidentifier' => 1, + 'uniqueid' => 1, 'unknown' => 1, - 'unknown_aacr' => 1, - 'unknown_cdek' => 1, - 'unknown_cdet' => 1, + 'unknown00' => 1, + 'unknown01' => 1, + 'unknown02' => 1, + 'unknown03' => 1, 'unknown_cndb' => 1, 'unknown_slmt' => 1, 'unknownd30' => 1, @@ -10214,10 +10657,8 @@ my %tagExists = ( 'unknownserial2' => 1, 'unknownserial3' => 1, 'unknownserial4' => 1, - 'unknowntags' => 1, 'unknowntemperature1' => 1, 'unknowntemperature2' => 1, - 'unknownthumbnail' => 1, 'unsharpdata' => 1, 'untitled0' => 1, 'untitled1' => 1, @@ -10239,7 +10680,6 @@ my %tagExists = ( 'usedextensionnumbers' => 1, 'useraccess' => 1, 'useradjsba_rgbshifts' => 1, - 'usercollection' => 1, 'usercustom1' => 1, 'usercustom2' => 1, 'userdata' => 1, @@ -10258,7 +10698,6 @@ my %tagExists = ( 'userplaycountnight' => 1, 'userplaycountweekday' => 1, 'userplaycountweekend' => 1, - 'userrating' => 1, 'userselectgrouptitle' => 1, 'userservicerating' => 1, 'userweburl' => 1, @@ -10273,6 +10712,7 @@ my %tagExists = ( 'usptooriginalcontenttype' => 1, 'utm' => 1, 'uuid-canon' => 1, + 'uuid-canon2' => 1, 'uuid-exif' => 1, 'uuid-exif2' => 1, 'uuid-exif_bad' => 1, @@ -10301,7 +10741,6 @@ my %tagExists = ( 'vddimdacnominalvalues' => 1, 'vegasversionmajor' => 1, 'vegasversionminor' => 1, - 'vendor' => 1, 'vendorid' => 1, 'vendorname' => 1, 'vendorurl' => 1, @@ -10318,6 +10757,7 @@ my %tagExists = ( 'verticaldivergence' => 1, 'verticalresolution' => 1, 'verticalscale' => 1, + 'verticalspeed' => 1, 'verticalunits' => 1, 'video' => 1, 'videoattributes' => 1, @@ -10329,7 +10769,6 @@ my %tagExists = ( 'videocodecid' => 1, 'videocodecinfo' => 1, 'videocodecname' => 1, - 'videocompression' => 1, 'videoencoding' => 1, 'videoformat' => 1, 'videoframecount' => 1, @@ -10361,6 +10800,7 @@ my %tagExists = ( 'vignettingcorrunknown2' => 1, 'vignettingcorrversion' => 1, 'vignettingparams' => 1, + 'vintagestrength' => 1, 'virtualimageheight' => 1, 'virtualimagewidth' => 1, 'virtualpage' => 1, @@ -10425,13 +10865,9 @@ my %tagExists = ( 'wb_grblevelsauto' => 1, 'wb_grblevelsstandard' => 1, 'wb_grgblevels' => 1, - 'wb_grgblevelsauto' => 1, - 'wb_grgblevelscloudy' => 1, - 'wb_grgblevelsdaylight' => 1, 'wb_grgblevelsdaylightfluor' => 1, 'wb_grgblevelsdaywhitefluor' => 1, 'wb_grgblevelslivingroomwarmwhitefluor' => 1, - 'wb_grgblevelstungsten' => 1, 'wb_grgblevelswarmwhitefluor' => 1, 'wb_grgblevelswhitefluorescent' => 1, 'wb_redlevelauto' => 1, @@ -10445,16 +10881,11 @@ my %tagExists = ( 'wb_rgblevels6000k' => 1, 'wb_rgblevels8500k' => 1, 'wb_rgblevelsasshot' => 1, - 'wb_rgblevelsauto' => 1, 'wb_rgblevelscloudy' => 1, 'wb_rgblevelscustom' => 1, - 'wb_rgblevelsdaylight' => 1, - 'wb_rgblevelsflash' => 1, - 'wb_rgblevelsfluorescent' => 1, 'wb_rgblevelsfluorescentm1' => 1, 'wb_rgblevelsfluorescentp1' => 1, 'wb_rgblevelsfluorescentp2' => 1, - 'wb_rgblevelsshade' => 1, 'wb_rgblevelstungsten' => 1, 'wbadjdata' => 1, 'wbblueasshot' => 1, @@ -10479,6 +10910,8 @@ my %tagExists = ( 'wbredflash' => 1, 'wbredfluorescent' => 1, 'wbredtungsten' => 1, + 'wbsettings' => 1, + 'wbsettings2' => 1, 'wcsprofiles' => 1, 'webpage' => 1, 'weight' => 1, @@ -10497,7 +10930,7 @@ my %tagExists = ( 'wide' => 1, 'widthbytes' => 1, 'widthresolution' => 1, - 'windowlocation' => 1, + 'wifirssi' => 1, 'windoworigin' => 1, 'windoworiginauto' => 1, 'windowsdevmode' => 1, @@ -10536,7 +10969,11 @@ my %tagExists = ( 'wwsfamilyname' => 1, 'wwssubfamilyname' => 1, 'x' => 1, + 'xattrapplemaildatereceived' => 1, + 'xattrapplemaildatesent' => 1, + 'xattrapplemailisremoteattachment' => 1, 'xattrfinderinfo' => 1, + 'xattrlastuseddate' => 1, 'xattrmditemdownloadeddate' => 1, 'xattrmditemfindercomment' => 1, 'xattrmditemwherefroms' => 1, @@ -10565,7 +11002,6 @@ my %tagExists = ( 'xyoffsetinfo' => 1, 'yclippathunits' => 1, 'ycrcbmatrix' => 1, - 'year' => 1, 'ylevel' => 1, 'ymag' => 1, 'ymethod' => 1, @@ -10583,6 +11019,7 @@ my %tagExists = ( 'zoomedpreviewimage' => 1, 'zoompos' => 1, 'zoomposition' => 1, + 'zoomstrength' => 1, 'zxif' => 1, ); @@ -10635,7 +11072,7 @@ if (@Image::ExifTool::pluginTags) { # Inputs: 0) tag table ref for flattened tags, 1) tagID, 2) lowercase tag name, # 3) tag ID list ref, 4) reference to list of lowercase tag names # 5) table number in lookup, 6) tagInfo hash for parent structure -# 7) tag ID of top-level stucture +# 7) tag ID of top-level structure # Notes: Used only for user-defined structures sub AddFields($$$$$$;$$) { @@ -10802,7 +11239,7 @@ sub FindTagInfo($) } } while ($lookup) { - foreach $tableNum (keys %$lookup) { + foreach $tableNum (sort { $a <=> $b } keys %$lookup) { my $table = GetTagTable($tableList[$tableNum]); my $le = $$lookup{$tableNum}; my ($tagID, $tagIDs); @@ -10826,7 +11263,10 @@ sub FindTagInfo($) my $reload; # call write proc if it exists in case it adds tags to the table my $writeProc = $table->{WRITE_PROC}; - $reload = 1 if $writeProc and &$writeProc(); + if ($writeProc) { + no strict 'refs'; + $reload = 1 if &$writeProc(); + } # load module with composite tag if necessary my $compMod = $compositeModules{$lcTag}; $reload = 1 if $compMod and eval "require $compMod"; @@ -10872,7 +11312,7 @@ Provides a fast, case insensitive lookup for tag names. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/TagNames.pod b/src/Image-ExifTool/lib/Image/ExifTool/TagNames.pod index 3646f385..663b8aef 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/TagNames.pod +++ b/src/Image-ExifTool/lib/Image/ExifTool/TagNames.pod @@ -12,6 +12,7 @@ meta information extracted from or written to a file. =head1 TAG TABLES The tables listed below give the names of all tags recognized by ExifTool. +They contain a total of 23357 tags, with 15304 unique tag names. B<Tag ID>, B<Index#> or B<Sequence> is given in the first column of each table. A B<Tag ID> is the computer-readable equivalent of a tag name, and @@ -19,8 +20,10 @@ is the identifier that is actually stored in the file. B<Index#> refers to the offset of a value when found at a fixed position within a data block (B<#> is the multiplier for calculating a byte offset: B<1>, B<2>, B<4> or B<8>). These offsets may have a decimal part which is used only to -differentiate tags which have values stored at the same position. -B<Sequence> gives the order of values for a serial data stream. +differentiate tags with values stored at the same position. (Note that +writable tags within binary data blocks are not individually deletable, +and the usual alternative is to set them to a value of zero.) B<Sequence> +gives the order of values for a serial data stream. A B<Tag Name> is the handle by which the information is accessed in ExifTool. In some instances, more than one name may correspond to a single @@ -36,20 +39,20 @@ instead of the descriptions, use C<exiftool -s>. The B<Writable> column indicates whether the tag is writable by ExifTool. Anything but a C<no> in this column means the tag is writable. A C<yes> indicates writable information that is either unformatted or written using -the existing format. Other expressions give details about the information -format, and vary depending on the general type of information. The format -name may be followed by a number in square brackets to indicate the number -of values written, or the number of characters in a fixed-length string -(including a null terminator which is added if required). +the existing format. Other expressions give details about the format of the +stored value, and vary depending on the general type of information. The +format name may be followed by a number in square brackets to indicate the +number of values written, or the number of characters in a fixed-length +string (including a null terminator which is added if required). A plus sign (C<+>) after an entry in the B<Writable> column indicates a I<List> tag which supports multiple values and allows individual values to be added and deleted. A slash (C</>) indicates a tag that ExifTool will -I<Avoid> when writing. These tags are not created when writing if another -same-named tag may be created instead. To write these tags, the group +I<Avoid> when writing. These will be edited but not created if another +same-named tag may be created instead. To create these tags, the group should be specified. A tilde (C<~>) indicates a tag this is writable only when the print conversion is disabled (by setting PrintConv to 0, using the --n option, or suffixing the tag name with a C<#> character). An exclamation +-n option, or suffixing the tag name with a C<#> character). An exclamation point (C<!>) indicates a tag that is considered I<Unsafe> to write under normal circumstances. These tags are not written unless specified explicitly (ie. not when wildcards or "all" are used), and care should be @@ -59,15 +62,16 @@ writable directly, but is written automatically by ExifTool (often when a corresponding L<Composite|Image::ExifTool::TagNames/Composite Tags> or L<Extra|Image::ExifTool::TagNames/Extra Tags> tag is written). A colon (C<:>) indicates a I<Mandatory> tag which may be added automatically when -writing. +writing. Normally MakerNotes tags may not be deleted individually, but a +caret (C<^>) indicates a I<Deletable> MakerNotes tag. The HTML version of these tables also lists possible B<Values> for discrete-valued tags, as well as B<Notes> for some tags. The B<Values> are -listed as the computer-readable and human-readable values on the left and -right hand side of an equals sign (C<=>) respectively. The human-readable +listed with the computer-readable values on the left of the equals sign +(C<=>), and the human-readable values on the right. The human-readable values are used by default when reading and writing, but the computer-readable values may be accessed by disabling the value conversion -with the -n option on the command line, by setting the ValueConv option to 0 +with the -n option on the command line, by setting the PrintConv option to 0 in the API, or or on a per-tag basis by adding a hash (C<#>) after the tag name. @@ -104,6 +108,7 @@ L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification. XMP XMP QVCI Casio QVCI FLIR FLIR FFF + RawThermalImage no 'APP2' ICC_Profile ICC_Profile FPXR FlashPix MPF MPF @@ -115,12 +120,14 @@ L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification. FPXR FlashPix PreviewImage no 'APP5' RMETA Ricoh RMETA + SamsungUniqueID Samsung APP5 PreviewImage no 'APP6' EPPIM JPEG EPPIM NITF JPEG NITF HP_TDHD HP TDHD GoPro GoPro GPMF 'APP7' Pentax Pentax + Huawei Unknown Qualcomm Qualcomm 'APP8' SPIFF JPEG SPIFF 'APP9' MediaJukebox JPEG MediaJukebox @@ -141,6 +148,8 @@ L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification. PhotoMechanic PhotoMechanic MIE MIE Samsung Samsung Trailer + EmbeddedVideo no + Insta360 no PreviewImage yes =head3 JPEG AVI1 Tags @@ -306,11 +315,11 @@ tags remain. The table below lists all EXIF tags. Also listed are TIFF, DNG, HDP and other tags which are not part of the EXIF specification, but may co-exist -with EXIF tags in some images. Tags which are part of the EXIF 2.31 +with EXIF tags in some images. Tags which are part of the EXIF 2.32 specification have an underlined B<Tag Name> in the HTML version of this documentation. See -L<http://www.cipa.jp/std/documents/e/DC-008-Translation-2016-E.pdf> for the -official EXIF 2.31 specification. +L<https://web.archive.org/web/20190624045241if_/http://www.cipa.jp:80/std/documents/e/DC-008-Translation-2019-E.pdf> +for the official EXIF 2.32 specification. Tag ID Tag Name Group Writable ------ -------- ----- -------- @@ -454,6 +463,8 @@ official EXIF 2.31 specification. 0x7035 ChromaticAberrationCorrParams SubIFD int16s[33]! 0x7036 DistortionCorrection SubIFD int16s! 0x7037 DistortionCorrParams SubIFD int16s[17]! + 0x74c7 SonyCropTopLeft SubIFD int32u[2]! + 0x74c8 SonyCropSize SubIFD int32u[2]! 0x800d ImageID - no 0x80a3 WangTag1 - no 0x80a4 WangAnnotation - no @@ -490,7 +501,7 @@ official EXIF 2.31 specification. 0x82aa MDPrepDate - no 0x82ab MDPrepTime - no 0x82ac MDFileUnits - no - 0x830e PixelScale - no + 0x830e PixelScale IFD0 double[3] 0x8335 AdventScale - no 0x8336 AdventRevision - no 0x835c UIC1Tag - no @@ -500,9 +511,9 @@ official EXIF 2.31 specification. 0x83bb IPTC-NAA IFD0 IPTC 0x847e IntergraphPacketData - no 0x847f IntergraphFlagRegisters - no - 0x8480 IntergraphMatrix - no + 0x8480 IntergraphMatrix IFD0 double[n] 0x8481 INGRReserved - no - 0x8482 ModelTiePoint - no + 0x8482 ModelTiePoint IFD0 double[n] 0x84e0 Site - no 0x84e1 ColorSequence - no 0x84e2 IT8Header - no @@ -524,7 +535,7 @@ official EXIF 2.31 specification. 0x8568 AFCP_IPTC - IPTC 0x85b8 PixelMagicJBIGOptions - no 0x85d7 JPLCartoIFD - no - 0x85d8 ModelTransform - no + 0x85d8 ModelTransform IFD0 double[16] 0x8602 WB_GRGBLevels - no 0x8606 LeafData - Leaf 0x8649 PhotoshopSettings IFD0 Photoshop @@ -535,8 +546,8 @@ official EXIF 2.31 specification. 0x8781 SharedData - no 0x8782 T88Options - no 0x87ac ImageLayer - no - 0x87af GeoTiffDirectory IFD0 undef - 0x87b0 GeoTiffDoubleParams IFD0 undef + 0x87af GeoTiffDirectory IFD0 int16u[0.5] + 0x87b0 GeoTiffDoubleParams IFD0 double[0.125] 0x87b1 GeoTiffAsciiParams IFD0 string 0x87be JBIGOptions - no 0x8822 ExposureProgram ExifIFD int16u @@ -648,6 +659,7 @@ official EXIF 2.31 specification. MakerNoteLeica7 ExifIFD Panasonic Leica6 MakerNoteLeica8 ExifIFD Panasonic Leica5 MakerNoteLeica9 ExifIFD Panasonic Leica9 + MakerNoteLeica10 ExifIFD Panasonic MakerNotePanasonic ExifIFD Panasonic MakerNotePanasonic2 ExifIFD Panasonic Type2 MakerNotePanasonic3 ExifIFD Panasonic @@ -660,6 +672,8 @@ official EXIF 2.31 specification. MakerNotePhaseOne ExifIFD PhaseOne MakerNoteReconyx ExifIFD Reconyx MakerNoteReconyx2 ExifIFD Reconyx Type2 + MakerNoteReconyx3 ExifIFD Reconyx Type3 + MakerNoteRicohPentax ExifIFD Pentax MakerNoteRicoh ExifIFD Ricoh MakerNoteRicoh2 ExifIFD Ricoh Type2 MakerNoteRicohText ExifIFD Ricoh Text @@ -744,8 +758,11 @@ official EXIF 2.31 specification. 0xa433 LensMake ExifIFD string 0xa434 LensModel ExifIFD string 0xa435 LensSerialNumber ExifIFD string - 0xa480 GDALMetadata - no - 0xa481 GDALNoData - no + 0xa460 CompositeImage ExifIFD int16u + 0xa461 CompositeImageCount ExifIFD int16u[2] + 0xa462 CompositeImageExposureTimes ExifIFD undef + 0xa480 GDALMetadata IFD0 string + 0xa481 GDALNoData IFD0 string 0xa500 Gamma ExifIFD rational64u 0xafc0 ExpandSoftware - no 0xafc1 ExpandLens - no @@ -753,6 +770,7 @@ official EXIF 2.31 specification. 0xafc3 ExpandFilterLens - no 0xafc4 ExpandScanner - no 0xafc5 ExpandFlashLamp - no + 0xb4c3 HasselbladRawImage - no 0xbc01 PixelFormat - no 0xbc02 Transformation - no 0xbc03 Uncompressed - no @@ -773,6 +791,7 @@ official EXIF 2.31 specification. 0xc42a OceImageLogic - no 0xc44f Annotations - no 0xc4a5 PrintIM IFD0 PrintIM + 0xc51b HasselbladExif - no 0xc573 OriginalFileName - no 0xc580 USPTOOriginalContentType - no 0xc5e0 CR2CFAPattern - no @@ -814,6 +833,7 @@ official EXIF 2.31 specification. DNGAdobeData IFD0 DNG AdobeData MakerNotePentax IFD0 Pentax MakerNotePentax5 IFD0 Pentax + MakerNoteRicohPentax IFD0 Pentax DNGPrivateData IFD0 int8u! 0xc635 MakerNoteSafety IFD0 int16u 0xc640 RawImageSegmentation - no @@ -880,6 +900,13 @@ official EXIF 2.31 specification. 0xc7a8 RawToPreviewGain IFD0 double! 0xc7aa CacheVersion SubIFD2 int32u! 0xc7b5 DefaultUserCrop SubIFD rational64u[4]! + 0xc7d5 NikonNEFInfo - Nikon NEFInfo + 0xc7e9 DepthFormat IFD0 int16u! + 0xc7ea DepthNear IFD0 rational64u! + 0xc7eb DepthFar IFD0 rational64u! + 0xc7ec DepthUnits IFD0 int16u! + 0xc7ed DepthMeasureType IFD0 int16u! + 0xc7ee EnhanceParams IFD0 string! 0xea1c Padding ExifIFD undef! 0xea1d OffsetSchema ExifIFD int32s! 0xfde8 OwnerName ExifIFD string/ @@ -1104,41 +1131,6 @@ IPTC group only in the standard location. ------ -------- -------- [no tags known] -=head2 DJI Tags - -This table lists tags found in the maker notes of images from some DJI -Phantom drones. - - Tag ID Tag Name Writable - ------ -------- -------- - 0x0001 Make string - 0x0003 SpeedX float - 0x0004 SpeedY float - 0x0005 SpeedZ float - 0x0006 Pitch float - 0x0007 Yaw float - 0x0008 Roll float - 0x0009 CameraPitch float - 0x000a CameraYaw float - 0x000b CameraRoll float - -=head3 DJI XMP Tags - -XMP tags used by DJI for images from drones. - -These tags belong to the ExifTool XMP-drone-dji family 1 group. - - Tag Name Writable - -------- -------- - AbsoluteAltitude real - FlightPitchDegree real - FlightRollDegree real - FlightYawDegree real - GimbalPitchDegree real - GimbalRollDegree real - GimbalYawDegree real - RelativeAltitude real - =head2 XMP Tags XMP stands for "Extensible Metadata Platform", an XML/RDF-based metadata @@ -1168,13 +1160,13 @@ When reading, C<struct> tags are extracted only if the Struct (-struct) option is used. Otherwise the corresponding I<Flattened> tags, indicated by an underline (C<_>) after the B<Writable> type, are extracted. When copying, by default both structured and flattened tags are available, but -the flattened tags are considered "unsafe" so they they aren't copied unless +the flattened tags are considered "unsafe" so they aren't copied unless specified explicitly. The Struct option may be disabled by setting Struct to 0 via the API or with --struct on the command line to copy only flattened tags, or enabled by setting Struct to 1 via the API or with -struct on the command line to copy only as structures. When writing, the Struct option has no effect, and both structured and flattened tags may be written. See -L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html> for more details. +L<https://exiftool.org/struct.html> for more details. Individual languages for C<lang-alt> tags are accessed by suffixing the tag name with a '-', followed by an RFC 3066 language code (eg. "XMP:Title-fr", @@ -1186,12 +1178,13 @@ to preserve other existing languages (eg. "XMP-dc:Description-x-default"). When reading, "x-default" is not specified. The XMP tags are organized according to schema B<Namespace> in the following -tables. In general, the ExifTool family 1 group names are derived from the -namespace prefixes by adding a leading "XMP-" (eg. "XMP-dc"), but a few of -the longer prefixes have been shortened for convenience (as mentioned in the -documentation below). The tags of any namespace may be deleted as a group -by specifying the family 1 group name (eg. "-XMP-dc:all=" on the command -line). This includes namespaces which are not pre-defined by ExifTool. +tables. The ExifTool family 1 group names are derived from the namespace +prefixes by adding a leading "XMP-" (eg. "XMP-dc"). A few of the longer +prefixes have been shortened (as mentioned in the documentation below) to +avoid excessively long ExifTool group names. The tags of any namespace may +be deleted as a group by specifying the family 1 group name (eg. +"-XMP-dc:all=" on the command line). This includes namespaces which are not +pre-defined by ExifTool. In cases where a tag name exists in more than one namespace, less common namespaces are avoided when writing. However, a specific namespace may be @@ -1204,7 +1197,7 @@ recommended if possible. For structures, the heading of the first column is B<Field Name>. Field names are very similar to tag names, except they are used to identify fields inside structures instead of stand-alone tags. See -L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Fields> for more +L<https://exiftool.org/struct.html#Fields> for more details. ExifTool will extract XMP information even if it is not listed in these @@ -1228,9 +1221,11 @@ L<http://www.adobe.com/devnet/xmp/> for the official XMP specification. aux XMP aux cc XMP cc cell XMP cell + crd XMP crd creatorAtom XMP creatorAtom crs XMP crs dc XMP dc + Device XMP Device dex XMP dex DICOM XMP DICOM digiKam XMP digiKam @@ -1242,6 +1237,8 @@ L<http://www.adobe.com/devnet/xmp/> for the official XMP specification. extensis XMP extensis fpv XMP fpv GAudio XMP GAudio + GCamera XMP GCamera + GCreations XMP GCreations GDepth XMP GDepth getty XMP GettyImages GFocus XMP GFocus @@ -1445,6 +1442,483 @@ These tags belong to the ExifTool XMP-cell family 1 group. MobileNetworkCode string CellR string +=head3 XMP crd Tags + +Adobe Camera Raw Defaults tags. + +These tags belong to the ExifTool XMP-crd family 1 group. + + Tag Name Writable + -------- -------- + AlreadyApplied boolean/ + AutoBrightness boolean/ + AutoContrast boolean/ + AutoExposure boolean/ + AutoLateralCA integer/ + AutoShadows boolean/ + AutoTone boolean/ + AutoWhiteVersion integer/ + Blacks2012 integer/ + BlueHue integer/ + BlueSaturation integer/ + Brightness integer/ + CameraProfile string/ + CameraProfileDigest string/ + ChromaticAberrationB integer/ + ChromaticAberrationR integer/ + CircularGradientBasedCorrections Correction Struct+ + CircGradBasedCorrActive boolean/_ + CircGradBasedCorrAmount real/_ + CircGradBasedCorrMasks CorrectionMask Struct_+ + CircGradBasedCorrMaskAlpha real/_ + CircGradBasedCorrMaskAngle real/_ + CircGradBasedCorrMaskBottom real/_ + CircGradBasedCorrMaskCenterValue real/_ + CircGradBasedCorrMaskCenterWeight real/_ + CircGradBasedCorrMaskDabs string/_ + CircGradBasedCorrMaskFeather real/_ + CircGradBasedCorrMaskFlipped boolean/_ + CircGradBasedCorrMaskFlow real/_ + CircGradBasedCorrMaskFullX real/_ + CircGradBasedCorrMaskFullY real/_ + CircGradBasedCorrMaskLeft real/_ + CircGradBasedCorrMaskValue real/_ + CircGradBasedCorrMaskMidpoint real/_ + CircGradBasedCorrMaskPerimeterValue real/_ + CircGradBasedCorrMaskRadius real/_ + CircGradBasedCorrMaskRight real/_ + CircGradBasedCorrMaskRoundness real/_ + CircGradBasedCorrMaskSizeX real/_ + CircGradBasedCorrMaskSizeY real/_ + CircGradBasedCorrMaskTop real/_ + CircGradBasedCorrMaskVersion integer/_ + CircGradBasedCorrMaskWhat string/_ + CircGradBasedCorrMaskX real/_ + CircGradBasedCorrMaskY real/_ + CircGradBasedCorrMaskZeroX real/_ + CircGradBasedCorrMaskZeroY real/_ + CircGradBasedCorrBrightness real/_ + CircGradBasedCorrClarity real/_ + CircGradBasedCorrClarity2012 real/_ + CircGradBasedCorrContrast real/_ + CircGradBasedCorrContrast2012 real/_ + CircGradBasedCorrDefringe real/_ + CircGradBasedCorrExposure real/_ + CircGradBasedCorrExposure2012 real/_ + CircGradBasedCorrHighlights2012 real/_ + CircGradBasedCorrLuminanceNoise real/_ + CircGradBasedCorrMoire real/_ + CircGradBasedCorrSaturation real/_ + CircGradBasedCorrShadows2012 real/_ + CircGradBasedCorrSharpness real/_ + CircGradBasedCorrTemperature real/_ + CircGradBasedCorrTint real/_ + CircGradBasedCorrHue real/_ + CircGradBasedCorrSaturation real/_ + CircGradBasedCorrWhat string/_ + Clarity integer/ + Clarity2012 integer/ + ColorNoiseReduction integer/ + ColorNoiseReductionDetail integer/ + ColorNoiseReductionSmoothness integer/ + Contrast integer/ + Contrast2012 integer/ + Converter string/ + ConvertToGrayscale boolean/ + CropAngle real/ + CropBottom real/ + CropConstrainToWarp integer/ + CropHeight real/ + CropLeft real/ + CropRight real/ + CropTop real/ + CropUnit integer/ + CropUnits integer/ + CropWidth real/ + DefaultAutoGray boolean/ + DefaultAutoTone boolean/ + DefaultsSpecificToISO boolean/ + DefaultsSpecificToSerial boolean/ + Defringe integer/ + DefringeGreenAmount integer/ + DefringeGreenHueHi integer/ + DefringeGreenHueLo integer/ + DefringePurpleAmount integer/ + DefringePurpleHueHi integer/ + DefringePurpleHueLo integer/ + Dehaze real/ + DNGIgnoreSidecars boolean/ + Exposure real/ + Exposure2012 real/ + FillLight integer/ + GradientBasedCorrections Correction Struct+ + GradientBasedCorrActive boolean/_ + GradientBasedCorrAmount real/_ + GradientBasedCorrMasks CorrectionMask Struct_+ + GradientBasedCorrMaskAlpha real/_ + GradientBasedCorrMaskAngle real/_ + GradientBasedCorrMaskBottom real/_ + GradientBasedCorrMaskCenterValue real/_ + GradientBasedCorrMaskCenterWeight real/_ + GradientBasedCorrMaskDabs string/_ + GradientBasedCorrMaskFeather real/_ + GradientBasedCorrMaskFlipped boolean/_ + GradientBasedCorrMaskFlow real/_ + GradientBasedCorrMaskFullX real/_ + GradientBasedCorrMaskFullY real/_ + GradientBasedCorrMaskLeft real/_ + GradientBasedCorrMaskValue real/_ + GradientBasedCorrMaskMidpoint real/_ + GradientBasedCorrMaskPerimeterValue real/_ + GradientBasedCorrMaskRadius real/_ + GradientBasedCorrMaskRight real/_ + GradientBasedCorrMaskRoundness real/_ + GradientBasedCorrMaskSizeX real/_ + GradientBasedCorrMaskSizeY real/_ + GradientBasedCorrMaskTop real/_ + GradientBasedCorrMaskVersion integer/_ + GradientBasedCorrMaskWhat string/_ + GradientBasedCorrMaskX real/_ + GradientBasedCorrMaskY real/_ + GradientBasedCorrMaskZeroX real/_ + GradientBasedCorrMaskZeroY real/_ + GradientBasedCorrBrightness real/_ + GradientBasedCorrClarity real/_ + GradientBasedCorrClarity2012 real/_ + GradientBasedCorrContrast real/_ + GradientBasedCorrContrast2012 real/_ + GradientBasedCorrDefringe real/_ + GradientBasedCorrExposure real/_ + GradientBasedCorrExposure2012 real/_ + GradientBasedCorrHighlights2012 real/_ + GradientBasedCorrLuminanceNoise real/_ + GradientBasedCorrMoire real/_ + GradientBasedCorrSaturation real/_ + GradientBasedCorrShadows2012 real/_ + GradientBasedCorrSharpness real/_ + GradientBasedCorrTemperature real/_ + GradientBasedCorrTint real/_ + GradientBasedCorrHue real/_ + GradientBasedCorrSaturation real/_ + GradientBasedCorrWhat string/_ + GrainAmount integer/ + GrainFrequency integer/ + GrainSize integer/ + GrayMixerAqua integer/ + GrayMixerBlue integer/ + GrayMixerGreen integer/ + GrayMixerMagenta integer/ + GrayMixerOrange integer/ + GrayMixerPurple integer/ + GrayMixerRed integer/ + GrayMixerYellow integer/ + GreenHue integer/ + GreenSaturation integer/ + HasCrop boolean/ + HasSettings boolean/ + Highlight2012 integer/ + HighlightRecovery integer/ + Highlights2012 integer/ + HueAdjustmentAqua integer/ + HueAdjustmentBlue integer/ + HueAdjustmentGreen integer/ + HueAdjustmentMagenta integer/ + HueAdjustmentOrange integer/ + HueAdjustmentPurple integer/ + HueAdjustmentRed integer/ + HueAdjustmentYellow integer/ + IncrementalTemperature integer/ + IncrementalTint integer/ + JPEGHandling string/ + LensManualDistortionAmount integer/ + LensProfileChromaticAberrationScale integer/ + LensProfileDigest string/ + LensProfileDistortionScale integer/ + LensProfileEnable integer/ + LensProfileFilename string/ + LensProfileMatchKeyCameraModelName string/ + LensProfileMatchKeyExifMake string/ + LensProfileMatchKeyExifModel string/ + LensProfileMatchKeyIsRaw boolean/ + LensProfileMatchKeyLensID string/ + LensProfileMatchKeyLensInfo string/ + LensProfileMatchKeyLensName string/ + LensProfileMatchKeySensorFormatFactor real/ + LensProfileName string/ + LensProfileSetup string/ + LensProfileVignettingScale integer/ + Look Look Struct + LookName string/_ + LuminanceAdjustmentAqua integer/ + LuminanceAdjustmentBlue integer/ + LuminanceAdjustmentGreen integer/ + LuminanceAdjustmentMagenta integer/ + LuminanceAdjustmentOrange integer/ + LuminanceAdjustmentPurple integer/ + LuminanceAdjustmentRed integer/ + LuminanceAdjustmentYellow integer/ + LuminanceNoiseReductionContrast integer/ + LuminanceNoiseReductionDetail integer/ + LuminanceSmoothing integer/ + MoireFilter string/ + NegativeCacheLargePreviewSize integer/ + NegativeCacheMaximumSize real/ + NegativeCachePath string/ + OverrideLookVignette boolean/ + PaintBasedCorrections Correction Struct+ + PaintCorrectionActive boolean/_ + PaintCorrectionAmount real/_ + PaintBasedCorrectionMasks CorrectionMask Struct_+ + PaintCorrectionMaskAlpha real/_ + PaintCorrectionMaskAngle real/_ + PaintCorrectionMaskBottom real/_ + PaintCorrectionMaskCenterValue real/_ + PaintCorrectionMaskCenterWeight real/_ + PaintCorrectionMaskDabs string/_ + PaintCorrectionMaskFeather real/_ + PaintCorrectionMaskFlipped boolean/_ + PaintCorrectionMaskFlow real/_ + PaintCorrectionMaskFullX real/_ + PaintCorrectionMaskFullY real/_ + PaintCorrectionMaskLeft real/_ + PaintCorrectionMaskValue real/_ + PaintCorrectionMaskMidpoint real/_ + PaintCorrectionMaskPerimeterValue real/_ + PaintCorrectionMaskRadius real/_ + PaintCorrectionMaskRight real/_ + PaintCorrectionMaskRoundness real/_ + PaintCorrectionMaskSizeX real/_ + PaintCorrectionMaskSizeY real/_ + PaintCorrectionMaskTop real/_ + PaintCorrectionMaskVersion integer/_ + PaintCorrectionMaskWhat string/_ + PaintCorrectionMaskX real/_ + PaintCorrectionMaskY real/_ + PaintCorrectionMaskZeroX real/_ + PaintCorrectionMaskZeroY real/_ + PaintCorrectionBrightness real/_ + PaintCorrectionClarity real/_ + PaintCorrectionClarity2012 real/_ + PaintCorrectionContrast real/_ + PaintCorrectionContrast2012 real/_ + PaintCorrectionDefringe real/_ + PaintCorrectionExposure real/_ + PaintCorrectionExposure2012 real/_ + PaintCorrectionHighlights2012 real/_ + PaintCorrectionLuminanceNoise real/_ + PaintCorrectionMoire real/_ + PaintCorrectionSaturation real/_ + PaintCorrectionShadows2012 real/_ + PaintCorrectionSharpness real/_ + PaintCorrectionTemperature real/_ + PaintCorrectionTint real/_ + PaintCorrectionHue real/_ + PaintCorrectionSaturation real/_ + PaintCorrectionWhat string/_ + ParametricDarks integer/ + ParametricHighlights integer/ + ParametricHighlightSplit integer/ + ParametricLights integer/ + ParametricMidtoneSplit integer/ + ParametricShadows integer/ + ParametricShadowSplit integer/ + PerspectiveAspect integer/ + PerspectiveHorizontal integer/ + PerspectiveRotate real/ + PerspectiveScale integer/ + PerspectiveUpright integer/ + PerspectiveVertical integer/ + PerspectiveX real/ + PerspectiveY real/ + PostCropVignetteAmount integer/ + PostCropVignetteFeather integer/ + PostCropVignetteHighlightContrast integer/ + PostCropVignetteMidpoint integer/ + PostCropVignetteRoundness integer/ + PostCropVignetteStyle integer/ + ProcessVersion string/ + RawFileName string/ + RedEyeInfo string/+ + RedHue integer/ + RedSaturation integer/ + RetouchAreas RetouchArea Struct+ + RetouchAreaFeather real/_ + RetouchAreaMasks CorrectionMask Struct_+ + RetouchAreaMaskAlpha real/_ + RetouchAreaMaskAngle real/_ + RetouchAreaMaskBottom real/_ + RetouchAreaMaskCenterValue real/_ + RetouchAreaMaskCenterWeight real/_ + RetouchAreaMaskDabs string/_ + RetouchAreaMaskFeather real/_ + RetouchAreaMaskFlipped boolean/_ + RetouchAreaMaskFlow real/_ + RetouchAreaMaskFullX real/_ + RetouchAreaMaskFullY real/_ + RetouchAreaMaskLeft real/_ + RetouchAreaMaskValue real/_ + RetouchAreaMaskMidpoint real/_ + RetouchAreaMaskPerimeterValue real/_ + RetouchAreaMaskRadius real/_ + RetouchAreaMaskRight real/_ + RetouchAreaMaskRoundness real/_ + RetouchAreaMaskSizeX real/_ + RetouchAreaMaskSizeY real/_ + RetouchAreaMaskTop real/_ + RetouchAreaMaskVersion integer/_ + RetouchAreaMaskWhat string/_ + RetouchAreaMaskX real/_ + RetouchAreaMaskY real/_ + RetouchAreaMaskZeroX real/_ + RetouchAreaMaskZeroY real/_ + RetouchAreaMethod string/_ + RetouchAreaOffsetY real/_ + RetouchAreaOpacity real/_ + RetouchAreaSeed integer/_ + RetouchAreaSourceState string/_ + RetouchAreaSourceX real/_ + RetouchAreaSpotType string/_ + RetouchInfo string/+ + Saturation integer/ + SaturationAdjustmentAqua integer/ + SaturationAdjustmentBlue integer/ + SaturationAdjustmentGreen integer/ + SaturationAdjustmentMagenta integer/ + SaturationAdjustmentOrange integer/ + SaturationAdjustmentPurple integer/ + SaturationAdjustmentRed integer/ + SaturationAdjustmentYellow integer/ + Shadows integer/ + Shadows2012 integer/ + ShadowTint integer/ + SharpenDetail integer/ + SharpenEdgeMasking integer/ + SharpenRadius real/ + Sharpness integer/ + Smoothness integer/ + SplitToningBalance integer/ + SplitToningHighlightHue integer/ + SplitToningHighlightSaturation integer/ + SplitToningShadowHue integer/ + SplitToningShadowSaturation integer/ + ColorTemperature integer/ + Texture integer/ + TIFFHandling string/ + Tint integer/ + ToneCurve string/+ + ToneCurveBlue string/+ + ToneCurveGreen string/+ + ToneCurveName string/ + ToneCurveName2012 string/ + ToneCurvePV2012 string/+ + ToneCurvePV2012Blue string/+ + ToneCurvePV2012Green string/+ + ToneCurvePV2012Red string/+ + ToneCurveRed string/+ + ToneMapStrength real/ + UprightCenterMode integer/ + UprightCenterNormX real/ + UprightCenterNormY real/ + UprightDependentDigest string/ + UprightFocalLength35mm real/ + UprightFocalMode integer/ + UprightFourSegmentsCount integer/ + UprightPreview boolean/ + UprightTransform_0 string/ + UprightTransform_1 string/ + UprightTransform_2 string/ + UprightTransform_3 string/ + UprightTransform_4 string/ + UprightTransform_5 string/ + UprightTransformCount integer/ + UprightVersion integer/ + Version string/ + Vibrance integer/ + VignetteAmount integer/ + VignetteMidpoint integer/ + What string/ + WhiteBalance string/ + Whites2012 integer/ + +=head3 XMP Correction Struct + + Field Name Writable + ---------- -------- + CorrectionActive boolean + CorrectionAmount real + CorrectionMasks CorrectionMask Struct+ + LocalBrightness real + LocalClarity real + LocalClarity2012 real + LocalContrast real + LocalContrast2012 real + LocalDefringe real + LocalExposure real + LocalExposure2012 real + LocalHighlights2012 real + LocalLuminanceNoise real + LocalMoire real + LocalSaturation real + LocalShadows2012 real + LocalSharpness real + LocalTemperature real + LocalTint real + LocalToningHue real + LocalToningSaturation real + What string + +=head3 XMP CorrectionMask Struct + + Field Name Writable + ---------- -------- + Alpha real + Angle real + Bottom real + CenterValue real + CenterWeight real + Dabs string+ + Feather real + Flipped boolean + Flow real + FullX real + FullY real + Left real + MaskValue real + Midpoint real + PerimeterValue real + Radius real + Right real + Roundness real + SizeX real + SizeY real + Top real + Version integer + What string + X real + Y real + ZeroX real + ZeroY real + +=head3 XMP Look Struct + + Field Name Writable + ---------- -------- + Name string + +=head3 XMP RetouchArea Struct + + Field Name Writable + ---------- -------- + Feather real + Masks CorrectionMask Struct+ + Method string + OffsetY real + Opacity real + Seed integer + SourceState string + SourceX real + SpotType string + =head3 XMP creatorAtom Tags Adobe creatorAtom tags, written by After Effects. @@ -1509,6 +1983,7 @@ These tags belong to the ExifTool XMP-crs family 1 group. AutoExposure boolean AutoLateralCA integer AutoShadows boolean + AutoTone boolean AutoWhiteVersion integer Blacks2012 integer BlueHue integer @@ -1668,6 +2143,7 @@ These tags belong to the ExifTool XMP-crs family 1 group. GreenSaturation integer HasCrop boolean HasSettings boolean + Highlight2012 integer HighlightRecovery integer Highlights2012 integer HueAdjustmentAqua integer @@ -1698,6 +2174,8 @@ These tags belong to the ExifTool XMP-crs family 1 group. LensProfileName string LensProfileSetup string LensProfileVignettingScale integer + Look Look Struct + LookName string_ LuminanceAdjustmentAqua integer LuminanceAdjustmentBlue integer LuminanceAdjustmentGreen integer @@ -1713,6 +2191,7 @@ These tags belong to the ExifTool XMP-crs family 1 group. NegativeCacheLargePreviewSize integer NegativeCacheMaximumSize real NegativeCachePath string + OverrideLookVignette boolean PaintBasedCorrections Correction Struct+ PaintCorrectionActive boolean_ PaintCorrectionAmount real_ @@ -1850,6 +2329,7 @@ These tags belong to the ExifTool XMP-crs family 1 group. SplitToningShadowHue integer SplitToningShadowSaturation integer ColorTemperature integer + Texture integer TIFFHandling string Tint integer ToneCurve string+ @@ -1887,102 +2367,314 @@ These tags belong to the ExifTool XMP-crs family 1 group. WhiteBalance string/ Whites2012 integer -=head3 XMP Correction Struct +=head3 XMP dc Tags + +Dublin Core namespace tags. + +These tags belong to the ExifTool XMP-dc family 1 group. + + Tag Name Writable + -------- -------- + Contributor string+ + Coverage string + Creator string+ + Date date+ + Description lang-alt + Format string + Identifier string + Language string+ + Publisher string+ + Relation string+ + Rights lang-alt + Source string/ + Subject string+ + Title lang-alt + Type string+ + +=head3 XMP Device Tags + +Google depth-map Device tags. See +L<https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf> for +the specification. + +These tags belong to the ExifTool XMP-Device family 1 group. + + Tag Name Writable + -------- -------- + AppInfo AppInfo Struct + AppInfoApplication string_ + AppInfoItemURI string_ + AppInfoVersion string_ + Cameras DeviceCameras Struct+ + Camera DeviceCamera Struct_+ + CameraAppInfo AppInfo Struct_+ + CameraAppInfoApplication string_+ + CameraAppInfoItemURI string_+ + CameraAppInfoVersion string_+ + CameraDepthMap DeviceDepthMap Struct_+ + CameraDepthMapConfidenceURI string_+ + CameraDepthMapDepthURI string_+ + CameraDepthMapFar real_+ + CameraDepthMapFocalTable string_+ + CameraDepthMapFocalTableEntryCount integer_+ + CameraDepthMapFormat string_+ + CameraDepthMapItemSemantic string_+ + CameraDepthMapMeasureType string_+ + CameraDepthMapNear real_+ + CameraDepthMapSoftware string_+ + CameraDepthMapUnits string_+ + CameraImage DeviceImage Struct_+ + CameraImageItemSemantic string_+ + CameraImageItemURI string_+ + CameraImagingModel DeviceImagingModel Struct_+ + CameraImagingModelDistortion string_+ + CameraImagingModelDistortionCount integer_+ + CameraImagingModelFocalLengthX real_+ + CameraImagingModelFocalLengthY real_+ + CameraImagingModelImageHeight integer_+ + CameraImagingModelImageWidth integer_+ + CameraImagingModelPixelAspectRatio real_+ + CameraImagingModelPrincipalPointX real_+ + CameraImagingModelPrincipalPointY real_+ + CameraImagingModelSkew real_+ + CameraLightEstimate DeviceLightEstimate Struct_+ + CameraLightEstimateColorCorrectionB real_+ + CameraLightEstimateColorCorrectionG real_+ + CameraLightEstimateColorCorrectionR real_+ + CameraLightEstimatePixelIntensity real_+ + CameraPointCloud DevicePointCloud Struct_+ + CameraPointCloudMetric boolean_+ + CameraPointCloudPointCloud integer_+ + CameraPointCloudPoints string_+ + CameraPose Pose Struct_+ + CameraPosePositionX real_+ + CameraPosePositionY real_+ + CameraPosePositionZ real_+ + CameraPoseRotationW real_+ + CameraPoseRotationX real_+ + CameraPoseRotationY real_+ + CameraPoseRotationZ real_+ + CameraPoseTimestamp integer_+ + CameraTrait string_+ + CameraVendorInfo VendorInfo Struct_+ + CameraVendorInfoManufacturer string_+ + CameraVendorInfoModel string_+ + CameraVendorInfoNotes string_+ + Container DeviceContainer Struct + ContainerDirectory DeviceDirectory Struct_+ + ContainerDirectoryItem DeviceItem Struct_+ + ContainerDirectoryItemDataURI string_+ + ContainerDirectoryItemLength integer_+ + ContainerDirectoryItemMime string_+ + ContainerDirectoryItemPadding integer_+ + EarthPos EarthPose Struct + EarthPosAltitude real_ + EarthPosLatitude real_ + EarthPosLongitude real_ + EarthPosRotationW real_ + EarthPosRotationX real_ + EarthPosRotationY real_ + EarthPosRotationZ real_ + EarthPosTimestamp integer_ + Planes DevicePlanes Struct+ + Plane DevicePlane Struct_+ + PlaneBoundary string_+ + PlaneBoundaryVertexCount integer_+ + PlaneExtentX real_+ + PlaneExtentZ real_+ + PlanePose Pose Struct_+ + PlanePosePositionX real_+ + PlanePosePositionY real_+ + PlanePosePositionZ real_+ + PlanePoseRotationW real_+ + PlanePoseRotationX real_+ + PlanePoseRotationY real_+ + PlanePoseRotationZ real_+ + PlanePoseTimestamp integer_+ + Pose Pose Struct + PosePositionX real_ + PosePositionY real_ + PosePositionZ real_ + PoseRotationW real_ + PoseRotationX real_ + PoseRotationY real_ + PoseRotationZ real_ + PoseTimestamp integer_ + Profiles DeviceProfiles Struct+ + Profile DeviceProfile Struct_+ + ProfileCameraIndices integer_+ + ProfileType string_+ + VendorInfo VendorInfo Struct + VendorInfoManufacturer string_ + VendorInfoModel string_ + VendorInfoNotes string_ + +=head3 XMP AppInfo Struct Field Name Writable ---------- -------- - CorrectionActive boolean - CorrectionAmount real - CorrectionMasks CorrectionMask Struct+ - LocalBrightness real - LocalClarity real - LocalClarity2012 real - LocalContrast real - LocalContrast2012 real - LocalDefringe real - LocalExposure real - LocalExposure2012 real - LocalHighlights2012 real - LocalLuminanceNoise real - LocalMoire real - LocalSaturation real - LocalShadows2012 real - LocalSharpness real - LocalTemperature real - LocalTint real - LocalToningHue real - LocalToningSaturation real - What string + Application string + ItemURI string + Version string -=head3 XMP CorrectionMask Struct +=head3 XMP DeviceCameras Struct Field Name Writable ---------- -------- - Alpha real - Angle real - Bottom real - CenterValue real - CenterWeight real - Dabs string+ - Feather real - Flipped boolean - Flow real - FullX real - FullY real - Left real - MaskValue real - Midpoint real - PerimeterValue real - Radius real - Right real - Roundness real - SizeX real - SizeY real - Top real - Version integer - What string - X real - Y real - ZeroX real - ZeroY real + Camera DeviceCamera Struct -=head3 XMP RetouchArea Struct +=head3 XMP DeviceCamera Struct Field Name Writable ---------- -------- - Feather real - Masks CorrectionMask Struct+ - Method string - OffsetY real - Opacity real - Seed integer - SourceState string - SourceX real - SpotType string + AppInfo AppInfo Struct + DepthMap DeviceDepthMap Struct + Image DeviceImage Struct + ImagingModel DeviceImagingModel Struct + LightEstimate DeviceLightEstimate Struct + PointCloud DevicePointCloud Struct + Pose Pose Struct + Trait string + VendorInfo VendorInfo Struct + +=head3 XMP DeviceDepthMap Struct + + Field Name Writable + ---------- -------- + ConfidenceURI string + DepthURI string + Far real + FocalTable string + FocalTableEntryCount integer + Format string + ItemSemantic string + MeasureType string + Near real + Software string + Units string + +=head3 XMP DeviceImage Struct + + Field Name Writable + ---------- -------- + ItemSemantic string + ItemURI string + +=head3 XMP DeviceImagingModel Struct + + Field Name Writable + ---------- -------- + Distortion string + DistortionCount integer + FocalLengthX real + FocalLengthY real + ImageHeight integer + ImageWidth integer + PixelAspectRatio real + PrincipalPointX real + PrincipalPointY real + Skew real + +=head3 XMP DeviceLightEstimate Struct + + Field Name Writable + ---------- -------- + ColorCorrectionB real + ColorCorrectionG real + ColorCorrectionR real + PixelIntensity real + +=head3 XMP DevicePointCloud Struct + + Field Name Writable + ---------- -------- + Metric boolean + PointCloud integer + Points string + +=head3 XMP Pose Struct + + Field Name Writable + ---------- -------- + PositionX real + PositionY real + PositionZ real + RotationW real + RotationX real + RotationY real + RotationZ real + Timestamp integer + +=head3 XMP VendorInfo Struct + + Field Name Writable + ---------- -------- + Manufacturer string + Model string + Notes string + +=head3 XMP DeviceContainer Struct + + Field Name Writable + ---------- -------- + Directory DeviceDirectory Struct+ + +=head3 XMP DeviceDirectory Struct + + Field Name Writable + ---------- -------- + Item DeviceItem Struct + +=head3 XMP DeviceItem Struct + + Field Name Writable + ---------- -------- + DataURI string + Length integer + Mime string + Padding integer + +=head3 XMP EarthPose Struct + + Field Name Writable + ---------- -------- + Altitude real + Latitude real + Longitude real + RotationW real + RotationX real + RotationY real + RotationZ real + Timestamp integer + +=head3 XMP DevicePlanes Struct + + Field Name Writable + ---------- -------- + Plane DevicePlane Struct -=head3 XMP dc Tags +=head3 XMP DevicePlane Struct -Dublin Core namespace tags. + Field Name Writable + ---------- -------- + Boundary string + BoundaryVertexCount integer + ExtentX real + ExtentZ real + Pose Pose Struct -These tags belong to the ExifTool XMP-dc family 1 group. +=head3 XMP DeviceProfiles Struct - Tag Name Writable - -------- -------- - Contributor string+ - Coverage string - Creator string+ - Date date+ - Description lang-alt - Format string - Identifier string - Language string+ - Publisher string+ - Relation string+ - Rights lang-alt - Source string/ - Subject string+ - Title lang-alt - Type string+ + Field Name Writable + ---------- -------- + Profile DeviceProfile Struct + +=head3 XMP DeviceProfile Struct + + Field Name Writable + ---------- -------- + CameraIndices integer+ + Type string =head3 XMP dex Tags @@ -2049,8 +2741,8 @@ These tags belong to the ExifTool XMP-digiKam family 1 group. =head3 XMP exif Tags EXIF namespace for EXIF tags. See -L<http://www.cipa.jp/std/documents/e/DC-010-2017_E.pdf> for the -specification. +L<https://web.archive.org/web/20180921145139if_/http://www.cipa.jp:80/std/documents/e/DC-010-2017_E.pdf> +for the specification. These tags belong to the ExifTool XMP-exif family 1 group. @@ -2205,6 +2897,19 @@ These tags belong to the ExifTool XMP-exifEX family 1 group. SerialNumber string CameraElevationAngle rational OwnerName string + CompositeImage integer + CompositeImageCount integer+ + CompositeImageExposureTimes CompImageExp Struct + CompImageMaxExposureAll rational_ + CompImageMaxExposureUsed rational_ + CompImageMinExposureAll rational_ + CompImageMinExposureUsed rational_ + CompImageImagesPerSequence integer_ + CompImageNumSequences integer_ + CompImageSumExposureAll rational_ + CompImageSumExposureUsed rational_ + CompImageTotalExposurePeriod rational_ + CompImageValues rational_+ Gamma rational Humidity rational InteropIndex string @@ -2223,6 +2928,21 @@ These tags belong to the ExifTool XMP-exifEX family 1 group. AmbientTemperature rational WaterDepth rational +=head3 XMP CompImageExp Struct + + Field Name Writable + ---------- -------- + MaxExposureTimesOfAll rational + MaxExposureTimesOfUsed rational + MinExposureTimesOfAll rational + MinExposureTimesOfUsed rational + NumberOfImagesInSequences integer + NumberOfSequences integer + SumOfExposureTimesOfAll rational + SumOfExposureTimesOfUsed rational + TotalExposurePeriod rational + Values rational+ + =head3 XMP ExpressionMedia Tags Microsoft Expression Media namespace tags. These tags are avoided when @@ -2274,6 +2994,33 @@ These tags belong to the ExifTool XMP-GAudio family 1 group. AudioData string AudioMimeType string +=head3 XMP GCamera Tags + +Camera information found in Google panorama images. + +These tags belong to the ExifTool XMP-GCamera family 1 group. + + Tag Name Writable + -------- -------- + BurstID string + BurstPrimary string + DisableAutoCreation string+ + HDRPMakerNote string + PortraitNote string + PortraitRequest string + PortraitVersion string + SpecialTypeID string+ + +=head3 XMP GCreations Tags + +Google creations tags. + +These tags belong to the ExifTool XMP-GCreations family 1 group. + + Tag Name Writable + -------- -------- + CameraBurstID string + =head3 XMP GDepth Tags Google depthmap information. See @@ -2285,7 +3032,7 @@ These tags belong to the ExifTool XMP-GDepth family 1 group. -------- -------- Confidence string/ ConfidenceMime string/ - Data string/ + DepthImage string/ Far real/ Format string/ ImageHeight real/ @@ -2322,7 +3069,7 @@ These tags belong to the ExifTool XMP-getty family 1 group. OriginalFileName string ParentMediaEventID string ParentMEID string - Personality string + Personality string+ PrimaryFTP string+ RoutingDestinations string+ RoutingExclusions string+ @@ -2390,7 +3137,8 @@ These tags belong to the ExifTool XMP-GPano family 1 group. =head3 XMP GSpherical Tags Not actually XMP. These RDF/XML tags are used in Google spherical MP4 -videos. See +videos. These tags are written into the video track of MOV/MP4 files, and +not at the top level like other XMP tags. See L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md> for the specification. @@ -2433,15 +3181,15 @@ These tags belong to the ExifTool XMP-ics family 1 group. LabelName1 string_+ ParentReference1 string_+ Reference1 string_+ - SubLables1 TagStructure Struct_+ + SubLabels1 TagStructure Struct_+ LabelName2 string_+ ParentReference2 string_+ Reference2 string_+ - SubLables2 TagStructure Struct_+ + SubLabels2 TagStructure Struct_+ LabelName3 string_+ ParentReference3 string_+ Reference3 string_+ - SubLables3 TagStructure Struct_+ + SubLabels3 TagStructure Struct_+ LabelName4 string_+ ParentReference4 string_+ Reference4 string_+ @@ -2512,9 +3260,9 @@ These tags belong to the ExifTool XMP-iptcCore family 1 group. =head3 XMP iptcExt Tags -IPTC Extension namespace tags. The actual namespace prefix is -"Iptc4xmpExt", but ExifTool shortens this for the family 1 group name. (see -L<http://www.iptc.org/IPTC4XMP/>) +This table contains tags defined by the IPTC Extension schema version 1.5. +The actual namespace prefix is "Iptc4xmpExt", but ExifTool shortens this for +the family 1 group name. (see L<http://www.iptc.org/IPTC4XMP/>) These tags belong to the ExifTool XMP-iptcExt family 1 group. @@ -2598,6 +3346,26 @@ These tags belong to the ExifTool XMP-iptcExt family 1 group. GenreCvTermName lang-alt_+ GenreCvTermRefinedAbout string_+ Headline lang-alt/ + ImageRegion ImageRegion Struct+ + ImageRegionName lang-alt_+ + ImageRegionCtype Entity Struct_+ + ImageRegionCtypeIdentifier string_+ + ImageRegionCtypeName lang-alt_+ + ImageRegionBoundary RegionBoundary Struct_+ + ImageRegionBoundaryH real_+ + ImageRegionBoundaryRx real_+ + ImageRegionBoundaryShape string_+ + ImageRegionBoundaryUnit string_+ + ImageRegionBoundaryVertices BoundaryPoint Struct_+ + ImageRegionBoundaryVerticesX real_+ + ImageRegionBoundaryVerticesY real_+ + ImageRegionBoundaryW real_+ + ImageRegionBoundaryX real_+ + ImageRegionBoundaryY real_+ + ImageRegionID string_+ + ImageRegionRole Entity Struct_+ + ImageRegionRoleIdentifier string_+ + ImageRegionRoleName lang-alt_+ IPTCLastEdited date LinkedEncRightsExpr LEREDetails Struct+ LinkedEncodedRightsExpr string_+ @@ -2660,7 +3428,7 @@ These tags belong to the ExifTool XMP-iptcExt family 1 group. PublicationEventIdentifier string_+ PublicationEventName string_+ Rating Rating Struct+ - RatingRatingRegion LocationDetails Struct_+ + RatingRegion LocationDetails Struct_+ RatingRegionCity string_+ RatingRegionCountryCode string_+ RatingRegionCountryName string_+ @@ -2822,6 +3590,41 @@ These tags belong to the ExifTool XMP-iptcExt family 1 group. Name string Number string +=head3 XMP ImageRegion Struct + +This structure is new in the IPTC Extension version 1.5 specification. As +well as the fields defined below, this structure may contain any top-level +XMP tags, but since they aren't pre-defined the only way to add these tags +is to write ImageRegion as a structure with these tags as new fields. + + Field Name Writable + ---------- -------- + Name lang-alt + RegionBoundary RegionBoundary Struct + RCtype Entity Struct+ + RId string + RRole Entity Struct+ + +=head3 XMP RegionBoundary Struct + + Field Name Writable + ---------- -------- + RbH real + RbRx real + RbShape string + RbUnit string + RbVertices BoundaryPoint Struct+ + RbW real + RbX real + RbY real + +=head3 XMP BoundaryPoint Struct + + Field Name Writable + ---------- -------- + RbX real + RbY real + =head3 XMP LEREDetails Struct Field Name Writable @@ -3052,7 +3855,7 @@ These tags belong to the ExifTool XMP-photoshop family 1 group. =head3 XMP PixelLive Tags -PixelLive namespace tags. These tags are not writable becase they are very +PixelLive namespace tags. These tags are not writable because they are very uncommon and I haven't been able to locate a reference which gives the namespace URI. @@ -3124,20 +3927,20 @@ These tags belong to the ExifTool XMP-prism family 1 group. AggregateIssueNumber integer/ AggregationType string/+ AlternateTitle prismAlternateTitle Struct+ - AlternateTitleA-lang string_+ - AlternateTitleA-platform string_+ - AlternateTitleText string_+ + AlternateTitleA-lang string/_+ + AlternateTitleA-platform string/_+ + AlternateTitleText string/_+ BlogTitle string/ BlogURL string/ BookEdition string/ ByteCount integer/ Channel prismChannel Struct+ - ChannelA-lang string_+ - ChannelChannel string_+ - ChannelSubchannel1 string_+ - ChannelSubchannel2 string_+ - ChannelSubchannel3 string_+ - ChannelSubchannel4 string_+ + ChannelA-lang string/_+ + ChannelChannel string/_+ + ChannelSubchannel1 string/_+ + ChannelSubchannel2 string/_+ + ChannelSubchannel3 string/_+ + ChannelSubchannel4 string/_+ ComplianceProfile string/ ContentType string/ CopyrightYear string/ @@ -3156,9 +3959,9 @@ These tags belong to the ExifTool XMP-prism family 1 group. Genre string/+ HasAlternative string/+ HasCorrection prismHasCorrection Struct - HasCorrectionA-lang string_ - HasCorrectionA-platform string_ - HasCorrectionText string_ + HasCorrectionA-lang string/_ + HasCorrectionA-platform string/_ + HasCorrectionText string/_ HasTranslation string/+ Industry string/+ IsAlternativeOf string/+ @@ -3172,8 +3975,8 @@ These tags belong to the ExifTool XMP-prism family 1 group. IsTranslationOf string/ Keyword string/+ KillDate prismKillDate Struct - KillDateA-platform string_ - KillDateDate date_ + KillDateA-platform string/_ + KillDateDate date/_ Link string/+ Location string/+ ModificationDate date/ @@ -3181,14 +3984,14 @@ These tags belong to the ExifTool XMP-prism family 1 group. Number string/ Object string/+ OffSaleDate prismOffSaleDate Struct+ - OffSaleDateA-platform string_+ - OffSaleDateDate date_+ + OffSaleDateA-platform string/_+ + OffSaleDateDate date/_+ OnSaleDate prismOnSaleDate Struct+ - OnSaleDateA-platform string_+ - OnSaleDateDate date_+ + OnSaleDateA-platform string/_+ + OnSaleDateDate date/_+ OnSaleDay prismOnSaleDay Struct+ - OnSaleDayA-platform string_+ - OnSaleDayDay string_+ + OnSaleDayA-platform string/_+ + OnSaleDayDay string/_+ Organization string/+ OriginPlatform string/+ PageCount integer/ @@ -3199,11 +4002,11 @@ These tags belong to the ExifTool XMP-prism family 1 group. ProductCode string/ Profession string/ PublicationDate prismPublicationDate Struct+ - PublicationDateA-platform string_+ - PublicationDateDate date_+ + PublicationDateA-platform string/_+ + PublicationDateDate date/_+ PublicationDisplayDate prismPublicationDate Struct+ - PublicationDisplayDateA-platform string_+ - PublicationDisplayDateDate date_+ + PublicationDisplayDateA-platform string/_+ + PublicationDisplayDateDate date/_+ PublicationName string/ PublishingFrequency string/ Rating string/ @@ -3226,8 +4029,8 @@ These tags belong to the ExifTool XMP-prism family 1 group. Ticker string/+ TimePeriod string/ URL prismUrl Struct+ - URLA-platform string_+ - URLUrl string_+ + URLA-platform string/_+ + URLUrl string/_+ UspsNumber string/ VersionIdentifier string/ Volume string/ @@ -3396,8 +4199,8 @@ These tags belong to the ExifTool XMP-swf family 1 group. =head3 XMP tiff Tags EXIF namespace for TIFF tags. See -L<http://www.cipa.jp/std/documents/e/DC-010-2017_E.pdf> for the -specification. +L<https://web.archive.org/web/20180921145139if_/http://www.cipa.jp:80/std/documents/e/DC-010-2017_E.pdf> +for the specification. These tags belong to the ExifTool XMP-tiff family 1 group. @@ -3921,6 +4724,7 @@ These tags belong to the ExifTool XMP-xmpMM family 1 group. ManifestReferenceVersionID string_+ OriginalDocumentID string Pantry PantryItem Struct+ + PantryInstanceID string_ PreservedFileName string RenditionClass string RenditionOf ResourceRef Struct @@ -4928,6 +5732,7 @@ boot, not including standby time. 0x0026 CanonAFInfo2 Canon AFInfo2 0x0027 ContrastInfo Canon ContrastInfo 0x0028 ImageUniqueID int8u + 0x0029 WBInfo Canon WBInfo 0x002f FaceDetect3 Canon FaceDetect3 0x0035 TimeInfo Canon TimeInfo 0x0038 BatteryType undef @@ -4992,6 +5797,7 @@ boot, not including standby time. 0x4024 FilterInfo Canon FilterInfo 0x4025 HDRInfo Canon HDRInfo 0x4028 AFConfig Canon AFConfig + 0x403f RawBurstModeRoll Canon RawBurstInfo =head3 Canon CameraSettings Tags @@ -6036,6 +6842,23 @@ may be 7, 9, 11, 19, 31, 45 or 61, depending on the camera model. ------ -------- -------- 4 IntelligentContrast int16u +=head3 Canon WBInfo Tags + +WB tags for the Canon G9. + + Index4 Tag Name Writable + ------ -------- -------- + 2 WB_GRGBLevelsAuto int32s[4] + 10 WB_GRGBLevelsDaylight int32s[4] + 18 WB_GRGBLevelsCloudy int32s[4] + 26 WB_GRGBLevelsTungsten int32s[4] + 34 WB_GRGBLevelsFluorescent int32s[4] + 42 WB_GRGBLevelsFluorHigh int32s[4] + 50 WB_GRGBLevelsFlash int32s[4] + 58 WB_GRGBLevelsUnderwater int32s[4] + 66 WB_GRGBLevelsCustom1 int32s[4] + 74 WB_GRGBLevelsCustom2 int32s[4] + =head3 Canon FaceDetect3 Tags Index2 Tag Name Writable @@ -6130,6 +6953,7 @@ These tags are used by the 10D and 300D. 21 WB_RGGBLevelsFluorescent int16s[4] 25 WB_RGGBLevelsFlash int16s[4] 29 WB_RGGBLevelsCustom int16s[4] + BlackLevels int16s[4] 33 WB_RGGBLevelsKelvin int16s[4] 37 WB_RGGBBlackLevels int16s[4] @@ -6435,6 +7259,8 @@ These tags are used by many EOS M and PowerShot models. 255 ColorCalib2? Canon ColorCalib2 264 PerChannelBlackLevel int16s[4] 333 PerChannelBlackLevel int16s[4] + 1385 NormalWhiteLevel int16u + 1386 SpecularWhiteLevel int16u =head3 Canon ColorCoefs2 Tags @@ -6868,9 +7694,11 @@ This information is found in images from newer EOS models. ------ -------- -------- 0 VignettingCorrVersion no 2 PeripheralLighting int16s + 3 DistortionCorrection int16s 4 ChromaticAberrationCorr int16s 5 ChromaticAberrationCorr int16s 6 PeripheralLightingValue int16s + 9 DistortionCorrectionValue int16s 11 OriginalImageWidth int16s 12 OriginalImageHeight int16s @@ -6888,6 +7716,7 @@ Vignetting correction from PowerShot models. ------ -------- -------- 5 PeripheralLightingSetting int32s 6 ChromaticAberrationSetting int32s + 7 DistortionCorrectionSetting int32s =head3 Canon LightingOpt Tags @@ -6969,12 +7798,68 @@ Information about creative filter settings. 18 AFStatusViewfinder int32s 19 InitialAFPointInServo int32s +=head3 Canon RawBurstInfo Tags + + Index4 Tag Name Writable + ------ -------- -------- + 1 RawBurstImageNum int32u + 2 RawBurstImageCount int32u + +=head3 Canon CTMD Tags + +Canon Timed MetaData tags found in CR3 images. The ExtractEmbedded option +is automatically applied when reading CR3 files to be able to extract this +information. + + Tag ID Tag Name Writable + ------ -------- -------- + 0x0001 TimeStamp no + 0x0004 FocalInfo Canon FocalInfo + 0x0005 ExposureInfo Canon ExposureInfo + 0x0007 ExifInfo7 Canon ExifInfo + 0x0008 ExifInfo8 Canon ExifInfo + 0x0009 ExifInfo9 Canon ExifInfo + +=head3 Canon FocalInfo Tags + + Index4 Tag Name Writable + ------ -------- -------- + 0 FocalLength no + +=head3 Canon ExposureInfo Tags + + Index4 Tag Name Writable + ------ -------- -------- + 0 FNumber no + 1 ExposureTime no + 2 ISO no + +=head3 Canon ExifInfo Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 0x8769 ExifIFD EXIF + 0x927c MakerNoteCanon Canon + =head3 Canon CDI1 Tags Tag ID Tag Name Writable ------ -------- -------- + 'IAD1' IAD1 Canon IAD1 + +=head3 Canon IAD1 Tags + + Index2 Tag Name Writable + ------ -------- -------- [no tags known] +=head3 Canon CMP1 Tags + + Index2 Tag Name Writable + ------ -------- -------- + 8 ImageWidth no + 10 ImageHeight no + =head3 Canon CNOP Tags Tag ID Tag Name Writable @@ -6983,12 +7868,12 @@ Information about creative filter settings. =head3 Canon CNTH Tags -Canon-specific QuickTime tags found in the CNTH atom of MOV videos from some -cameras such as the PowerShot S95. +Canon-specific QuickTime tags found in the CNTH atom of MOV/MP4 videos from +some cameras. Tag ID Tag Name Writable ------ -------- -------- - 'CNDA' ThumbnailImage no + 'CNDA' ThumbnailImage undef =head3 Canon uuid Tags @@ -7021,41 +7906,11 @@ Information found in the "skip" atom of Canon MOV videos. ------ -------- -------- 'CNDB' Unknown_CNDB? no -=head3 Canon CTMD Tags - -Canon Timed MetaData tags found in CR3 images. The ExtractEmbedded option -is automatically applied when reading CR3 files to be able to extract this -information. - - Tag ID Tag Name Writable - ------ -------- -------- - 0x0001 TimeStamp no - 0x0004 FocalInfo Canon FocalInfo - 0x0005 ExposureInfo Canon ExposureInfo - 0x0007 ExifInfo7 Canon ExifInfo - 0x0008 ExifInfo8 Canon ExifInfo - 0x0009 ExifInfo9 Canon ExifInfo - -=head3 Canon FocalInfo Tags - - Index4 Tag Name Writable - ------ -------- -------- - 0 FocalLength no - -=head3 Canon ExposureInfo Tags - - Index4 Tag Name Writable - ------ -------- -------- - 0 FNumber no - 1 ExposureTime no - 2 ISO no - -=head3 Canon ExifInfo Tags +=head3 Canon uuid2 Tags Tag ID Tag Name Writable ------ -------- -------- - 0x8769 ExifIFD EXIF - 0x927c MakerNoteCanon Canon + 'CNOP' CanonVRD CanonVRD =head2 CanonCustom Tags @@ -7426,6 +8281,7 @@ well as newer tags and values added by later models. 0x0813 DefaultEraseOption int32s 0x0814 RetractLensOnPowerOff int32s 0x0815 AddIPTCInformation int32s + 0x0816 AudioCompression int32s =head2 CanonVRD Tags @@ -7979,6 +8835,61 @@ This information is found in Casio GV-10 AVI videos. ------ -------- -------- 0 Software no +=head2 DJI Tags + +This table lists tags found in the maker notes of images from some DJI +Phantom drones. + + Tag ID Tag Name Writable + ------ -------- -------- + 0x0001 Make string + 0x0003 SpeedX float + 0x0004 SpeedY float + 0x0005 SpeedZ float + 0x0006 Pitch float + 0x0007 Yaw float + 0x0008 Roll float + 0x0009 CameraPitch float + 0x000a CameraYaw float + 0x000b CameraRoll float + +=head3 DJI XMP Tags + +XMP tags used by DJI for images from drones. + +These tags belong to the ExifTool XMP-drone-dji family 1 group. + + Tag Name Writable + -------- -------- + AbsoluteAltitude real + CalibratedFocalLength real + CalibratedOpticalCenterX real + CalibratedOpticalCenterY real + CamReverse string + DewarpData string + DewarpFlag string + FlightPitchDegree real + FlightRollDegree real + FlightXSpeed real + FlightYSpeed real + FlightYawDegree real + FlightZSpeed real + GPSLatitude real/ + GPSLongitude real/ + GPSLongtitude real + GimbalPitchDegree real + GimbalReverse string + GimbalRollDegree real + GimbalYawDegree real + Latitude real + Longitude real + RelativeAltitude real + RtkFlag string + RtkStdHgt real + RtkStdLat real + RtkStdLon real + SelfData string + =head2 FLIR Tags Information extracted from the maker notes of JPEG images from thermal @@ -8075,7 +8986,7 @@ Information found in FFF-format .CRS correction image files. FLIR camera information. The Planck tags are variables used in the temperature calculation. See -L<http://u88.n24.queensu.ca/exiftool/forum/index.php?topic=4898.msg23972#msg23972> +L<https://exiftool.org/forum/index.php?topic=4898.msg23972#msg23972> for details. Index1 Tag Name Writable @@ -8116,6 +9027,8 @@ for details. 540 FilterSerialNumber no 776 PlanckO no 780 PlanckR2 no + 784 RawValueRangeMin no + 786 RawValueRangeMax no 824 RawValueMedian no 828 RawValueRange no 900 DateTimeOriginal no @@ -8448,6 +9361,8 @@ Tags extracted from FLIR Public image Format (FPF) files. 0x1047 GrainEffect int32s 0x1048 ColorChromeEffect int32s 0x1049 BWAdjustment int8s + 0x104d CropMode int16u + 0x104e ColorChromeFXBlue int32s 0x1050 ShutterType int16u 0x1100 AutoBracketing int16u 0x1101 SequenceNumber int16u @@ -8478,9 +9393,14 @@ Tags extracted from FLIR Public image Format (FPF) files. 0x1444 DRangePriorityAuto int16u 0x1445 DRangePriorityFixed int16u 0x1446 FlickerReduction int32u + 0x3803 VideoRecordingMode int32u + 0x3804 PeripheralLighting int16u + 0x3806 VideoCompression int16u 0x3820 FrameRate int16u 0x3821 FrameWidth int16u 0x3822 FrameHeight int16u + 0x3824 FullHDHighSpeedRec int32u + 0x4005 FaceElementSelected int16u[4] 0x4100 FacesDetected int16u 0x4103 FacePositions int16u[n] 0x4200 NumFaceElements int16u @@ -8565,6 +9485,9 @@ RAF-format information. Tag ID Tag Name Writable ------ -------- -------- 0x0100 RawImageFullSize no + 0x0110 RawImageCropTopLeft no + 0x0111 RawImageCroppedSize no + 0x0115 RawImageAspectRatio no 0x0121 RawImageSize no 0x0130 FujiLayout no 0x0131 XTransLayout no @@ -9595,6 +10518,7 @@ data, however ExifTool will extract information from any tags found here. 'ISO' ISO no 'ISO Speed' ISO no 'Image Number' ImageNumber no + 'Lens' Lens no 'Max Aperture' MaxAperture no 'Meter Mode' MeterMode no 'Min Aperture' MinAperture no @@ -10048,7 +10972,7 @@ they don't appear in these tables. Tag ID Tag Name Writable ------ -------- -------- - 'JPEG_preview_data' PreviewImage undef + 'JPEG_preview_data' PreviewImage no 'JPEG_preview_info' PreviewInfo no 'PDA_histogram_data' PDAHistogram no 'back_serial_number' BackSerial no @@ -10702,6 +11626,8 @@ DiMAGE X and Xt. Tag ID Tag Name Writable ------ -------- -------- + 0x5500 BuildNumber string + 0x5501 SerialNumber string 0x665e Sensor string 0x6705 ManufactureDate string @@ -10745,16 +11671,20 @@ DiMAGE X and Xt. 0x0022 ActiveD-Lighting int16u 0x0023 PictureControlData Nikon PictureControl Nikon PictureControl2 + Nikon PictureControl3 + Nikon PictureControlUnknown 0x0024 WorldTime Nikon WorldTime 0x0025 ISOInfo Nikon ISOInfo 0x002a VignetteControl int16u 0x002b DistortInfo Nikon DistortInfo 0x002c UnknownInfo Nikon UnknownInfo 0x0032 UnknownInfo2 Nikon UnknownInfo2 + 0x0034 ShutterMode int16u 0x0035 HDRInfo Nikon HDRInfo 0x0037 MechanicalShutterCount int32u 0x0039 LocationInfo Nikon LocationInfo 0x003d BlackLevel int16u[4] + 0x0045 CropArea int16u[4] 0x004f ColorTemperatureAuto int16u 0x0080 ImageAdjustment string 0x0081 ToneComp string @@ -10799,7 +11729,7 @@ DiMAGE X and Xt. ShotInfoUnknown Nikon ShotInfo 0x0092 HueAdjustment int16s 0x0093 NEFCompression int16u - 0x0094 Saturation int16s + 0x0094 SaturationAdj int16s 0x0095 NoiseReduction string 0x0096 NEFLinearizationTable undef! 0x0097 ColorBalance0100 Nikon ColorBalance1 @@ -10819,10 +11749,14 @@ DiMAGE X and Xt. LensData0201 Nikon LensData01 LensData0204 Nikon LensData0204 LensData0400 Nikon LensData0400 + LensData0402 Nikon LensData0402 + LensData0403 Nikon LensData0403 + LensData0800 Nikon LensData0800 LensDataUnknown Nikon LensDataUnknown 0x0099 RawImageCenter int16u[2] 0x009a SensorPixelSize rational64u[2] 0x009c SceneAssist string + 0x009d DateStampMode int16u 0x009e RetouchHistory int16u[10] 0x00a0 SerialNumber string 0x00a2 ImageDataSize int32u @@ -10854,11 +11788,11 @@ DiMAGE X and Xt. 0x00c3 BarometerInfo Nikon BarometerInfo 0x0e00 PrintIM PrintIM 0x0e01 NikonCaptureData NikonCapture - 0x0e09 NikonCaptureVersion string + 0x0e09 NikonCaptureVersion string^ 0x0e0e NikonCaptureOffsets Nikon CaptureOffsets 0x0e10 NikonScanIFD Nikon Scan 0x0e13 NikonCaptureEditVersions NikonCapture - NikonCaptureEditVersions undef! + NikonCaptureEditVersions undef!^ 0x0e1d NikonICCProfile ICC_Profile 0x0e1e NikonCaptureOutput Nikon CaptureOutput 0x0e22 NEFBitDepth int16u[4]! @@ -10989,6 +11923,32 @@ Color balance tags used by the P1000, P7000, P7100 and B700. 64 ToningEffect int8u 65 ToningSaturation int8u +=head3 Nikon PictureControl3 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 0 PictureControlVersion no + 8 PictureControlName string[20] + 28 PictureControlBase string[20] + 54 PictureControlAdjust int8u + 55 PictureControlQuickAdjust int8u + 57 Sharpness int8u + 59 MidRangeSharpness int8u + 61 Clarity int8u + 63 Contrast int8u + 65 Brightness int8u + 67 Saturation int8u + 69 Hue int8u + 71 FilterEffect int8u + 72 ToningEffect int8u + 73 ToningSaturation int8u + +=head3 Nikon PictureControlUnknown Tags + + Index1 Tag Name Writable + ------ -------- -------- + 0 PictureControlVersion no + =head3 Nikon WorldTime Tags Index1 Tag Name Writable @@ -11226,19 +12186,18 @@ These tags are extracted from encrypted data in images from the D800. =head3 Nikon ShotInfoD810 Tags -These tags are extracted from encrypted data in images from the D810. +These tags are extracted from encrypted data in images from the D810. Note +that the indices listed below are for firmware version 1.0, but they may be +different for other firmware versions. Index Tag Name Writable ----- -------- -------- 0 ShotInfoVersion no 4 FirmwareVersion no - 36 BracketingOffset no - 64 CustomSettingsOffset no - 132 OrientationOffset no 464 SecondarySlotFunction int8u & 0x03 5974 AEBracketingSteps int8u & 0xff 5975 WBBracketingSteps int8u & 0xff - 5982 D810MeteringMode int8u & 0x03 + 5982 NikonMeteringMode int8u & 0x03 6236 ISOAutoShutterTime int8u & 0x3f 6237 ISOAutoHiLimit int8u & 0xff 6315 CustomSettingsD810 NikonCustom SettingsD810 @@ -11254,7 +12213,6 @@ These tags are extracted from encrypted data in images from the D850. ----- -------- -------- 0 ShotInfoVersion no 4 FirmwareVersion no - 88 CustomSettingsOffset no 1937 PhotoShootingMenuBankImageArea int8u & 0x07 4029 PhotoShootingMenuBank int8u & 0x03 4031 PrimarySlot int8u & 0x80 @@ -11343,12 +12301,6 @@ These tags are extracted from encrypted data in images from the D5 and D500. ----- -------- -------- 0 ShotInfoVersion no 4 FirmwareVersion no - 16 RotationInfoOffset no - 20 JPGInfoOffset no - 44 BracketingInfoOffset no - 80 ShootingMenuOffset no - 88 CustomSettingsOffset no - 160 OrientationOffset no 202 Rotation int8u & 0x03 1506 FlickerReductionIndicator int8u & 0x01 2004 JPGCompression int8u & 0x01 @@ -11367,6 +12319,7 @@ These tags are extracted from encrypted data in images from the D5 and D500. 11300 RollAngle fixed32u 11304 PitchAngle fixed32u 11308 YawAngle fixed32u + 11940 NikonMeteringMode int8u & 0x03 =head3 Nikon ShotInfoD610 Tags @@ -11492,13 +12445,57 @@ extracted. =head3 Nikon LensData0400 Tags -Tags extracted from the encrypted lens data of Nikon 1 models. +Tags extracted from the encrypted lens data of the Nikon 1J1/1V1/1J2. Index1 Tag Name Writable ------ -------- -------- 0 LensDataVersion no 394 LensModel string[64] +=head3 Nikon LensData0402 Tags + +Tags extracted from the encrypted lens data of the Nikon 1J3/1S1/1V2. + + Index1 Tag Name Writable + ------ -------- -------- + 0 LensDataVersion no + 395 LensModel string[64] + +=head3 Nikon LensData0403 Tags + +Tags extracted from the encrypted lens data of the Nikon 1J4/1J5. + + Index1 Tag Name Writable + ------ -------- -------- + 0 LensDataVersion no + 684 LensModel string[64] + +=head3 Nikon LensData0800 Tags + +Tags found in the encrypted LensData from cameras such as the Z6 and Z7. + + Index1 Tag Name Writable + ------ -------- -------- + 0 LensDataVersion no + 4 ExitPupilPosition int8u + 5 AFAperture int8u + 9 FocusPosition int8u + 11 FocusDistance int8u + 12 FocalLength int8u + 13 LensIDNumber int8u + 14 LensFStops int8u + 15 MinFocalLength int8u + 16 MaxFocalLength int8u + 17 MaxApertureAtMinFocal int8u + 18 MaxApertureAtMaxFocal int8u + 19 MCUVersion int8u + 20 EffectiveMaxAperture int8u + 48 LensID int16u + 54 MaxAperture int16u + 56 FNumber int16u + 60 FocalLength int16u + 79 FocusDistance int8u + =head3 Nikon LensDataUnknown Tags Index1 Tag Name Writable @@ -11684,6 +12681,7 @@ These tags are written by Nikon DSLR's which have the live view feature. AFPointsUsed undef[21] AFPointsUsed undef[29] AFPointsUsed undef[20] + AFPointsUsed undef[13] AFPointsUsed undef[7] 16 AFImageWidth int16u 18 AFImageHeight int16u @@ -11692,6 +12690,12 @@ These tags are written by Nikon DSLR's which have the live view feature. 24 AFAreaWidth int16u 26 AFAreaHeight int16u 28 ContrastDetectAFInFocus int8u + 42 AFImageWidth int16u + 44 AFImageHeight int16u + 46 AFAreaXPosition int16u + 48 AFAreaYPosition int16u + 50 AFAreaWidth int16u + 52 AFAreaHeight int16u 68 PrimaryAFPoint int8u 70 AFImageWidth int16u 72 AFImageHeight int16u @@ -11792,6 +12796,15 @@ This information is written by the Nikon Scan software. 0x000a DigitalZoom yes 0x000b Converter yes +=head3 Nikon NEFInfo Tags + +As-yet unknown information found in SubIFD1 tag 0xc7d5 of NEF images from +cameras such as the Z6 and Z7, and NRW images from some Coolpix cameras. + + Tag ID Tag Name Writable + ------ -------- -------- + [no tags known] + =head3 Nikon NCDT Tags Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from @@ -11861,28 +12874,33 @@ videos from some Nikon cameras. 0x120001d GPSDateStamp no 0x2000001 MakerNoteVersion no 0x2000005 WhiteBalance no - 0x2000007 FocusMode string + 0x2000007 FocusMode no 0x200000b WhiteBalanceFineTune no - 0x200001b CropHiSpeed int16u[7] + 0x200001b CropHiSpeed no 0x200001e ColorSpace no 0x200001f VRInfo Nikon VRInfo - 0x2000022 ActiveD-Lighting int16u + 0x2000022 ActiveD-Lighting no 0x2000023 PictureControlData Nikon PictureControl Nikon PictureControl2 + Nikon PictureControl3 + Nikon PictureControlUnknown 0x2000024 WorldTime Nikon WorldTime 0x2000025 ISOInfo Nikon ISOInfo - 0x200002a VignetteControl int16u + 0x200002a VignetteControl no 0x200002c UnknownInfo Nikon UnknownInfo 0x2000032 UnknownInfo2 Nikon UnknownInfo2 0x2000039 LocationInfo Nikon LocationInfo 0x2000083 LensType no 0x2000084 Lens no - 0x2000087 FlashMode int8u + 0x2000087 FlashMode no 0x2000098 LensData0100 Nikon LensData00 LensData0101 Nikon LensData01 LensData0201 Nikon LensData01 LensData0204 Nikon LensData0204 LensData0400 Nikon LensData0400 + LensData0402 Nikon LensData0402 + LensData0403 Nikon LensData0403 + LensData0800 Nikon LensData0800 LensDataUnknown Nikon LensDataUnknown 0x20000a7 ShutterCount no 0x20000a8 FlashInfo0100 Nikon FlashInfo0100 @@ -11891,8 +12909,8 @@ videos from some Nikon cameras. FlashInfo0106 Nikon FlashInfo0106 FlashInfo0107 Nikon FlashInfo0107 FlashInfoUnknown Nikon FlashInfoUnknown - 0x20000ab VariProgram string - 0x20000b1 HighISONoiseReduction int16u + 0x20000ab VariProgram no + 0x20000b1 HighISONoiseReduction no 0x20000b7 AFInfo2 Nikon AFInfo2 0x20000c3 BarometerInfo Nikon BarometerInfo @@ -12773,9 +13791,9 @@ Custom settings for the D5. ------ -------- -------- 0.1 CustomSettingsBank int8u & 0x03 1.1 AF-CPrioritySelection int8u & 0xc0 - 1.2 NumberOfFocusPoints int8u & 0x10 - 1.3 Three-DTrackingFaceDetection int8u & 0x08 - 1.4 AF-SPrioritySelection int8u & 0x20 + 1.2 AF-SPrioritySelection int8u & 0x20 + 1.3 NumberOfFocusPoints int8u & 0x10 + 1.4 Three-DTrackingFaceDetection int8u & 0x08 1.5 BlockShotAFResponse int8u & 0x07 2.1 FocusPointWrap int8u & 0x08 2.2 AFPointBrightness int8u & 0x06 @@ -12869,9 +13887,9 @@ Custom settings for the D500. ------ -------- -------- 0.1 CustomSettingsBank int8u & 0x03 1.1 AF-CPrioritySelection int8u & 0xc0 - 1.2 NumberOfFocusPoints int8u & 0x10 - 1.3 Three-DTrackingFaceDetection int8u & 0x08 - 1.4 AF-SPrioritySelection int8u & 0x20 + 1.2 AF-SPrioritySelection int8u & 0x20 + 1.3 NumberOfFocusPoints int8u & 0x10 + 1.4 Three-DTrackingFaceDetection int8u & 0x08 1.5 BlockShotAFResponse int8u & 0x07 2.1 FocusPointWrap int8u & 0x08 2.2 AFPointBrightness int8u & 0x06 @@ -13219,8 +14237,8 @@ Pentax, Ricoh, Samsung, Sanyo, SeaLife, Sony, Supra and Vivitar. 0x0207 CameraType string 0x0208 TextInfo Olympus TextInfo 0x0209 CameraID string - 0x020b EpsonImageWidth int16u - 0x020c EpsonImageHeight int16u + 0x020b EpsonImageWidth int32u + 0x020c EpsonImageHeight int32u 0x020d EpsonSoftware string 0x0280 PreviewImage int8u 0x0300 PreCaptureFrames int16u @@ -13228,6 +14246,7 @@ Pentax, Ricoh, Samsung, Sanyo, SeaLife, Sony, Supra and Vivitar. 0x0302 OneTouchWB int16u 0x0303 WhiteBalanceBracket int16u 0x0304 WhiteBalanceBias int16u + 0x0400 SensorArea undef[8] 0x0401 BlackLevel int32u[4] 0x0403 SceneMode int16u 0x0404 SerialNumber string @@ -13953,6 +14972,10 @@ These tags are used in Panasonic/Leica cameras. 0x00b9 RedEyeRemoval int16u 0x00bb VideoBurstMode int32u 0x00bc DiffractionCorrection int16u + 0x00c4 LensTypeMake int16u + 0x00c5 LensTypeModel int16u + 0x00d1 ISO int32u + 0x00d6 NoiseReductionStrength rational64s 0x0e00 PrintIM PrintIM 0x2003 TimeInfo Panasonic TimeInfo 0x8000 MakerNoteVersion undef @@ -14144,13 +15167,16 @@ images. =head3 Panasonic Leica9 Tags -This information is written by the Leica S (Typ 007). +This information is written by the Leica S (Typ 007) and M10 models. Tag ID Tag Name Writable ------ -------- -------- 0x0304 FocusDistance int32u 0x0311 ExternalSensorBrightnessValue rational64s 0x0312 MeasuredLV rational64s + 0x034c UserProfile string + 0x0359 ISOSelected int32s + 0x035a FNumber int32s =head3 Panasonic Type2 Tags @@ -14299,7 +15325,7 @@ These tags are used in Pentax/Asahi cameras. 0x0080 AspectRatio yes 0x0082 BlurControl int8u[4] 0x0085 HDR int8u[4] - 0x0088 NeutralDensityFilter int8u + 0x0088 NeutralDensityFilter int8u[n] 0x008b ISO int32u 0x0092 IntervalShooting int16u[2] 0x0095 SkinToneCorrection int8s[2] @@ -14940,7 +15966,7 @@ Tags extracted from the maker notes of AVI videos from the Optio S1. Tag ID Tag Name Writable ------ -------- -------- - 0x0000 MakerNoteVersion undef[4] + 0x0000 MakerNoteVersion no =head3 Pentax PENT Tags @@ -15136,6 +16162,38 @@ Tags extracted from models such as the UltraFire. 75 SerialNumber string[15] 90 UserLabel string[21] +=head3 Reconyx Type3 Tags + +Tags extracted from models such as the HF2 PRO. + + Index1 Tag Name Writable + ------ -------- -------- + 16 FileNumber int16u + 18 DirectoryNumber int16u + 42 FirmwareVersion int16u[3] + 48 FirmwareDate int16u[2] + 52 TriggerMode string[2] + 54 Sequence int16u[2] + 58 EventNumber int16u[2] + 62 DateTimeOriginal int16u[6] + 74 DayOfWeek int16u + 76 MoonPhase int16u + 78 AmbientTemperatureFahrenheit int16s + 80 AmbientTemperature int16s + 82 Contrast int16u + 84 Brightness int16u + 86 Sharpness int16u + 88 Saturation int16u + 90 Flash int16u + 92 AmbientInfrared int16u + 94 AmbientLight int16u + 96 MotionSensitivity int16u + 98 BatteryVoltage int16u + 100 BatteryVoltageAvg int16u + 102 BatteryType int16u + 104 UserLabel string[22] + 126 SerialNumber unicode[15] + =head2 Sanyo Tags Tag ID Tag Name Writable @@ -15320,6 +16378,12 @@ Camera orientation information written by the Gear 360 (SM-C200). 3 PictureWizardSharpness int16u 4 PictureWizardContrast int16u +=head3 Samsung APP5 Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 'ssuniqueid' UniqueID no + =head3 Samsung Trailer Tags Tags extracted from the trailer of JPEG images written when using certain @@ -15332,23 +16396,58 @@ as the Galaxy S4 and Tab S. DepthMapName no DualCameraImage no DualCameraImageName no - DualShotInfo Samsung DualShotInfo + DualShotExtra Samsung DualShotExtra EmbeddedAudioFile no EmbeddedAudioFileName no EmbeddedImage no EmbeddedImageName no EmbeddedVideoFile no EmbeddedVideoType no + SingleShotDepthMap no + SingleShotMeta Samsung SingleShotMeta SurroundShotVideo no SurroundShotVideoName no TimeStamp no -=head3 Samsung DualShotInfo Tags +=head3 Samsung DualShotExtra Tags Index4 Tag Name Writable ------ -------- -------- - 9 DepthMapWidth no - 10 DepthMapHeight no + 16 DepthMapWidth no + 17 DepthMapHeight no + +=head3 Samsung SingleShotMeta Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 'beautyColorLevel' BeautyColorLevel no + 'beautyRetouchLevel' BeautyRetouchLevel no + 'blurStrength' BlurStrength no + 'bokehShape' BokehShape no + 'colorpopStrength' ColorpopStrength no + 'depthHWHeight' DepthHWHeight no + 'depthHWWidth' DepthHWWidth no + 'depthSWHeight' DepthSWHeight no + 'depthSWWidth' DepthSWWidth no + 'deviceOrientation' DeviceOrientation no + 'effectStrength' EffectStrength no + 'effectType' EffectType no + 'flipStatus' FlipStatus no + 'inputHeight' InputHeight no + 'inputWidth' InputWidth no + 'isArtBokeh' IsArtBokeh no + 'lensFacing' LensFacing no + 'monoStrength' MonoStrength no + 'objectOrientation' ObjectOrientation no + 'outputHeight' OutputHeight no + 'outputWidth' OutputWidth no + 'perfMode' PerfMode no + 'segHeight' SegHeight no + 'segWidth' SegWidth no + 'sidelightStrength' SidelightStrength no + 'spinStrength' SpinStrength no + 'vintageStrength' VintageStrength no + 'zoomStrength' ZoomStrength no =head3 Samsung sec Tags @@ -15450,7 +16549,7 @@ such as the Galaxy S4. 0x1015 ToningEffect int16u 0x1016 HueAdjust int16u 0x1017 WideAdapter int16u - 0x1018 CropMode35mm int16u + 0x1018 CropMode int16u 0x1019 NDFilter int16u 0x101a WBBracketShotNumber int16u 0x1200 AFStatus int16u @@ -15547,7 +16646,7 @@ cameras. Tag ID Tag Name Writable ------ -------- -------- - 0x0207 RicohModel string + 0x0207 RicohModel no 0x0300 RicohMake no =head3 Ricoh Text Tags @@ -15643,6 +16742,8 @@ are less than consistent about their metadata formats. 0x0024 Calibration string 0x0026 FileFormat string 0x0027 LensType string + LensType - + Sigma LensType 0x002a LensFocalRange rational64u[2] 0x002b LensMaxApertureRange rational64u[2] 0x002c ColorMode int32u @@ -15665,10 +16766,47 @@ are less than consistent about their metadata formats. 0x004d ExposureCompensation rational64s 0x0055 SensorTemperature string 0x0056 FlashExposureComp rational64s - 0x0057 Firmware string + 0x0057 Firmware2 string 0x0058 WhiteBalance string 0x0059 DigitalFilter string 0x0084 Model string + 0x0086 ISO int16u + 0x0087 ResolutionMode string + 0x0088 WhiteBalance string + 0x008c Firmware string + 0x011f CameraCalibration float[9] + 0x0120 WBSettings Sigma WBSettings + 0x0121 WBSettings2 Sigma WBSettings2 + +=head3 Sigma WBSettings Tags + + Index4 Tag Name Writable + ------ -------- -------- + 0 WB_RGBLevelsAuto float[3] + 3 WB_RGBLevelsDaylight float[3] + 6 WB_RGBLevelsShade float[3] + 9 WB_RGBLevelsOvercast float[3] + 12 WB_RGBLevelsIncandescent float[3] + 15 WB_RGBLevelsFluorescent float[3] + 18 WB_RGBLevelsFlash float[3] + 21 WB_RGBLevelsCustom1 float[3] + 24 WB_RGBLevelsCustom2 float[3] + 27 WB_RGBLevelsCustom3 float[3] + +=head3 Sigma WBSettings2 Tags + + Index4 Tag Name Writable + ------ -------- -------- + 0 WB_RGBLevelsUnknown0? float[3] + 3 WB_RGBLevelsUnknown1? float[3] + 6 WB_RGBLevelsUnknown2? float[3] + 9 WB_RGBLevelsUnknown3? float[3] + 12 WB_RGBLevelsUnknown4? float[3] + 15 WB_RGBLevelsUnknown5? float[3] + 18 WB_RGBLevelsUnknown6? float[3] + 21 WB_RGBLevelsUnknown7? float[3] + 24 WB_RGBLevelsUnknown8? float[3] + 27 WB_RGBLevelsUnknown9? float[3] =head2 Sony Tags @@ -15755,6 +16893,7 @@ MakerNotes. 0x9400 Tag9400a Sony Tag9400a Tag9400b Sony Tag9400b Tag9400c Sony Tag9400c + 0x9401 Tag9401 Sony Tag9401 0x9402 Tag9402 Sony Tag9402 0x9403 Tag9403 Sony Tag9403 0x9404 Tag9404a Sony Tag9404a @@ -16337,25 +17476,25 @@ rotation -- the width is always the longer dimension. Valid for NEX-5N. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x04b0 MeterInfo? Sony MeterInfo - 0x1128 ReleaseMode3 int8u - 0x112c ReleaseMode2 int8u - 0x1134 SelfTimer int8u - 0x1138 FlashMode int8u - 0x113e StopsAboveBaseISO int16u - 0x1140 BrightnessValue int16u - 0x1144 DynamicRangeOptimizer int8u - 0x1148 HDRSetting int8u - 0x114c ExposureCompensation int16s - 0x115e PictureProfile int8u - 0x115f PictureProfile int8u - 0x1163 PictureEffect2 int8u - 0x1170 Quality2 int8u - 0x1174 MeteringMode int8u - 0x1175 ExposureProgram int8u - 0x117c WB_RGBLevels int16u[3] + 1200 MeterInfo? Sony MeterInfo + 4392 ReleaseMode3 int8u + 4396 ReleaseMode2 int8u + 4404 SelfTimer int8u + 4408 FlashMode int8u + 4414 StopsAboveBaseISO int16u + 4416 BrightnessValue int16u + 4420 DynamicRangeOptimizer int8u + 4424 HDRSetting int8u + 4428 ExposureCompensation int16s + 4446 PictureProfile int8u + 4447 PictureProfile int8u + 4451 PictureEffect2 int8u + 4464 Quality2 int8u + 4468 MeteringMode int8u + 4469 ExposureProgram int8u + 4476 WB_RGBLevels int16u[3] =head3 Sony MeterInfo Tags @@ -16385,281 +17524,282 @@ option is used. Valid for SLT-A65/A77, NEX-7/VG20E. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0000 SequenceImageNumber int32u - 0x0004 SequenceFileNumber int32u - 0x0008 ReleaseMode2 int32u - 0x01b6 SonyDateTime undef[7] - 0x0324 DynamicRangeOptimizer int8u - 0x04b4 MeterInfo? Sony MeterInfo - 0x1128 ReleaseMode3 int8u - 0x112c ReleaseMode2 int8u - 0x1134 SelfTimer int8u - 0x1138 FlashMode int8u - 0x113e StopsAboveBaseISO int16u - 0x1140 BrightnessValue int16u - 0x1144 DynamicRangeOptimizer int8u - 0x1148 HDRSetting int8u - 0x114c ExposureCompensation int16s - 0x1162 PictureProfile int8u - 0x1163 PictureProfile int8u - 0x1167 PictureEffect2 int8u - 0x1174 Quality2 int8u - 0x1178 MeteringMode int8u - 0x1179 ExposureProgram int8u - 0x1180 WB_RGBLevels int16u[3] - 0x1218 SonyISO int16u - 0x1a23 DistortionCorrParams int16s[16] + 0 SequenceImageNumber int32u + 4 SequenceFileNumber int32u + 8 ReleaseMode2 int32u + 438 SonyDateTime undef[7] + 804 DynamicRangeOptimizer int8u + 1204 MeterInfo? Sony MeterInfo + 4392 ReleaseMode3 int8u + 4396 ReleaseMode2 int8u + 4404 SelfTimer int8u + 4408 FlashMode int8u + 4414 StopsAboveBaseISO int16u + 4416 BrightnessValue int16u + 4420 DynamicRangeOptimizer int8u + 4424 HDRSetting int8u + 4428 ExposureCompensation int16s + 4450 PictureProfile int8u + 4451 PictureProfile int8u + 4455 PictureEffect2 int8u + 4468 Quality2 int8u + 4472 MeteringMode int8u + 4473 ExposureProgram int8u + 4480 WB_RGBLevels int16u[3] + 4632 SonyISO int16u + 6691 DistortionCorrParams int16s[16] =head3 Sony Tag2010c Tags Valid for SLT-A37/A57 and NEX-F3. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0000 SequenceImageNumber int32u - 0x0004 SequenceFileNumber int32u - 0x0008 ReleaseMode2 int32u - 0x0200 DigitalZoomRatio int8u - 0x0210 SonyDateTime undef[7] - 0x0300 DynamicRangeOptimizer int8u - 0x0490 MeterInfo? Sony MeterInfo - 0x1104 ReleaseMode3 int8u - 0x1108 ReleaseMode2 int8u - 0x1110 SelfTimer int8u - 0x1114 FlashMode int8u - 0x111a StopsAboveBaseISO int16u - 0x111c BrightnessValue int16u - 0x1120 DynamicRangeOptimizer int8u - 0x1124 HDRSetting int8u - 0x1128 ExposureCompensation int16s - 0x113e PictureProfile int8u - 0x113f PictureProfile int8u - 0x1143 PictureEffect2 int8u - 0x1150 Quality2 int8u - 0x1154 MeteringMode int8u - 0x1155 ExposureProgram int8u - 0x115c WB_RGBLevels int16u[3] - 0x11f4 SonyISO int16u + 0 SequenceImageNumber int32u + 4 SequenceFileNumber int32u + 8 ReleaseMode2 int32u + 512 DigitalZoomRatio int8u + 528 SonyDateTime undef[7] + 768 DynamicRangeOptimizer int8u + 1168 MeterInfo? Sony MeterInfo + 4356 ReleaseMode3 int8u + 4360 ReleaseMode2 int8u + 4368 SelfTimer int8u + 4372 FlashMode int8u + 4378 StopsAboveBaseISO int16u + 4380 BrightnessValue int16u + 4384 DynamicRangeOptimizer int8u + 4388 HDRSetting int8u + 4392 ExposureCompensation int16s + 4414 PictureProfile int8u + 4415 PictureProfile int8u + 4419 PictureEffect2 int8u + 4432 Quality2 int8u + 4436 MeteringMode int8u + 4437 ExposureProgram int8u + 4444 WB_RGBLevels int16u[3] + 4596 SonyISO int16u =head3 Sony Tag2010d Tags Valid for DSC-HX10V/HX20V/HX200V/TX66/TX200V/TX300V/WX50/WX100/WX150, but not valid for panorama images. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0000 SequenceImageNumber int32u - 0x0004 SequenceFileNumber int32u - 0x0008 ReleaseMode2 int32u - 0x01fe SonyDateTime undef[7] - 0x037c DynamicRangeOptimizer int8u - 0x050c MeterInfo? Sony MeterInfo - 0x1180 ReleaseMode3 int8u - 0x1184 ReleaseMode2 int8u - 0x118c SelfTimer int8u - 0x1190 FlashMode int8u - 0x1196 StopsAboveBaseISO int16u - 0x1198 BrightnessValue int16u - 0x119c DynamicRangeOptimizer int8u - 0x11a0 HDRSetting int8u - 0x11ba PictureProfile int8u - 0x11bb PictureProfile int8u - 0x11bf PictureEffect2 int8u - 0x11d0 MeteringMode int8u - 0x11d1 ExposureProgram int8u - 0x11d8 WB_RGBLevels int16u[3] - 0x1270 SonyISO int16u + 0 SequenceImageNumber int32u + 4 SequenceFileNumber int32u + 8 ReleaseMode2 int32u + 510 SonyDateTime undef[7] + 892 DynamicRangeOptimizer int8u + 1292 MeterInfo? Sony MeterInfo + 4480 ReleaseMode3 int8u + 4484 ReleaseMode2 int8u + 4492 SelfTimer int8u + 4496 FlashMode int8u + 4502 StopsAboveBaseISO int16u + 4504 BrightnessValue int16u + 4508 DynamicRangeOptimizer int8u + 4512 HDRSetting int8u + 4538 PictureProfile int8u + 4539 PictureProfile int8u + 4543 PictureEffect2 int8u + 4560 MeteringMode int8u + 4561 ExposureProgram int8u + 4568 WB_RGBLevels int16u[3] + 4720 SonyISO int16u =head3 Sony Tag2010e Tags -Valid for SLT-A58/A99, ILCE-3000/3500, NEX-3N/5R/5T/6/VG30E/VG900, DSC-RX100, -DSC-RX1/RX1R. Also valid for DSC-HX300/HX50V/TX30/WX60/WX200/WX300, but not -for panorama images. - - Tag ID Tag Name Writable - ------ -------- -------- - 0x0000 SequenceImageNumber int32u - 0x0004 SequenceFileNumber int32u - 0x0008 ReleaseMode2 int32u - 0x021c DigitalZoomRatio int8u - 0x022c SonyDateTime undef[7] - 0x0328 DynamicRangeOptimizer int8u - 0x04b8 MeterInfo? Sony MeterInfo - 0x115c ReleaseMode3 int8u - 0x1160 ReleaseMode2 int8u - 0x1168 SelfTimer int8u - 0x116c FlashMode int8u - 0x1172 StopsAboveBaseISO int16u - 0x1174 BrightnessValue int16u - 0x1178 DynamicRangeOptimizer int8u - 0x117c HDRSetting int8u - 0x1180 ExposureCompensation int16s - 0x1196 PictureProfile int8u - 0x1197 PictureProfile int8u - 0x119b PictureEffect2 int8u - 0x11a8 Quality2 int8u - 0x11ac MeteringMode int8u - 0x11ad ExposureProgram int8u - 0x11b4 WB_RGBLevels int16u[3] - 0x1254 SonyISO int16u - 0x1258 SonyISO int16u - 0x1278 FocalLength int16u - 0x127a MinFocalLength int16u - 0x127c MaxFocalLength int16u - 0x1280 SonyISO int16u - 0x1870 DistortionCorrParams int16s[16] - 0x1891 LensFormat int8u - 0x1892 LensMount int8u - 0x1893 LensType2 int16u - 0x1896 LensType int16u - 0x1898 DistortionCorrParamsPresent int8u - 0x1899 DistortionCorrParamsNumber int8u +Valid for SLT-A58/A99, ILCE-3000/3500, NEX-3N/5R/5T/6/VG30E/VG900, +DSC-RX100, DSC-RX1/RX1R. Also valid for DSC-HX300/HX50V/TX30/WX60/WX200/ +WX300, but not for panorama images. + + Index1 Tag Name Writable + ------ -------- -------- + 0 SequenceImageNumber int32u + 4 SequenceFileNumber int32u + 8 ReleaseMode2 int32u + 540 DigitalZoomRatio int8u + 556 SonyDateTime undef[7] + 808 DynamicRangeOptimizer int8u + 1208 MeterInfo? Sony MeterInfo + 4444 ReleaseMode3 int8u + 4448 ReleaseMode2 int8u + 4456 SelfTimer int8u + 4460 FlashMode int8u + 4466 StopsAboveBaseISO int16u + 4468 BrightnessValue int16u + 4472 DynamicRangeOptimizer int8u + 4476 HDRSetting int8u + 4480 ExposureCompensation int16s + 4502 PictureProfile int8u + 4503 PictureProfile int8u + 4507 PictureEffect2 int8u + 4520 Quality2 int8u + 4524 MeteringMode int8u + 4525 ExposureProgram int8u + 4532 WB_RGBLevels int16u[3] + 4692 SonyISO int16u + 4696 SonyISO int16u + 4728 FocalLength int16u + 4730 MinFocalLength int16u + 4732 MaxFocalLength int16u + 4736 SonyISO int16u + 6256 DistortionCorrParams int16s[16] + 6289 LensFormat int8u + 6290 LensMount int8u + 6291 LensType2 int16u + 6294 LensType int16u + 6296 DistortionCorrParamsPresent int8u + 6297 DistortionCorrParamsNumber int8u =head3 Sony Tag2010f Tags Valid for DSC-RX100M2, DSC-QX10/QX100. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0004 ReleaseMode2 int32u - 0x0050 DynamicRangeOptimizer int8u - 0x01e0 MeterInfo? Sony MeterInfo - 0x1014 ReleaseMode3 int8u - 0x1018 ReleaseMode2 int8u - 0x1020 SelfTimer int8u - 0x1024 FlashMode int8u - 0x102a StopsAboveBaseISO int16u - 0x102c BrightnessValue int16u - 0x1030 DynamicRangeOptimizer int8u - 0x1034 HDRSetting int8u - 0x1038 ExposureCompensation int16s - 0x104e PictureProfile int8u - 0x104f PictureProfile int8u - 0x1053 PictureEffect2 int8u - 0x1060 Quality2 int8u - 0x1064 MeteringMode int8u - 0x1065 ExposureProgram int8u - 0x106c WB_RGBLevels int16u[3] - 0x1134 FocalLength int16u - 0x1136 MinFocalLength int16u - 0x1138 MaxFocalLength int16u - 0x113c SonyISO int16u + 4 ReleaseMode2 int32u + 80 DynamicRangeOptimizer int8u + 480 MeterInfo? Sony MeterInfo + 4116 ReleaseMode3 int8u + 4120 ReleaseMode2 int8u + 4128 SelfTimer int8u + 4132 FlashMode int8u + 4138 StopsAboveBaseISO int16u + 4140 BrightnessValue int16u + 4144 DynamicRangeOptimizer int8u + 4148 HDRSetting int8u + 4152 ExposureCompensation int16s + 4174 PictureProfile int8u + 4175 PictureProfile int8u + 4179 PictureEffect2 int8u + 4192 Quality2 int8u + 4196 MeteringMode int8u + 4197 ExposureProgram int8u + 4204 WB_RGBLevels int16u[3] + 4404 FocalLength int16u + 4406 MinFocalLength int16u + 4408 MaxFocalLength int16u + 4412 SonyISO int16u =head3 Sony Tag2010g Tags Valid for DSC-HX60V/HX350/HX400V/QX30/RX10/RX100M3/WX220/WX350, ILCE-7/7R/7S/7M2/5000/5100/6000/QX1, ILCA-68/77M2. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0004 ReleaseMode2 int32u - 0x0050 DynamicRangeOptimizer int8u - 0x020c ReleaseMode3 int8u - 0x0210 ReleaseMode2 int8u - 0x0218 SelfTimer int8u - 0x021c FlashMode int8u - 0x0222 StopsAboveBaseISO int16u - 0x0224 BrightnessValue int16u - 0x0228 DynamicRangeOptimizer int8u - 0x022c HDRSetting int8u - 0x0230 ExposureCompensation int16s - 0x0246 PictureProfile int8u - 0x0247 PictureProfile int8u - 0x024b PictureEffect2 int8u - 0x0258 Quality2 int8u - 0x025c MeteringMode int8u - 0x025d ExposureProgram int8u - 0x0264 WB_RGBLevels int16u[3] - 0x032c FocalLength int16u - 0x032e MinFocalLength int16u - 0x0330 MaxFocalLength int16u - 0x0344 SonyISO int16u - 0x0388 MeterInfo? Sony MeterInfo - 0x189c DistortionCorrParams int16s[16] - 0x18bd LensFormat int8u - 0x18be LensMount int8u - 0x18bf LensType2 int16u - 0x18c2 LensType int16u - 0x18c4 DistortionCorrParamsPresent int8u - 0x18c5 DistortionCorrParamsNumber int8u + 4 ReleaseMode2 int32u + 80 DynamicRangeOptimizer int8u + 524 ReleaseMode3 int8u + 528 ReleaseMode2 int8u + 536 SelfTimer int8u + 540 FlashMode int8u + 546 StopsAboveBaseISO int16u + 548 BrightnessValue int16u + 552 DynamicRangeOptimizer int8u + 556 HDRSetting int8u + 560 ExposureCompensation int16s + 582 PictureProfile int8u + 583 PictureProfile int8u + 587 PictureEffect2 int8u + 600 Quality2 int8u + 604 MeteringMode int8u + 605 ExposureProgram int8u + 612 WB_RGBLevels int16u[3] + 812 FocalLength int16u + 814 MinFocalLength int16u + 816 MaxFocalLength int16u + 836 SonyISO int16u + 904 MeterInfo? Sony MeterInfo + 6300 DistortionCorrParams int16s[16] + 6333 LensFormat int8u + 6334 LensMount int8u + 6335 LensType2 int16u + 6338 LensType int16u + 6340 DistortionCorrParamsPresent int8u + 6341 DistortionCorrParamsNumber int8u =head3 Sony Tag2010h Tags -Valid for DSC-HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500, +Valid for DSC-HX80/HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500, ILCE-6300/6500/7RM2/7SM2, ILCA-99M2. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0004 ReleaseMode2 int32u - 0x0050 DynamicRangeOptimizer int8u - 0x020c ReleaseMode3 int8u - 0x0210 ReleaseMode2 int8u - 0x0218 SelfTimer int8u - 0x021c FlashMode int8u - 0x0222 StopsAboveBaseISO int16u - 0x0224 BrightnessValue int16u - 0x0228 DynamicRangeOptimizer int8u - 0x022c HDRSetting int8u - 0x0230 ExposureCompensation int16s - 0x0246 PictureProfile int8u - 0x0247 PictureProfile int8u - 0x024b PictureEffect2 int8u - 0x0258 Quality2 int8u - 0x025c MeteringMode int8u - 0x025d ExposureProgram int8u - 0x0264 WB_RGBLevels int16u[3] - 0x032c FocalLength int16u - 0x032e MinFocalLength int16u - 0x0330 MaxFocalLength int16u - 0x0346 SonyISO int16u - 0x0388 MeterInfo? Sony MeterInfo - 0x0398 MeterInfo? Sony MeterInfo - 0x18cc DistortionCorrParams int16s[16] - 0x18ed LensFormat int8u - 0x18ee LensMount int8u - 0x18ef LensType2 int16u - 0x18f2 LensType int16u - 0x18f4 DistortionCorrParamsPresent int8u - 0x18f5 DistortionCorrParamsNumber int8u + 4 ReleaseMode2 int32u + 80 DynamicRangeOptimizer int8u + 524 ReleaseMode3 int8u + 528 ReleaseMode2 int8u + 536 SelfTimer int8u + 540 FlashMode int8u + 546 StopsAboveBaseISO int16u + 548 BrightnessValue int16u + 552 DynamicRangeOptimizer int8u + 556 HDRSetting int8u + 560 ExposureCompensation int16s + 582 PictureProfile int8u + 583 PictureProfile int8u + 587 PictureEffect2 int8u + 600 Quality2 int8u + 604 MeteringMode int8u + 605 ExposureProgram int8u + 612 WB_RGBLevels int16u[3] + 812 FocalLength int16u + 814 MinFocalLength int16u + 816 MaxFocalLength int16u + 838 SonyISO int16u + 904 MeterInfo? Sony MeterInfo + 920 MeterInfo? Sony MeterInfo + 6348 DistortionCorrParams int16s[16] + 6381 LensFormat int8u + 6382 LensMount int8u + 6383 LensType2 int16u + 6386 LensType int16u + 6388 DistortionCorrParamsPresent int8u + 6389 DistortionCorrParamsNumber int8u =head3 Sony Tag2010i Tags -Valid for ILCE-7M3/7RM3/9, DSC-RX10M4/RX100M6/RX100M5A. - - Tag ID Tag Name Writable - ------ -------- -------- - 0x0004 ReleaseMode2 int32u - 0x004e DynamicRangeOptimizer int8u - 0x0204 ReleaseMode3 int8u - 0x0208 ReleaseMode2 int8u - 0x0210 SelfTimer int8u - 0x0211 FlashMode int8u - 0x0217 StopsAboveBaseISO int16u - 0x0219 BrightnessValue int16u - 0x021b DynamicRangeOptimizer int8u - 0x021f HDRSetting int8u - 0x0223 ExposureCompensation int16s - 0x0237 PictureProfile int8u - 0x0238 PictureProfile int8u - 0x023c PictureEffect2 int8u - 0x0247 Quality2 int8u - 0x024b MeteringMode int8u - 0x024c ExposureProgram int8u - 0x0252 WB_RGBLevels int16u[3] - 0x030a FocalLength int16u - 0x030c MinFocalLength int16u - 0x030e MaxFocalLength int16u - 0x0320 SonyISO int16u - 0x036d MeterInfo? Sony MeterInfo9 - 0x17d0 DistortionCorrParams int16s[16] - 0x17f1 LensFormat int8u - 0x17f2 LensMount int8u - 0x17f3 LensType2 int16u - 0x17f6 LensType int16u - 0x17f8 DistortionCorrParamsPresent int8u - 0x17f9 DistortionCorrParamsNumber int8u +Valid for ILCE-6100/6400/6600/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M6/ +RX100M5A/RX100M7/HX99. + + Index1 Tag Name Writable + ------ -------- -------- + 4 ReleaseMode2 int32u + 78 DynamicRangeOptimizer int8u + 516 ReleaseMode3 int8u + 520 ReleaseMode2 int8u + 528 SelfTimer int8u + 529 FlashMode int8u + 535 StopsAboveBaseISO int16u + 537 BrightnessValue int16u + 539 DynamicRangeOptimizer int8u + 543 HDRSetting int8u + 547 ExposureCompensation int16s + 567 PictureProfile int8u + 568 PictureProfile int8u + 572 PictureEffect2 int8u + 583 Quality2 int8u + 587 MeteringMode int8u + 588 ExposureProgram int8u + 594 WB_RGBLevels int16u[3] + 778 FocalLength int16u + 780 MinFocalLength int16u + 782 MaxFocalLength int16u + 800 SonyISO int16u + 877 MeterInfo? Sony MeterInfo9 + 6096 DistortionCorrParams int16s[16] + 6129 LensFormat int8u + 6130 LensMount int8u + 6131 LensType2 int16u + 6134 LensType int16u + 6136 DistortionCorrParamsPresent int8u + 6137 DistortionCorrParamsNumber int8u =head3 Sony MeterInfo9 Tags @@ -16749,282 +17889,323 @@ option is used. =head3 Sony Tag900b Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0002 FacesDetected no - 0x00bd FaceDetection no + 2 FacesDetected no + 189 FaceDetection no =head3 Sony Tag9050a Tags Data for tags 0x9050, 0x94xx and 0x2010 is encrypted by a simple substitution cipher, but the deciphered values are listed below. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0000 SonyMaxAperture int8u - 0x0001 SonyMinAperture int8u - 0x0031 FlashStatus int8u - 0x0032 ImageCount int32u - 0x003a SonyExposureTime int16u - 0x003c SonyFNumber int16u - 0x003f ReleaseMode2 int8u - 0x004c ImageCount2 int32u - 0x0051 SonyDateTime2 undef[6] - 0x0067 ReleaseMode2 int8u - 0x007c InternalSerialNumber int8u[4]~ - 0x00f0 InternalSerialNumber int8u[5] - 0x0105 LensMount int8u - 0x0106 LensFormat int8u - 0x0107 LensType2 int16u - 0x0109 LensType int16u - 0x010b DistortionCorrParamsPresent int8u - 0x0115 LensSpecFeatures undef[2] - 0x0116 LensSpecFeatures undef[2] - 0x01a0 ImageCount3 int32u - 0x01aa ImageCount3 int32u - 0x01bd ImageCount3 int32u + 0 SonyMaxAperture int8u + 1 SonyMinAperture int8u + 32 Shutter int16u[3] + 49 FlashStatus int8u + 50 ShutterCount int32u + 58 SonyExposureTime int16u + 60 SonyFNumber int16u + 63 ReleaseMode2 int8u + 76 ShutterCount2 int32u + 81 SonyDateTime2 undef[6] + 103 ReleaseMode2 int8u + 124 InternalSerialNumber int8u[4]~ + 240 InternalSerialNumber int8u[5] + 261 LensMount int8u + 262 LensFormat int8u + 263 LensType2 int16u + 265 LensType int16u + 267 DistortionCorrParamsPresent int8u + 276 APS-CSizeCapture int8u + 277 LensSpecFeatures undef[2] + 278 LensSpecFeatures undef[2] + 416 ShutterCount3 int32u + 426 ShutterCount3 int32u + 445 ShutterCount3 int32u =head3 Sony Tag9050b Tags -Valid from July 2015 for ILCE-6300/6500/7M3/7RM2/7RM3/7SM2/9, ILCA-99M2. - - Tag ID Tag Name Writable - ------ -------- -------- - 0x0000 SonyMaxAperture int8u - 0x0001 SonyMinAperture int8u - 0x0039 FlashStatus int8u - 0x003a ImageCount int32u - 0x0046 SonyExposureTime int16u - 0x0048 SonyFNumber int16u - 0x004b ReleaseMode2 int8u - 0x0052 ImageCount2 int32u~ - 0x0058 ImageCount2 int32u - 0x0061 SonyTimeMinSec no - 0x0073 ReleaseMode2 int8u - 0x0088 InternalSerialNumber int8u[6]~ - 0x0105 LensMount int8u - 0x0106 LensFormat int8u - 0x0107 LensType2 int16u - 0x0109 LensType int16u - 0x010b DistortionCorrParamsPresent int8u - 0x0116 LensSpecFeatures undef[2] - 0x019f ImageCount3 int32u - 0x01cb ImageCount3 int32u - 0x01cd ImageCount3 int32u - 0x021c LensSpecFeatures undef[2] - 0x021e LensSpecFeatures undef[2] +Valid from July 2015 for ILCE-6100/6300/6400/6500/6600/7M3/7RM2/7RM3/7RM4/ +7SM2/9/9M2, ILCA-99M2. + + Index1 Tag Name Writable + ------ -------- -------- + 0 SonyMaxAperture int8u + 1 SonyMinAperture int8u + 38 Shutter int16u[3] + 57 FlashStatus int8u + 58 ShutterCount int32u + 70 SonyExposureTime int16u + 72 SonyFNumber int16u + 75 ReleaseMode2 int8u + 80 ShutterCount2 int32u + 82 ShutterCount2 int32u + 88 ShutterCount2 int32u + 97 SonyTimeMinSec no + 107 ReleaseMode2 int8u + 109 ReleaseMode2 int8u + 115 ReleaseMode2 int8u + 136 InternalSerialNumber int8u[6]~ + 261 LensMount int8u + 262 LensFormat int8u + 263 LensType2 int16u + 265 LensType int16u + 267 DistortionCorrParamsPresent int8u + 276 APS-CSizeCapture int8u + 278 LensSpecFeatures undef[2] + 415 ShutterCount3 int32u + 459 ShutterCount3 int32u + 461 ShutterCount3 int32u + 491 APS-CSizeCapture int8u + 493 LensSpecFeatures undef[2] + 494 APS-CSizeCapture int8u + 496 LensSpecFeatures undef[2] + 538 APS-CSizeCapture int8u + 540 LensSpecFeatures undef[2] + APS-CSizeCapture int8u + 542 LensSpecFeatures undef[2] =head3 Sony Tag9400a Tags Valid for many DSC, NEX and SLT models - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0008 SequenceImageNumber int32u - 0x000c SequenceFileNumber int32u - 0x0010 ReleaseMode2 int8u - 0x0012 DigitalZoom int8u - 0x001a ShotNumberSincePowerUp int32u - 0x0022 SequenceLength int8u - 0x0028 CameraOrientation int8u - 0x0029 Quality2 int8u - 0x0044 SonyImageHeight int16u~ - 0x0052 ModelReleaseYear int8u~ + 8 SequenceImageNumber int32u + 12 SequenceFileNumber int32u + 16 ReleaseMode2 int8u + 18 DigitalZoom int8u + 26 ShotNumberSincePowerUp int32u + 34 SequenceLength int8u + 40 CameraOrientation int8u + 41 Quality2 int8u + 68 SonyImageHeight int16u~ + 82 ModelReleaseYear int8u~ =head3 Sony Tag9400b Tags Valid for NEX-3N, ILCE-3000/3500, SLT-A58, DSC-WX60, DSC-WX300, DSC-RX100M2, DSC-HX50V, DSC-QX10/QX100. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0008 SequenceImageNumber int32u - 0x000c SequenceFileNumber int32u - 0x0010 ReleaseMode2 int8u - 0x0012 DigitalZoom int8u - 0x0016 ShotNumberSincePowerUp int32u - 0x001e SequenceLength int8u - 0x0024 CameraOrientation int8u - 0x0025 Quality2 int8u - 0x003f SonyImageHeight int16u~ - 0x0046 ModelReleaseYear int8u~ + 8 SequenceImageNumber int32u + 12 SequenceFileNumber int32u + 16 ReleaseMode2 int8u + 18 DigitalZoom int8u + 22 ShotNumberSincePowerUp int32u + 30 SequenceLength int8u + 36 CameraOrientation int8u + 37 Quality2 int8u + 63 SonyImageHeight int16u~ + 70 ModelReleaseYear int8u~ =head3 Sony Tag9400c Tags -Valid for DSC-HX60V/HX90V/HX350/HX400V/QX30/RX0/RX1RM2/RX10/RX10M2/RX10M3/ -RX10M4/RX100M3/RX100M4/RX100M5/RX100M6/WX220/WX350/WX500, ILCE-7/7R/7S/ -7M2/7M3/7RM2/7RM3/7SM2/9/5000/5100/6000/6300/6500/QX1, ILCA-68/77M2/99M2. +Valid for DSC-HX60V/HX80/HX90V/HX99/HX350/HX400V/QX30/RX0/RX1RM2/RX10/ +RX10M2/RX10M3/RX10M4/RX100M3/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/WX220/ +WX350/WX500, ILCE-7/7R/7S/7M2/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2/5000/5100/6000/ +6100/6300/6400/6500/6600/QX1, ILCA-68/77M2/99M2. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0009 ReleaseMode2 int8u - 0x000a ShotNumberSincePowerUp int8u + 9 ReleaseMode2 int8u + 10 ShotNumberSincePowerUp int8u ShotNumberSincePowerUp int32u - 0x0012 SequenceImageNumber int32u - 0x0016 SequenceLength int8u - 0x001a SequenceFileNumber int32u - 0x001e SequenceLength int8u - 0x0029 CameraOrientation int8u - 0x002a Quality2 int8u - 0x0047 SonyImageHeight int16u~ - 0x0053 ModelReleaseYear int8u~ + 18 SequenceImageNumber int32u + 22 SequenceLength int8u + 26 SequenceFileNumber int32u + 30 SequenceLength int8u + 41 CameraOrientation int8u + 42 Quality2 int8u + 71 SonyImageHeight int16u~ + 83 ModelReleaseYear int8u~ + +=head3 Sony Tag9401 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 1176 ISOInfo Sony ISOInfo + 1186 ISOInfo Sony ISOInfo + 1437 ISOInfo Sony ISOInfo + 1588 ISOInfo Sony ISOInfo + 1590 ISOInfo Sony ISOInfo + 1612 ISOInfo Sony ISOInfo + 1619 ISOInfo Sony ISOInfo + 1656 ISOInfo Sony ISOInfo + 1720 ISOInfo Sony ISOInfo + 1758 ISOInfo Sony ISOInfo + 1767 ISOInfo Sony ISOInfo + +=head3 Sony ISOInfo Tags + + Index1 Tag Name Writable + ------ -------- -------- + 0 ISOSetting int8u + 2 ISOAutoMin int8u + 4 ISOAutoMax int8u =head3 Sony Tag9402 Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0004 AmbientTemperature int8s - 0x0016 FocusMode int8u & 0x7f - 0x0017 AFAreaMode int8u - 0x002d FocusPosition2 int8u + 4 AmbientTemperature int8s + 22 FocusMode int8u & 0x7f + 23 AFAreaMode int8u + 45 FocusPosition2 int8u =head3 Sony Tag9403 Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0005 CameraTemperature int8s + 5 CameraTemperature int8s =head3 Sony Tag9404a Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x000b ExposureProgram int8u - 0x000d IntelligentAuto int8u - 0x0019 LensZoomPosition int16u + 11 ExposureProgram int8u + 13 IntelligentAuto int8u + 25 LensZoomPosition int16u =head3 Sony Tag9404b Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x000c ExposureProgram int8u - 0x000e IntelligentAuto int8u - 0x001e LensZoomPosition int16u - 0x0020 FocusPosition2 int8u + 12 ExposureProgram int8u + 14 IntelligentAuto int8u + 30 LensZoomPosition int16u + 32 FocusPosition2 int8u =head3 Sony Tag9404c Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x000b ExposureProgram int8u - 0x000d IntelligentAuto int8u + 11 ExposureProgram int8u + 13 IntelligentAuto int8u =head3 Sony Tag9405a Tags Valid for SLT, NEX, ILCE-3000/3500 and several DSC models. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0600 DistortionCorrParamsPresent int8u - 0x0601 DistortionCorrection int8u - 0x0603 LensFormat int8u - 0x0604 LensMount int8u - 0x0605 LensType2 int16u - 0x0608 LensType int16u - 0x064a VignettingCorrParams int16s[16] - 0x066a ChromaticAberrationCorrParams int16s[32] - 0x06ca DistortionCorrParams int16s[16] + 1536 DistortionCorrParamsPresent int8u + 1537 DistortionCorrection int8u + 1539 LensFormat int8u + 1540 LensMount int8u + 1541 LensType2 int16u + 1544 LensType int16u + 1610 VignettingCorrParams int16s[16] + 1642 ChromaticAberrationCorrParams int16s[32] + 1738 DistortionCorrParams int16s[16] =head3 Sony Tag9405b Tags -Valid for DSC-HX60V/HX350/HX400V/QX30/RX0/RX10/RX10M2/RX10M3/RX10M4/ -RX100M3/RX100M4/RX100M5/RX100M6/WX220/WX350, ILCE-7/7M2/7M3/7R/7RM2/ -7S/7SM2/9/5000/5100/6000/6300/6500/QX1, ILCA-68/77M2/99M2. - - Tag ID Tag Name Writable - ------ -------- -------- - 0x0004 SonyISO int16u - 0x0006 BaseISO int16u - 0x000a StopsAboveBaseISO int16u - 0x000e SonyExposureTime2 int16u - 0x0010 ExposureTime rational32u - 0x0014 SonyFNumber int16u - 0x0016 SonyMaxApertureValue int16u - 0x0024 SequenceImageNumber int32u - 0x0034 ReleaseMode2 int8u - 0x003e SonyImageWidthMax int16u - 0x0040 SonyImageHeightMax int16u - 0x0042 HighISONoiseReduction int8u - 0x0044 LongExposureNoiseReduction int8u - 0x0046 PictureEffect2 int8u - 0x0048 ExposureProgram int8u - 0x004a CreativeStyle int8u - 0x0052 Sharpness int8s - 0x005a DistortionCorrParamsPresent int8u - 0x005b DistortionCorrection int8u - 0x005d LensFormat int8u - 0x005e LensMount int8u - 0x0060 LensType2 int16u - 0x0062 LensType int16u - 0x0064 DistortionCorrParams int16s[16] - 0x0342 LensZoomPosition int16u - 0x034a VignettingCorrParams int16s[16] - 0x0350 VignettingCorrParams int16s[16] - 0x035a LensZoomPosition int16u - 0x035c VignettingCorrParams int16s[16] - 0x0368 VignettingCorrParams int16s[16] - 0x037c ChromaticAberrationCorrParams int16s[32] - 0x0384 ChromaticAberrationCorrParams int16s[32] - 0x039c ChromaticAberrationCorrParams int16s[32] - 0x03b0 ChromaticAberrationCorrParams int16s[32] - 0x03b8 ChromaticAberrationCorrParams int16s[32] +Valid for DSC-HX60V/HX80/HX90V/HX99/HX350/HX400V/QX30/RX0/RX10/RX10M2/ +RX10M3/RX10M4/RX100M3/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/WX220/WX350, +ILCE-7/7M2/7M3/7R/7RM2/7RM3/7RM4/7S/7SM2/9/9M2/5000/5100/6000/6100/6300/ +6400/6500/6600/QX1, ILCA-68/77M2/99M2. + + Index1 Tag Name Writable + ------ -------- -------- + 4 SonyISO int16u + 6 BaseISO int16u + 10 StopsAboveBaseISO int16u + 14 SonyExposureTime2 int16u + 16 ExposureTime rational32u + 20 SonyFNumber int16u + 22 SonyMaxApertureValue int16u + 36 SequenceImageNumber int32u + 52 ReleaseMode2 int8u + 62 SonyImageWidthMax int16u + 64 SonyImageHeightMax int16u + 66 HighISONoiseReduction int8u + 68 LongExposureNoiseReduction int8u + 70 PictureEffect2 int8u + 72 ExposureProgram int8u + 74 CreativeStyle int8u + 82 Sharpness int8s + 90 DistortionCorrParamsPresent int8u + 91 DistortionCorrection int8u + 93 LensFormat int8u + 94 LensMount int8u + 96 LensType2 int16u + 98 LensType int16u + 100 DistortionCorrParams int16s[16] + 834 LensZoomPosition int16u + 842 VignettingCorrParams int16s[16] + 846 LensZoomPosition int16u + 848 VignettingCorrParams int16s[16] + 858 LensZoomPosition int16u + 860 VignettingCorrParams int16s[16] + 872 VignettingCorrParams int16s[16] + 892 ChromaticAberrationCorrParams int16s[32] + 900 ChromaticAberrationCorrParams int16s[32] + 924 ChromaticAberrationCorrParams int16s[32] + 944 ChromaticAberrationCorrParams int16s[32] + 952 ChromaticAberrationCorrParams int16s[32] =head3 Sony Tag9406 Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0005 BatteryTemperature int8u - 0x0006 BatteryLevelGrip1 int8u - 0x0007 BatteryLevel int8u - 0x0008 BatteryLevelGrip2 int8u + 5 BatteryTemperature int8u + 6 BatteryLevelGrip1 int8u + 7 BatteryLevel int8u + 8 BatteryLevelGrip2 int8u =head3 Sony Tag940a Tags These tags are currently extracted for SLT models only. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0004 AFPointsSelected int32u + 4 AFPointsSelected int32u =head3 Sony Tag940c Tags NEX and ILCE models only. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0008 LensMount2 int8u - 0x0009 LensType3 int16u - 0x000b CameraE-mountVersion int16u - 0x000d LensE-mountVersion int16u - 0x0014 LensFirmwareVersion int16u~ + 8 LensMount2 int8u + 9 LensType3 int16u + 11 CameraE-mountVersion int16u + 13 LensE-mountVersion int16u + 20 LensFirmwareVersion int16u~ =head3 Sony AFInfo Tags These tags are currently extracted for SLT models only. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x0002 AFType int8u - 0x0004 AFStatusActiveSensor int16s - 0x0005 FocusMode int8u - 0x0007 AFPoint int8u - 0x0008 AFPointInFocus int8u - 0x0009 AFPointAtShutterRelease int8u - 0x000a AFAreaMode int8u - 0x000b FocusMode int8u - 0x0010 AFPointsUsed int8u[10] - 0x0011 AFStatus15 Sony AFStatus15 + 2 AFType int8u + 4 AFStatusActiveSensor int16s + 5 FocusMode int8u + 7 AFPoint int8u + 8 AFPointInFocus int8u + 9 AFPointAtShutterRelease int8u + 10 AFAreaMode int8u + 11 FocusMode int8u + 16 AFPointsUsed int8u[10] + 17 AFStatus15 Sony AFStatus15 AFStatus19 Sony AFStatus19 - 0x0037 AFPoint int8u - 0x0038 AFPointInFocus int8u - 0x0039 AFPointAtShutterRelease int8u - 0x003a AFAreaMode int8u - 0x003b AFStatusActiveSensor int16s - 0x0043 ExposureProgram int8u - 0x0050 AFMicroAdj int8s - 0x007d AFStatus79 Sony AFStatus79 - 0x016e AFPointsUsed int32u - 0x017d AFMicroAdj int8s - 0x017e ExposureProgram int8u + 55 AFPoint int8u + 56 AFPointInFocus int8u + 57 AFPointAtShutterRelease int8u + 58 AFAreaMode int8u + 59 AFStatusActiveSensor int16s + 67 ExposureProgram int8u + 80 AFMicroAdj int8s + 125 AFStatus79 Sony AFStatus79 + 366 AFPointsUsed int32u + 381 AFMicroAdj int8s + 382 ExposureProgram int8u =head3 Sony AFStatus19 Tags @@ -17169,11 +18350,11 @@ AF Status information for models with 79-point AF. E-mount models. - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 0x1a06 TiffMeteringImageWidth no - 0x1a07 TiffMeteringImageHeight no - 0x1a08 TiffMeteringImage no + 6662 TiffMeteringImageWidth no + 6663 TiffMeteringImageHeight no + 6664 TiffMeteringImage no =head3 Sony PIC Tags @@ -17498,6 +18679,7 @@ still proprietary) Adobe format. MakerNoteLeica7 Panasonic Leica6 MakerNoteLeica8 Panasonic Leica5 MakerNoteLeica9 Panasonic Leica9 + MakerNoteLeica10 Panasonic MakerNotePanasonic Panasonic MakerNotePanasonic2 Panasonic Type2 MakerNotePanasonic3 Panasonic @@ -17510,6 +18692,8 @@ still proprietary) Adobe format. MakerNotePhaseOne PhaseOne MakerNoteReconyx Reconyx MakerNoteReconyx2 Reconyx Type2 + MakerNoteReconyx3 Reconyx Type3 + MakerNoteRicohPentax Pentax MakerNoteRicoh Ricoh MakerNoteRicoh2 Ricoh Type2 MakerNoteRicohText Ricoh Text @@ -17556,7 +18740,9 @@ These tags apply to CRW-format Canon RAW files and information in the APP0 "CIFF" segment of JPEG images. When writing CanonRaw/CIFF information, the length of the information is preserved (and the new information is truncated or padded as required) unless B<Writable> is C<resize>. Currently, only -JpgFromRaw and ThumbnailImage are allowed to change size. +JpgFromRaw and ThumbnailImage are allowed to change size. See +L<https://exiftool.org/canon_raw.html> for a description of the Canon CRW +format. CRW images also support the addition of a CanonVRD trailer, which in turn supports XMP. This trailer is created automatically if necessary when @@ -17615,8 +18801,8 @@ ExifTool is used to write XMP to a CRW image. 0x1835 DecoderTable CanonRaw DecoderTable 0x183b SerialNumberFormat int32u 0x2005 RawData no - 0x2007 JpgFromRaw resize - 0x2008 ThumbnailImage resize + 0x2007 JpgFromRaw resize^ + 0x2008 ThumbnailImage resize^ 0x2804 ImageDescription CanonRaw 0x2807 CameraObject CanonRaw 0x3002 ShootingRecord CanonRaw @@ -17901,23 +19087,25 @@ Lens distortion correction information. Tag ID Tag Name Writable ------ -------- -------- - 0x1001 MultishotOn int32u - 0x1100 FocusStepNear int16s - 0x1101 FocusStepCount int16s - 0x1102 FlashFired int32u - 0x1105 ZoomPosition int32u - 0x1200 LensAttached int32u - 0x1203 FocalLengthIn35mmFormat int16u - 0x1305 HighISOMode int16u - 0x3200 WB_CFA0_LevelDaylight int16u - 0x3201 WB_CFA1_LevelDaylight int16u - 0x3202 WB_CFA2_LevelDaylight int16u - 0x3203 WB_CFA3_LevelDaylight int16u - 0x3300 WhiteBalanceSet int8u - 0x3420 WB_RedLevelAuto int16u - 0x3421 WB_BlueLevelAuto int16u - 0x3501 Orientation int8u - 0x3600 WhiteBalanceDetected int8u + 0x1001 MultishotOn no + 0x1100 FocusStepNear no + 0x1101 FocusStepCount no + 0x1102 FlashFired no + 0x1105 ZoomPosition no + 0x1200 LensAttached no + 0x1201 LensTypeMake no + 0x1202 LensTypeModel no + 0x1203 FocalLengthIn35mmFormat no + 0x1305 HighISOMode no + 0x3200 WB_CFA0_LevelDaylight no + 0x3201 WB_CFA1_LevelDaylight no + 0x3202 WB_CFA2_LevelDaylight no + 0x3203 WB_CFA3_LevelDaylight no + 0x3300 WhiteBalanceSet no + 0x3420 WB_RedLevelAuto no + 0x3421 WB_BlueLevelAuto no + 0x3501 Orientation no + 0x3600 WhiteBalanceDetected no =head2 SigmaRaw Tags @@ -18103,7 +19291,8 @@ FPXR segment of JPEG images. As well, FlashPix information is extracted from DOC, PPT, XLS (Microsoft Word, PowerPoint and Excel) documents, VSD (Microsoft Visio) drawings, and FLA (Macromedia/Adobe Flash project) files since these are based on the same file format as FlashPix (the Windows -Compound Binary File format). See +Compound Binary File format). Note that ExifTool identifies any +unrecognized Windows Compound Binary file as a FlashPix (FPX) file. See L<http://graphcomp.com/info/specs/livepicture/fpx.pdf> for the FlashPix specification. @@ -18554,12 +19743,12 @@ L<http://www.scalado.com/>.) =head3 GoPro GPMF Tags -Tags extracted from the GPMF box of GoPro MP4 videos, the APP6 "GoPro" segment -of JPEG files, and from the "gpmd" timed metadata if the ExtractEmbedded option -is enabled. Many more tags exist, but are currently unknown and extracted only -with the -u option. Please let me know if you discover the meaning of any of -these unknown tags. See L<https://github.com/gopro/gpmf-parser> for details -about this format. +Tags extracted from the GPMF box of GoPro MP4 videos, the APP6 "GoPro" +segment of JPEG files, and from the "gpmd" timed metadata if the +ExtractEmbedded (-ee) option is enabled. Many more tags exist, but are +currently unknown and extracted only with the Unknown (-u) option. Please +let me know if you discover the meaning of any of these unknown tags. See +L<https://github.com/gopro/gpmf-parser> for details about this format. Tag ID Tag Name Writable ------ -------- -------- @@ -18576,6 +19765,7 @@ about this format. 'DVID' DeviceID? no 'DVNM' DeviceName no 'DZOM' DigitalZoom no + 'EISA' ElectronicImageStabilization no 'EMPT' Empty? no 'ESCS' EscapeStatus? no 'FACE' FaceDetected no @@ -18678,7 +19868,7 @@ Battery status information found in GoPro Karma videos. =head3 GoPro fdsc Tags Tags extracted from the MP4 "fdsc" timed metadata when the ExtractEmbedded -option is used. +(-ee) option is used. Index1 Tag Name Writable ------ -------- -------- @@ -21158,8 +22348,8 @@ written. 4) ExifTool writes compressed metadata to MIE files if the Compress (-z) option is used and Compress::Zlib is available. -See L<http://owl.phy.queensu.ca/~phil/exiftool/MIE1.1-20070121.pdf> for the -official MIE specification. +See L<https://exiftool.org/MIE1.1-20070121.pdf> for the official MIE +specification. Tag ID Tag Name Writable ------ -------- -------- @@ -21853,6 +23043,19 @@ it is specifically deleted with C<-Trailer:All=>. When reading, a minor warning is issued if this trailer exists, and ExifTool will attempt to parse this data as additional PNG chunks. +Also according to the PNG specification, there is no restriction on the +location of text-type chunks (tEXt, zTXt and iTXt). However, certain +utilities (including some Apple and Adobe utilities) won't read the XMP iTXt +chunk if it comes after the IDAT chunk, and at least one utility won't read +other text chunks here. For this reason, when writing, ExifTool 11.63 and +later create new text chunks (including XMP) before IDAT, and move existing +text chunks to before IDAT. + +The PNG format contains CRC checksums that are validated when reading with +either the Verbose or Validate option. When writing, these checksums are +validated by default, but the FastScan option may be used to bypass this +check if speed is more of a concern. + Tag ID Tag Name Writable ------ -------- -------- 'IHDR' ImageHeader PNG ImageHeader @@ -21901,7 +23104,7 @@ this data as additional PNG chunks. =head3 PNG AnimationControl Tags -Tags found in the Animation Conrol chunk. See +Tags found in the Animation Control chunk. See L<https://wiki.mozilla.org/APNG_Specification> for details. Index4 Tag Name Writable @@ -22464,6 +23667,28 @@ decode any tags found in the image. 'units' Units no 'white-point' WhitePoint no +=head2 PCX Tags + +Tags extracted from PC Paintbrush images. + + Index1 Tag Name Writable + ------ -------- -------- + 0 Manufacturer no + 1 Software no + 2 Encoding no + 3 BitsPerPixel no + 4 LeftMargin no + 6 TopMargin no + 8 ImageWidth no + 10 ImageHeight no + 12 XResolution no + 14 YResolution no + 65 ColorPlanes no + 66 BytesPerLine no + 68 ColorMode no + 70 ScreenWidth no + 72 ScreenHeight no + =head2 PGF Tags The following table lists information extracted from the header of @@ -22762,6 +23987,7 @@ This is the PDF document catalog. Tag ID Tag Name Writable ------ -------- -------- 'Cs1' Cs1 PDF Cs1 + 'DefaultCMYK' DefaultCMYK PDF DefaultRGB 'DefaultRGB' DefaultRGB PDF DefaultRGB =head3 PDF Cs1 Tags @@ -23723,41 +24949,69 @@ Frame rate information stored by some Canon video cameras. The QuickTime format is used for many different types of audio, video and image files (most notably, MOV/MP4 videos and HEIC/CR3 images). Exiftool -extracts standard meta information a variety of audio, video and image +extracts standard meta information and a variety of audio, video and image parameters, as well as proprietary information written by many camera models. Tags with a question mark after their name are not extracted unless the Unknown option is set. -ExifTool currently has a very limited ability to write metadata in -QuickTime-format videos. It can edit/create/delete any XMP tags, but may -only be used to edit certain date/time tags and the video orientation in -native QuickTime metadata. - -According to the specification, many QuickTime date/time tags should be -stored as UTC. Unfortunately, digital cameras often store local time values -instead (presumably because they don't know the time zone). For this -reason, by default ExifTool does not assume a time zone for these values. -However, if the QuickTimeUTC API option is set, then ExifTool will assume -these values are properly stored as UTC, and will convert them to local time -when extracting. +When writing, ExifTool creates both QuickTime and XMP tags by default, but +the group may be specified to write one or the other separately. If no +location is specified, newly created QuickTime tags are added in the +L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> location if +possible, otherwise in +L<UserData|Image::ExifTool::TagNames/QuickTime UserData Tags>, and +finally in L<Keys|Image::ExifTool::TagNames/QuickTime Keys Tags>, +but this order may be changed by setting the PREFERRED level of the +appropriate table in the config file (see +example.config in the full distribution for +an example). ExifTool currently writes only top-level metadata in +QuickTime-based files; it extracts other track-specific and timed +metadata, but can not yet edit tags in these locations (with the +exception of track-level date/time tags). + +Alternate language tags may be accessed for +L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> and +L<Keys|Image::ExifTool::TagNames/QuickTime Keys Tags> tags by adding +a 3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2 +country code to the tag name (eg. "ItemList:Artist-deu" or +"ItemList::Artist-deu-DE"). Most +L<UserData|Image::ExifTool::TagNames/QuickTime UserData Tags> tags support a +language code, but without a country code. If no language code is specified +when writing, alternate languages for the tag are deleted. Use the "und" +language code to write the default language without deleting alternate +languages. Note that "eng" is treated as a default language when reading, +but not when writing. + +According to the specification, integer-format QuickTime date/time tags +should be stored as UTC. Unfortunately, digital cameras often store local +time values instead (presumably because they don't know the time zone). For +this reason, by default ExifTool does not assume a time zone for these +values. However, if the QuickTimeUTC API option is set, then ExifTool will +assume these values are properly stored as UTC, and will convert them to +local time when extracting. See -L<http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html> +L<https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/> for the official specification. Tag ID Tag Name Writable ------ -------- -------- + 'IDIT' DateTimeOriginal string 'PICT' PreviewPICT no '_htc' HTCInfo QuickTime HTCInfo 'ardt' ARDroneFile no 'frea' Kodak_frea Kodak frea 'free' KodakFree Kodak Free + Pittasoft QuickTime Pittasoft Free? no 'ftyp' FileType QuickTime FileType + 'gps0' GPSTrack QuickTime Stream + 'gsen' GSensor QuickTime Stream 'junk' Junk? no - 'mdat' MovieData? no - 'mdat-offset' MovieDataOffset no - 'mdat-size' MovieDataSize no + 'mdat' MediaData? no + 'mdat-offset' MediaDataOffset no + 'mdat-size' MediaDataSize no + 'meco' OtherMeta QuickTime OtherMeta 'meta' Meta QuickTime Meta 'moof' MovieFragment QuickTime MovieFragment 'moov' Movie QuickTime Movie @@ -23765,6 +25019,7 @@ for the official specification. 'pnot' Preview QuickTime Preview 'prrt' ARDroneTelemetry no 'skip' CanonSkip Canon Skip + PreviewImage no Skip? no 'thum' ThumbnailImage no 'udat' GPSLog no @@ -23772,6 +25027,7 @@ for the official specification. 'uuid' XMP XMP UUID-PROF QuickTime Profile UUID-Flip QuickTime Flip + UUID-Canon2 Canon uuid2 PreviewImage no UUID-Unknown? no 'wide' Wide? no @@ -23784,6 +25040,291 @@ Tags written by some HTC camera phones. ------ -------- -------- 'slmt' Unknown_slmt? no +=head3 QuickTime Pittasoft Tags + +Tags found in Pittasoft Blackvue dashcam "free" data. + + Tag ID Tag Name Writable + ------ -------- -------- + '3gf ' AccelData QuickTime Stream + 'cprt' Copyright no + 'gps ' GPSLog no + 'ptnm' OriginalFileName no + 'ptrh' Ptrh QuickTime Pittasoft + 'sttm' StartTime no + 'thum' PreviewImage no + +=head3 QuickTime Stream Tags + +Timed metadata extracted from QuickTime media data and some AVI videos when +the ExtractEmbedded option is used. Although most of these tags are +combined into the single table below, ExifTool currently reads 37 different +formats of timed GPS metadata from video files. + + Tag Name Writable + -------- -------- + Accelerometer no + AccelerometerData no + AngularVelocity no + CTMD Canon CTMD + CameraDateTime no + Car no + Distance no + ExposureCompensation no + ExposureTime no + FNumber no + FrameNumber no + GPSAltitude no + GPSDOP no + GPSDateTime no + GPSLatitude no + GPSLongitude no + GPSSatellites no + GPSSpeed no + GPSSpeedRef no + GPSTimeStamp no + GPSTrack no + GPSTrackRef no + GSensor no + INSV QuickTime INSV_MakerNotes + ISO no + JpgFromRaw no + PreviewInfo QuickTime PreviewInfo + RVMI_gReV QuickTime RVMI_gReV + RVMI_sReV QuickTime RVMI_sReV + RawGSensor no + SampleDuration no + SampleTime no + Text no + TimeCode no + Unknown00? no + Unknown01? no + Unknown02? no + Unknown03? no + UserLabel no + VerticalSpeed no + camm0 QuickTime camm0 + camm1 QuickTime camm1 + camm2 QuickTime camm2 + camm3 QuickTime camm3 + camm4 QuickTime camm4 + camm5 QuickTime camm5 + camm6 QuickTime camm6 + camm7 QuickTime camm7 + fdsc GoPro fdsc + gpmd GoPro GPMF + mebx QuickTime Keys + mett Parrot mett + rtmd Sony rtmd + tx3g QuickTime tx3g + +=head3 QuickTime INSV_MakerNotes Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 0x000a SerialNumber no + 0x0012 Model no + 0x001a Firmware no + 0x002a Parameters no + +=head3 QuickTime PreviewInfo Tags + +Preview stored by TomTom Bandit ActionCam. + + Index1 Tag Name Writable + ------ -------- -------- + 8 PreviewImage no + +=head3 QuickTime RVMI_gReV Tags + +GPS information extracted from the RVMI box of MOV videos. + + Index1 Tag Name Writable + ------ -------- -------- + 4 GPSLatitude no + 8 GPSLongitude no + 16 GPSSpeed no + 18 GPSTrack no + +=head3 QuickTime RVMI_sReV Tags + +G-sensor information extracted from the RVMI box of MOV videos. + + Index1 Tag Name Writable + ------ -------- -------- + 4 GSensor no + +=head3 QuickTime camm0 Tags + +The camm0 through camm7 tables define tags extracted from the Google Street +View Camera Motion Metadata of MP4 videos. See +L<https://developers.google.com/streetview/publish/camm-spec> for the +specification. + + Index1 Tag Name Writable + ------ -------- -------- + 4 AngleAxis no + +=head3 QuickTime camm1 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 PixelExposureTime no + 8 RollingShutterSkewTime no + +=head3 QuickTime camm2 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 AngularVelocity no + +=head3 QuickTime camm3 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 Acceleration no + +=head3 QuickTime camm4 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 Position no + +=head3 QuickTime camm5 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 GPSLatitude no + 12 GPSLongitude no + 20 GPSAltitude no + +=head3 QuickTime camm6 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 GPSDateTime no + 12 GPSMeasureMode no + 16 GPSLatitude no + 24 GPSLongitude no + 32 GPSAltitude no + 36 GPSHorizontalAccuracy no + 40 GPSVerticalAccuracy no + 44 GPSVelocityEast no + 48 GPSVelocityNorth no + 52 GPSVelocityUp no + 56 GPSSpeedAccuracy no + +=head3 QuickTime camm7 Tags + + Index1 Tag Name Writable + ------ -------- -------- + 4 MagneticField no + +=head3 QuickTime Keys Tags + +This directory contains a list of key names which are used to decode tags +written by the "mdta" handler. Also in this table are a few tags found in +timed metadata that are not yet writable by ExifTool. The prefix of +"com.apple.quicktime." has been removed from the TagID's below. These tags +support alternate languages in the same way as the +L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> tags. Note +that by default, +L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> and +L<UserData|Image::ExifTool::TagNames/QuickTime UserData Tags> tags are +preferred when writing, so to create a tag when a same-named tag exists in +either of these tables, either the "Keys" location must be specified (eg. +C<-Keys:Author=Phil> on the command line), or the PREFERRED level must be +changed via the config file. + + Tag ID Tag Name Writable + ------ -------- -------- + 'Encoded_With' EncodedWith string + 'album' Album string + 'artist' Artist string + 'artwork' Artwork string + 'author' Author string + 'camera.framereadouttimeinmicroseconds' + FrameReadoutTime string + 'camera.identifier' CameraIdentifier string + 'collection.user' UserCollection string + 'com.android.version' AndroidVersion string + 'com.apple.photos.captureMode' CaptureMode string + 'comment' Comment string + 'copyright' Copyright string + 'creationdate' CreationDate string + 'description' Description string + 'detected-face' FaceInfo QuickTime FaceInfo + 'detected-face.bounds' DetectedFaceBounds no + 'detected-face.face-id' DetectedFaceID no + 'detected-face.roll-angle' + DetectedFaceRollAngle no + 'detected-face.yaw-angle' + DetectedFaceYawAngle no + 'direction.facing' CameraDirection string + 'direction.motion' CameraMotion string + 'director' Director string + 'displayname' DisplayName string + 'genre' Genre string + 'information' Information string + 'keywords' Keywords string + 'live-photo-info' LivePhotoInfo no + 'location.ISO6709' GPSCoordinates string + 'location.body' LocationBody string + 'location.date' LocationDate string + 'location.name' LocationName string + 'location.note' LocationNote string + 'location.role' LocationRole string + 'make' Make string + 'model' Model string + 'player.movie.audio.balance' Balance string + 'player.movie.audio.bass' Bass string + 'player.movie.audio.gain' AudioGain string + 'player.movie.audio.mute' Mute int8u + 'player.movie.audio.pitchshift' PitchShift string + 'player.movie.audio.treble' Trebel string + 'player.movie.visual.brightness' Brightness string + 'player.movie.visual.color' Color string + 'player.movie.visual.contrast' Contrast string + 'player.movie.visual.tint' Tint string + 'player.version' PlayerVersion string + 'producer' Producer string + 'publisher' Publisher string + 'rating.user' UserRating string + 'software' Software string + 'still-image-time' StillImageTime no + 'title' Title string + 'version' Version string + 'video-orientation' VideoOrientation no + 'year' Year string + +=head3 QuickTime FaceInfo Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 'crec' FaceRec QuickTime FaceRec + +=head3 QuickTime FaceRec Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 'cits' FaceItem QuickTime Keys + +=head3 QuickTime tx3g Tags + +Tags extracted from the tx3g sbtl timed metadata of Yuneec drones. + + Tag ID Tag Name Writable + ------ -------- -------- + 'Alt' GPSAltitude no + 'GimPitch' GimbalPitch no + 'GimRoll' GimbalRoll no + 'GimYaw' GimbalYaw no + 'Lat' GPSLatitude no + 'Lon' GPSLongitude no + 'Pitch' Pitch no + 'Roll' Roll no + 'Yaw' Yaw no + =head3 QuickTime FileType Tags Index4 Tag Name Writable @@ -23792,12 +25333,25 @@ Tags written by some HTC camera phones. 1 MinorVersion no 2 CompatibleBrands no +=head3 QuickTime OtherMeta Tags + + Tag ID Tag Name Writable + ------ -------- -------- + 'mere' MetaRelation QuickTime MetaRelation + 'meta' Meta QuickTime Meta + +=head3 QuickTime MetaRelation Tags + + Index4 Tag Name Writable + ------ -------- -------- + [no tags known] + =head3 QuickTime Meta Tags Tag ID Tag Name Writable ------ -------- -------- 'bxml' BinaryXML? no - 'dinf' DataInformation? no + 'dinf' DataInfo QuickTime DataInfo 'free' Free? no 'hdlr' Handler QuickTime Handler 'iinf' ItemInformation QuickTime ItemInfo @@ -23812,6 +25366,24 @@ Tags written by some HTC camera phones. 'pitm' PrimaryItemReference no 'xml ' XML XMP XML +=head3 QuickTime DataInfo Tags + +MP4 data information box. + + Tag ID Tag Name Writable + ------ -------- -------- + 'dref' DataRef QuickTime DataRef + +=head3 QuickTime DataRef Tags + +MP4 data reference box. + + Tag ID Tag Name Writable + ------ -------- -------- + "url\0" URL no + 'url ' URL no + 'urn ' URN no + =head3 QuickTime Handler Tags Index1 Tag Name Writable @@ -23829,93 +25401,100 @@ Tags written by some HTC camera phones. =head3 QuickTime ItemList Tags -As well as these tags, the "mdta" handler uses numerical tag ID's which are -added dynamically to this table after processing the Meta Keys information. +This is the preferred location for creating new QuickTime tags. Tags in +this table support alternate languages which are accessed by adding a +3-character ISO 639-2 language code and an optional ISO 3166-1 alpha 2 +country code to the tag name (eg. "ItemList:Title-fra" or +"ItemList::Title-fra-FR"). When creating a new Meta box to contain the +ItemList directory, by default ExifTool does not specify a +L<Handler|Image::ExifTool::TagNames/QuickTime Handler Tags>, but the +API QuickTimeHandler option may be used to include an 'mdir' Handler box. Tag ID Tag Name Writable ------ -------- -------- '----' iTunesInfo QuickTime iTunesInfo - '@PST' ParentShortTitle no - '@ppi' ParentProductID no - '@pti' ParentTitle no - '@sti' ShortTitle no - 'AACR' Unknown_AACR? no - 'CDEK' Unknown_CDEK? no - 'CDET' Unknown_CDET? no - 'GUID' GUID no - 'VERS' ProductVersion no - 'aART' AlbumArtist no - 'akID' AppleStoreAccountType no - 'albm' Album no - 'apID' AppleStoreAccount no - 'atID' AlbumTitleID no - 'auth' Author no - 'catg' Category no - 'cnID' AppleStoreCatalogID no - 'covr' CoverArt no - 'cpil' Compilation no - 'cprt' Copyright no - 'desc' Description no - 'disk' DiskNumber no - 'dscp' Description no - 'egid' EpisodeGlobalUniqueID no - 'geID' GenreID no - 'gnre' Genre no - 'grup' Grouping no - 'gshh' GoogleHostHeader no - 'gspm' GooglePingMessage no - 'gspu' GooglePingURL no - 'gssd' GoogleSourceData no - 'gsst' GoogleStartTime no - 'gstd' GoogleTrackDuration no - 'hdvd' HDVideo no - 'itnu' iTunesU no - 'keyw' Keyword no - 'ldes' LongDescription no - 'pcst' Podcast no - 'perf' Performer no - 'pgap' PlayGap no - 'plID' PlayListID no - 'prID' ProductID no - 'purd' PurchaseDate no - 'purl' PodcastURL no - 'rate' RatingPercent no - 'rldt' ReleaseDate no - 'rtng' Rating no - 'sfID' AppleStoreCountry no - 'soaa' SortAlbumArtist no - 'soal' SortAlbum no - 'soar' SortArtist no - 'soco' SortComposer no - 'sonm' SortName no - 'sosn' SortShow no - 'stik' MediaType no - 'titl' Title no - 'tmpo' BeatsPerMinute no - 'trkn' TrackNumber no - 'tven' TVEpisodeID no - 'tves' TVEpisode no - 'tvnn' TVNetworkName no - 'tvsh' TVShow no - 'tvsn' TVSeason no - 'yrrc' Year no - "\xa9ART" Artist no - "\xa9alb" Album no - "\xa9cmt" Comment no - "\xa9com" Composer no - "\xa9cpy" Copyright no - "\xa9day" ContentCreateDate no - "\xa9des" Description no - "\xa9enc" EncodedBy no - "\xa9gen" Genre no - "\xa9grp" Grouping no - "\xa9lyr" Lyrics no - "\xa9nam" Title no - "\xa9nrt" Narrator no - "\xa9pub" Publisher no - "\xa9too" Encoder no - "\xa9trk" Track no - "\xa9wrt" Composer no + '@PST' ParentShortTitle string + '@ppi' ParentProductID string + '@pti' ParentTitle string + '@sti' ShortTitle string + 'AACR' Unknown_AACR? string + 'CDEK' Unknown_CDEK? string + 'CDET' Unknown_CDET? string + 'GUID' GUID string + 'VERS' ProductVersion string + 'aART' AlbumArtist string + 'akID' AppleStoreAccountType int8u + 'albm' Album string/ + 'apID' AppleStoreAccount string + 'atID' AlbumTitleID int32u + 'auth' Author string + 'catg' Category string + 'cnID' AppleStoreCatalogID int32u + 'covr' CoverArt string + 'cpil' Compilation int8u + 'cprt' Copyright string + 'desc' Description string/ + 'disk' DiskNumber undef + 'dscp' Description string/ + 'egid' EpisodeGlobalUniqueID string + 'geID' GenreID int32u + 'gnre' Genre string/ + 'grup' Grouping string/ + 'gshh' GoogleHostHeader string + 'gspm' GooglePingMessage string + 'gspu' GooglePingURL string + 'gssd' GoogleSourceData string + 'gsst' GoogleStartTime string + 'gstd' GoogleTrackDuration string + 'hdvd' HDVideo int8u + 'itnu' iTunesU int8s + 'keyw' Keyword string + 'ldes' LongDescription string + 'pcst' Podcast int8u + 'perf' Performer string + 'pgap' PlayGap int8u + 'plID' PlayListID int8u + 'prID' ProductID string + 'purd' PurchaseDate string + 'purl' PodcastURL string + 'rate' RatingPercent string + 'rldt' ReleaseDate string + 'rtng' Rating int8u + 'sfID' AppleStoreCountry int32u + 'soaa' SortAlbumArtist string + 'soal' SortAlbum string + 'soar' SortArtist string + 'soco' SortComposer string + 'sonm' SortName string + 'sosn' SortShow string + 'stik' MediaType int8u + 'titl' Title string/ + 'tmpo' BeatsPerMinute int16u + 'trkn' TrackNumber undef + 'tven' TVEpisodeID string + 'tves' TVEpisode int32u + 'tvnn' TVNetworkName string + 'tvsh' TVShow string + 'tvsn' TVSeason int32u + 'yrrc' Year string + "\xa9ART" Artist string + "\xa9alb" Album string + "\xa9aut" Author string/ + "\xa9cmt" Comment string + "\xa9com" Composer string/ + "\xa9cpy" Copyright string/ + "\xa9day" ContentCreateDate string + "\xa9des" Description string + "\xa9enc" EncodedBy string + "\xa9gen" Genre string + "\xa9grp" Grouping string + "\xa9lyr" Lyrics string + "\xa9nam" Title string + "\xa9nrt" Narrator string + "\xa9pub" Publisher string + "\xa9too" Encoder string + "\xa9trk" Track string + "\xa9wrt" Composer string =head3 QuickTime iTunesInfo Tags @@ -23977,106 +25556,77 @@ defined in this table. Tag ID Tag Name Writable ------ -------- -------- 'auxC' AuxiliaryImageType no + 'av1C' AV1Configuration QuickTime AV1Config 'clap' CleanAperture no 'colr' ICC_Profile ICC_Profile - 'hvcC' HEVCConfiguration? no - 'irot' Rotation no + ColorRepresentation no + 'hvcC' HEVCConfiguration QuickTime HEVCConfig + 'irot' Rotation int8u 'ispe' ImageSpatialExtent no - 'pasp' PixelAspectRatio no + 'pasp' PixelAspectRatio int32u 'pixi' ImagePixelDepth no 'rloc' RelativeLocation no -=head3 QuickTime ItemRef Tags +=head3 QuickTime AV1Config Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 'cdsc' ContentDescribes no - -=head3 QuickTime Keys Tags - -This directory contains a list of key names which are used to decode -ItemList tags written by the "mdta" handler. The prefix of -"com.apple.quicktime." has been removed from all TagID's below. - - Tag ID Tag Name Writable - ------ -------- -------- - 'Encoded_With' EncodedWith no - 'album' Album no - 'artist' Artist no - 'artwork' Artwork no - 'author' Author no - 'camera.framereadouttimeinmicroseconds' - FrameReadoutTime no - 'camera.identifier' CameraIdentifier no - 'collection.user' UserCollection no - 'comment' Comment no - 'copyright' Copyright no - 'creationdate' CreationDate no - 'description' Description no - 'detected-face' FaceInfo QuickTime FaceInfo - 'detected-face.bounds' DetectedFaceBounds no - 'detected-face.face-id' DetectedFaceID no - 'detected-face.roll-angle' - DetectedFaceRollAngle no - 'detected-face.yaw-angle' - DetectedFaceYawAngle no - 'direction.facing' CameraDirection no - 'direction.motion' CameraMotion no - 'director' Director no - 'genre' Genre no - 'information' Information no - 'keywords' Keywords no - 'location.ISO6709' GPSCoordinates no - 'location.body' LocationBody no - 'location.date' LocationDate no - 'location.name' LocationName no - 'location.note' LocationNote no - 'location.role' LocationRole no - 'make' Make no - 'model' Model no - 'player.movie.audio.balance' Balance no - 'player.movie.audio.bass' Bass no - 'player.movie.audio.gain' AudioGain no - 'player.movie.audio.mute' Mute no - 'player.movie.audio.pitchshift' PitchShift no - 'player.movie.audio.treble' Trebel no - 'player.movie.visual.brightness' Brightness no - 'player.movie.visual.color' Color no - 'player.movie.visual.contrast' Contrast no - 'player.movie.visual.tint' Tint no - 'player.version' PlayerVersion no - 'producer' Producer no - 'publisher' Publisher no - 'rating.user' UserRating no - 'software' Software no - 'title' Title no - 'version' Version no - 'video-orientation' VideoOrientation no - 'year' Year no + 0 AV1ConfigurationVersion no + 1 SeqProfile? no + 1.1 SeqLevelIdx0? no + 2 SeqTier0? no + 2.1 HighBitDepth? no + 2.2 TwelveBit? no + 2.3 ChromaFormat no + 2.4 ChromaSamplePosition no + 3 InitialDelaySamples? no -=head3 QuickTime FaceInfo Tags +=head3 QuickTime HEVCConfig Tags - Tag ID Tag Name Writable + Index1 Tag Name Writable ------ -------- -------- - 'crec' FaceRec QuickTime FaceRec + 0 HEVCConfigurationVersion no + 1 GeneralProfileSpace no + 1.1 GeneralTierFlag no + 1.2 GeneralProfileIDC no + 2 GenProfileCompatibilityFlags no + 6 ConstraintIndicatorFlags no + 12 GeneralLevelIDC no + 13 MinSpatialSegmentationIDC no + 15 ParallelismType no + 16 ChromaFormat no + 17 BitDepthLuma no + 18 BitDepthChroma no + 19 AverageFrameRate no + 21 ConstantFrameRate no + 21.1 NumTemporalLayers no + 21.2 TemporalIDNested no -=head3 QuickTime FaceRec Tags +=head3 QuickTime ItemRef Tags Tag ID Tag Name Writable ------ -------- -------- - 'cits' FaceItem QuickTime Keys + 'cdsc' ContentDescribes no =head3 QuickTime MovieFragment Tags Tag ID Tag Name Writable ------ -------- -------- + 'meta' Meta QuickTime Meta + 'mfhd' MovieFragmentHeader QuickTime MovieFragHdr 'traf' TrackFragment QuickTime TrackFragment +=head3 QuickTime MovieFragHdr Tags + + Index4 Tag Name Writable + ------ -------- -------- + 1 MovieFragmentSequence no + =head3 QuickTime TrackFragment Tags Tag ID Tag Name Writable ------ -------- -------- - [no tags known] + 'meta' Meta QuickTime Meta =head3 QuickTime Movie Tags @@ -24086,6 +25636,7 @@ ItemList tags written by the "mdta" handler. The prefix of 'gps ' GPSDataList? no 'htka' HTCTrack QuickTime Track 'iods' InitialObjectDescriptor? no + 'meco' OtherMeta QuickTime OtherMeta 'meta' Meta QuickTime Meta 'mvhd' MovieHeader QuickTime MovieHeader 'trak' Track QuickTime Track @@ -24105,6 +25656,7 @@ ItemList tags written by the "mdta" handler. The prefix of Tag ID Tag Name Writable ------ -------- -------- 'mdia' Media QuickTime Media + 'meco' OtherMeta QuickTime OtherMeta 'meta' Meta QuickTime Meta 'tapt' TrackAperture QuickTime TrackAperture 'tkhd' TrackHeader QuickTime TrackHeader @@ -24150,24 +25702,6 @@ MP4 media info box. 'stbl' SampleTable QuickTime SampleTable 'vmhd' VideoHeader QuickTime VideoHeader -=head3 QuickTime DataInfo Tags - -MP4 data information box. - - Tag ID Tag Name Writable - ------ -------- -------- - 'dref' DataRef QuickTime DataRef - -=head3 QuickTime DataRef Tags - -MP4 data reference box. - - Tag ID Tag Name Writable - ------ -------- -------- - "url\0" URL no - 'url ' URL no - 'urn ' URN no - =head3 QuickTime GenMediaHeader Tags Tag ID Tag Name Writable @@ -24373,6 +25907,7 @@ Child atoms found in "sinf" and/or "pinf" atoms. 25 CompressorName no 41 BitDepth no 'CDI1' CDI1 Canon CDI1 + 'CMP1' CMP1 Canon CMP1 'JPEG' JPEGInfo? no 'avcC' AVCConfiguration? no 'btrt' BitrateInfo QuickTime Bitrate @@ -24473,6 +26008,7 @@ MP4 metadata sample description. ------ -------- -------- 0x0004 OtherFormat no 'ftab' FontTable no + 'name' OtherName no =head3 QuickTime VideoHeader Tags @@ -24518,31 +26054,37 @@ MP4 video media header. =head3 QuickTime UserData Tags Tag ID's beginning with the copyright symbol (hex 0xa9) are multi-language -text. Alternate language tags are accessed by adding a dash followed by the -language/country code to the tag name. ExifTool will extract any -multi-language user data tags found, even if they don't exist in this table. +text. Alternate language tags are accessed by adding a dash followed by a +3-character ISO 639-2 language code to the tag name. ExifTool will extract +any multi-language user data tags found, even if they aren't in this table. +Note when creating new tags, +L<ItemList|Image::ExifTool::TagNames/QuickTime ItemList Tags> tags are +preferred over these, so to create the tag when a same-named ItemList tag +exists, either "UserData" must be specified (eg. C<-UserData:Artist=Monet> +on the command line), or the PREFERRED level must be changed via +the config file. Tag ID Tag Name Writable ------ -------- -------- '@sec' SamsungSec Samsung sec - 'AllF' PlayAllFrames no - 'CAME' SerialNumberHash no - 'CNCV' CompressorVersion no - 'CNFV' FirmwareVersion no - 'CNMN' Model no + 'AllF' PlayAllFrames int8u + 'CAME' SerialNumberHash string + 'CNCV' CompressorVersion string + 'CNFV' FirmwareVersion string + 'CNMN' Model string/ 'CNOP' CanonCNOP Canon CNOP 'CNTH' CanonCNTH Canon CNTH 'DcMD' KodakDcMD Kodak DcMD 'FFMV' FujiFilmFFMV FujiFilm FFMV - 'FIRM' FirmwareVersion no - "FOV\0" FieldOfView no + 'FIRM' FirmwareVersion string/ + "FOV\0" FieldOfView string 'GPMF' GoProGPMF GoPro GPMF - 'GoPr' GoProType no + 'GoPr' GoProType string 'INFO' SamsungINFO Samsung INFO 'LEIC' LeicaLEIC Panasonic PANA - 'LENS' LensSerialNumber no - 'LOOP' LoopStyle no - 'Lvlm' LevelMeter? no + 'LENS' LensSerialNumber string + 'LOOP' LoopStyle int32u + 'Lvlm' LevelMeter? rational64s 'MMA0' MinoltaMMA0 Minolta MMA 'MMA1' MinoltaMMA1 Minolta MMA 'MVTG' FujiFilmMVTG EXIF @@ -24551,14 +26093,14 @@ multi-language user data tags found, even if they don't exist in this table. 'PENT' PentaxPENT Pentax PENT 'PXMN' MakerNotePentax5b Pentax MakerNotePentax5c Pentax - MakerNotePentaxUnknown no + MakerNotePentaxUnknown string 'PXTH' PentaxPreview Pentax PXTH 'QVMI' CasioQVMI EXIF 'RMKN' RicohRMKN EXIF 'RTHU' PreviewImage no - 'SDLN' PlayMode no - 'SNum' SerialNumber no - 'SelO' PlaySelection no + 'SDLN' PlayMode string + 'SNum' SerialNumber string/ + 'SelO' PlaySelection int8u 'TAGS' FujiFilmTags FujiFilm MOV KodakTags Kodak MOV KonicaMinoltaTags Minolta MOV1 @@ -24572,132 +26114,147 @@ multi-language user data tags found, even if they don't exist in this table. SamsungTags Samsung MP4 SanyoMOV Sanyo MOV SanyoMP4 Sanyo MP4 - UnknownTags? no - 'WLOC' WindowLocation no + UnknownTags? string + 'TTMD' TomTomMetaData QuickTime TomTom + 'WLOC' WindowLocation int16u 'XMP_' XMP XMP 'Xtra' MicrosoftXtra Microsoft Xtra - '_cx_' CX? no - '_cy_' CY? no - '_yaw' Yaw no - 'albm' Album no - 'albr' AlbumArtist no - 'angl' CameraAngle no - 'apmd' ApertureMode no - 'auth' Author no - 'ccid' ContentID no - 'cdis' ContentDistributorID no + '_cx_' CX? rational64s + '_cy_' CY? rational64s + '_yaw' Yaw rational64s/ + 'albm' Album string/ + 'albr' AlbumArtist string + 'angl' CameraAngle string + 'apmd' ApertureMode undef + 'auth' Author string/ + 'ccid' ContentID string + 'cdis' ContentDistributorID string 'chpl' ChapterList no - 'clfn' ClipFileName no - 'clid' ClipID no + 'clfn' ClipFileName string + 'clid' ClipID string 'clsf' Classification no - 'cmid' CameraID no - 'cmnm' Model no - 'coll' CollectionName no - 'cprt' Copyright no - 'cver' CodeVersion no - 'cvru' CoverURI no - 'date' DateTimeOriginal no - 'dscp' Description no - 'gnre' Genre no + 'cmid' CameraID string + 'cmnm' Model string/ + 'coll' CollectionName string/ + 'cprt' Copyright string/ + 'cver' CodeVersion string + 'cvru' CoverURI string + 'date' DateTimeOriginal string + 'dscp' Description string/ + 'gnre' Genre string/ 'hinf' HintTrackInfo QuickTime HintTrackInfo - 'hinv' HintVersion no + 'hinv' HintVersion string 'hnti' HintInfo QuickTime HintInfo 'htcb' HTCBinary QuickTime HTCBinary - 'icnu' IconURI no - 'infu' InfoURL no - 'kgtt' TrackType no + 'icnu' IconURI string + 'infu' InfoURL string + 'kgtt' TrackType string 'kywd' Keywords no 'loci' LocationInformation no - 'lrcu' LyricsURI no - 'lvlm' LevelMeter? no + 'lrcu' LyricsURI string + 'lvlm' LevelMeter? rational64s 'manu' Make no 'meta' Meta QuickTime Meta 'modl' Model no - 'name' Name no - 'perf' Performer no + 'name' Name string + 'perf' Performer string/ 'pose' pose Kodak pose - 'ptch' Pitch no + 'ptch' Pitch rational64s/ 'ptv ' PrintToVideo QuickTime Video - 'rads' Rads? no - 'reel' ReelName no - 'roll' Roll no + 'rads' Rads? rational64s + 'reel' ReelName string + 'roll' Roll rational64s/ 'rtng' Rating no - 'scen' Scene no + 'scen' Scene string 'scrn' OlympusPreview Olympus scrn - 'shot' ShotName no - 'slno' SerialNumber no + 'shot' ShotName string + 'slno' SerialNumber string 'smta' SamsungSmta Samsung smta 'tags' Audible_tags Audible tags 'thmb' MakerNotePentax5a Pentax OlympusThumbnail Olympus thmb - ThumbnailImage no - ThumbnailPNG no - UnknownThumbnail no - 'titl' Title no + ThumbnailImage string + ThumbnailPNG string + UnknownThumbnail string + 'titl' Title string/ 'urat' UserRating no - 'vndr' Vendor no + 'vndr' Vendor string + 'vrot' AccelerometerData no 'yrrc' Year no - "\xa9ART" Artist no - "\xa9TSC" StartTimeScale no - "\xa9TSZ" StartTimeSampleSize no - "\xa9alb" Album no - "\xa9arg" Arranger no - "\xa9ark" ArrangerKeywords no - "\xa9cmt" Comment no - "\xa9cok" ComposerKeywords no - "\xa9com" Composer no - "\xa9cpy" Copyright no - "\xa9day" ContentCreateDate no - "\xa9dir" Director no - "\xa9ed1" Edit1 no - "\xa9ed2" Edit2 no - "\xa9ed3" Edit3 no - "\xa9ed4" Edit4 no - "\xa9ed5" Edit5 no - "\xa9ed6" Edit6 no - "\xa9ed7" Edit7 no - "\xa9ed8" Edit8 no - "\xa9ed9" Edit9 no - "\xa9enc" EncoderID no - "\xa9fmt" Format no - "\xa9fpt" Pitch no - "\xa9frl" Roll no - "\xa9fyw" Yaw no - "\xa9gen" Genre no - "\xa9gpt" CameraPitch no - "\xa9grl" CameraRoll no - "\xa9grp" Grouping no - "\xa9gyw" CameraYaw no - "\xa9inf" Information no - "\xa9isr" ISRCCode no - "\xa9lab" RecordLabelName no - "\xa9lal" RecordLabelURL no - "\xa9lyr" Lyrics no - "\xa9mak" Make no - "\xa9mal" MakerURL no - "\xa9mdl" Model no - "\xa9mod" Model no - "\xa9nam" Title no - "\xa9pdk" ProducerKeywords no - "\xa9phg" RecordingCopyright no - "\xa9prd" Producer no - "\xa9prf" Performers no - "\xa9prk" PerformerKeywords no - "\xa9prl" PerformerURL no - "\xa9req" Requirements no - "\xa9snk" SubtitleKeywords no - "\xa9snm" Subtitle no - "\xa9src" SourceCredits no - "\xa9swf" SongWriter no - "\xa9swk" SongWriterKeywords no - "\xa9swr" SoftwareVersion no - "\xa9too" Encoder no - "\xa9trk" Track no - "\xa9wrt" Composer no - "\xa9xsp" SpeedX no - "\xa9xyz" GPSCoordinates no - "\xa9ysp" SpeedY no - "\xa9zsp" SpeedZ no + "\xa9ART" Artist string + "\xa9TIM" StartTimecode string + "\xa9TSC" StartTimeScale string + "\xa9TSZ" StartTimeSampleSize string + "\xa9alb" Album string + "\xa9arg" Arranger string + "\xa9ark" ArrangerKeywords string + "\xa9cmt" Comment string + "\xa9cok" ComposerKeywords string + "\xa9com" Composer string + "\xa9cpy" Copyright string + "\xa9day" ContentCreateDate string + "\xa9dir" Director string + "\xa9ed1" Edit1 string + "\xa9ed2" Edit2 string + "\xa9ed3" Edit3 string + "\xa9ed4" Edit4 string + "\xa9ed5" Edit5 string + "\xa9ed6" Edit6 string + "\xa9ed7" Edit7 string + "\xa9ed8" Edit8 string + "\xa9ed9" Edit9 string + "\xa9enc" EncoderID string + "\xa9fmt" Format string + "\xa9fpt" Pitch string + "\xa9frl" Roll string + "\xa9fyw" Yaw string + "\xa9gen" Genre string + "\xa9gpt" CameraPitch string + "\xa9grl" CameraRoll string + "\xa9grp" Grouping string + "\xa9gyw" CameraYaw string + "\xa9inf" Information string + "\xa9isr" ISRCCode string + "\xa9lab" RecordLabelName string + "\xa9lal" RecordLabelURL string + "\xa9lyr" Lyrics string + "\xa9mak" Make string + "\xa9mal" MakerURL string + "\xa9mdl" Model string/ + "\xa9mod" Model string + "\xa9nam" Title string + "\xa9pdk" ProducerKeywords string + "\xa9phg" RecordingCopyright string + "\xa9prd" Producer string + "\xa9prf" Performers string + "\xa9prk" PerformerKeywords string + "\xa9prl" PerformerURL string + "\xa9req" Requirements string + "\xa9snk" SubtitleKeywords string + "\xa9snm" Subtitle string + "\xa9src" SourceCredits string + "\xa9swf" SongWriter string + "\xa9swk" SongWriterKeywords string + "\xa9swr" SoftwareVersion string + "\xa9too" Encoder string + "\xa9trk" Track string + "\xa9wrt" Composer string/ + "\xa9xsp" SpeedX string + "\xa9xyz" GPSCoordinates string + "\xa9ysp" SpeedY string + "\xa9zsp" SpeedZ string + +=head3 QuickTime TomTom Tags + +Tags found in TomTom Bandit Action Cam MP4 videos. + + Tag ID Tag Name Writable + ------ -------- -------- + 'TTAD' TomTomAD QuickTime Stream + 'TTHL' TomTomHL? no + 'TTID' TomTomID no + 'TTVD' TomTomVD no + 'TTVI' TomTomVI? no =head3 QuickTime HintTrackInfo Tags @@ -24856,151 +26413,148 @@ Tags used in QTIF QuickTime Image Files. 'idsc' ImageDescription QuickTime ImageDesc 'iicc' ICC_Profile ICC_Profile -=head3 QuickTime Stream Tags - -Timed metadata extracted from QuickTime movie data and some AVI videos when -the ExtractEmbedded option is used. - - Tag Name Writable - -------- -------- - Accelerometer no - CTMD Canon CTMD - CameraDateTime no - FrameNumber no - GPSAltitude no - GPSDOP no - GPSDateTime no - GPSLatitude no - GPSLongitude no - GPSSatellites no - GPSSpeed no - GPSSpeedRef no - GPSTimeStamp no - GPSTrack no - GPSTrackRef no - JpgFromRaw no - RVMI_gReV QuickTime RVMI_gReV - RVMI_sReV QuickTime RVMI_sReV - RawGSensor no - SampleDuration no - SampleTime no - Text no - TimeCode no - UserLabel no - camm0 QuickTime camm0 - camm1 QuickTime camm1 - camm2 QuickTime camm2 - camm3 QuickTime camm3 - camm4 QuickTime camm4 - camm5 QuickTime camm5 - camm6 QuickTime camm6 - camm7 QuickTime camm7 - fdsc GoPro fdsc - gpmd GoPro GPMF - mebx QuickTime Keys - rtmd Sony rtmd - tx3g QuickTime tx3g - -=head3 QuickTime RVMI_gReV Tags - -GPS information extracted from the RVMI box of MOV videos. - - Index1 Tag Name Writable - ------ -------- -------- - 4 GPSLatitude no - 8 GPSLongitude no - 16 GPSSpeed no - 18 GPSTrack no +=head2 Parrot Tags -=head3 QuickTime RVMI_sReV Tags +=head3 Parrot mett Tags -G-sensor information extracted from the RVMI box of MOV videos. +Streaming metadata found in Parrot drone videos. See +L<https://developer.parrot.com/docs/pdraw/metadata.html> for the +specification. - Index1 Tag Name Writable + Tag ID Tag Name Writable ------ -------- -------- - 4 GSensor no + 'P1' ParrotV1 Parrot V1 + 'P2' ParrotV2 Parrot V2 + 'P3' ParrotV3 Parrot V3 + 'E1' ParrotTimeStamp Parrot TimeStamp + 'E2' ParrotFollowMe Parrot FollowMe + 'E3' ParrotAutomation Parrot Automation -=head3 QuickTime camm0 Tags +=head3 Parrot V1 Tags -The camm0 through camm7 tables define tags extracted from the Google Street -View Camera Motion Metadata of MP4 videos. See -L<https://developers.google.com/streetview/publish/camm-spec> for the -specification. +Parrot version 1 streaming metadata. Index1 Tag Name Writable ------ -------- -------- - 4 AngleAxis no - -=head3 QuickTime camm1 Tags + 4 DroneYaw no + 6 DronePitch no + 8 DroneRoll no + 10 CameraPan no + 12 CameraTilt no + 14 FrameView no + 22 ExposureTime no + 24 ISO no + 26 WifiRSSI no + 27 Battery no + 28 GPSLatitude no + 32 GPSLongitude no + 36 GPSAltitude no + 36.1 GPSSatellites no + 40 AltitudeFromTakeOff no + 44 DistanceFromHome no + 48 SpeedX no + 50 SpeedY no + 52 SpeedZ no + 54 Binning no + 54.1 FlyingState no + 55 Animation no + 55.1 PilotingMode no - Index1 Tag Name Writable - ------ -------- -------- - 4 PixelExposureTime no - 8 RollingShutterSkewTime no +=head3 Parrot V2 Tags -=head3 QuickTime camm2 Tags +Parrot version 2 basic streaming metadata. Index1 Tag Name Writable ------ -------- -------- - 4 AngularVelocity no - -=head3 QuickTime camm3 Tags + 4 Elevation no + 8 GPSLatitude no + 12 GPSLongitude no + 16 GPSAltitude no + 16.1 GPSSatellites no + 20 GPSVelocityNorth no + 22 GPSVelocityEast no + 24 GPSVelocityDown no + 26 AirSpeed no + 28 DroneQuaternion no + 36 FrameView no + 44 CameraPan no + 46 CameraTilt no + 48 ExposureTime no + 50 ISO no + 52 Binning no + 52.1 FlyingState no + 53 Animation no + 53.1 PilotingMode no + 54 WifiRSSI no + 55 Battery no + 'Groups' Groups no + +=head3 Parrot V3 Tags + +Parrot version 3 basic streaming metadata. + + Index1 Tag Name Writable + ------ -------- -------- + 4 Elevation no + 8 GPSLatitude no + 12 GPSLongitude no + 16 GPSAltitude no + 16.1 GPSSatellites no + 20 GPSVelocityNorth no + 22 GPSVelocityEast no + 24 GPSVelocityDown no + 26 AirSpeed no + 28 DroneQuaternion no + 36 FrameBaseView no + 44 FrameView no + 52 ExposureTime no + 54 ISO no + 56 RedBalance no + 58 BlueBalance no + 60 FOV no + 64 LinkGoodput no + 64.1 LinkQuality no + 68 WifiRSSI no + 69 Battery no + 70 Binning no + 70.1 FlyingState no + 71 Animation no + 71.1 PilotingMode no + +=head3 Parrot TimeStamp Tags + +Parrot streaming metadata timestamp extension. Index1 Tag Name Writable ------ -------- -------- - 4 Acceleration no - -=head3 QuickTime camm4 Tags + 4 TimeStamp no - Index1 Tag Name Writable - ------ -------- -------- - 4 Position no +=head3 Parrot FollowMe Tags -=head3 QuickTime camm5 Tags +Parrot streaming metadata follow-me extension. Index1 Tag Name Writable ------ -------- -------- - 4 GPSLatitude no - 12 GPSLongitude no - 20 GPSAltitude no + 4 GPSTargetLatitude no + 8 GPSTargetLongitude no + 12 GPSTargetAltitude no + 16 Follow-meMode no + 17 Follow-meAnimation no -=head3 QuickTime camm6 Tags - - Index1 Tag Name Writable - ------ -------- -------- - 4 GPSDateTime no - 12 GPSMeasureMode no - 16 GPSLatitude no - 24 GPSLongitude no - 32 GPSAltitude no - 36 GPSHorizontalAccuracy no - 40 GPSVerticalAccuracy no - 44 GPSVelocityEast no - 48 GPSVelocityNorth no - 52 GPSVelocityUp no - 56 GPSSpeedAccuracy no +=head3 Parrot Automation Tags -=head3 QuickTime camm7 Tags +Parrot streaming metadata automation extension. Index1 Tag Name Writable ------ -------- -------- - 4 MagneticField no - -=head3 QuickTime tx3g Tags - -Tags extracted from the tx3g sbtl timed metadata of Yuneec drones. - - Tag ID Tag Name Writable - ------ -------- -------- - 'Alt' GPSAltitude no - 'GimPitch' GimbalPitch no - 'GimRoll' GimbalRoll no - 'GimYaw' GimbalYaw no - 'Lat' GPSLatitude no - 'Lon' GPSLongitude no - 'Pitch' Pitch no - 'Roll' Roll no - 'Yaw' Yaw no + 4 GPSFramingLatitude no + 8 GPSFramingLongitude no + 12 GPSFramingAltitude no + 16 GPSDestLatitude no + 20 GPSDestLongitude no + 24 GPSDestAltitude no + 28 AutomationAnimation no + 29 AutomationFlags no =head2 PLIST Tags @@ -27389,6 +28943,7 @@ sub-documents, but the Duration is calculated for the full video. PentaxJunk2 Pentax Junk2 TextJunk no 'JUNQ' OldXMP no + 'LIST_INF0' Info RIFF Info 'LIST_INFO' Info RIFF Info 'LIST_Tdat' Tdat RIFF Tdat 'LIST_exif' Exif RIFF Exif @@ -27403,12 +28958,16 @@ sub-documents, but the Duration is calculated for the full video. 'VP8X' VP8X RIFF VP8X 'XMP ' XMP XMP '_PMX' XMP XMP + 'aXML' AXML XMP XML 'afsp' Afsp no 'bext' BroadcastExtension RIFF BroadcastExt 'cue ' CuePoints no 'ds64' DataSize64 RIFF DS64 'fact' NumberOfSamples no 'fmt ' AudioFormat RIFF AudioFormat + 'gps0' GPSTrack QuickTime Stream + 'gsen' GSensor QuickTime Stream + 'iXML' IXML XMP XML 'labl' Label RIFF Label 'list' ListType no 'olym' Olym Olympus WAV @@ -27442,12 +29001,12 @@ WebP animation frame chunk. =head3 RIFF CSET Tags - Tag ID Tag Name Writable + Index2 Tag Name Writable ------ -------- -------- - 0x0000 CodePage no - 0x0001 CountryCode no - 0x0002 LanguageCode no - 0x0003 Dialect no + 0 CodePage no + 1 CountryCode no + 2 LanguageCode no + 3 Dialect no =head3 RIFF Info Tags @@ -27692,6 +29251,7 @@ L<http://tech.ebu.ch/docs/tech/tech3285.pdf>). 320 DateTimeOriginal no 338 TimeReference no 346 BWFVersion no + 348 BWF_UMID no 602 CodingHistory no =head3 RIFF DS64 Tags @@ -31290,6 +32850,27 @@ L<XMP DICOM Tags|Image::ExifTool::TagNames/XMP DICOM Tags>. FFFE,E00D EndOfItems no FFFE,E0DD EndOfSequence no +=head2 FITS Tags + +This table lists some standard Flexible Image Transport System (FITS) tags, +but ExifTool will extract any other tags found. See +L<https://fits.gsfc.nasa.gov/fits_standard.html> for the specification. + + Tag ID Tag Name Writable + ------ -------- -------- + 'AUTHOR' Author no + 'BACKGRND' Background no + 'DATE' CreateDate no + 'DATE-END' ObservationDateEnd no + 'DATE-OBS' ObservationDate no + 'INSTRUME' Instrument no + 'OBJECT' Object no + 'OBSERVER' Observer no + 'REFERENC' Reference no + 'TELESCOP' Telescope no + 'TIME-END' ObservationTimeEnd no + 'TIME-OBS' ObservationTime no + =head2 JSON Tags No JSON tags have been pre-defined, but ExifTool will read any existing @@ -32070,6 +33651,29 @@ name. See L<http://tools.ietf.org/html/rfc5545> for the official iCalendar 'X-wr-relcalid' CalendarID no 'X-wr-timezone' TimeZone2 no +=head2 Text Tags + +Although basic text files contain no metadata, the following tags are +determined from a simple analysis of the data in TXT and CSV files. +Statistics are generated only for 8-bit encodings, but the FastScan (-fast) +option may be used to limit processing to the first 64 kB in which case some +tags are not produced. To avoid long processing delays, ExifTool will issue +a minor warning and process only the first 64 kB of any file larger than 20 +MB unless the IgnoreMinorErrors (-m) +option is used. + + Tag Name Writable + -------- -------- + ByteOrderMark no + ColumnCount no + Delimiter no + LineCount no + MIMEEncoding no + Newlines no + Quoting no + RowCount no + WordCount no + =head2 RSRC Tags Tags extracted from Mac OS resource files and DFONT files. These tags may @@ -32328,10 +33932,9 @@ Tags extracted from ISO 9660 disk images. =head2 MacOS Tags -On MacOS systems, there are a number of additional tags with names beginning -with "MDItem" and "XAttr" that may be extracted. These tags are not -extracted by default -- they must be specifically requested or enabled via -an API option. +On MacOS systems, the there are additional MDItem and XAttr Finder tags that +may be extracted. These tags are not extracted by default -- they must be +specifically requested or enabled via an API option. The tables below list some of the tags that may be extracted, but ExifTool will extract all available information even for tags not listed. @@ -32345,12 +33948,16 @@ these tables may be changed without having to rewrite the file. MDItem tags are extracted using the "mdls" utility. They are extracted if any "MDItem*" tag or the MacOS group is specifically requested, or by setting the MDItemTags API option to 1 or the RequestAll API option to 2 or -higher. +higher. Note that these tags do not necessarily reflect the current +metadata of a file -- it may take some time for the MacOS mdworker daemon to +index the file after a metadata change. Tag Name Writable -------- -------- AppleMailDateReceived no + AppleMailDateSent no AppleMailFlagged no + AppleMailIsRemoteAttachment no AppleMailMessageID no AppleMailPriority no AppleMailRead no @@ -32361,14 +33968,18 @@ higher. MDItemAcquisitionModel no MDItemAltitude no MDItemAperture no + MDItemAudioBitRate no + MDItemAudioChannelCount no MDItemAuthorEmailAddresses no MDItemAuthors no MDItemBitsPerSample no MDItemBundleIdentifier no MDItemCity no + MDItemCodecs no MDItemColorSpace no MDItemComment no MDItemContentCreationDate no + MDItemContentCreationDateRanking no MDItemContentCreationDate_Ranking no MDItemContentModificationDate no MDItemContentType no @@ -32382,6 +33993,7 @@ higher. MDItemDescription no MDItemDisplayName no MDItemDownloadedDate no + MDItemDurationSeconds no MDItemEXIFGPSVersion no MDItemEXIFVersion no MDItemEmailConversationID no @@ -32415,6 +34027,7 @@ higher. MDItemISOSpeed no MDItemIdentifier no MDItemImageDirection no + MDItemInterestingDateRanking no MDItemInterestingDate_Ranking no MDItemIsApplicationManaged no MDItemIsExistingThread no @@ -32422,11 +34035,14 @@ higher. MDItemKeywords no MDItemKind no MDItemLastUsedDate no + MDItemLastUsedDate_Ranking no MDItemLatitude no + MDItemLensModel no MDItemLogicalSize no MDItemLongitude no MDItemMailDateReceived_Ranking no MDItemMailboxes no + MDItemMediaTypes no MDItemNumberOfPages no MDItemOrientation no MDItemOriginApplicationIdentifier no @@ -32449,13 +34065,24 @@ higher. MDItemSecurityMethod no MDItemSpeed no MDItemStateOrProvince no + MDItemStreamable no MDItemSubject no MDItemTimestamp no MDItemTitle no + MDItemTotalBitRate no MDItemUseCount no MDItemUsedDates no + MDItemUserDownloadedDate no + MDItemUserDownloadedUserHandle no + MDItemUserSharedReceivedDate no + MDItemUserSharedReceivedRecipient no + MDItemUserSharedReceivedRecipientHandle no + MDItemUserSharedReceivedSender no + MDItemUserSharedReceivedSenderHandle no + MDItemUserSharedReceivedTransport no MDItemUserTags yes!+ MDItemVersion no + MDItemVideoBitRate no MDItemWhereFroms no MDItemWhiteBalance no @@ -32467,7 +34094,11 @@ the XAttrTags API option to 1 or the RequestAll API option to 2 or higher. Tag Name Writable -------- -------- + XAttrAppleMailDateReceived no + XAttrAppleMailDateSent no + XAttrAppleMailIsRemoteAttachment no XAttrFinderInfo no + XAttrLastUsedDate no XAttrMDItemDownloadedDate no XAttrMDItemFinderComment no XAttrMDItemWhereFroms no @@ -32492,12 +34123,13 @@ FileName. Tag Name Group Writable -------- ----- -------- Adobe Adobe yes! - CanonDR4 CanonVRD yes! - CanonVRD CanonVRD yes! + CanonDR4 CanonVRD yes!^ + CanonVRD CanonVRD yes!^ Comment File yes CurrentIPTCDigest File no Directory System yes! EXIF EXIF yes! + EmbeddedVideo File no Error ExifTool no ExifByteOrder File yes ExifToolVersion ExifTool no @@ -32533,6 +34165,7 @@ FileName. ImageHeight File no ImageWidth File no JPEGDigest File no + JPEGImageLength File no JPEGQualityEstimate File no MIMEType File no MaxVal File no @@ -32547,8 +34180,10 @@ FileName. ProcessingTime ExifTool no RAFVersion File no ResourceForkSize System no + SymLink - yes! TestName - yes! ThumbnailImage File no + Trailer File yes! Validate ExifTool no Warning ExifTool no XMP XMP yes! @@ -32577,7 +34212,7 @@ values, may created via the ExifTool configuration file. MPEG:VBRFrames AutoFocus Nikon:PhaseDetectAF no Nikon:ContrastDetectAF - AvgBitrate QuickTime::MovieDataSize no + AvgBitrate QuickTime::MediaDataSize no QuickTime::Duration BlueBalance WB_RGGBLevels no WB_RGBGLevels @@ -32627,14 +34262,14 @@ values, may created via the ExifTool configuration file. Canon:DigitalZoom DriveMode ContinuousDrive no SelfTimer - Duration FLAC:SampleRate no - FLAC:TotalSamples - Duration Vorbis:NominalBitrate no - FileSize + Duration AIFF:SampleRate no + AIFF:NumSampleFrames Duration APE:SampleRate no APE:TotalFrames APE:BlocksPerFrame APE:FinalFrameBlocks + Duration FLAC:SampleRate no + FLAC:TotalSamples Duration FileSize no ID3Size MPEG:AudioBitrate @@ -32650,8 +34285,8 @@ values, may created via the ExifTool configuration file. FileSize FrameCount VideoFrameCount - Duration AIFF:SampleRate no - AIFF:NumSampleFrames + Duration Vorbis:NominalBitrate no + FileSize ExtenderStatus Olympus:Extender no Olympus:LensType MaxApertureValue @@ -32683,22 +34318,25 @@ values, may created via the ExifTool configuration file. GPSAltitudeRef QuickTime:LocationInformation no GPSDateTime GPS:GPSDateStamp no GPS:GPSTimeStamp + GPSDateTime Parrot:GPSLatitude no + Main:CreateDate + SampleTime GPSDestLatitude GPS:GPSDestLatitude no GPS:GPSDestLatitudeRef - GPSDestLatitudeRef XMP:GPSDestLatitude no + GPSDestLatitudeRef XMP-exif:GPSDestLatitude no GPSDestLongitude GPS:GPSDestLongitude no GPS:GPSDestLongitudeRef - GPSDestLongitudeRef XMP:GPSDestLongitude no + GPSDestLongitudeRef XMP-exif:GPSDestLongitude no GPSLatitude GPS:GPSLatitude no GPS:GPSLatitudeRef GPSLatitude QuickTime:GPSCoordinates no GPSLatitude QuickTime:LocationInformation no - GPSLatitudeRef XMP:GPSLatitude no + GPSLatitudeRef XMP-exif:GPSLatitude no GPSLongitude GPS:GPSLongitude no GPS:GPSLongitudeRef GPSLongitude QuickTime:GPSCoordinates no GPSLongitude QuickTime:LocationInformation no - GPSLongitudeRef XMP:GPSLongitude no + GPSLongitudeRef XMP-exif:GPSLongitude no GPSPosition GPSLatitude no GPSLongitude HyperfocalDistance FocalLength no @@ -32709,18 +34347,19 @@ values, may created via the ExifTool configuration file. ISO Canon:CameraISO no Canon:BaseISO Canon:AutoISO - ImageHeight Main:PostScript:ImageData no - PostScript:BoundingBox ImageHeight IFD0:SensorTopBorder no IFD0:SensorBottomBorder + ImageHeight Main:PostScript:ImageData no + PostScript:BoundingBox ImageSize ImageWidth no ImageHeight ExifImageWidth ExifImageHeight - ImageWidth Main:PostScript:ImageData no - PostScript:BoundingBox + RawImageCroppedSize ImageWidth IFD0:SensorLeftBorder no IFD0:SensorRightBorder + ImageWidth Main:PostScript:ImageData no + PostScript:BoundingBox JpgFromRaw JpgFromRawStart yes JpgFromRawLength Lens Canon:MinFocalLength no @@ -32739,13 +34378,8 @@ values, may created via the ExifTool configuration file. LensFocalRange LensSpec LensType2 + LensType3 LensFocalLength - LensID XMP-aux:LensID no - Make - LensInfo - FocalLength - LensModel - MaxApertureValue LensID Nikon:LensIDNumber no LensFStops MinFocalLength @@ -32755,8 +34389,16 @@ values, may created via the ExifTool configuration file. MCUVersion Nikon:LensType LensID Ricoh:LensFirmware no + LensID XMP-aux:LensID no + Make + LensInfo + FocalLength + LensModel + MaxApertureValue LensSpec Nikon:Lens no Nikon:LensType + LensType LensTypeMake no + LensTypeModel LightValue Aperture no ShutterSpeed ISO @@ -32819,6 +34461,9 @@ values, may created via the ExifTool configuration file. ShutterSpeed ExposureTime no ShutterSpeedValue BulbDuration + SingleShotDepthMapTiff SingleShotDepthMap no + SegWidth + SegHeight SubSecCreateDate EXIF:CreateDate yes SubSecTimeDigitized OffsetTimeDigitized @@ -33030,6 +34675,7 @@ for more details. MakerNoteLeica7 MakerNoteLeica8 MakerNoteLeica9 + MakerNoteLeica10 MakerNotePanasonic MakerNotePanasonic2 MakerNotePanasonic3 @@ -33042,8 +34688,10 @@ for more details. MakerNotePhaseOne MakerNoteReconyx MakerNoteReconyx2 + MakerNoteReconyx3 MakerNoteRicoh MakerNoteRicoh2 + MakerNoteRicohPentax MakerNoteRicohText MakerNoteSamsung1a MakerNoteSamsung1b @@ -33217,7 +34865,8 @@ implements this policy and changes EXIF:Artist to a list-type tag. Image region metadata defined by the MWG 2.0 specification. These tags may be accessed without the need to load the MWG Composite tags above. See -L<http://www.metadataworkinggroup.org/> for the official specification. +L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> +for the official specification. These tags belong to the ExifTool XMP-mwg-rs family 1 group. @@ -33285,8 +34934,9 @@ conversion). Hierarchical keywords metadata defined by the MWG 2.0 specification. ExifTool unrolls keyword structures to an arbitrary depth of 6 to allow individual levels to be accessed with different tag names, and to avoid -infinite recursion. See L<http://www.metadataworkinggroup.org/> for the -official specification. +infinite recursion. See +L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> +for the official specification. These tags belong to the ExifTool XMP-mwg-kw family 1 group. @@ -33329,7 +34979,8 @@ These tags belong to the ExifTool XMP-mwg-kw family 1 group. =head3 MWG Collections Tags Collections metadata defined by the MWG 2.0 specification. See -L<http://www.metadataworkinggroup.org/> for the official specification. +L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/> +for the official specification. These tags belong to the ExifTool XMP-mwg-coll family 1 group. @@ -33353,7 +35004,7 @@ L<Image::ExifTool::BuildTagLookup|Image::ExifTool::BuildTagLookup>. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Text.pm b/src/Image-ExifTool/lib/Image/ExifTool/Text.pm new file mode 100644 index 00000000..6590c963 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Text.pm @@ -0,0 +1,245 @@ +#------------------------------------------------------------------------------ +# File: Text.pm +# +# Description: Deduce characteristics of TXT and CSV files +# +# Revisions: 2019-11-01 - P. Harvey Created +# 2020-02-13 - PH Added CSV file support +# +# References: 1) https://github.com/file/file +#------------------------------------------------------------------------------ + +package Image::ExifTool::Text; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); +use Image::ExifTool::XMP; + +$VERSION = '1.03'; + +# Text tags +%Image::ExifTool::Text::Main = ( + VARS => { NO_ID => 1 }, + GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Document' }, + NOTES => q{ + Although basic text files contain no metadata, the following tags are + determined from a simple analysis of the data in TXT and CSV files. + Statistics are generated only for 8-bit encodings, but the L<FastScan|../ExifTool.html#FastScan> (-fast) + option may be used to limit processing to the first 64 kB in which case some + tags are not produced. To avoid long processing delays, ExifTool will issue + a minor warning and process only the first 64 kB of any file larger than 20 + MB unless the L<IgnoreMinorErrors|../ExifTool.html#IgnoreMinorErrors> (-m) + option is used. + }, + MIMEEncoding => { Groups => { 2 => 'Other' } }, + Newlines => { + PrintConv => { + "\r\n" => 'Windows CRLF', + "\r" => 'Macintosh CR', + "\n" => 'Unix LF', + '' => '(none)', + }, + }, + ByteOrderMark => { PrintConv => { 0 => 'No', 1 => 'Yes' } }, + LineCount => { }, + WordCount => { }, + Delimiter => { PrintConv => { '' => '(none)', ',' => 'Comma', ';' => 'Semicolon', "\t" => 'Tab' }}, + Quoting => { PrintConv => { '' => '(none)', '"' => 'Double quotes', "'" => 'Single quotes' }}, + RowCount => { }, + ColumnCount => { }, +); + +#------------------------------------------------------------------------------ +# Extract some stats from a text file +# Inputs: 0) ExifTool ref, 1) dirInfo ref +# Returns: 1 on success, 0 if this wasn't a text file +sub ProcessTXT($$) +{ + my ($et, $dirInfo) = @_; + my $dataPt = $$dirInfo{TestBuff}; + my $raf = $$dirInfo{RAF}; + my $fast = $et->Options('FastScan') || 0; + my ($buff, $enc, $isBOM, $isUTF8); + my $nl = ''; + + return 0 unless length $$dataPt; # can't call it a text file if it has no text + + # read more from the file if necessary + if ($fast < 3 and length($$dataPt) == $Image::ExifTool::testLen) { + $raf->Read($buff, 65536) or return 0; + $dataPt = \$buff; + } +# +# make our best guess at the character encoding (EBCDIC is not supported) +# + if ($$dataPt =~ /([\0-\x06\x0e-\x1a\x1c-\x1f\x7f])/) { + # file contains weird control characters, could be multi-byte Unicode + if ($$dataPt =~ /^(\xff\xfe\0\0|\0\0\xfe\xff)/) { + if ($1 eq "\xff\xfe\0\0") { + $enc = 'utf-32le'; + $nl = $1 if $$dataPt =~ /(\r\0\0\0\n|\r|\n)\0\0\0/; + } else { + $enc = 'utf-32be'; + $nl = $1 if $$dataPt =~ /\0\0\0(\r\0\0\0\n|\r|\n)/; + } + } elsif ($$dataPt =~ /^(\xff\xfe|\xfe\xff)/) { + if ($1 eq "\xff\xfe") { + $enc = 'utf-16le'; + $nl = $1 if $$dataPt =~ /(\r\0\n|\r|\n)\0/; + } else { + $enc = 'utf-16be'; + $nl = $1 if $$dataPt =~ /\0(\r\0\n|\r|\n)/; + } + } else { + return 0; # probably not a text file + } + $nl =~ tr/\0//d; # remove nulls from newline sequence + $isBOM = 1; # (we don't recognize UTF-16/UTF-32 without one) + } else { + $isUTF8 = Image::ExifTool::XMP::IsUTF8($dataPt, 1); + if ($isUTF8 == 0) { + $enc = 'us-ascii'; + } elsif ($isUTF8 > 0) { + $enc = 'utf-8'; + $isBOM = ($$dataPt =~ /^\xef\xbb\xbf/ ? 1 : 0); + } elsif ($$dataPt !~ /[\x80-\x9f]/) { + $enc = 'iso-8859-1'; + } else { + $enc = 'unknown-8bit'; + } + $nl = $1 if $$dataPt =~ /(\r\n|\r|\n)/; + } + + my $tagTablePtr = GetTagTable('Image::ExifTool::Text::Main'); + + $et->SetFileType(); + $et->HandleTag($tagTablePtr, MIMEEncoding => $enc); + + return 1 if $fast == 3 or not $raf->Seek(0,0); + + $et->HandleTag($tagTablePtr, ByteOrderMark => $isBOM) if defined $isBOM; + $et->HandleTag($tagTablePtr, Newlines => $nl); + + return 1 if $fast or not defined $isUTF8; +# +# generate stats for CSV files +# + if ($$et{FileType} eq 'CSV') { + my ($delim, $quot, $ncols); + my $nrows = 0; + while ($raf->ReadLine($buff)) { + if (not defined $delim) { + my %count = ( ',' => 0, ';' => 0, "\t" => 0 ); + ++$count{$_} foreach $buff =~ /[,;\t]/g; + if ($count{','} > $count{';'} and $count{','} > $count{"\t"}) { + $delim = ','; + } elsif ($count{';'} > $count{"\t"}) { + $delim = ';'; + } elsif ($count{"\t"}) { + $delim = "\t"; + } else { + $delim = ''; + $ncols = 1; + } + unless ($ncols) { + # account for delimiters in quotes (simplistically) + while ($buff =~ /(^|$delim)(["'])(.*?)\2(?=$delim|$)/sg) { + $quot = $2; + my $field = $3; + $count{$delim} -= () = $field =~ /$delim/g; + } + $ncols = $count{$delim} + 1; + } + } elsif (not $quot) { + $quot = $2 if $buff =~ /(^|$delim)(["'])(.*?)\2(?=$delim|$)/sg; + } + if (++$nrows == 1000 and $et->Warn('Not counting rows past 1000', 2)) { + undef $nrows; + last; + } + } + $et->HandleTag($tagTablePtr, Delimiter => ($delim || '')); + $et->HandleTag($tagTablePtr, Quoting => ($quot || '')); + $et->HandleTag($tagTablePtr, ColumnCount => $ncols); + $et->HandleTag($tagTablePtr, RowCount => $nrows) if $nrows; + return 1; + } + return 1 if $$et{VALUE}{FileSize} and $$et{VALUE}{FileSize} > 20000000 and + $et->Warn('Not counting lines/words in text file larger than 20 MB', 2); +# +# count lines/words and check encoding of the rest of the file +# + my ($lines, $words) = (0, 0); + my $oldNL = $/; + $/ = $nl if $nl; + while ($raf->ReadLine($buff)) { + ++$lines; + ++$words while $buff =~ /\S+/g; + if (not $nl and $buff =~ /(\r\n|\r|\n)$/) { + # (the first line must have been longer than 64 kB) + $$et{VALUE}{Newlines} = $nl = $1; + } + next if $raf->Tell() < 65536; + # continue to check encoding after the first 64 kB + if ($isUTF8 >= 0) { # (if ascii or utf8) + $isUTF8 = Image::ExifTool::XMP::IsUTF8(\$buff); + if ($isUTF8 > 0) { + $enc = 'utf-8'; + } elsif ($isUTF8 < 0) { + $enc = $buff =~ /[\x80-\x9f]/ ? 'unknown-8bit' : 'iso-8859-1'; + } + } elsif ($enc eq 'iso-8859-1' and $buff =~ /[\x80-\x9f]/) { + $enc = 'unknown-8bit'; + } + } + if ($$et{VALUE}{MIMEEncoding} ne $enc) { + $$et{VALUE}{MIMEEncoding} = $enc; + $et->VPrint(0," MIMEEncoding [override] = $enc\n"); + } + $/ = $oldNL; + $et->HandleTag($tagTablePtr, LineCount => $lines); + $et->HandleTag($tagTablePtr, WordCount => $words); + return 1; +} + + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Text - Read Text meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to deduce some +characteristics of TXT and CSV files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://github.com/file/file> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/Text Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Theora.pm b/src/Image-ExifTool/lib/Image/ExifTool/Theora.pm index 3936d26e..f7e81cb2 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Theora.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Theora.pm @@ -122,7 +122,7 @@ information from Theora video streams. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Torrent.pm b/src/Image-ExifTool/lib/Image/ExifTool/Torrent.pm index ea88a1ca..3ae1ff38 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Torrent.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Torrent.pm @@ -14,7 +14,7 @@ use strict; use vars qw($VERSION); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.03'; +$VERSION = '1.04'; sub ReadBencode($$); sub ExtractTags($$$;$$@); @@ -41,7 +41,10 @@ sub ExtractTags($$$;$$@); PrintConv => '$self->ConvertDateTime($val)', }, 'encoding' => { }, - 'info' => { SubDirectory => { TagTable => 'Image::ExifTool::Torrent::Info' } }, + 'info' => { + SubDirectory => { TagTable => 'Image::ExifTool::Torrent::Info' }, + Notes => 'extracted as a structure with the Struct option', + }, 'url-list' => { Name => 'URLList1' }, ); @@ -232,6 +235,11 @@ sub ExtractTags($$$;$$@) $tagInfo = $et->GetTagInfo($tagTablePtr, $id) or next; } if (ref $val eq 'HASH') { + if ($et->Options('Struct') and $tagInfo and $$tagInfo{Name} eq 'Info') { + $et->FoundTag($tagInfo, $val); + ++$count; + next; + } # extract tags from this dictionary my ($table, $rootID, $rootName); if ($$tagInfo{SubDirectory}) { @@ -268,7 +276,7 @@ sub ProcessTorrent($$) my $dict = ReadBencode($raf, \$buff); my $err = $$raf{BencodeError}; $et->Warn("Bencode error: $err") if $err; - if (ref $dict eq 'HASH' and $$dict{announce}) { + if (ref $dict eq 'HASH' and ($$dict{announce} or $$dict{'created by'})) { $et->SetFileType(); my $tagTablePtr = GetTagTable('Image::ExifTool::Torrent::Main'); ExtractTags($et, $dict, $tagTablePtr) and $success = 1; @@ -295,7 +303,7 @@ bencoded information from BitTorrent files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Unknown.pm b/src/Image-ExifTool/lib/Image/ExifTool/Unknown.pm index 0f47b7fd..57314857 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Unknown.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Unknown.pm @@ -53,7 +53,7 @@ unknown manufacturers. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/VCard.pm b/src/Image-ExifTool/lib/Image/ExifTool/VCard.pm new file mode 100644 index 00000000..8de1275d --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/VCard.pm @@ -0,0 +1,443 @@ +#------------------------------------------------------------------------------ +# File: VCard.pm +# +# Description: Read vCard and iCalendar meta information +# +# Revisions: 2015/04/05 - P. Harvey Created +# 2015/05/02 - PH Added iCalendar support +# +# References: 1) http://en.m.wikipedia.org/wiki/VCard +# 2) http://tools.ietf.org/html/rfc6350 +# 3) http://tools.ietf.org/html/rfc5545 +#------------------------------------------------------------------------------ + +package Image::ExifTool::VCard; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.06'; + +my %unescapeVCard = ( '\\'=>'\\', ','=>',', 'n'=>"\n", 'N'=>"\n" ); + +# lookup for iCalendar components (used to generate family 1 group names if top level) +my %isComponent = ( Event=>1, Todo=>1, Journal=>1, Freebusy=>1, Timezone=>1, Alarm=>1 ); + +my %timeInfo = ( + # convert common date/time formats to EXIF style + ValueConv => q{ + $val =~ s/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})(Z?)/$1:$2:$3 $4:$5:$6$7/g; + $val =~ s/(\d{4})(\d{2})(\d{2})/$1:$2:$3/g; + $val =~ s/(\d{4})-(\d{2})-(\d{2})/$1:$2:$3/g; + return $val; + }, + PrintConv => '$self->ConvertDateTime($val)', +); + +# vCard tags (ref 1/2/PH) +# Note: The case of all tag ID's is normalized to lowercase with uppercase first letter +%Image::ExifTool::VCard::Main = ( + GROUPS => { 2 => 'Document' }, + VARS => { NO_LOOKUP => 1 }, # omit tags from lookup + NOTES => q{ + This table lists common vCard tags, but ExifTool will also extract any other + vCard tags found. Tag names may have "Pref" added to indicate the preferred + instance of a vCard property, and other "TYPE" parameters may also added to + the tag name. VCF files may contain multiple vCard entries which are + distinguished by the ExifTool family 3 group name (document number). See + L<http://tools.ietf.org/html/rfc6350> for the vCard 4.0 specification. + }, + Version => { Name => 'VCardVersion', Description => 'VCard Version' }, + Fn => { Name => 'FormattedName', Groups => { 2 => 'Author' } }, + N => { Name => 'Name', Groups => { 2 => 'Author' } }, + Bday => { Name => 'Birthday', Groups => { 2 => 'Time' }, %timeInfo }, + Tz => { Name => 'TimeZone', Groups => { 2 => 'Time' } }, + Adr => { Name => 'Address', Groups => { 2 => 'Location' } }, + Geo => { + Name => 'Geolocation', + Groups => { 2 => 'Location' }, + # when used as a parameter, VCard 4.0 adds a "geo:" prefix that we need to remove + ValueConv => '$val =~ s/^geo://; $val', + }, + Anniversary => { }, + Email => { }, + Gender => { }, + Impp => 'IMPP', + Lang => 'Language', + Logo => { }, + Nickname => { }, + Note => { }, + Org => 'Organization', + Photo => { Groups => { 2 => 'Preview' } }, + Prodid => 'Software', + Rev => 'Revision', + Sound => { }, + Tel => 'Telephone', + Title => 'JobTitle', + Uid => 'UID', + Url => 'URL', + 'X-ablabel' => { Name => 'ABLabel', PrintConv => '$val =~ s/^_\$!<(.*)>!\$_$/$1/; $val' }, + 'X-abdate' => { Name => 'ABDate', Groups => { 2 => 'Time' }, %timeInfo }, + 'X-aim' => 'AIM', + 'X-icq' => 'ICQ', + 'X-abuid' => 'AB_UID', + 'X-abrelatednames' => 'ABRelatedNames', + 'X-socialprofile' => 'SocialProfile', +); + +%Image::ExifTool::VCard::VCalendar = ( + GROUPS => { 1 => 'VCalendar', 2 => 'Document' }, + VARS => { + NO_LOOKUP => 1, # omit tags from lookup + LONG_TAGS => 6, # some X-microsoft tags have unavoidably long ID's + }, + NOTES => q{ + The VCard module is also used to process iCalendar ICS files since they use + a format similar to vCard. The following table lists standard iCalendar + tags, but any existing tags will be extracted. Top-level iCalendar + components (eg. Event, Todo, Timezone, etc.) are used for the family 1 group + names, and embedded components (eg. Alarm) are added as a prefix to the tag + name. See L<http://tools.ietf.org/html/rfc5545> for the official iCalendar + 2.0 specification. + }, + Version => { Name => 'VCalendarVersion', Description => 'VCalendar Version' }, + Calscale => 'CalendarScale', + Method => { }, + Prodid => 'Software', + Attach => 'Attachment', + Categories => { }, + Class => 'Classification', + Comment => { }, + Description => { }, + Geo => { + Name => 'Geolocation', + Groups => { 2 => 'Location' }, + ValueConv => '$val =~ s/^geo://; $val', + }, + Location => { Name => 'Location', Groups => { 2 => 'Location' } }, + 'Percent-complete' => 'PercentComplete', + Priority => { }, + Resources => { }, + Status => { }, + Summary => { }, + Completed => { Name => 'DateTimeCompleted', Groups => { 2 => 'Time' }, %timeInfo }, + Dtend => { Name => 'DateTimeEnd', Groups => { 2 => 'Time' }, %timeInfo }, + Due => { Name => 'DateTimeDue', Groups => { 2 => 'Time' }, %timeInfo }, + Dtstart => { Name => 'DateTimeStart', Groups => { 2 => 'Time' }, %timeInfo }, + Duration => { }, + Freebusy => 'FreeBusyTime', + Transp => 'TimeTransparency', + Tzid => { Name => 'TimezoneID', Groups => { 2 => 'Time' } }, + Tzname => { Name => 'TimezoneName', Groups => { 2 => 'Time' } }, + Tzoffsetfrom=> { Name => 'TimezoneOffsetFrom', Groups => { 2 => 'Time' } }, + Tzoffsetto => { Name => 'TimezoneOffsetTo', Groups => { 2 => 'Time' } }, + Tzurl => { Name => 'TimeZoneURL', Groups => { 2 => 'Time' } }, + Attendee => { }, + Contact => { }, + Organizer => { }, + 'Recurrence-id' => 'RecurrenceID', + 'Related-to' => 'RelatedTo', + Url => 'URL', + Uid => 'UID', + Exdate => { Name => 'ExceptionDateTimes', Groups => { 2 => 'Time' }, %timeInfo }, + Rdate => { Name => 'RecurrenceDateTimes', Groups => { 2 => 'Time' }, %timeInfo }, + Rrule => { Name => 'RecurrenceRule', Groups => { 2 => 'Time' } }, + Action => { }, + Repeat => { }, + Trigger => { }, + Created => { Name => 'DateCreated', Groups => { 2 => 'Time' }, %timeInfo }, + Dtstamp => { Name => 'DateTimeStamp', Groups => { 2 => 'Time' }, %timeInfo }, + 'Last-modified' => { Name => 'ModifyDate', Groups => { 2 => 'Time' }, %timeInfo }, + Sequence => 'SequenceNumber', + 'Request-status' => 'RequestStatus', + Acknowledged=> { Name => 'Acknowledged', Groups => { 2 => 'Time' }, %timeInfo }, +# +# Observed X-tags (not a comprehensive list): +# + 'X-apple-calendar-color'=> 'CalendarColor', + 'X-apple-default-alarm' => 'DefaultAlarm', + 'X-apple-local-default-alarm' => 'LocalDefaultAlarm', + 'X-microsoft-cdo-appt-sequence' => 'AppointmentSequence', + 'X-microsoft-cdo-ownerapptid' => 'OwnerAppointmentID', + 'X-microsoft-cdo-busystatus' => 'BusyStatus', + 'X-microsoft-cdo-intendedstatus' => 'IntendedBusyStatus', + 'X-microsoft-cdo-alldayevent' => 'AllDayEvent', + 'X-microsoft-cdo-importance' => { + Name => 'Importance', + PrintConv => { + 0 => 'Low', + 1 => 'Normal', + 2 => 'High', + }, + }, + 'X-microsoft-cdo-insttype' => { + Name => 'InstanceType', + PrintConv => { + 0 => 'Non-recurring Appointment', + 1 => 'Recurring Appointment', + 2 => 'Single Instance of Recurring Appointment', + 3 => 'Exception to Recurring Appointment', + }, + }, + 'X-microsoft-donotforwardmeeting' => 'DoNotForwardMeeting', + 'X-microsoft-disallow-counter' => 'DisallowCounterProposal', + 'X-microsoft-locations' => { Name => 'MeetingLocations', Groups => { 2 => 'Location' } }, + 'X-wr-caldesc' => 'CalendarDescription', + 'X-wr-calname' => 'CalendarName', + 'X-wr-relcalid' => 'CalendarID', + 'X-wr-timezone' => { Name => 'TimeZone2', Groups => { 2 => 'Time' } }, + 'X-wr-alarmuid' => 'AlarmUID', +); + +#------------------------------------------------------------------------------ +# Get vCard tag, creating if necessary +# Inputs: 0) ExifTool ref, 1) tag table ref, 2) tag ID, 3) tag Name, +# 4) source tagInfo ref, 5) lang code +# Returns: tagInfo ref +sub GetVCardTag($$$$;$$) +{ + my ($et, $tagTablePtr, $tag, $name, $srcInfo, $langCode) = @_; + my $tagInfo = $$tagTablePtr{$tag}; + unless ($tagInfo) { + if ($srcInfo) { + $tagInfo = { %$srcInfo }; + } else { + $tagInfo = { }; + $et->VPrint(0, $$et{INDENT}, "[adding $tag]\n"); + } + $$tagInfo{Name} = $name; + delete $$tagInfo{Description}; # create new description + AddTagToTable($tagTablePtr, $tag, $tagInfo); + } + # handle alternate languages (the "language" parameter) + $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, $langCode) if $langCode; + return $tagInfo; +} + +#------------------------------------------------------------------------------ +# Decode vCard text +# Inputs: 0) ExifTool ref, 1) vCard text, 2) encoding +# Returns: decoded text (or array ref for a list of values) +sub DecodeVCardText($$;$) +{ + my ($et, $val, $enc) = @_; + $enc = defined($enc) ? lc $enc : ''; + if ($enc eq 'b' or $enc eq 'base64') { + require Image::ExifTool::XMP; + $val = Image::ExifTool::XMP::DecodeBase64($val); + } else { + if ($enc eq 'quoted-printable') { + # convert "=HH" hex codes to characters + $val =~ s/=([0-9a-f]{2})/chr(hex($1))/ige; + } + $val = $et->Decode($val, 'UTF8'); # convert from UTF-8 + # convert unescaped commas to nulls to separate list items + $val =~ s/(\\.)|(,)/$1 || "\0"/sge; + # unescape necessary characters in value + $val =~ s/\\(.)/$unescapeVCard{$1}||$1/sge; + # split into list if necessary + my @vals = split /\0/, $val; + $val = \@vals if @vals > 1; + } + return $val; +} + +#------------------------------------------------------------------------------ +# Read information in a vCard file +# Inputs: 0) ExifTool ref, 1) dirInfo ref +# Returns: 1 on success, 0 if this wasn't a valid vCard file +sub ProcessVCard($$) +{ + local $_; + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my ($buff, $val, $ok, $component, %compNum, @count); + + return 0 unless $raf->Read($buff, 24) and $raf->Seek(0,0) and $buff=~/^BEGIN:(VCARD|VCALENDAR)\r\n/i; + my ($type, $lbl, $tbl, $ext) = uc($1) eq 'VCARD' ? qw(VCard vCard Main VCF) : qw(ICS iCalendar VCalendar ICS); + $et->SetFileType($type, undef, $ext); + return 1 if $$et{OPTIONS}{FastScan} and $$et{OPTIONS}{FastScan} == 3; + local $/ = "\r\n"; + my $tagTablePtr = GetTagTable("Image::ExifTool::VCard::$tbl"); + my $more = $raf->ReadLine($buff); # read first line + chomp $buff if $more; + while ($more) { + # retrieve previous line from $buff + $val = $buff if defined $buff; + # read ahead to next line to see if is a continuation + $more = $raf->ReadLine($buff); + if ($more) { + chomp $buff; + # add continuation line if necessary + $buff =~ s/^[ \t]// and $val .= $buff, undef($buff), next; + } + if ($val =~ /^(BEGIN|END):(V?)(\w+)$/i) { + my ($begin, $v, $what) = ((lc($1) eq 'begin' ? 1 : 0), $2, ucfirst lc $3); + if ($what eq 'Card' or $what eq 'Calendar') { + if ($begin) { + @count = ( { } ); # reset group counters + } else { + $ok = 1; # ok if we read at least on full VCARD or VCALENDAR + } + next; + } + # absorb top-level component into family 1 group name + if ($isComponent{$what}) { + if ($begin) { + unless ($component) { + # begin a new top-level component + @count = ( { } ); + $component = $what; + $compNum{$component} = ($compNum{$component} || 0) + 1; + next; + } + } elsif ($component and $component eq $what) { + # this top-level component has ended + undef $component; + next; + } + } + # keep count of each component at this level + if ($begin) { + $count[-1]{$what} = ($count[-1]{$what} || 0) + 1 if $v; + push @count, { obj => $what }; + } elsif (@count > 1) { + pop @count; + } + next; + } elsif ($ok) { + $ok = 0; + $$et{DOC_NUM} = ++$$et{DOC_COUNT}; # read next card as a new document + } + unless ($val =~ s/^([-A-Za-z0-9.]+)//) { + $et->WarnOnce("Unrecognized line in $lbl file"); + next; + } + my $tag = $1; + # set group if it exists + if ($tag =~ s/^([-A-Za-z0-9]+)\.//) { + $$et{SET_GROUP1} = ucfirst lc $1; + } elsif ($component) { + $$et{SET_GROUP1} = $component . $compNum{$component}; + } else { + delete $$et{SET_GROUP1}; + } + my ($name, %param, $p); + # vCard tag ID's are case-insensitive, so normalize to lowercase with + # an uppercase first letter for use as a tag name + $name = ucfirst $tag if $tag =~ /[a-z]/; # preserve mixed case in name if it exists + $tag = ucfirst lc $tag; + # get source tagInfo reference + my $srcInfo = $et->GetTagInfo($tagTablePtr, $tag); + if ($srcInfo) { + $name = $$srcInfo{Name}; # use our name + } else { + $name or $name = $tag; + # remove leading "X-" from name if it exists + $name =~ s/^X-// and $name = ucfirst $name; + } + # add object name(s) to tag if necessary + if (@count > 1) { + my $i; + for ($i=$#count-1; $i>=0; --$i) { + my $pre = $count[$i-1]{obj}; # use containing object name as tag prefix + my $c = $count[$i]{$pre}; # add index for object number + $c = '' unless defined $c; + $tag = $pre . $c . $tag; + $name = $pre . $c . $name; + } + } + # parse parameters + while ($val =~ s/^;([-A-Za-z0-9]*)(=?)//) { + $p = ucfirst lc $1; + # convert old vCard 2.x parameters to the new "TYPE=" format + $2 or $val = $1 . $val, $p = 'Type'; + # read parameter value + for (;;) { + last unless $val =~ s/^"([^"]*)",?// or $val =~ s/^([^";:,]+,?)//; + my $v = $p eq 'Type' ? ucfirst lc $1 : $1; + $param{$p} = defined($param{$p}) ? $param{$p} . $v : $v; + } + if (defined $param{$p}) { + $param{$p} =~ s/\\(.)/$unescapeVCard{$1}||$1/sge; + } else { + $param{$p} = ''; + } + } + $val =~ s/^:// or $et->WarnOnce("Invalid line in $lbl file"), next; + # add 'Type' parameter to id and name if it exists + $param{Type} and $tag .= $param{Type}, $name .= $param{Type}; + # convert base64-encoded data + if ($val =~ s{^data:(\w+)/(\w+);base64,}{}) { + my $xtra = ucfirst(lc $1) . ucfirst(lc $2); + $tag .= $xtra; + $name .= $xtra; + $param{Encoding} = 'base64'; + } + $val = DecodeVCardText($et, $val, $param{Encoding}); + my $tagInfo = GetVCardTag($et, $tagTablePtr, $tag, $name, $srcInfo, $param{Language}); + $et->HandleTag($tagTablePtr, $tag, $val, TagInfo => $tagInfo); + # handle some other parameters that we care about (ignore the rest for now) + foreach $p (qw(Geo Label Tzid)) { + next unless defined $param{$p}; + # use tag attributes from our table if it exists + my $srcTag2 = $et->GetTagInfo($tagTablePtr, $p); + my $pn = $srcTag2 ? $$srcTag2{Name} : $p; + $val = DecodeVCardText($et, $param{$p}); + # add parameter to tag ID and name + my ($tg, $nm) = ($tag . $p, $name . $pn); + $tagInfo = GetVCardTag($et, $tagTablePtr, $tg, $nm, $srcTag2, $param{Language}); + $et->HandleTag($tagTablePtr, $tg, $val, TagInfo => $tagInfo); + } + } + delete $$et{SET_GROUP1}; + delete $$et{DOC_NUM}; + $ok or $et->Warn("Missing $lbl end"); + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::VCard - Read vCard and iCalendar meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read meta +information from vCard VCF and iCalendar ICS files. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<http://en.m.wikipedia.org/wiki/VCard> + +=item L<http://tools.ietf.org/html/rfc6350> + +=item L<http://tools.ietf.org/html/rfc5545> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/VCard Tags>, +L<Image::ExifTool::TagNames/VCard VCalendar Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Validate.pm b/src/Image-ExifTool/lib/Image/ExifTool/Validate.pm new file mode 100644 index 00000000..9e1d0634 --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/Validate.pm @@ -0,0 +1,672 @@ +#------------------------------------------------------------------------------ +# File: Validate.pm +# +# Description: Additional metadata validation +# +# Created: 2017/01/18 - P. Harvey +# +# Notes: My apologies for the convoluted logic contained herein, but it +# is done this way to retro-fit the Validate feature into the +# existing ExifTool code while reducing the possibility of +# introducing bugs or slowing down processing when this feature +# is not used. +#------------------------------------------------------------------------------ + +package Image::ExifTool::Validate; + +use strict; +use vars qw($VERSION %exifSpec); + +$VERSION = '1.17'; + +use Image::ExifTool qw(:Utils); +use Image::ExifTool::Exif; + +# EXIF table tag ID's which are part of the EXIF 2.32 specification +# (with ExifVersion numbers for tags where I can determine the version) +# (also used by BuildTagLookup to add underlines in HTML version of EXIF Tag Table) +%exifSpec = ( + 0x1 => 210, + 0x100 => 1, 0x8298 => 1, 0x9207 => 1, 0xa217 => 1, + 0x101 => 1, 0x829a => 1, 0x9208 => 1, 0xa300 => 1, + 0x102 => 1, 0x829d => 1, 0x9209 => 1, 0xa301 => 1, + 0x103 => 1, 0x8769 => 1, 0x920a => 1, 0xa302 => 1, + 0x106 => 1, 0x8822 => 1, 0x9214 => 220, 0xa401 => 220, + 0x10e => 1, 0x8824 => 1, 0x927c => 1, 0xa402 => 220, + 0x10f => 1, 0x8825 => 200, 0x9286 => 1, 0xa403 => 220, + 0x110 => 1, 0x8827 => 1, 0x9290 => 1, 0xa404 => 220, + 0x111 => 1, 0x8828 => 1, 0x9291 => 1, 0xa405 => 220, + 0x112 => 1, 0x8830 => 230, 0x9292 => 1, 0xa406 => 220, + 0x115 => 1, 0x8831 => 230, 0x9400 => 231, 0xa407 => 220, + 0x116 => 1, 0x8832 => 230, 0x9401 => 231, 0xa408 => 220, + 0x117 => 1, 0x8833 => 230, 0x9402 => 231, 0xa409 => 220, + 0x11a => 1, 0x8834 => 230, 0x9403 => 231, 0xa40a => 220, + 0x11b => 1, 0x8835 => 230, 0x9404 => 231, 0xa40b => 220, + 0x11c => 1, 0x9000 => 1, 0x9405 => 231, 0xa40c => 220, + 0x128 => 1, 0x9003 => 1, 0xa000 => 1, 0xa460 => 232, + 0x12d => 1, 0x9004 => 1, 0xa001 => 1, 0xa461 => 232, + 0x131 => 1, 0x9010 => 231, 0xa002 => 1, 0xa462 => 232, + 0x132 => 1, 0x9011 => 231, 0xa003 => 1, 0xa420 => 220, + 0x13b => 1, 0x9012 => 231, 0xa004 => 1, 0xa430 => 230, + 0x13e => 1, 0x9101 => 1, 0xa005 => 210, 0xa431 => 230, + 0x13f => 1, 0x9102 => 1, 0xa20b => 1, 0xa432 => 230, + 0x201 => 1, 0x9201 => 1, 0xa20c => 1, 0xa433 => 230, + 0x202 => 1, 0x9202 => 1, 0xa20e => 1, 0xa434 => 230, + 0x211 => 1, 0x9203 => 1, 0xa20f => 1, 0xa435 => 230, + 0x212 => 1, 0x9204 => 1, 0xa210 => 1, 0xa500 => 221, + 0x213 => 1, 0x9205 => 1, 0xa214 => 1, + 0x214 => 1, 0x9206 => 1, 0xa215 => 1, +); + +# GPSVersionID numbers when each tag was introduced +my %gpsVer = ( + 0x01 => 2000, 0x09 => 2000, 0x11 => 2000, 0x19 => 2000, + 0x02 => 2000, 0x0a => 2000, 0x12 => 2000, 0x1a => 2000, + 0x03 => 2000, 0x0b => 2000, 0x13 => 2000, 0x1b => 2200, + 0x04 => 2000, 0x0c => 2000, 0x14 => 2000, 0x1c => 2200, + 0x05 => 2000, 0x0d => 2000, 0x15 => 2000, 0x1d => 2200, + 0x06 => 2000, 0x0e => 2000, 0x16 => 2000, 0x1e => 2200, + 0x07 => 2000, 0x0f => 2000, 0x17 => 2000, 0x1f => 2300, + 0x08 => 2000, 0x10 => 2000, 0x18 => 2000, +); + +# lookup to check version numbers +my %verCheck = ( + ExifIFD => { ExifVersion => \%exifSpec }, + InteropIFD => { ExifVersion => \%exifSpec }, + GPS => { GPSVersionID => \%gpsVer }, +); + +# tags standard in various RAW file formats +my %otherSpec = ( + CR2 => { 0xc5d8 => 1, 0xc5d9 => 1, 0xc5e0 => 1, 0xc640 => 1, 0xc6dc => 1, 0xc6dd => 1 }, + NEF => { 0x9216 => 1, 0x9217 => 1 }, + DNG => { 0x882a => 1, 0x9211 => 1, 0x9216 => 1 }, + ARW => { 0x7000 => 1, 0x7001 => 1, 0x7010 => 1, 0x7011 => 1, 0x7020 => 1, + 0x7031 => 1, 0x7032 => 1, 0x7034 => 1, 0x7035 => 1, 0x7036 => 1, 0x7037 => 1, + 0x7310 => 1, 0x7313 => 1, 0x7316 => 1, 0x74c7 => 1, 0x74c8 => 1, 0xa500 => 1 }, + RW2 => { All => 1 }, # ignore all unknown tags in RW2 + RWL => { All => 1 }, + RAF => { All => 1 }, # (temporary) + DCR => { All => 1 }, + KDC => { All => 1 }, + JXR => { All => 1 }, + SRW => { 0xa010 => 1, 0xa011 => 1, 0xa101 => 1, 0xa102 => 1 }, + NRW => { 0x9216 => 1, 0x9217 => 1 }, + X3F => { 0xa500 => 1 }, +); + +# standard format for tags (not necessary for exifSpec or GPS tags where Writable is defined) +my %stdFormat = ( + ExifIFD => { + 0xa002 => 'int(16|32)u', + 0xa003 => 'int(16|32)u', + }, + InteropIFD => { + 0x01 => 'string', + 0x02 => 'undef', + 0x1000 => 'string', + 0x1001 => 'int(16|32)u', + 0x1002 => 'int(16|32)u', + }, + IFD => { + # TIFF, EXIF, XMP, IPTC, ICC_Profile and PrintIM standard tags: + 0xfe => 'int32u', 0x11f => 'rational64u', 0x14a => 'int32u', 0x205 => 'int16u', + 0xff => 'int16u', 0x120 => 'int32u', 0x14c => 'int16u', 0x206 => 'int16u', + 0x100 => 'int(16|32)u', 0x121 => 'int32u', 0x14d => 'string', 0x207 => 'int32u', + 0x101 => 'int(16|32)u', 0x122 => 'int16u', 0x14e => 'int16u', 0x208 => 'int32u', + 0x107 => 'int16u', 0x123 => 'int16u', 0x150 => 'int(8|16)u', 0x209 => 'int32u', + 0x108 => 'int16u', 0x124 => 'int32u', 0x151 => 'string', 0x211 => 'rational64u', + 0x109 => 'int16u', 0x125 => 'int32u', 0x152 => 'int16u', 0x212 => 'int16u', + 0x10a => 'int16u', 0x129 => 'int16u', 0x153 => 'int16u', 0x213 => 'int16u', + 0x10d => 'string', 0x13c => 'string', 0x154 => '.*', 0x214 => 'rational64u', + 0x111 => 'int(16|32)u', 0x13d => 'int16u', 0x155 => '.*', 0x2bc => 'int8u', + 0x116 => 'int(16|32)u', 0x140 => 'int16u', 0x156 => 'int16u', 0x828d => 'int16u', + 0x117 => 'int(16|32)u', 0x141 => 'int16u', 0x15b => 'undef', 0x828e => 'int8u', + 0x118 => 'int16u', 0x142 => 'int(16|32)u', 0x200 => 'int16u', 0x83bb => 'int32u', + 0x119 => 'int16u', 0x143 => 'int(16|32)u', 0x201 => 'int32u', 0x8649 => 'int8u', + 0x11d => 'string', 0x144 => 'int32u', 0x202 => 'int32u', 0x8773 => 'undef', + 0x11e => 'rational64u', 0x145 => 'int(16|32)u', 0x203 => 'int16u', 0xc4a5 => 'undef', + # Windows Explorer tags: + 0x9c9b => 'int8u', 0x9c9d => 'int8u', 0x9c9f => 'int8u', + 0x9c9c => 'int8u', 0x9c9e => 'int8u', + # GeoTiff tags: + 0x830e => 'double', 0x8482 => 'double', 0x87af => 'int16u', 0x87b1 => 'string', + 0x8480 => 'double', 0x85d8 => 'double', 0x87b0 => 'double', + # DNG tags: + 0xc615 => '(string|int8u)', 0xc6d3 => '', + 0xc61a => '(int16u|int32u|rational64u)', 0xc6f4 => '(string|int8u)', + 0xc61d => 'int(16|32)u', 0xc6f6 => '(string|int8u)', + 0xc61f => '(int16u|int32u|rational64u)', 0xc6f8 => '(string|int8u)', + 0xc620 => '(int16u|int32u|rational64u)', 0xc6fe => '(string|int8u)', + 0xc628 => '(int16u|rational64u)', 0xc716 => '(string|int8u)', + 0xc634 => 'int8u', 0xc717 => '(string|int8u)', + 0xc640 => '', 0xc718 => '(string|int8u)', + 0xc660 => '', 0xc71e => 'int(16|32)u', + 0xc68b => '(string|int8u)', 0xc71f => 'int(16|32)u', + 0xc68d => 'int(16|32)u', 0xc791 => 'int(16|32)u', + 0xc68e => 'int(16|32)u', 0xc792 => 'int(16|32)u', + 0xc6d2 => '', 0xc793 => '(int16u|int32u|rational64u)', + }, +); + +# generate lookup for any IFD +my %stdFormatAnyIFD = map { %{$stdFormat{$_}} } keys %stdFormat; + +# tag values to validate based on file type (from EXIF specification) +# - validation code may access $val and %val, and returns 1 on success, +# or error message otherwise ('' for a generic message) +# - entry is undef if tag must not exist (same as 'not defined $val' in code) +my %validValue = ( + JPEG => { + IFD0 => { + 0x100 => undef, # ImageWidth + 0x101 => undef, # ImageLength + 0x102 => undef, # BitsPerSample + 0x103 => undef, # Compression + 0x106 => undef, # PhotometricInterpretation + 0x111 => undef, # StripOffsets + 0x115 => undef, # SamplesPerPixel + 0x116 => undef, # RowsPerStrip + 0x117 => undef, # StripByteCounts + 0x11a => 'defined $val', # XResolution + 0x11b => 'defined $val', # YResolution + 0x11c => undef, # PlanarConfiguration + 0x128 => '$val =~ /^[123]$/', # ResolutionUnit + 0x201 => undef, # JPEGInterchangeFormat + 0x202 => undef, # JPEGInterchangeFormatLength + 0x212 => undef, # YCbCrSubSampling + 0x213 => '$val =~ /^[12]$/', # YCbCrPositioning + }, + IFD1 => { + 0x100 => undef, # ImageWidth + 0x101 => undef, # ImageLength + 0x102 => undef, # BitsPerSample + 0x103 => '$val == 6', # Compression + 0x106 => undef, # PhotometricInterpretation + 0x111 => undef, # StripOffsets + 0x115 => undef, # SamplesPerPixel + 0x116 => undef, # RowsPerStrip + 0x117 => undef, # StripByteCounts + 0x11a => 'defined $val', # XResolution + 0x11b => 'defined $val', # YResolution + 0x11c => undef, # PlanarConfiguration + 0x128 => '$val =~ /^[123]$/', # ResolutionUnit + 0x201 => 'defined $val', # JPEGInterchangeFormat + 0x202 => 'defined $val', # JPEGInterchangeFormatLength + 0x212 => undef, # YCbCrSubSampling + }, + ExifIFD => { + 0x9000 => 'defined $val and $val =~ /^\d{4}$/', # ExifVersion + 0x9101 => 'defined $val', # ComponentsConfiguration + 0xa000 => 'defined $val', # FlashpixVersion + 0xa001 => '$val == 1 or $val == 0xffff', # ColorSpace + 0xa002 => 'defined $val', # PixelXDimension + 0xa003 => 'defined $val', # PixelYDimension + }, + GPS => { + 0x00 => 'defined $val and $val =~ /^\d \d \d \d$/', # GPSVersionID + 0x1b => 'not defined $val or $val =~ /^(GPS|CELLID|WLAN|MANUAL)$/', # GPSProcessingMethod + }, + InteropIFD => { }, # (needed for ExifVersion check) + }, + TIFF => { + IFD0 => { + 0x100 => 'defined $val', # ImageWidth + 0x101 => 'defined $val', # ImageLength + 0x102 => 'defined $val', # BitsPerSample + 0x103 => q{ + not defined $val or $val =~ /^(1|5|6|32773)$/ or + ($val == 2 and (not defined $val{0x102} or $val{0x102} == 1)); + }, # Compression + 0x106 => '$val =~ /^[0123]$/', # PhotometricInterpretation + 0x111 => 'defined $val', # StripOffsets + # SamplesPerPixel + 0x115 => q{ + my $pi = $val{0x106} || 0; + my $xtra = ($val{0x152} ? scalar(split ' ', $val{0x152}) : 0); + if ($pi == 2 or $pi == 6) { + return $val == 3 + $xtra; + } elsif ($pi == 5) { + return $val == 4 + $xtra; + } else { + return 1; + } + }, + 0x116 => 'defined $val', # RowsPerStrip + 0x117 => 'defined $val', # StripByteCounts + 0x11a => 'defined $val', # XResolution + 0x11b => 'defined $val', # YResolution + 0x128 => '$val =~ /^[123]$/', # ResolutionUnit + # ColorMap (must be palette image with correct number of colors) + 0x140 => q{ + return '' if defined $val{0x106} and $val{0x106} == 3 xor defined $val; + return 1 if not defined $val or length($val) == 6 * 2 ** ($val{0x102} || 0); + return 'Invalid count for'; + }, + 0x201 => undef, # JPEGInterchangeFormat + 0x202 => undef, # JPEGInterchangeFormatLength + }, + ExifIFD => { + 0x9000 => 'defined $val', # ExifVersion + 0x9101 => undef, # ComponentsConfiguration + 0x9102 => undef, # CompressedBitsPerPixel + 0xa000 => 'defined $val', # FlashpixVersion + 0xa001 => '$val == 1 or $val == 0xffff', # ColorSpace + 0xa002 => undef, # PixelXDimension + 0xa003 => undef, # PixelYDimension + }, + InteropIFD => { + 0x0001 => undef, # InteropIndex + }, + GPS => { + 0x00 => 'defined $val and $val =~ /^\d \d \d \d$/', # GPSVersionID + 0x1b => '$val =~ /^(GPS|CELLID|WLAN|MANUAL)$/', # GPSProcessingMethod + }, + }, +); + +# validity ranges for constrained date/time fields +my @validDateField = ( + [ 'Month', 1, 12 ], + [ 'Day', 1, 31 ], + [ 'Hour', 0, 23 ], + [ 'Minutes', 0, 59 ], + [ 'Seconds', 0, 59 ], + [ 'TZhr', 0, 14 ], + [ 'TZmin', 0, 59 ], +); + +# "Validate" tag information +my %validateInfo = ( + Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'ExifTool' }, + Notes => q{ + generated only if specifically requested. Requesting this tag automatically + enables the API L<Validate|../ExifTool.html#Validate> option, imposing + additional validation checks when extracting metadata. Returns the number + of errors, warnings and minor warnings encountered. Note that the Validate + feature focuses mainly on validation of EXIF/TIFF metadata + }, + PrintConv => { + '0 0 0' => 'OK', + OTHER => sub { + my @val = split ' ', shift; + my @rtn; + push @rtn, sprintf('%d Error%s', $val[0], $val[0] == 1 ? '' : 's') if $val[0]; + push @rtn, sprintf('%d Warning%s', $val[1], $val[1] == 1 ? '' : 's') if $val[1]; + if ($val[2]) { + my $str = ($val[1] == $val[2] ? ($val[1] == 1 ? '' : 'all ') : "$val[2] "); + $rtn[-1] .= " (${str}minor)"; + } + return join(' and ', @rtn); + }, + }, +); + +# add "Validate" tag to Extra table +AddTagToTable(\%Image::ExifTool::Extra, Validate => \%validateInfo, 1); + +#------------------------------------------------------------------------------ +# Validate the raw value of a tag +# Inputs: 0) ExifTool ref, 1) tag key, 2) raw tag value +# Returns: nothing, but issues a minor Warning if a problem was detected +sub ValidateRaw($$$) +{ + my ($self, $tag, $val) = @_; + my $tagInfo = $$self{TAG_INFO}{$tag}; + my $wrn; + + # evaluate Validate code if specified + if ($$tagInfo{Validate}) { + local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning; + undef $Image::ExifTool::evalWarning; + #### eval Validate ($self, $val, $tagInfo) + my $wrn = eval $$tagInfo{Validate}; + my $err = $Image::ExifTool::evalWarning || $@; + if ($wrn or $err) { + my $name = $$tagInfo{Table}{GROUPS}{0} . ':' . Image::ExifTool::GetTagName($tag); + $self->Warn("Validate $name: $err", 1) if $err; + $self->Warn("$wrn for $name", 1) if $wrn; + } + } + # check for unknown values in PrintConv lookup for all standard EXIF tags + if (ref $$tagInfo{PrintConv} eq 'HASH' and ($$tagInfo{Table}{SHORT_NAME} eq 'GPS::Main' or + ($$tagInfo{Table} eq \%Image::ExifTool::Exif::Main and $exifSpec{$$tagInfo{TagID}}))) + { + my $prt = $self->GetValue($tag, 'PrintConv'); + $wrn = 'Unknown value for' if $prt and $prt =~ /^Unknown \(/; + } + $wrn = 'Undefined value for' if $val eq 'undef'; + if ($wrn) { + my $name = $$self{DIR_NAME} . ':' . Image::ExifTool::GetTagName($tag); + $self->Warn("$wrn $name", 1); + } +} + +#------------------------------------------------------------------------------ +# Validate raw EXIF date/time value +# Inputs: 0) date/time value +# Returns: error string +sub ValidateExifDate($) +{ + my $val = shift; + if ($val =~ /^\d{4}:(\d{2}):(\d{2}) (\d{2}):(\d{2}):(\d{2})$/) { + my @a = ($1,$2,$3,$4,$5); + my ($i, @bad); + for ($i=0; $i<@a; ++$i) { + next if $a[$i] eq ' ' or ($a[$i] >= $validDateField[$i][1] and $a[$i] <= $validDateField[$i][2]); + push @bad, $validDateField[$i][0]; + } + return join('+', @bad) . ' out of range' if @bad; + # the EXIF specification allows blank fields or an entire blank value + } elsif ($val ne ' : : : : ' and $val ne ' ') { + return 'Invalid date/time format'; + } + return undef; # OK! +} + +#------------------------------------------------------------------------------ +# Validate EXIF-reformatted XMP date/time value +# Inputs: 0) date/time value +# Returns: error string +sub ValidateXMPDate($) +{ + my $val = shift; + if ($val =~ /^\d{4}$/ or + $val =~ /^\d{4}:(\d{2})$/ or + $val =~ /^\d{4}:(\d{2}):(\d{2})$/ or + $val =~ /^\d{4}:(\d{2}):(\d{2}) (\d{2}):(\d{2})()(Z|[-+](\d{2}):(\d{2}))?$/ or + $val =~ /^\d{4}:(\d{2}):(\d{2}) (\d{2}):(\d{2}):(\d{2})(Z|[-+](\d{2}):(\d{2}))?$/ or + $val =~ /^\d{4}:(\d{2}):(\d{2}) (\d{2}):(\d{2}):(\d{2})\.?\d*(Z|[-+](\d{2}):(\d{2}))?$/) + { + my @a = ($1,$2,$3,$4,$5,$7,$8); + my ($i, @bad); + for ($i=0; $i<@a; ++$i) { + last unless defined $a[$i]; + next if $a[$i] eq '' or ($a[$i] >= $validDateField[$i][1] and $a[$i] <= $validDateField[$i][2]); + push @bad, $validDateField[$i][0]; + } + return join('+', @bad) . ' out of range' if @bad; + } else { + return 'Invalid date/time format'; + } + return undef; # OK! +} + +#------------------------------------------------------------------------------ +# Validate EXIF tag +# Inputs: 0) ExifTool ref, 1) tag table ref, 2) tag ID, 3) tagInfo ref, +# 4) previous tag ID, 5) IFD name, 6) number of values, 7) value format string +# Returns: Nothing, but sets Warning tags if any problems are found +sub ValidateExif($$$$$$$$) +{ + my ($et, $tagTablePtr, $tag, $tagInfo, $lastTag, $ifd, $count, $formatStr) = @_; + + $et->WarnOnce("Entries in $ifd are out of order") if $tag <= $lastTag; + + # (get tagInfo for unknown tags if Unknown option not used) + if (not defined $tagInfo and $$tagTablePtr{$tag} and ref $$tagTablePtr{$tag} eq 'HASH') { + $tagInfo = $$tagTablePtr{$tag}; + } + if (defined $tagInfo) { + my $ti = $tagInfo || $$tagTablePtr{$tag}; + $ti = $$ti[-1] if ref $ti eq 'ARRAY'; + my $stdFmt = $stdFormat{$ifd} || $stdFormat{IFD}; + if (defined $$stdFmt{All} or ($tagTablePtr eq \%Image::ExifTool::Exif::Main and + ($exifSpec{$tag} or $$stdFmt{$tag} or + ($tag >= 0xc612 and $tag <= 0xc7b5 and not defined $$stdFmt{$tag}))) or # (DNG tags) + $$tagTablePtr{SHORT_NAME} eq 'GPS::Main') + { + my $wgp = $$ti{WriteGroup} || $$tagTablePtr{WRITE_GROUP}; + if ($wgp and $wgp ne $ifd and $wgp ne 'All' and not $$ti{OffsetPair} and + ($ifd =~ /^(Sub|Profile)?IFD\d*$/ xor $wgp =~ /^(Sub)?IFD\d*$/) and + ($$ti{Writable} or $$ti{WriteGroup}) and $ifd !~ /^SRF\d+$/) + { + $et->Warn(sprintf('Wrong IFD for 0x%.4x %s (should be %s not %s)', $tag, $$ti{Name}, $wgp, $ifd)); + } + my $fmt = $$stdFmt{$tag} || $$ti{Writable}; + if ($fmt and $formatStr !~ /^$fmt$/ and (not $tagInfo or + not $$tagInfo{IsOffset} or $Image::ExifTool::Exif::intFormat{$formatStr})) + { + $et->Warn(sprintf('Non-standard format (%s) for %s 0x%.4x %s', $formatStr, $ifd, $tag, $$ti{Name})) + } + } elsif ($stdFormatAnyIFD{$tag}) { + if ($$ti{Writable} || $$ti{WriteGroup}) { + my $wgp = $$ti{WriteGroup} || $$tagTablePtr{WRITE_GROUP}; + if ($wgp and $wgp ne $ifd) { + $et->Warn(sprintf('Wrong IFD for 0x%.4x %s (should be %s not %s)', $tag, $$ti{Name}, $wgp, $ifd)); + } + } + } elsif (not $otherSpec{$$et{VALUE}{FileType}} or + (not $otherSpec{$$et{VALUE}{FileType}}{$tag} and not $otherSpec{$$et{VALUE}{FileType}}{All})) + { + if ($tagTablePtr eq \%Image::ExifTool::Exif::Main or $$tagInfo{Unknown}) { + $et->Warn(sprintf('Non-standard %s tag 0x%.4x %s', $ifd, $tag, $$ti{Name}), 1); + } + } + # change expected count from read Format to Writable size + my $tiCount = $$ti{Count}; + if ($tiCount) { + if ($$ti{Format} and $$ti{Writable} and + $Image::ExifTool::Exif::formatNumber{$$ti{Format}} and + $Image::ExifTool::Exif::formatNumber{$$ti{Writable}}) + { + my $s1 = $Image::ExifTool::Exif::formatSize[$Image::ExifTool::Exif::formatNumber{$$ti{Format}}]; + my $s2 = $Image::ExifTool::Exif::formatSize[$Image::ExifTool::Exif::formatNumber{$$ti{Writable}}]; + $tiCount = int($tiCount * $s1 / $s2); + } + if ($tiCount > 0 and $count != $tiCount) { + $et->Warn(sprintf('Non-standard count (%d) for %s 0x%.4x %s', $count, $ifd, $tag, $$ti{Name})); + } + } + } elsif (not $otherSpec{$$et{VALUE}{FileType}} or + (not $otherSpec{$$et{VALUE}{FileType}}{$tag} and not $otherSpec{$$et{VALUE}{FileType}}{All})) + { + $et->Warn(sprintf('Unknown %s tag 0x%.4x', $ifd, $tag), 1); + } +} + +#------------------------------------------------------------------------------ +# Validate image data offsets/sizes +# Inputs: 0) ExifTool ref, 1) offset info hash ref (arrays of tagInfo/value pairs, keyed by tagID) +# 2) directory name, 3) optional flag for minor warning +sub ValidateOffsetInfo($$$;$) +{ + local $_; + my ($et, $offsetInfo, $dirName, $minor) = @_; + + my $fileSize = $$et{VALUE}{FileSize} or return; + + # (don't test RWZ files and some other file types) + return if $$et{DontValidateImageData}; + # (Minolta A200 uses wrong byte order for these) + return if $$et{TIFF_TYPE} eq 'MRW' and $dirName eq 'IFD0' and $$et{Model} =~ /^DiMAGE A200/; + # (don't test 3FR, RWL or RW2 files) + return if $$et{TIFF_TYPE} =~ /^(3FR|RWL|RW2)$/; + + Image::ExifTool::Exif::ValidateImageData($et, $offsetInfo, $dirName); + + # loop through all offsets + while (%$offsetInfo) { + my ($id1) = sort keys %$offsetInfo; + my $offsets = $$offsetInfo{$id1}; + delete $$offsetInfo{$id1}; + next unless ref $offsets eq 'ARRAY'; + my $id2 = $$offsets[0]{OffsetPair}; + unless (defined $id2 and $$offsetInfo{$id2}) { + unless ($$offsets[0]{NotRealPair} or (defined $id2 and $id2 == -1)) { + my $corr = $$offsets[0]{IsOffset} ? 'size' : 'offset'; + $et->Warn("$dirName:$$offsets[0]{Name} is missing the corresponding $corr tag") unless $minor; + } + next; + } + my $sizes = $$offsetInfo{$id2}; + delete $$offsetInfo{$id2}; + ($sizes, $offsets) = ($offsets, $sizes) if $$sizes[0]{IsOffset}; + my @offsets = split ' ', $$offsets[1]; + my @sizes = split ' ', $$sizes[1]; + if (@sizes != @offsets) { + $et->Warn(sprintf('Wrong number of values in %s 0x%.4x %s', + $dirName, $$offsets[0]{TagID}, $$offsets[0]{Name}), $minor); + next; + } + while (@offsets) { + my $start = pop @offsets; + my $end = $start + pop @sizes; + $et->WarnOnce("$dirName:$$offsets[0]{Name} is zero", $minor) if $start == 0; + $et->WarnOnce("$dirName:$$sizes[0]{Name} is zero", $minor) if $start == $end; + next unless $end > $fileSize; + if ($start >= $fileSize) { + if ($start == 0xffffffff) { + $et->Warn("$dirName:$$offsets[0]{Name} is invalid (0xffffffff)", $minor); + } else { + $et->Warn("$dirName:$$offsets[0]{Name} is past end of file", $minor); + } + } else { + $et->Warn("$dirName:$$offsets[0]{Name}+$$sizes[0]{Name} runs past end of file", $minor); + } + last; + } + } +} + +#------------------------------------------------------------------------------ +# Finish Validating tags +# Inputs: 0) ExifTool ref, 1) True to generate Validate tag +sub FinishValidate($$) +{ + local $_; + my ($et, $mkTag) = @_; + + my $fileType = $$et{FILE_TYPE} || ''; + $fileType = $$et{TIFF_TYPE} if $fileType eq 'TIFF'; + + if ($validValue{$fileType}) { + my ($grp, $tag, %val); + local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning; + foreach $grp (sort keys %{$validValue{$fileType}}) { + next unless $$et{FOUND_DIR}{$grp}; + my ($key, %val, %info, $minor, $verTag, $ver, $vstr); + my $verCheck = $verCheck{$grp}; + if ($verCheck) { + ($verTag) = keys %$verCheck; + ($ver = $$et{VALUE}{$verTag}) =~ tr/0-9//dc; # (remove non-digits) + undef $ver unless $ver =~ /^\d{4}$/; # (already warned if invalid version) + } + # get all tags in this group + foreach $key (sort keys %{$$et{VALUE}}) { + next unless $et->GetGroup($key, 1) eq $grp; + next if $$et{TAG_EXTRA}{$key} and $$et{TAG_EXTRA}{$key}{G3}; # ignore sub-documents + # fill in %val lookup with values based on tag ID + my $tag = $$et{TAG_INFO}{$key}{TagID}; + $val{$tag} = $$et{VALUE}{$key}; + # save TagInfo ref for later + $info{$tag} = $$et{TAG_INFO}{$key}; + next unless defined $ver; + my $chk = $$verCheck{$verTag}; + next if not defined $$chk{$tag} or $$chk{$tag} == 1 or $ver >= $$chk{$tag}; + if ($verTag eq 'GPSVersionID') { + ($vstr = $$chk{$tag}) =~ s/^(\d)(\d)(\d)/$1.$2.$3./; + } else { + $vstr = sprintf('%.4d', $$chk{$tag}); + } + $et->Warn(sprintf('%s tag 0x%.4x %s requires %s %s or higher', + $grp, $tag, $$et{TAG_INFO}{$key}{Name}, $verTag, $vstr)); + } + # make quick lookup for values based on tag ID + my $validValue = $validValue{$fileType}{$grp}; + foreach $tag (sort { $a <=> $b } keys %$validValue) { + my $val = $val{$tag}; + my ($pre, $post); + if (defined $$validValue{$tag}) { + #### eval ($val, %val) + my $result = eval $$validValue{$tag}; + if (not defined $result) { + $pre = 'Internal error validating'; + } elsif ($result eq '') { + $pre = defined $val ? 'Invalid value for' : "Missing required $fileType"; + } else { + next if $result eq '1'; + $pre = $result; + } + } else { + next unless defined $val; + $post = "is not allowed in $fileType"; + $minor = 1; + } + my $name; + if ($info{$tag}) { + $name = $info{$tag}{Name}; + } else { + my $table = 'Image::ExifTool::'.($grp eq 'GPS' ? 'GPS' : 'Exif').'::Main'; + my $tagInfo = GetTagTable($table)->{$tag}; + $tagInfo = $$tagInfo[0] if ref $tagInfo eq 'ARRAY'; + $name = $tagInfo ? $$tagInfo{Name} : '<unknown>'; + } + next if $$et{WrongFormat} and $$et{WrongFormat}{"$grp:$name"}; + $pre ? ($pre .= ' ') : ($pre = ''); + $post ? ($post = ' '.$post) : ($post = ''); + $et->Warn(sprintf('%s%s tag 0x%.4x %s%s', $pre, $grp, $tag, $name, $post), $minor); + } + } + } + # validate file extension + if ($$et{FILENAME} ne '') { + my $fileExt = ($$et{FILENAME} =~ /^.*\.([^.]+)$/s) ? uc($1) : ''; + my $extFileType = Image::ExifTool::GetFileType($fileExt); + if ($extFileType and $extFileType ne $fileType) { + my $normExt = $$et{VALUE}{FileTypeExtension}; + if ($normExt and $normExt ne $fileExt) { + my $lkup = $Image::ExifTool::fileTypeLookup{$fileExt}; + if (ref $lkup or $lkup ne $normExt) { + $et->Warn("File has wrong extension (should be $normExt, not $fileExt)"); + } + } + } + } + # issue warning if FastScan option used + $et->Warn('Validation incomplete because FastScan option used') if $et->Options('FastScan'); + + # generate Validate tag if necessary + if ($mkTag) { + my (@num, $key); + push @num, $$et{VALUE}{Error} ? ($$et{DUPL_TAG}{Error} || 0) + 1 : 0, + $$et{VALUE}{Warning} ? ($$et{DUPL_TAG}{Warning} || 0) + 1 : 0, 0; + for ($key = 'Warning'; ; ) { + ++$num[2] if $$et{VALUE}{$key} and $$et{VALUE}{$key} =~ /^\[minor\]/i; + $key = $et->NextTagKey($key) or last; + } + $et->FoundTag(Validate => "@num"); + } +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::Validate - Additional metadata validation + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains additional routines and definitions used when the +ExifTool Validate option is enabled. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 SEE ALSO + +L<Image::ExifTool(3pm)|Image::ExifTool>, +L<Image::ExifTool::TagNames/Extra Tags> + +=cut diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Vorbis.pm b/src/Image-ExifTool/lib/Image/ExifTool/Vorbis.pm index b9a07193..a11c71a9 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Vorbis.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/Vorbis.pm @@ -228,7 +228,7 @@ information from Ogg Vorbis audio headers. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WTV.pm b/src/Image-ExifTool/lib/Image/ExifTool/WTV.pm new file mode 100644 index 00000000..d6223c7a --- /dev/null +++ b/src/Image-ExifTool/lib/Image/ExifTool/WTV.pm @@ -0,0 +1,319 @@ +#------------------------------------------------------------------------------ +# File: WTV.pm +# +# Description: Read WTV meta information +# +# Revisions: 2018-05-30 - P. Harvey Created +# +# References: 1) https://wiki.multimedia.cx/index.php?title=WTV +#------------------------------------------------------------------------------ + +package Image::ExifTool::WTV; + +use strict; +use vars qw($VERSION); +use Image::ExifTool qw(:DataAccess :Utils); + +$VERSION = '1.00'; + +sub ProcessMetadata($$$); + +my %timeInfo = ( + # time looks like 100 ns intervals since 0:00 UTC Jan 1, 0001 (ref PH) + ValueConv => q{ # (719162 days from 0001:01:01 to 1970:01:01) + my $t = $val / 1e7 - 719162*24*3600; + return Image::ExifTool::ConvertUnixTime($t) . 'Z'; + }, + PrintConv => '$self->ConvertDateTime($val)', +); + +my %bool = ( PrintConv => { 0 => 'No', 1 => 'Yes' }, PrintConvColumns => 2 ); + +# WTV chunks +%Image::ExifTool::WTV::Main = ( + GROUPS => { 0 => 'WTV', 1 => 'WTV', 2 => 'Video' }, + NOTES => 'Tags found in Windows recorded TV (WTV) videos.', + # 'timeline.table.0.header.Events' (not decoded) + # 'timeline.table.0.entries.Events' (not decoded) + # 'timeline' (not decoded) + # 'table.0.header.legacy_attrib' (not decoded) + 'table.0.entries.legacy_attrib' => { + Name => 'Metdata', + SubDirectory => { TagTable => 'Image::ExifTool::WTV::Metadata' }, + }, + # 'table.0.redirector.legacy_attrib' (not decoded) + # 'table.0.header.time' (not decoded) + # 'table.0.entries.time' (not decoded) +); + +# Note: Many of these tags are similar to those found in Image::ExifTool::Microsoft::Xtra +# and Image::ExifTool::ASF::ExtendedDescr +%Image::ExifTool::WTV::Metadata = ( + GROUPS => { 0 => 'WTV', 1 => 'WTV', 2 => 'Video' }, + PROCESS_PROC => \&ProcessMetadata, + NOTES => 'ExifTool will extract any tag found, even if not in this table.', + VARS => { NO_ID => 1 }, + 'Duration' => { + Name => 'Duration', + ValueConv => '$val/1e7', + PrintConv => 'ConvertDuration($val)', + }, + 'Title' => { }, + 'WM/Genre' => 'Genre', + 'WM/Language' => 'Language', + 'WM/MediaClassPrimaryID' => 'MediaClassPrimaryID', + 'WM/MediaClassSecondaryID' => 'MediaClassSecondaryID', + 'WM/MediaCredits' => 'MediaCredits', + 'WM/MediaIsDelay' => { Name => 'MediaIsDelay', %bool }, + 'WM/MediaIsFinale' => { Name => 'MediaIsFinale', %bool }, + 'WM/MediaIsLive' => { Name => 'MediaIsLive', %bool }, + 'WM/MediaIsMovie' => { Name => 'MediaIsMovie', %bool }, + 'WM/MediaIsPremiere' => { Name => 'MediaIsPremiere', %bool }, + 'WM/MediaIsRepeat' => { Name => 'MediaIsRepeat', %bool }, + 'WM/MediaIsSAP' => { Name => 'MediaIsSAP', %bool }, + 'WM/MediaIsSport' => { Name => 'MediaIsSport', %bool }, + 'WM/MediaIsStereo' => { Name => 'MediaIsStereo', %bool, Groups => { 2 => 'Audio' } }, + 'WM/MediaIsSubtitled' => { Name => 'MediaIsSubtitled',%bool }, + 'WM/MediaIsTape' => { Name => 'MediaIsTape', %bool }, + 'WM/MediaNetworkAffiliation'=> 'MediaNetworkAffiliation', + 'WM/MediaOriginalBroadcastDateTime' => { + Name => 'MediaOriginalBroadcastDateTime', + Groups => { 2 => 'Time' }, + ValueConv => '$val =~ tr/-T/: /; $val', + PrintConv => '$self->ConvertDateTime($val)', + }, + 'WM/MediaOriginalChannel' => { Name => 'MediaOriginalChannel' }, + 'WM/MediaOriginalChannelSubNumber' => { Name => 'MediaOriginalChannelSubNumber' }, + 'WM/MediaOriginalRunTime' => { + Name => 'MediaOriginalRunTime', + ValueConv => '$val / 1e7', + PrintConv => 'ConvertDuration($val)', + }, + 'WM/MediaStationCallSign' => 'MediaStationCallSign', + 'WM/MediaStationName' => 'MediaStationName', + 'WM/MediaThumbAspectRatioX' => 'MediaThumbAspectRatioX', + 'WM/MediaThumbAspectRatioY' => 'MediaThumbAspectRatioY', + 'WM/MediaThumbHeight' => 'MediaThumbHeight', + 'WM/MediaThumbRatingAttributes' => { Name => 'MediaThumbRatingAttributes' }, + 'WM/MediaThumbRatingLevel' => 'MediaThumbRatingLevel', + 'WM/MediaThumbRatingSystem' => 'MediaThumbRatingSystem', + 'WM/MediaThumbRet' => 'MediaThumbRet', + 'WM/MediaThumbStride' => 'MediaThumbStride', + 'WM/MediaThumbTimeStamp' => { Name => 'MediaThumbTimeStamp', Notes => 'unknown units', Unknown => 1 }, + 'WM/MediaThumbWidth' => 'MediaThumbWidth', + 'WM/OriginalReleaseTime' => { + Name => 'OriginalReleaseTime', + Groups => { 2 => 'Time' }, + ValueConv => '$val=~tr/-T/: /; $val', + PrintConv => '$self->ConvertDateTime($val)', + }, + 'WM/ParentalRating' => 'ParentalRating', + 'WM/ParentalRatingReason' => 'ParentalRatingReason', + 'WM/Provider' => 'Provider', + 'WM/ProviderCopyright' => 'ProviderCopyright', + 'WM/ProviderRating' => 'ProviderRating', + 'WM/SubTitle' => 'Subtitle', + 'WM/SubTitleDescription' => 'SubtitleDescription', + 'WM/VideoClosedCaptioning' => { Name => 'VideoClosedCaptioning', %bool }, + 'WM/WMRVATSCContent' => { Name => 'ATSCContent', %bool }, + 'WM/WMRVActualSoftPostPadding' => 'ActualSoftPostPadding', + 'WM/WMRVActualSoftPrePadding' => 'ActualSoftPrePadding', + 'WM/WMRVBitrate' => { Name => 'Bitrate', Notes => 'unknown units', Unknown => 1 }, + 'WM/WMRVBrandingImageID' => 'BrandingImageID', + 'WM/WMRVBrandingName' => 'BrandingName', + 'WM/WMRVContentProtected' => { Name => 'ContentProtected', %bool }, + 'WM/WMRVContentProtectedPercent' => 'ContentProtectedPercent', + 'WM/WMRVDTVContent' => { Name => 'DTVContent', %bool }, + 'WM/WMRVEncodeTime' => { Name => 'EncodeTime', Groups => { 2 => 'Time' }, %timeInfo }, + 'WM/WMRVEndTime' => { Name => 'EndTime', Groups => { 2 => 'Time' }, %timeInfo }, + 'WM/WMRVExpirationDate' => { Name => 'ExpirationDate', Groups => { 2 => 'Time' }, %timeInfo, Unknown => 1 }, + 'WM/WMRVExpirationSpan' => { Name => 'ExpirationSpan', Notes => 'unknown units', Unknown => 1 }, + 'WM/WMRVHDContent' => { Name => 'HDContent', %bool }, + 'WM/WMRVHardPostPadding' => 'HardPostPadding', + 'WM/WMRVHardPrePadding' => 'HardPrePadding', + 'WM/WMRVInBandRatingAttributes' => 'InBandRatingAttributes', + 'WM/WMRVInBandRatingLevel' => 'InBandRatingLevel', + 'WM/WMRVInBandRatingSystem' => 'InBandRatingSystem', + 'WM/WMRVKeepUntil' => 'KeepUntil', + 'WM/WMRVOriginalSoftPostPadding'=> 'OriginalSoftPostPadding', + 'WM/WMRVOriginalSoftPrePadding' => 'OriginalSoftPrePadding', + 'WM/WMRVProgramID' => 'ProgramID', + 'WM/WMRVQuality' => 'Quality', + 'WM/WMRVRequestID' => 'RequestID', + 'WM/WMRVScheduleItemID' => 'ScheduleItemID', + 'WM/WMRVSeriesUID' => 'SeriesUID', + 'WM/WMRVServiceID' => 'ServiceID', + 'WM/WMRVWatched' => { Name => 'Watched', %bool }, +); + +#------------------------------------------------------------------------------ +# Read specified sectors from the file +# Inputs: 0) raf ref, 1) sector table ref, 2) offset in sector table, 3) sector size +# Returns: Data or undef on error +sub ReadSectors($$$$) +{ + my ($raf, $secPt, $pos, $secSize) = @_; + my ($data, $buff); + while ($pos <= length($$secPt) - 4) { + my $sec = Get32u($secPt, $pos); + return undef if $sec == 0xffff; # (just in case) + last unless $sec; # a null marks the end of the sector table + defined($data) ? ($data .= $buff) : ($data = $buff); + return undef unless $raf->Seek($sec*$secSize,0) and $raf->Read($buff,$secSize) == $secSize; + $pos += 4; + } + return defined($data) ? $data . $buff : $buff; +} + +#------------------------------------------------------------------------------ +# Process WTV metadata +# Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref +# Returns: 1 on success +sub ProcessMetadata($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + my $dataPt = $$dirInfo{DataPt}; + my $pos = 0; + my $end = length $$dataPt; + $et->VerboseDir('WTV Metadata', undef, $end); + while ($pos + 0x18 < $end) { + last unless substr($$dataPt,$pos,16) eq "\x5a\xfe\xd7\x6d\xc8\x1d\x8f\x4a\x99\x22\xfa\xb1\x1c\x38\x14\x53"; + my $fmt = Get32u($dataPt, $pos + 0x10); + my $len = Get32u($dataPt, $pos + 0x14); + my $str = ''; + $pos += 0x18; + for (;;) { + $pos + 2 > $end and $et->Warn('Corrupt metadata directory'), last; + my $ch = substr($$dataPt, $pos, 2); + $pos += 2; + last if $ch eq "\0\0"; + $str .= $ch; + } + last if $pos + $len > $end; + my $tag = $et->Decode($str, 'UCS2', undef, 'UTF8'); + my $dat = substr($$dataPt, $pos, $len); + # add tag if not already there + unless ($$tagTablePtr{$tag}) { + my $name = $tag; + $name =~ s{^(WTV_Metadata_)?WM/(WMRV)?}{}; + AddTagToTable($tagTablePtr, $tag, $name); + $et->VPrint(0, $$et{INDENT}, "[adding WTV:$name]\n"); + } + my $val; + if ($fmt==0 or $fmt==3) { # int32u or boolean32 + $val = Get32s(\$dat, 0); + } elsif ($fmt == 1) { # string + $val = $et->Decode($dat, 'UCS2'); + } elsif ($fmt == 6) { # GUID + $val = unpack('H*', $dat); + } elsif ($fmt == 4) { # int64u (date/time values use this) + $val = Get64u(\$dat, 0); + } else { + $val = $dat; + $fmt = "Unknown($fmt)"; + } + $et->HandleTag($tagTablePtr, $tag, $val, + Format => "format $fmt", + Size => length $dat, + ); + $et->VerboseDump(\$dat); + $pos += $len; + } +} + +#------------------------------------------------------------------------------ +# Extract information from a WTV video +# Inputs: 0) ExifTool object reference, 1) dirInfo reference +# Returns: 1 on success, 0 if this wasn't a valid WTV file +sub ProcessWTV($$) +{ + my ($et, $dirInfo) = @_; + my $raf = $$dirInfo{RAF}; + my $verbose = $et->Options('Verbose'); + my ($buff, $tagTablePtr, $pos, $len); + + # verify this is a valid WTV file + return 0 unless $raf->Read($buff, 0x60) == 0x60; + return 0 unless $buff =~ /^\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d/; + $et->SetFileType(); + SetByteOrder('II'); + # 0x28 - int32u: sector size? (=0x1000) (PH NC) + # 0x38 - int32u: sector number for main WTV directory (PH assume this is a sector table, NC) + # 0x58 - int32u: total number of sectors in file + my $secSize = Get32u(\$buff, 0x28); + # in case I'm wrong about this, constrain sector size to + # either 0x1000 (standard) or 0x100 (ExifTool test file) - PH + $secSize = 0x1000 unless $secSize == 0x1000 or $secSize == 0x100; + $buff = ReadSectors($raf, \$buff, 0x38, $secSize); # read the WTV directory + return 0 unless defined $buff; + $tagTablePtr = GetTagTable('Image::ExifTool::WTV::Main'); + # parse the WTV directory + $et->VerboseDir('WTV'); + for ($pos=0; $pos<length($buff)-0x28; $pos+=$len) { + unless (substr($buff,$pos,0x10) eq "\x92\xb7\x74\x91\x59\x70\x70\x44\x88\xdf\x06\x3b\x82\xcc\x21\x3d") { + $et->Warn("WTV directory wasn't at expected location") unless $pos; + last; + } + $len = Get32u(\$buff, $pos+0x10); + last if $pos + $len > length($buff); + my $n = Get32u(\$buff, $pos + 0x20); + 0x28 + $n*2 + 8 > $len and $et->Warn('WTV directory error'), last; + my $tag = $et->Decode(substr($buff,$pos+0x28,$n*2), 'UCS2', undef, 'UTF8'); + my $ptr = $pos + 0x28 + $n * 2; + my $flg = Get32u(\$buff, $ptr + 4); + if ($verbose) { + my $s = Get32s(\$buff, $ptr); + $s = sprintf('0x%x', $s) unless $s < 0; + $et->VPrint(1,"- Tag '${tag}' (sector=$s, flag=$flg)"); + } + next unless $$tagTablePtr{$tag} and ($flg == 0 or $flg == 1); + my $sec = substr($buff, $ptr, 4); + my $data = ReadSectors($raf, \$sec, 0, $secSize); + last unless defined $data; + # read sectors from table if necessary (flag=1 indicates a sector table) + $data = ReadSectors($raf, \$data, 0, $secSize) if $flg == 1; + defined $data or $et->Warn("Error fetching data for $tag"), next; + $et->HandleTag($tagTablePtr, $tag, $data); + } + return 1; +} + +1; # end + +__END__ + +=head1 NAME + +Image::ExifTool::WTV - Read WTV meta information + +=head1 SYNOPSIS + +This module is used by Image::ExifTool + +=head1 DESCRIPTION + +This module contains definitions required by Image::ExifTool to read WTV +(Windows recorded TV show) videos. + +=head1 AUTHOR + +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) + +This library is free software; you can redistribute it and/or modify it +under the same terms as Perl itself. + +=head1 REFERENCES + +=over 4 + +=item L<https://wiki.multimedia.cx/index.php?title=WTV> + +=back + +=head1 SEE ALSO + +L<Image::ExifTool::TagNames/WTV Tags>, +L<Image::ExifTool(3pm)|Image::ExifTool> + +=cut + diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WriteCanonRaw.pl b/src/Image-ExifTool/lib/Image/ExifTool/WriteCanonRaw.pl index 8cbcbb55..bfbb79b1 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WriteCanonRaw.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WriteCanonRaw.pl @@ -454,7 +454,7 @@ ($$$) # pad with original garbage in case it contained something useful $value .= substr($buff, $pt+2+8-$len, 8-$len); } elsif ($len > 8) { # this shouldn't happen - warn "Value too long! -- trucated\n"; + warn "Value too long! -- truncated\n"; $value = substr($value, 0, 8); } # create new directory entry @@ -521,7 +521,7 @@ ($$) if ($$et{DEL_GROUP}{MakerNotes}) { if ($type eq 'CCDR') { - $et->Error("Can't delete MakerNotes group in CRW file"); + $et->Error("Can't delete MakerNotes from CRW"); return 0; } else { ++$$et{CHANGED}; @@ -617,13 +617,13 @@ =head1 DESCRIPTION =head1 NOTES The CRW format is a pleasure to work with. All pointer offsets are relative -to the start of the data for each directory. If TIFF/EXIF had implemented -pointers in this way, it would be MUCH easier to read and write TIFF/JPEG -files, and would lead to far fewer problems with corrupted metadata. +to the start of the data for each directory. If EXIF/TIFF had implemented +pointers in this way, it would be MUCH easier to read and write TIFF and +JPEG files, and would lead to far fewer problems with corrupted metadata. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. @@ -632,6 +632,6 @@ =head1 SEE ALSO L<Image::ExifTool::CanonRaw(3pm)|Image::ExifTool::CanonRaw>, L<Image::ExifTool(3pm)|Image::ExifTool>, -L<http://owl.phy.queensu.ca/~phil/exiftool/canon_raw.html> +L<https://exiftool.org/canon_raw.html> =cut diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WriteExif.pl b/src/Image-ExifTool/lib/Image/ExifTool/WriteExif.pl index cc80d9da..29ee7579 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WriteExif.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WriteExif.pl @@ -38,7 +38,7 @@ package Image::ExifTool::Exif; 0x0128 => 2, # ResolutionUnit (inches) }, ExifIFD => { - 0x9000 => '0231', # ExifVersion + 0x9000 => '0232', # ExifVersion 0x9101 => "1 2 3 0",# ComponentsConfiguration 0xa000 => '0100', # FlashpixVersion 0xa001 => 0xffff, # ColorSpace (uncalibrated) @@ -367,9 +367,11 @@ ($$$;$) my $minor; $minor = 1 if $$et{DOC_NUM} or $$et{FILE_TYPE} ne 'TIFF'; unless (@bitsPerSample == $samplesPerPix) { - # (just a warning for this problem) - my $s = $samplesPerPix eq '1' ? '' : 's'; - $et->Warn("$dirName BitsPerSample should have $samplesPerPix value$s", $minor); + unless ($$et{FILE_TYPE} eq 'EPS' and @bitsPerSample == 1) { + # (just a warning for this problem) + my $s = $samplesPerPix eq '1' ? '' : 's'; + $et->Warn("$dirName BitsPerSample should have $samplesPerPix value$s", $minor); + } push @bitsPerSample, $bitsPerSample[0] while @bitsPerSample < $samplesPerPix; foreach (@bitsPerSample) { $et->WarnOnce("$dirName BitsPerSample values are different", $minor) if $_ ne $bitsPerSample[0]; @@ -412,7 +414,7 @@ ($$$) { my ($et, $errStr, $tagTablePtr) = @_; # MakerNote errors are minor by default - my $minor = ($$tagTablePtr{GROUPS}{0} eq 'MakerNotes'); + my $minor = ($$tagTablePtr{GROUPS}{0} eq 'MakerNotes' or $$et{FILE_TYPE} eq 'MOV'); if ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{MINOR_ERRORS}) { $et->Warn("$errStr. IFD dropped.") and return '' if $minor; $minor = 1; @@ -520,6 +522,9 @@ ($$$) my $name = $$dirInfo{Name}; $name = $dirName unless $name and $dirName eq 'MakerNotes' and $name !~ /^MakerNote/; + # save byte order of existing EXIF + $$et{SaveExifByteOrder} = GetByteOrder() if $dirName eq 'IFD0' or $dirName eq 'ExifIFD'; + # set encoding for strings $strEnc = $et->Options('CharsetEXIF') if $$tagTablePtr{GROUPS}{0} eq 'EXIF'; @@ -574,7 +579,7 @@ ($$$) # only account for nextIFD pointer if we are going to use it $len += 4 if $dataLen==$len+6 and ($$dirInfo{Multi} or $buff =~ /\0{4}$/); UpdateTiffEnd($et, $offset+$base+2+$len); - } elsif ($dirLen) { + } elsif ($dirLen and $dirStart + 4 >= $dataLen) { # error if we can't load IFD (unless we are creating # from scratch, in which case dirLen will be zero) my $str = $et->Options('IgnoreMinorErrors') ? 'Deleted bad' : 'Bad'; @@ -586,7 +591,10 @@ ($$$) $numEntries = Get16u($dataPt, $dirStart); $dirEnd = $dirStart + 2 + 12 * $numEntries; if ($dirEnd > $dataLen) { - return ExifErr($et, "Truncated $name directory", $tagTablePtr); + my $n = int(($dataLen - $dirStart - 2) / 12); + my $rtn = ExifErr($et, "Truncated $name directory", $tagTablePtr); + return undef unless $n and defined $rtn; + $numEntries = $n; # continue processing the entries we have } # sort entries if necessary (but not in maker notes IFDs) unless ($inMakerNotes) { @@ -1318,7 +1326,7 @@ ($$$) unless (defined $offsetData{$dataTag} or $dataTag eq 'LeicaTrailer') { # prefer tag from Composite table if it exists (otherwise # PreviewImage data would be taken from Extra tag) - my $compInfo = $Image::ExifTool::Composite{$dataTag}; + my $compInfo = Image::ExifTool::GetCompositeTagInfo($dataTag); $offsetData{$dataTag} = $et->GetNewValue($compInfo || $dataTag); my $err; if (defined $offsetData{$dataTag}) { @@ -1345,11 +1353,15 @@ ($$$) if ($$et{DEL_GROUP}{MakerNotes} and ($$et{DEL_GROUP}{MakerNotes} != 2 or $isNew <= 0)) { - if ($isNew <= 0) { - ++$$et{CHANGED}; - $verbose and print $out " Deleting MakerNotes\n"; + if ($et->IsRawType()) { + $et->WarnOnce("Can't delete MakerNotes from $$et{FileType}",1); + } else { + if ($isNew <= 0) { + ++$$et{CHANGED}; + $verbose and print $out " Deleting MakerNotes\n"; + } + next; } - next; } my $saveOrder = GetByteOrder(); if ($isNew >= 0 and defined $set{$newID}) { @@ -1765,7 +1777,7 @@ ($$$) # - I'm going out of my way here to preserve data which is # invalidated anyway by our edits my $odd; - my $oddInfo = $Image::ExifTool::Composite{OriginalDecisionData}; + my $oddInfo = Image::ExifTool::GetCompositeTagInfo('OriginalDecisionData'); if ($oddInfo and $$et{NEW_VALUE}{$oddInfo}) { $odd = $et->GetNewValue($dataTag); if ($verbose > 1) { @@ -2550,7 +2562,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WriteIPTC.pl b/src/Image-ExifTool/lib/Image/ExifTool/WriteIPTC.pl index e740bc3e..f8930b31 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WriteIPTC.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WriteIPTC.pl @@ -105,7 +105,7 @@ ($$$) my $format = $$tagInfo{Format} || $$tagInfo{Table}{FORMAT} || ''; if ($format =~ /^int(\d+)/) { my $bytes = int(($1 || 0) / 8); - if ($bytes ne 1 and $bytes ne 2 and $bytes ne 4) { + if ($bytes != 1 and $bytes != 2 and $bytes != 4) { return "Can't write $bytes-byte integer"; } my $val = $$valPtr; @@ -191,7 +191,7 @@ ($$$$$;$) my $len = length $$valPtr; $maxlen or $maxlen = $minlen; if ($len < $minlen) { - if ($et->Warn("String to short for IPTC:$$tagInfo{Name} (padded)", 2)) { + if ($et->Warn("String too short for IPTC:$$tagInfo{Name} (padded)", 2)) { $$valPtr .= ' ' x ($minlen - $len); } } elsif ($len > $maxlen) { @@ -215,7 +215,7 @@ ($$$$$;$) sub IptcDate($) { my $val = shift; - unless ($val =~ s/^.*(\d{4}):?(\d{2}):?(\d{2}).*/$1$2$3/s) { + unless ($val =~ s{^.*(\d{4})[-:/.]?(\d{2})[-:/.]?(\d{2}).*}{$1$2$3}s) { warn "Invalid date format (use YYYY:mm:dd)\n"; undef $val; } @@ -242,7 +242,7 @@ ($) if ($date and $date =~ /^(\d{4}):(\d{2}):(\d{2})\s*$/ and eval { require Time::Local }) { # we were given a date too, so determine the local timezone # offset at the specified date/time - my @d = ($3,$2-1,$1-1900); + my @d = ($3,$2-1,$1); $val =~ /(\d{2})(\d{2})(\d{2})/; @tm = ($3,$2,$1,@d); $time = Image::ExifTool::TimeLocal(@tm); @@ -715,7 +715,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WritePDF.pl b/src/Image-ExifTool/lib/Image/ExifTool/WritePDF.pl index 4d67d99f..47699e35 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WritePDF.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WritePDF.pl @@ -298,15 +298,13 @@ ($$) # not a valid PDF file unless we got a version number # (note: can't just check $$info{PDFVersion} due to possibility of XMP-pdf:PDFVersion) my $vers = $newTool->GetInfo('PDF:PDFVersion'); - ($pdfVer) = values %$vers; + # take highest version number if multiple versions in an incremental save + ($pdfVer) = sort { $b <=> $a } values %$vers; $pdfVer or $et->Error('Missing PDF:PDFVersion'), return 0; # check version number if ($pdfVer > 1.7) { - if ($pdfVer >= 2.0) { - $et->Error("Can't yet write PDF version $pdfVer"); # (future major version changes) - return 1; - } - $et->Warn("ExifTool is untested with PDF version $pdfVer files", 1); + $et->Warn("The PDF $pdfVer specification is not freely available", 1); + # (so writing by ExifTool is based on trial and error) } # fail if we had any serious errors while extracting information if ($capture{Error} or $$info{Error}) { @@ -751,7 +749,7 @@ =head1 NOTES =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WritePNG.pl b/src/Image-ExifTool/lib/Image/ExifTool/WritePNG.pl index 0e89331b..743477cd 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WritePNG.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WritePNG.pl @@ -13,7 +13,7 @@ package Image::ExifTool::PNG; #------------------------------------------------------------------------------ # Calculate CRC or update running CRC (ref 1) -# Inputs: 0) data reference, 1) running crc to update (undef intially) +# Inputs: 0) data reference, 1) running crc to update (undef initially) # 2) data position (undef for 0), 3) data length (undef for all data), # Returns: updated CRC my @crcTable; @@ -80,9 +80,9 @@ ($$$;$) } else { $chunk = $rawType; if ($rawType eq $stdCase{zxif}) { - $prefix = "\0" . pack('N', length $$dataPt); + $prefix = "\0" . pack('N', length $$dataPt); # (proposed compressed EXIF) } else { - $prefix = ''; + $prefix = ''; # standard EXIF } } if ($deflate) { @@ -116,7 +116,7 @@ ($$$;$) } #------------------------------------------------------------------------------ -# Add iCCP to the PNG image if necessary (must come before PLTE and IDAT) +# Add iCCP chunk to the PNG image if necessary (must come before PLTE and IDAT) # Inputs: 0) ExifTool object ref, 1) output file or scalar ref # Returns: true on success sub Add_iCCP($$) @@ -130,7 +130,6 @@ ($$) if (defined $buff and length $buff and WriteProfile($outfile, 'icm', \$buff)) { $et->VPrint(0, "Created ICC profile\n"); delete $$et{ADD_DIRS}{ICC_Profile}; # don't add it again - $$et{PNGDoneDir}{ICC_Profile} = 2; } } return 1; @@ -144,29 +143,15 @@ ($$) sub DoneDir($$$;$) { my ($et, $dir, $outBuff, $nonStandard) = @_; - $dir = 'IFD0' if $dir eq 'EXIF'; + my $saveDir = $dir; + $dir = 'EXIF' if $dir eq 'IFD0'; # don't add this directory again unless this is in a non-standard location - delete $$et{ADD_DIRS}{$dir} unless $nonStandard; - # handle problem with duplicate XMP when using PNGEarlyXMP option - return unless $dir eq 'XMP' and defined $$outBuff and length $$outBuff; - if ($nonStandard and $$et{DEL_GROUP}{$dir}) { + if (not $nonStandard) { + delete $$et{ADD_DIRS}{$dir}; + delete $$et{ADD_DIRS}{IFD0} if $dir eq 'EXIF'; + } elsif ($$et{DEL_GROUP}{$dir} or $$et{DEL_GROUP}{$saveDir}) { $et->VPrint(0," Deleting non-standard $dir\n"); $$outBuff = ''; - } elsif (not $$et{PNGDoneDir}{$dir}) { - $$et{PNGDoneDir}{$dir} = 1; # set flag indicating the directory exists - } elsif ($$et{OPTIONS}{PNGEarlyXMP}) { - if ($$et{PNGDoneDir}{$dir} == 2) { - if ($$et{OPTIONS}{IgnoreMinorErrors}) { - $et->Warn("Deleted existing $dir"); - } else { - $et->Error("Duplicate $dir created. Ignore to delete existing $dir", 1); - return; - } - } elsif ($et->Warn("Duplicate $dir. Ignore to delete", 2)) { - return; # warning not ignored: don't delete the duplicate - } - $et->VPrint(0," Deleting duplicate $dir\n"); - $$outBuff = ''; } } @@ -238,15 +223,16 @@ ($$$$$) #------------------------------------------------------------------------------ # Add any outstanding new chunks to the PNG image # Inputs: 0) ExifTool object ref, 1) output file or scalar ref -# 2-N) dirs to add (empty to add all, including PNG tags) +# 2-N) dirs to add (empty to add all except EXIF 'IFD0', including PNG tags) # Returns: true on success sub AddChunks($$;@) { my ($et, $outfile, @add) = @_; - my ($addTags, $tag, $dir, $err, $tagTablePtr); + my ($addTags, $tag, $dir, $err, $tagTablePtr, $specified); if (@add) { $addTags = { }; # don't add any PNG tags + $specified = 1; } else { $addTags = $$et{ADD_PNG}; # add all PNG tags... delete $$et{ADD_PNG}; # ...once @@ -274,7 +260,6 @@ ($$;@) my $cbuf = pack('N', CalculateCRC(\$data, undef)); Write($outfile, $hdr, $data, $cbuf) or $err = 1; $et->VerboseValue("+ PNG:$$tagInfo{Name}", $val); - $$et{PNGDoneTag}{$tag} = 1; # set flag indicating this tag was added ++$$et{CHANGED}; } } @@ -287,6 +272,7 @@ ($$;@) DirName => $dir, ); if ($dir eq 'IFD0') { + next unless $specified; # wait until specifically asked to write EXIF 'IFD0' my $chunk = $stdCase{exif}; # (zxIf was not adopted) #if ($et->Options('Compress')) { @@ -322,7 +308,7 @@ ($$;@) Write($outfile, $hdr, $buff, $cbuf) or $err = 1; } } elsif ($dir eq 'IPTC') { - $et->Warn('Creating non-standard EXIF in PNG', 1); + $et->Warn('Creating non-standard IPTC in PNG', 1); $et->VPrint(0, "Creating IPTC profile:\n"); # write new IPTC data (stored in a Photoshop directory) $dirInfo{DirName} = 'Photoshop'; @@ -341,7 +327,7 @@ ($$;@) $et->Warn('Wrote ICC as a raw profile (no Compress::Zlib)'); } } elsif ($dir eq 'PNG-pHYs') { - $et->VPrint(0, "Creating pHYs chunk:\n"); + $et->VPrint(0, "Creating pHYs chunk (default 2834 pixels per meter):\n"); $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::PNG::PhysicalPixel'); my $blank = "\0\0\x0b\x12\0\0\x0b\x12\x01"; # 2834 pixels per meter (72 dpi) $dirInfo{DataPt} = \$blank; @@ -356,8 +342,6 @@ ($$;@) next; } delete $$et{ADD_DIRS}{$dir}; # don't add again - # keep track of the directories that we added - $$et{PNGDoneDir}{$dir} = 2 if defined $buff and length $buff; } return not $err; } @@ -395,7 +379,7 @@ =head1 NOTES =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WritePhotoshop.pl b/src/Image-ExifTool/lib/Image/ExifTool/WritePhotoshop.pl index 2623709e..fcaaf227 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WritePhotoshop.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WritePhotoshop.pl @@ -138,6 +138,10 @@ ($$$) unless ($tagInfo) { # process subdirectory anyway if writable (except EXIF to avoid recursion) # --> this allows IPTC to be processed if found here in TIFF images + # (note that I have seen a case of XMP in PSD-EXIFInfo-IFD0, and the EXIF + # exclusion means that this won't be written unless an EXIF tag is + # specifically edited, see forum10768 -- maybe this should be changed + # if it happens again) my $tmpInfo = $et->GetTagInfo($tagTablePtr, $tagID); if ($tmpInfo and $$tmpInfo{SubDirectory} and $tmpInfo->{SubDirectory}->{TagTable} ne 'Image::ExifTool::Exif::Main') @@ -253,7 +257,7 @@ =head1 NOTES =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WritePostScript.pl b/src/Image-ExifTool/lib/Image/ExifTool/WritePostScript.pl index 6bc96fbc..2815a0ab 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WritePostScript.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WritePostScript.pl @@ -156,11 +156,11 @@ ($$$$$) # it would be really difficult to delete the XMP, # so instead we write a blank XMP record $val = <<EMPTY_XMP; -<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?> +<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'?> <x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='Image::ExifTool $Image::ExifTool::VERSION'> </x:xmpmeta> EMPTY_XMP - $val .= ((' ' x 100) . "\n") x 24 unless $et->Options('Compact'); + $val .= ((' ' x 100) . "\n") x 24 unless $$et{OPTIONS}{Compact}{NoPadding}; $val .= q{<?xpacket end='w'?>}; $dataPt = \$val; $len = length $val; @@ -302,54 +302,6 @@ ($$$) return $success; } -#------------------------------------------------------------------------------ -# check to be sure we haven't read past end of PS data in DOS-style file -# Inputs: 0) RAF ref, 1) pointer to end of PS, 2) data -# - modifies data and sets RAF to EOF if end of PS is reached -sub CheckPSEnd($$$) -{ - my $pos = $_[0]->Tell(); - if ($pos >= $_[1]) { - $_[0]->Seek(0, 2); # seek to end of file so we can't read any more - $_[2] = substr($_[2], 0, length($_[2]) - $pos + $_[1]) if $pos > $_[1]; - } -} - -#------------------------------------------------------------------------------ -# Split into lines ending in any CR, LF or CR+LF combination -# (this is annoying, and could be avoided if EPS files didn't mix linefeeds!) -# Inputs: 0) data pointer, 1) reference to lines array -# Notes: Updates data to contain next line and fills list with remaining lines -sub SplitLine($$) -{ - my ($dataPt, $lines) = @_; - for (;;) { - my $endl; - # find the position of the first LF (\x0a) - $endl = pos($$dataPt), pos($$dataPt) = 0 if $$dataPt =~ /\x0a/g; - if ($$dataPt =~ /\x0d/g) { # find the first CR (\x0d) - if (defined $endl) { - # (remember, CR+LF is a DOS newline...) - $endl = pos($$dataPt) if pos($$dataPt) < $endl - 1; - } else { - $endl = pos($$dataPt); - } - } elsif (not defined $endl) { - push @$lines, $$dataPt; - last; - } - # split into separate lines - if (length $$dataPt == $endl) { - push @$lines, $$dataPt; - last; - } else { - push @$lines, substr($$dataPt, 0, $endl); - $$dataPt = substr($$dataPt, $endl); - } - } - $$dataPt = shift @$lines; # set $$dataPt to first line -} - #------------------------------------------------------------------------------ # Write PS file # Inputs: 0) ExifTool object reference, 1) source dirInfo reference @@ -365,7 +317,7 @@ ($$) my $verbose = $et->Options('Verbose'); my $out = $et->Options('TextOut'); my ($data, $buff, %flags, $err, $mode, $endToken); - my ($dos, $psStart, $psEnd, $psNewStart, $xmpHint); + my ($dos, $psStart, $psNewStart, $xmpHint, @lines); $raf->Read($data, 4) == 4 or return 0; return 0 unless $data =~ /^(%!PS|%!Ad|\xc5\xd0\xd3\xc6)/; @@ -390,7 +342,7 @@ ($$) $et->Error('Invalid PS header'); return 1; } - $psEnd = $psStart + Get32u(\$dos, 8); + $$raf{PSEnd} = $psStart + Get32u(\$dos, 8); my $base = Get32u(\$dos, 20); Set16u(0xffff, \$dos, 28); # ignore checksum if ($base) { @@ -465,34 +417,9 @@ ($$) $xmpHint = 0 if $$et{DEL_GROUP}{XMP}; $$newTags{XMP_HINT} = $xmpHint if $xmpHint; # add special tag to newTags list - my (@lines, $changedNL); - my $altnl = ($/ eq "\x0d") ? "\x0a" : "\x0d"; - for (;;) { - if (@lines) { - $data = shift @lines; - } else { - $raf->ReadLine($data) or last; - $dos and CheckPSEnd($raf, $psEnd, $data); - # split line if it contains other newline sequences - if ($data =~ /$altnl/) { - if (length($data) > 500000 and IsPC()) { - # patch for Windows memory problem - unless ($changedNL) { - $changedNL = 1; - my $t = $/; - $/ = $altnl; - $altnl = $t; - $raf->Seek(-length($data), 1); - next; - } - } else { - # split into separate lines - SplitLine(\$data, \@lines); - } - } - } - undef $changedNL; + @lines or GetNextLine($raf, \@lines) or last; + $data = shift @lines; if ($endToken) { # look for end token if ($data =~ m/^$endToken\s*$/is) { @@ -641,7 +568,7 @@ ($$) $data = shift @lines; } else { $raf->ReadLine($data) or undef($data), last; - $dos and CheckPSEnd($raf, $psEnd, $data); + $dos and CheckPSEnd($raf, \$data); if ($data =~ /[\x0d\x0a]%%EOF\b/g) { # split data before "%%EOF" # (necessary if data contains other newline sequences) @@ -659,7 +586,7 @@ ($$) Write($outfile, $data) or $err = 1; Write($outfile, @lines) or $err = 1 if @lines; while ($raf->Read($data, 65536)) { - $dos and CheckPSEnd($raf, $psEnd, $data); + $dos and CheckPSEnd($raf, \$data); Write($outfile, $data) or $err = 1; } } @@ -759,7 +686,7 @@ =head1 ACKNOWLEDGEMENTS =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WriteQuickTime.pl b/src/Image-ExifTool/lib/Image/ExifTool/WriteQuickTime.pl index a52f1f79..4f8b75d8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WriteQuickTime.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WriteQuickTime.pl @@ -9,33 +9,718 @@ package Image::ExifTool::QuickTime; use strict; -# map for adding directories to QuickTime-format files +# maps for adding metadata to various QuickTime-based file types my %movMap = ( - # MOV (no 'ftyp', or 'ftyp'='qt ') -> 'moov'-'udta'-'XMP_' - XMP => 'UserData', - UserData => 'Movie', - Movie => 'MOV', + # MOV (no 'ftyp', or 'ftyp'='qt ') -> XMP in 'moov'-'udta'-'XMP_' + QuickTime => 'ItemList', # (default location for QuickTime tags) + ItemList => 'Meta', # MOV-Movie-UserData-Meta-ItemList + Keys => 'Movie', # MOV-Movie-Meta-Keys !! (hack due to different Meta location) + Meta => 'UserData', + XMP => 'UserData', # MOV-Movie-UserData-XMP + UserData => 'Movie', # MOV-Movie-UserData + Movie => 'MOV', + GSpherical => 'SphericalVideoXML', # MOV-Movie-Track-SphericalVideoXML + SphericalVideoXML => 'Track', # (video track specifically, don't create if it doesn't exist) + Track => 'Movie', ); my %mp4Map = ( - # MP4 ('ftyp' compatible brand 'mp41', 'mp42' or 'f4v ') -> top level 'uuid' - XMP => 'MOV', + # MP4 ('ftyp' compatible brand 'mp41', 'mp42' or 'f4v ') -> XMP at top level + QuickTime => 'ItemList', # (default location for QuickTime tags) + ItemList => 'Meta', # MOV-Movie-UserData-Meta-ItemList + Keys => 'Movie', # MOV-Movie-Meta-Keys !! (hack due to different Meta location) + Meta => 'UserData', + UserData => 'Movie', # MOV-Movie-UserData + Movie => 'MOV', + XMP => 'MOV', # MOV-XMP + GSpherical => 'SphericalVideoXML', # MOV-Movie-Track-SphericalVideoXML + SphericalVideoXML => 'Track', # (video track specifically, don't create if it doesn't exist) + Track => 'Movie', +); +my %heicMap = ( + # HEIC/HEIF/AVIF ('ftyp' compatible brand 'heic','mif1','avif') -> XMP/EXIF in top level 'meta' + Meta => 'MOV', + ItemInformation => 'Meta', + ItemPropertyContainer => 'Meta', + XMP => 'ItemInformation', + EXIF => 'ItemInformation', + ICC_Profile => 'ItemPropertyContainer', + IFD0 => 'EXIF', + IFD1 => 'IFD0', + ExifIFD => 'IFD0', + GPS => 'IFD0', + SubIFD => 'IFD0', + GlobParamIFD => 'IFD0', + PrintIM => 'IFD0', + InteropIFD => 'ExifIFD', + MakerNotes => 'ExifIFD', +); +my %cr3Map = ( + # CR3 ('ftyp' compatible brand 'crx ') -> XMP at top level + Movie => 'MOV', + XMP => 'MOV', + 'UUID-Canon'=>'Movie', + ExifIFD => 'UUID-Canon', + IFD0 => 'UUID-Canon', + GPS => 'UUID-Canon', + #MakerNoteCanon => 'UUID-Canon', # (doesn't yet work -- goes into ExifIFD instead) + 'UUID-Canon2' => 'MOV', + CanonVRD => 'UUID-Canon2', ); my %dirMap = ( - MOV => \%movMap, - MP4 => \%mp4Map, - HEIC => { }, # can't currently write XMP to HEIC files + MOV => \%movMap, + MP4 => \%mp4Map, + CR3 => \%cr3Map, + HEIC => \%heicMap, +); + +# convert ExifTool Format to QuickTime type +my %qtFormat = ( + 'undef' => 0x00, string => 0x01, + int8s => 0x15, int16s => 0x15, int32s => 0x15, + int8u => 0x16, int16u => 0x16, int32u => 0x16, + float => 0x17, double => 0x18, +); +my $undLang = 0x55c4; # numeric code for default ('und') language + +my $maxReadLen = 100000000; # maximum size of atom to read into memory (100 MB) + +# boxes that may exist in an "empty" Meta box: +my %emptyMeta = ( + hdlr => 'Handler', 'keys' => 'Keys', lang => 'Language', ctry => 'Country', free => 'Free', ); +# lookup for CTBO ID number based on uuid for Canon CR3 files +my %ctboID = ( + "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac" => 1, # XMP + "\xea\xf4\x2b\x5e\x1c\x98\x4b\x88\xb9\xfb\xb7\xdc\x40\x6e\x4d\x16" => 2, # PreviewImage + # ID 3 is used for 'mdat' atom (not a uuid) +); + +# mark UserData tags that don't have ItemList counterparts as Preferred +# - and set Preferred to 0 for any Avoid-ed tag +# - also, for now, set Writable to 0 for any tag with a RawConv and no RawConvInv +{ + my $itemList = \%Image::ExifTool::QuickTime::ItemList; + my $userData = \%Image::ExifTool::QuickTime::UserData; + my (%pref, $tag); + foreach $tag (TagTableKeys($itemList)) { + my $tagInfo = $$itemList{$tag}; + if (ref $tagInfo ne 'HASH') { + next if ref $tagInfo; + $tagInfo = $$itemList{$tag} = { Name => $tagInfo }; + } else { + $$tagInfo{Writable} = 0 if $$tagInfo{RawConv} and not $$tagInfo{RawConvInv}; + $$tagInfo{Avoid} and $$tagInfo{Preferred} = 0, next; + next if defined $$tagInfo{Preferred} and not $$tagInfo{Preferred}; + } + $pref{$$tagInfo{Name}} = 1; + } + foreach $tag (TagTableKeys($userData)) { + my $tagInfo = $$userData{$tag}; + if (ref $tagInfo ne 'HASH') { + next if ref $tagInfo; + $tagInfo = $$userData{$tag} = { Name => $tagInfo }; + } else { + $$tagInfo{Writable} = 0 if $$tagInfo{RawConv} and not $$tagInfo{RawConvInv}; + $$tagInfo{Avoid} and $$tagInfo{Preferred} = 0, next; + next if defined $$tagInfo{Preferred} or $pref{$$tagInfo{Name}}; + } + $$tagInfo{Preferred} = 1; + } +} + +#------------------------------------------------------------------------------ +# Format GPSCoordinates for writing +# Inputs: 0) PrintConv value +# Returns: ValueConv value +sub PrintInvGPSCoordinates($) +{ + my ($val, $et) = @_; + my @v = split /, */, $val; + if (@v == 2 or @v == 3) { + my $below = ($v[2] and $v[2] =~ /below/i); + $v[0] = Image::ExifTool::GPS::ToDegrees($v[0], 1); + $v[1] = Image::ExifTool::GPS::ToDegrees($v[1], 1); + $v[2] = Image::ExifTool::ToFloat($v[2]) * ($below ? -1 : 1) if @v == 3; + return "@v"; + } + return $val if $val =~ /^([-+]\d+(\.\d*)?){2,3}(CRS.*)?$/; # already in ISO6709 format? + return undef; +} + #------------------------------------------------------------------------------ -# Check to see if path is current -# Inputs: 0) ExifTool object ref, 1) directory name -# Returns: true if current path is the root of the specified directory -sub IsCurPath($$) +# Convert GPS coordinates back to ISO6709 format +# Inputs: 0) ValueConv value +# Returns: ISO6709 coordinates +sub ConvInvISO6709($) { local $_; - my ($et, $dir) = @_; - $dir = $$et{DirMap}{$dir} and $dir eq $_ or last foreach reverse @{$$et{PATH}}; - return($dir and $dir eq 'MOV'); + my $val = shift; + my @a = split ' ', $val; + if (@a == 2 or @a == 3) { + # latitude must have 2 digits before the decimal, and longitude 3, + # and all values must start with a "+" or "-" + my @fmt = ('%s%02d','%s%03d','%s%d'); + foreach (@a) { + return undef unless Image::ExifTool::IsFloat($_); + $_ =~ s/^([-+]?)(\d+)/sprintf(shift(@fmt), $1 || '+', $2)/e; + } + return join '', @a; + } + return $val if $val =~ /^([-+]\d+(\.\d*)?){2,3}(CRS.*)?$/; # already in ISO6709 format? + return undef; +} + +#------------------------------------------------------------------------------ +# Handle offsets in iloc (ItemLocation) atom when writing (ref ISO 14496-12:2015 pg.79) +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) data ref, 3) output buffer ref +# Returns: true on success +# Notes: see also ParseItemLocation() in QuickTime.pm +# (variable names with underlines correspond to names in ISO 14496-12) +sub Handle_iloc($$$$) +{ + my ($et, $dirInfo, $dataPt, $outfile) = @_; + my ($i, $j, $num, $pos, $id); + + my $off = $$dirInfo{ChunkOffset}; + my $len = length $$dataPt; + return 0 if $len < 8; + my $ver = Get8u($dataPt, 0); + my $siz = Get16u($dataPt, 4); + my $noff = ($siz >> 12); + my $nlen = ($siz >> 8) & 0x0f; + my $nbas = ($siz >> 4) & 0x0f; + my $nind = $siz & 0x0f; + my %ok = ( 0 => 1, 4 => 1, 8 => 8 ); + return 0 unless $ok{$noff} and $ok{$nlen} and $ok{$nbas} and $ok{$nind}; + # piggy-back on existing code to fix up stco/co64 4/8-byte offsets + my $tag = $noff == 4 ? 'stco_iloc' : 'co64_iloc'; + if ($ver < 2) { + $num = Get16u($dataPt, 6); + $pos = 8; + } else { + return 0 if $len < 10; + $num = Get32u($dataPt, 6); + $pos = 10; + } + for ($i=0; $i<$num; ++$i) { + if ($ver < 2) { + return 0 if $pos + 2 > $len; + $id = Get16u($dataPt, $pos); + $pos += 2; + } else { + return 0 if $pos + 4 > $len; + $id = Get32u($dataPt, $pos); + $pos += 4; + } + my ($constOff, @offBase, @offItem, $minOffset); + if ($ver == 1 or $ver == 2) { + return 0 if $pos + 2 > $len; + # offsets are absolute only if ConstructionMethod is 0, otherwise + # the relative offsets are constant as far as we are concerned + $constOff = Get16u($dataPt, $pos) & 0x0f; + $pos += 2; + } + return 0 if $pos + 2 > $len; + my $drefIdx = Get16u($dataPt, $pos); + if ($drefIdx) { + if ($$et{QtDataRef} and $$et{QtDataRef}[$drefIdx - 1]) { + my $dref = $$et{QtDataRef}[$drefIdx - 1]; + # these offsets are constant unless the data is in this file + $constOff = 1 unless $$dref[1] == 1 and $$dref[0] ne 'rsrc'; + } else { + $et->Error("No data reference for iloc entry $i"); + return 0; + } + } + $pos += 2; + # get base offset and save its location if in this file + my $base_offset = GetVarInt($dataPt, $pos, $nbas); + if ($base_offset and not $constOff) { + my $tg = ($nbas == 4 ? 'stco' : 'co64') . '_iloc'; + push @offBase, [ $tg, length($$outfile) + 8 + $pos - $nbas, $nbas, 0, $id ]; + } + return 0 if $pos + 2 > $len; + my $ext_num = Get16u($dataPt, $pos); + $pos += 2; + my $listStartPos = $pos; + # run through the item list to get offset locations and the minimum offset in this file + for ($j=0; $j<$ext_num; ++$j) { + $pos += $nind if $ver == 1 or $ver == 2; + my $extent_offset = GetVarInt($dataPt, $pos, $noff); + return 0 unless defined $extent_offset; + unless ($constOff) { + push @offItem, [ $tag, length($$outfile) + 8 + $pos - $noff, $noff, 0, $id ] if $noff; + $minOffset = $extent_offset if not defined $minOffset or $minOffset > $extent_offset; + } + return 0 if $pos + $nlen > length $$dataPt; + $pos += $nlen; + } + # decide whether to fix up the base offset or individual item offsets + # (adjust the one that is larger) + if (defined $minOffset and $minOffset > $base_offset) { + $$_[3] = $base_offset foreach @offItem; + push @$off, @offItem; + } else { + $$_[3] = $minOffset foreach @offBase; + push @$off, @offBase; + } + } + return 1; +} + +#------------------------------------------------------------------------------ +# Get localized version of tagInfo hash +# Inputs: 0) tagInfo hash ref, 1) language code (eg. "fra-FR") +# Returns: new tagInfo hash ref, or undef if invalid or no language code +sub GetLangInfo($$) +{ + my ($tagInfo, $langCode) = @_; + return undef unless $langCode; + # only allow alternate language tags in lang-alt lists + my $writable = $$tagInfo{Writable}; + $writable = $$tagInfo{Table}{WRITABLE} unless defined $writable; + return undef unless $writable; + $langCode =~ tr/_/-/; # RFC 3066 specifies '-' as a separator + my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $langCode); + return $langInfo; +} + +#------------------------------------------------------------------------------ +# validate raw values for writing +# Inputs: 0) ExifTool ref, 1) tagInfo hash ref, 2) raw value ref +# Returns: error string or undef (and possibly changes value) on success +sub CheckQTValue($$$) +{ + my ($et, $tagInfo, $valPtr) = @_; + my $format = $$tagInfo{Format} || $$tagInfo{Table}{FORMAT}; + return undef unless $format; + return Image::ExifTool::CheckValue($valPtr, $format, $$tagInfo{Count}); +} + +#------------------------------------------------------------------------------ +# Format QuickTime value for writing +# Inputs: 0) ExifTool ref, 1) value ref, 2) Format (or undef) +# Returns: Flags for QT data type, and reformats value as required +sub FormatQTValue($$;$) +{ + my ($et, $valPt, $format) = @_; + my $flags; + if ($format and $format ne 'string') { + $$valPt = WriteValue($$valPt, $format); + $flags = $qtFormat{$format} || 0; + } elsif ($$valPt =~ /^\xff\xd8\xff/) { + $flags = 0x0d; # JPG + } elsif ($$valPt =~ /^(\x89P|\x8aM|\x8bJ)NG\r\n\x1a\n/) { + $flags = 0x0e; # PNG + } elsif ($$valPt =~ /^BM.{15}\0/s) { + $flags = 0x1b; # BMP + } else { + $flags = 0x01; # UTF8 + $$valPt = $et->Encode($$valPt, 'UTF8'); + } + return $flags; +} + +#------------------------------------------------------------------------------ +# Set variable-length integer (used by WriteItemInfo) +# Inputs: 0) value, 1) integer size in bytes (0, 4 or 8), +# Returns: packed integer +sub SetVarInt($$) +{ + my ($val, $n) = @_; + if ($n == 4) { + return Set32u($val); + } elsif ($n == 8) { + return Set64u($val); + } + return ''; +} + +#------------------------------------------------------------------------------ +# Write Meta Keys to add/delete entries as necessary ('mdta' handler) (ref PH) +# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref +# Returns: updated keys box data +sub WriteKeys($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + $et or return 1; # allow dummy access to autoload this package + my $dataPt = $$dirInfo{DataPt}; + my $dirLen = length $$dataPt; + my $outfile = $$dirInfo{OutFile}; + my ($tag, %done, %remap, %info, %add, $i); + + $dirLen < 8 and $et->Warn('Short Keys box'), $dirLen = 8, $$dataPt = "\0" x 8; + if ($$et{DEL_GROUP}{Keys}) { + $dirLen = 8; # delete all existing keys + # deleted keys are identified by a zero entry in the Remap lookup + my $n = Get32u($dataPt, 4); + for ($i=1; $i<=$n; ++$i) { $remap{$i} = 0; } + $et->VPrint(0, " [deleting $n Keys entr".($n==1 ? 'y' : 'ies')."]\n"); + ++$$et{CHANGED}; + } + my $pos = 8; + my $newTags = $et->GetNewTagInfoHash($tagTablePtr); + my $newData = substr($$dataPt, 0, $pos); + + my $newIndex = 1; + my $index = 1; + while ($pos < $dirLen - 4) { + my $len = unpack("x${pos}N", $$dataPt); + last if $len < 8 or $pos + $len > $dirLen; + my $ns = substr($$dataPt, $pos + 4, 4); + $tag = substr($$dataPt, $pos + 8, $len - 8); + $tag =~ s/\0.*//s; # truncate at null + $tag =~ s/^com\.apple\.quicktime\.// if $ns eq 'mdta'; # remove apple quicktime domain + $tag = "Tag_$ns" unless $tag; + $done{$tag} = 1; # set flag to avoid creating this tag + my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); + if ($tagInfo) { + $info{$index} = $tagInfo; + if ($$newTags{$tag}) { + my $nvHash = $et->GetNewValueHash($tagInfo); + # drop this tag if it is being deleted + if ($nvHash and $et->IsOverwriting($nvHash) > 0 and not defined $et->GetNewValue($nvHash)) { + # don't delete this key if we could be writing any alternate-language version of this tag + my ($t, $dontDelete); + foreach $t (keys %$newTags) { + next unless $$newTags{$t}{SrcTagInfo} and $$newTags{$t}{SrcTagInfo} eq $tagInfo; + my $nv = $et->GetNewValueHash($$newTags{$t}); + next unless $et->IsOverwriting($nv) and defined $et->GetNewValue($nv); + $dontDelete = 1; + last; + } + unless ($dontDelete) { + # delete this key + $et->VPrint(1, "$$et{INDENT}\[deleting Keys entry $index '${tag}']\n"); + $pos += $len; + $remap{$index++} = 0; + ++$$et{CHANGED}; + next; + } + } + } + } + # add to the Keys box data + $newData .= substr($$dataPt, $pos, $len); + $remap{$index++} = $newIndex++; + $pos += $len; + } + # add keys for any tags we need to create + foreach $tag (sort keys %$newTags) { + my $tagInfo = $$newTags{$tag}; + my $id; + if ($$tagInfo{LangCode} and $$tagInfo{SrcTagInfo}) { + $id = $$tagInfo{SrcTagInfo}{TagID}; + } else { + $id = $tag; + } + next if $done{$id}; + my $nvHash = $et->GetNewValueHash($tagInfo); + next unless $$nvHash{IsCreating} and $et->IsOverwriting($nvHash) and + defined $et->GetNewValue($nvHash); + # add new entry to 'keys' data + my $val = $id =~ /^com\./ ? $id : "com.apple.quicktime.$id"; + $newData .= Set32u(8 + length($val)) . 'mdta' . $val; + $et->VPrint(1, "$$et{INDENT}\[adding Keys entry $newIndex '${id}']\n"); + $add{$newIndex++} = $tagInfo; + ++$$et{CHANGED}; + } + my $num = $newIndex - 1; + if ($num) { + Set32u($num, \$newData, 4); # update count in header + } else { + $newData = ''; # delete empty Keys box + } + # save temporary variables for use when writing ItemList: + # Remap - lookup for remapping Keys ID numbers (0 if item is deleted) + # Info - Keys tag information, based on old index value + # Add - Keys items deleted, based on old index value + # Num - Number of items in edited Keys box + $$et{Keys} = { Remap => \%remap, Info => \%info, Add => \%add, Num => $num }; + + return $newData; # return updated Keys box +} + +#------------------------------------------------------------------------------ +# Write ItemInformation in HEIC files +# Inputs: 0) ExifTool ref, 1) dirInfo ref (with BoxPos entry), 2) output buffer ref +# Returns: mdat edit list ref (empty if nothing changed) +sub WriteItemInfo($$$) +{ + my ($et, $dirInfo, $outfile) = @_; + my $boxPos = $$dirInfo{BoxPos}; # hash of [length,position] for each box + my $raf = $$et{RAF}; + my $items = $$et{ItemInfo}; + my (%did, @mdatEdit, $name); + + return () unless $items and $raf; + + # extract information from EXIF/XMP metadata items + if ($items and $raf) { + my $curPos = $raf->Tell(); + my $primary = $$et{PrimaryItem} || 0; + my $id; + foreach $id (sort { $a <=> $b } keys %$items) { + my $item = $$items{$id}; + # only edit primary EXIF/XMP metadata + next unless $$item{RefersTo} and $$item{RefersTo}{$primary}; + my $type = $$item{ContentType} || $$item{Type} || next; + # get ExifTool name for this item + $name = { Exif => 'EXIF', 'application/rdf+xml' => 'XMP' }->{$type}; + next unless $name; # only care about EXIF and XMP + next unless $$et{EDIT_DIRS}{$name}; + $did{$name} = 1; # set flag to prevent creating this metadata + my ($warn, $extent, $buff, @edit); + $warn = 'Missing iloc box' unless $$boxPos{iloc}; + $warn = "No Extents for $type item" unless $$item{Extents} and @{$$item{Extents}}; + $warn = "Can't currently decode encoded $type metadata" if $$item{ContentEncoding}; + $warn = "Can't currently decode protected $type metadata" if $$item{ProtectionIndex}; + $warn = "Can't currently extract $type with construction method $$item{ConstructionMethod}" if $$item{ConstructionMethod}; + $warn = "$type metadata is not this file" if $$item{DataReferenceIndex}; + $warn and $et->Warn($warn), next; + my $base = $$item{BaseOffset} || 0; + my $val = ''; + foreach $extent (@{$$item{Extents}}) { + $val .= $buff if defined $buff; + my $pos = $$extent[1] + $base; + if ($$extent[2]) { + $raf->Seek($pos, 0) or last; + $raf->Read($buff, $$extent[2]) or last; + } else { + $buff = ''; + } + push @edit, [ $pos, $pos + $$extent[2] ]; # replace or delete this if changed + } + next unless defined $buff; + $buff = $val . $buff if length $val; + my ($hdr, $subTable, $proc); + if ($name eq 'EXIF') { + if (length($buff) < 4 or length($buff) < 4 + unpack('N',$buff)) { + $et->Warn('Invalid Exif header'); + next; + } + $hdr = substr($buff, 0, 4 + unpack('N',$buff)); + $subTable = GetTagTable('Image::ExifTool::Exif::Main'); + $proc = \&Image::ExifTool::WriteTIFF; + } else { + $hdr = ''; + $subTable = GetTagTable('Image::ExifTool::XMP::Main'); + } + my %dirInfo = ( + DataPt => \$buff, + DataLen => length $buff, + DirStart => length $hdr, + DirLen => length($buff) - length $hdr, + ); + my $changed = $$et{CHANGED}; + my $newVal = $et->WriteDirectory(\%dirInfo, $subTable, $proc); + if (defined $newVal and $changed ne $$et{CHANGED} and + # nothing changed if deleting an empty directory + ($dirInfo{DirLen} or length $newVal)) + { + $newVal = $hdr . $newVal if length $hdr and length $newVal; + $edit[0][2] = \$newVal; # replace the old chunk with the new data + $edit[0][3] = $id; # mark this chunk with the item ID + push @mdatEdit, @edit; + # update item extent_length + my $n = length $newVal; + foreach $extent (@{$$item{Extents}}) { + my ($nlen, $lenPt) = @$extent[3,4]; + if ($nlen == 8) { + Set64u($n, $outfile, $$boxPos{iloc}[0] + 8 + $lenPt); + } elsif ($n <= 0xffffffff) { + Set32u($n, $outfile, $$boxPos{iloc}[0] + 8 + $lenPt); + } else { + $et->Error("Can't yet promote iloc length to 64 bits"); + return (); + } + $n = 0; + } + if (@{$$item{Extents}} != 1) { + $et->Error("Can't yet handle $name in multiple parts. Please submit sample for testing"); + } + } + $$et{CHANGED} = $changed; # (will set this later if successful in editing mdat) + } + $raf->Seek($curPos, 0); # seek back to original position + } + # add necessary metadata types if they didn't already exist + my ($countNew, %add, %usedID); + foreach $name ('EXIF','XMP') { + next if $did{$name} or not $$et{ADD_DIRS}{$name}; + my @missing; + $$boxPos{$_} or push @missing, $_ foreach qw(iinf iloc); + if (@missing) { + my $str = @missing > 1 ? join(' and ', @missing) . ' boxes' : "@missing box"; + $et->Warn("Can't create $name. Missing expected $str"); + last; + } + my $primary = $$et{PrimaryItem}; + unless (defined $primary) { + $et->Warn("Can't create $name. No primary item reference"); + last; + } + my $buff = ''; + my ($hdr, $subTable, $proc); + if ($name eq 'EXIF') { + $hdr = "\0\0\0\x06Exif\0\0"; + $subTable = GetTagTable('Image::ExifTool::Exif::Main'); + $proc = \&Image::ExifTool::WriteTIFF; + } else { + $hdr = ''; + $subTable = GetTagTable('Image::ExifTool::XMP::Main'); + } + my %dirInfo = ( + DataPt => \$buff, + DataLen => 0, + DirStart => 0, + DirLen => 0, + ); + my $changed = $$et{CHANGED}; + my $newVal = $et->WriteDirectory(\%dirInfo, $subTable, $proc); + if (defined $newVal and $changed ne $$et{CHANGED}) { + my $irefVer; + if ($$boxPos{iref}) { + $irefVer = Get8u($outfile, $$boxPos{iref}[0] + 8); + } else { + # create iref box after end of iinf box (and save version in boxPos list) + $irefVer = ($primary > 0xffff ? 1 : 0); + $$boxPos{iref} = [ $$boxPos{iinf}[0] + $$boxPos{iinf}[1], 0, $irefVer ]; + } + $newVal = $hdr . $newVal if length $hdr; + # add new infe to iinf + $add{iinf} = $add{iref} = $add{iloc} = '' unless defined $add{iinf}; + my ($type, $mime); + if ($name eq 'XMP') { + $type = "mime\0"; + $mime = "application/rdf+xml\0"; + } else { + $type = "Exif\0"; + $mime = ''; + } + my $id = 1; + ++$id while $$items{$id} or $usedID{$id}; # find next unused item ID + my $n = length($type) + length($mime) + 16; + if ($id < 0x10000) { + $add{iinf} .= pack('Na4CCCCnn', $n, 'infe', 2, 0, 0, 1, $id, 0) . $type . $mime; + } else { + $n += 2; + $add{iinf} .= pack('Na4CCCCNn', $n, 'infe', 3, 0, 0, 1, $id, 0) . $type . $mime; + } + # add new cdsc to iref + if ($irefVer) { + $add{iref} .= pack('Na4NnN', 18, 'cdsc', $id, 1, $primary); + } else { + $add{iref} .= pack('Na4nnn', 14, 'cdsc', $id, 1, $primary); + } + # add new entry to iloc table (see ISO14496-12:2015 pg.79) + my $ilocVer = Get8u($outfile, $$boxPos{iloc}[0] + 8); + my $siz = Get16u($outfile, $$boxPos{iloc}[0] + 12); # get size information + my $noff = ($siz >> 12); + my $nlen = ($siz >> 8) & 0x0f; + my $nbas = ($siz >> 4) & 0x0f; + my $nind = $siz & 0x0f; + my ($pbas, $poff); + if ($ilocVer == 0) { + # set offset to 0 as flag that this is a new idat chunk being added + $pbas = length($add{iloc}) + 4; + $poff = $pbas + $nbas + 2; + $add{iloc} .= pack('nn',$id,0) . SetVarInt(0,$nbas) . Set16u(1) . + SetVarInt(0,$noff) . SetVarInt(length($newVal),$nlen); + } elsif ($ilocVer == 1) { + $pbas = length($add{iloc}) + 6; + $poff = $pbas + $nbas + 2 + $nind; + $add{iloc} .= pack('nnn',$id,0,0) . SetVarInt(0,$nbas) . Set16u(1) . SetVarInt(0,$nind) . + SetVarInt(0,$noff) . SetVarInt(length($newVal),$nlen); + } elsif ($ilocVer == 2) { + $pbas = length($add{iloc}) + 8; + $poff = $pbas + $nbas + 2 + $nind; + $add{iloc} .= pack('Nnn',$id,0,0) . SetVarInt(0,$nbas) . Set16u(1) . SetVarInt(0,$nind) . + SetVarInt(0,$noff) . SetVarInt(length($newVal),$nlen); + } else { + $et->Warn("Can't create $name. Unsupported iloc version $ilocVer"); + last; + } + # add new ChunkOffset entry to update this new offset + my $off = $$dirInfo{ChunkOffset} or $et->Warn('Internal error. Missing ChunkOffset'), last; + my $newOff; + if ($noff == 4) { + $newOff = [ 'stco_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $poff, $noff, 0, $id ]; + } elsif ($noff == 8) { + $newOff = [ 'co64_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $poff, $noff, 0, $id ]; + } elsif ($noff == 0) { + # offset_size is zero, so store the offset in base_offset instead + if ($nbas == 4) { + $newOff = [ 'stco_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $pbas, $nbas, 0, $id ]; + } elsif ($nbas == 8) { + $newOff = [ 'co64_iloc', $$boxPos{iloc}[0] + $$boxPos{iloc}[1] + $pbas, $nbas, 0, $id ]; + } else { + $et->Warn("Can't create $name. Invalid iloc offset+base size"); + last; + } + } else { + $et->Warn("Can't create $name. Invalid iloc offset size"); + last; + } + # add directory as a new mdat chunk + push @$off, $newOff; + push @mdatEdit, [ 0, 0, \$newVal, $id ]; + $usedID{$id} = 1; + $countNew = ($countNew || 0) + 1; + $$et{CHANGED} = $changed; # set this later if successful in editing mdat + } + } + if ($countNew) { + # insert new entries into iinf, iref and iloc boxes + my $added = 0; + my $tag; + foreach $tag (sort { $$boxPos{$a}[0] <=> $$boxPos{$b}[0] } keys %$boxPos) { + next unless $add{$tag}; + my $pos = $$boxPos{$tag}[0] + $added; + unless ($$boxPos{$tag}[1]) { + $tag eq 'iref' or $et->Error('Internal error adding iref box'), last; + # create new iref box + $add{$tag} = Set32u(12 + length $add{$tag}) . $tag . + Set8u($$boxPos{$tag}[2]) . "\0\0\0" . $add{$tag}; + } else { + my $n = Get32u($outfile, $pos); + Set32u($n + length($add{$tag}), $outfile, $pos); # increase box size + } + if ($tag eq 'iinf') { + my $iinfVer = Get8u($outfile, $pos + 8); + if ($iinfVer == 0) { + my $n = Get16u($outfile, $pos + 12); + Set16u($n + $countNew, $outfile, $pos + 12); # incr count + } else { + my $n = Get32u($outfile, $pos + 12); + Set32u($n + $countNew, $outfile, $pos + 12); # incr count + } + } elsif ($tag eq 'iref') { + # nothing more to do + } elsif ($tag eq 'iloc') { + my $ilocVer = Get8u($outfile, $pos + 8); + if ($ilocVer < 2) { + my $n = Get16u($outfile, $pos + 14); + Set16u($n + $countNew, $outfile, $pos + 14); # incr count + } else { + my $n = Get32u($outfile, $pos + 14); + Set32u($n + $countNew, $outfile, $pos + 14); # incr count + } + # must also update pointer locations in this box + if ($added) { + $$_[1] += $added foreach @{$$dirInfo{ChunkOffset}}; + } + } else { + next; + } + # add new entries to this box + substr($$outfile, $pos + $$boxPos{$tag}[1], 0) = $add{$tag}; + $added += length $add{$tag}; # positions are shifted by length of new entries + } + } + delete $$et{ItemInfo}; + return @mdatEdit ? \@mdatEdit : undef; } #------------------------------------------------------------------------------ @@ -44,115 +729,285 @@ ($$) # Returns: A) if dirInfo contains DataPt: new directory data # B) otherwise: true on success, 0 if a write error occurred # (true but sets an Error on a file format error) +# Notes: Yes, this is a real mess. Just like the QuickTime metadata situation. sub WriteQuickTime($$$) { + local $_; my ($et, $dirInfo, $tagTablePtr) = @_; - my ($foundMDAT, $lengthChanged, @hold, $track); - my $outfile = $$dirInfo{OutFile} or return 0; - my $raf = $$dirInfo{RAF}; - my $dataPt = $$dirInfo{DataPt}; + $et or return 1; # allow dummy access to autoload this package + my ($mdat, @mdat, @mdatEdit, $edit, $track, $outBuff, $co, $term, $delCount); + my (%langTags, $canCreate, $delGrp, %boxPos, %didDir, $writeLast, $err, $atomCount); + my $outfile = $$dirInfo{OutFile} || return 0; + my $raf = $$dirInfo{RAF}; # (will be null for lower-level atoms) + my $dataPt = $$dirInfo{DataPt}; # (will be null for top-level atoms) my $dirName = $$dirInfo{DirName}; + my $dirStart = $$dirInfo{DirStart} || 0; my $parent = $$dirInfo{Parent}; my $addDirs = $$et{ADD_DIRS}; - my $rtnVal = 1; + my $didTag = $$et{DidTag}; + my $newTags = { }; + my $createKeys = 0; + my ($rtnVal, $rtnErr) = $dataPt ? (undef, undef) : (1, 0); if ($dataPt) { $raf = new File::RandomAccess($dataPt); - my $outBuff = ''; - $outfile = \$outBuff; } else { return 0 unless $raf; } - for (;;) { - my ($hdr, $buff); + # use buffered output for everything but 'mdat' atoms + $outBuff = ''; + $outfile = \$outBuff; + + $raf->Seek($dirStart, 1) if $dirStart; # skip header if it exists + + my $curPath = join '-', @{$$et{PATH}}; + my ($dir, $writePath) = ($dirName, $dirName); + $writePath = "$dir-$writePath" while defined($dir = $$et{DirMap}{$dir}); + # hack to create Keys directories if necessary (its containing Meta is in a different location) + if ($$addDirs{Keys} and $curPath =~ /^MOV-Movie(-Meta)?$/) { + $createKeys = 1; # create new Keys directories + } elsif ($curPath eq 'MOV-Movie-Meta-ItemList') { + $createKeys = 2; # create new Keys tags + my $keys = $$et{Keys}; + if ($keys) { + # add new tag entries for existing Keys tags, now that we know their ID's + # - first make lookup to convert Keys tagInfo ref to index number + my ($index, %keysInfo); + foreach $index (keys %{$$keys{Info}}) { + $keysInfo{$$keys{Info}{$index}} = $index if $$keys{Remap}{$index}; + } + my $keysTable = GetTagTable('Image::ExifTool::QuickTime::Keys'); + my $newKeysTags = $et->GetNewTagInfoHash($keysTable); + foreach (keys %$newKeysTags) { + my $tagInfo = $$newKeysTags{$_}; + $index = $keysInfo{$tagInfo} || ($$tagInfo{SrcTagInfo} and $keysInfo{$$tagInfo{SrcTagInfo}}); + next unless $index; + my $id = Set32u($index); + if ($$tagInfo{LangCode}) { + # add to lookup of language tags we are writing with this ID + $langTags{$id} = { } unless $langTags{$id}; + $langTags{$id}{$_} = $tagInfo; + $id .= '-' . $$tagInfo{LangCode}; + } + $$newTags{$id} = $tagInfo; + } + } + } else { + # get hash of new tags to edit/create in this directory + $newTags = $et->GetNewTagInfoHash($tagTablePtr); + # make lookup of language tags for each ID + foreach (keys %$newTags) { + next unless $$newTags{$_}{LangCode} and $$newTags{$_}{SrcTagInfo}; + my $id = $$newTags{$_}{SrcTagInfo}{TagID}; + $langTags{$id} = { } unless $langTags{$id}; + $langTags{$id}{$_} = $$newTags{$_}; + } + } + if ($curPath eq $writePath or $createKeys) { + $canCreate = 1; + $delGrp = $$et{DEL_GROUP}{$dirName}; + } + $atomCount = $$tagTablePtr{VARS}{ATOM_COUNT} if $$tagTablePtr{VARS}; + + for (;;) { # loop through all atoms at this level + if (defined $atomCount and --$atomCount < 0 and $dataPt) { + # stop processing now and just copy the rest of the atom + Write($outfile, substr($$dataPt, $raf->Tell())) or $rtnVal=$rtnErr, $err=1; + last; + } + my ($hdr, $buff, $keysIndex); my $n = $raf->Read($hdr, 8); unless ($n == 8) { if ($n == 4 and $hdr eq "\0\0\0\0") { # "for historical reasons" the udta is optionally terminated by 4 zeros (ref 1) # --> hold this terminator to the end - push @hold, $hdr; + $term = $hdr; } elsif ($n != 0) { $et->Error('File format error'); } last; } - my ($size, $tag) = unpack('Na4', $hdr); - if ($size >= 8) { - $size -= 8; - } elsif ($size == 1) { + my $size = Get32u(\$hdr, 0) - 8; # (atom size without 8-byte header) + my $tag = substr($hdr, 4, 4); + if ($size == -7) { # read the extended size $raf->Read($buff, 8) == 8 or $et->Error('Truncated extended atom'), last; $hdr .= $buff; my ($hi, $lo) = unpack('NN', $buff); + if ($hi or $lo > 0x7fffffff) { + if ($hi > 0x7fffffff) { + $et->Error('Invalid atom size'); + last; + } elsif (not $et->Options('LargeFileSupport')) { + $et->Error('End of processing at large atom (LargeFileSupport not enabled)'); + last; + } + } $size = $hi * 4294967296 + $lo - 16; $size < 0 and $et->Error('Invalid extended atom size'), last; - } elsif (not $size and not $dataPt) { - # size of zero is only valid for top-level atom, and - # indicates the atom extends to the end of file - if (not $raf->{FILE_PT}) { - # get file size from image in memory - $size = length ${$$raf{BUFF_PT}}; - } else { - $size = -s $$raf{FILE_PT}; - } - if ($size and ($size -= $raf->Tell()) >= 0 and $size <= 0x7fffffff) { - Set32u($size + 8, \$hdr, 0); - } elsif (@hold) { - $et->Error("Sorry, can't yet add tags to this type of QuickTime file"); - return $rtnVal; + } elsif ($size == -8) { + if ($dataPt) { + last if $$dirInfo{DirName} eq 'CanonCNTH'; # (this is normal for Canon CNTH atom) + my $pos = $raf->Tell() - 4; + $raf->Seek(0,2); + my $str = $$dirInfo{DirName} . ' with ' . ($raf->Tell() - $pos) . ' bytes'; + $et->Error("Terminator found in $str remaining", 1); } else { - # blindly copy the rest of the file - Write($outfile, $hdr) or $rtnVal = 0; - while ($raf->Read($buff, 65536)) { - Write($outfile, $buff) or $rtnVal = 0, last; - } - return $rtnVal; + # size of zero is only valid for top-level atom, and + # indicates the atom extends to the end of file + # (save in mdat list to write later; with zero end position to copy rest of file) + push @mdat, [ $raf->Tell(), 0, $hdr ]; } - } else { + last; + } elsif ($size < 0) { $et->Error('Invalid atom size'); last; } - # set flag if we have passed the 'mdat' atom + # keep track of 'mdat' atom locations for writing later if ($tag eq 'mdat') { if ($dataPt) { $et->Error("'mdat' not at top level"); - } elsif ($foundMDAT and $foundMDAT == 1 and $lengthChanged and - not $et->Options('FixCorruptedMOV')) - { - $et->Error("Multiple 'mdat' blocks! Can only edit existing tags"); - $foundMDAT = 2; + last; + } + push @mdat, [ $raf->Tell(), $raf->Tell() + $size, $hdr ]; + $raf->Seek($size, 1) or $et->Error("Seek error in mdat atom"), return $rtnVal; + next; + } elsif ($tag eq 'cmov') { + $et->Error("Can't yet write compressed movie metadata"); + return $rtnVal; + } elsif ($tag eq 'wide') { + next; # drop 'wide' tag + } + + # read the atom data + my $got; + if (not $size) { + $buff = ''; + $got = 0; + } else { + # read the atom data (but only first 64kB if data is huge) + $got = $raf->Read($buff, $size > $maxReadLen ? 0x10000 : $size); + } + if ($got != $size) { + # ignore up to 256 bytes of garbage at end of file + if ($got <= 256 and $size >= 1024 and $tag ne 'mdat') { + my $bytes = $got + length $hdr; + if ($$et{OPTIONS}{IgnoreMinorErrors}) { + $et->Warn("Deleted garbage at end of file ($bytes bytes)"); + $buff = $hdr = ''; + } else { + $et->Error("Possible garbage at end of file ($bytes bytes)", 1); + return $rtnVal; + } } else { - $foundMDAT = 1; + $tag = PrintableTagID($tag,3); + if ($size > $maxReadLen and $got == 0x10000) { + my $mb = int($size / 0x100000 + 0.5); + $et->Error("'${tag}' atom is too large for rewriting ($mb MB)"); + } else { + $et->Error("Truncated '${tag}' atom"); + } + return $rtnVal; + } + } + # save the handler type for this track + if ($tag eq 'hdlr' and length $buff >= 12) { + my $hdlr = substr($buff,8,4); + $$et{HandlerType} = $hdlr if $hdlr =~ /^(vide|soun)$/; + } + + # if this atom stores offsets, save its location so we can fix up offsets later + # (are there any other atoms that may store absolute file offsets?) + if ($tag =~ /^(stco|co64|iloc|mfra|moof|sidx|saio|gps |CTBO|uuid)$/) { + # (note that we only need to do this if the media data is stored in this file) + my $flg = $$et{QtDataFlg}; + if ($tag eq 'mfra' or $tag eq 'moof') { + $et->Error("Can't yet handle movie fragments when writing"); + return $rtnVal; + } elsif ($tag eq 'sidx' or $tag eq 'saio') { + $et->Error("Can't yet handle $tag box when writing"); + return $rtnVal; + } elsif ($tag eq 'iloc') { + Handle_iloc($et, $dirInfo, \$buff, $outfile) or $et->Error('Error parsing iloc atom'); + } elsif ($tag eq 'gps ') { + # (only care about the 'gps ' box in 'moov') + if ($$dirInfo{DirID} and $$dirInfo{DirID} eq 'moov' and length $buff > 8) { + my $off = $$dirInfo{ChunkOffset}; + my $num = Get32u(\$buff, 4); + $num = int((length($buff) - 8) / 8) if $num * 8 + 8 > length($buff); + my $i; + for ($i=0; $i<$num; ++$i) { + push @$off, [ 'stco_gps ', length($$outfile) + length($hdr) + 8 + $i * 8, 4 ]; + } + } + } elsif ($tag eq 'CTBO' or $tag eq 'uuid') { # hack for updating CR3 CTBO offsets + push @{$$dirInfo{ChunkOffset}}, [ $tag, length($$outfile), length($hdr) + $size ]; + } elsif (not $flg) { + my $grp = $$et{CUR_WRITE_GROUP} || $parent; + $et->Error("Can't locate data reference to update offsets for $grp"); + return $rtnVal; + } elsif ($flg == 3) { + $et->Error("Can't write files with mixed internal/external media data"); + return $rtnVal; + } elsif ($flg == 1) { + # must update offsets since the data is in this file + push @{$$dirInfo{ChunkOffset}}, [ $tag, length($$outfile) + length($hdr), $size ]; } } # rewrite this atom - my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag); - if (defined $tagInfo and not $tagInfo) { - my $n = $size < 256 ? $size : 256; - unless ($raf->Read($buff, $n) == $n and $raf->Seek(-$n, 1)) { - $et->Error("Read/seek error in $tag atom"); - last; + my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$buff); + + # call write hook if it exists + &{$$tagInfo{WriteHook}}($buff,$et) if $tagInfo and $$tagInfo{WriteHook}; + + # allow numerical tag ID's (ItemList entries defined by Keys) + if (not $tagInfo and $dirName eq 'ItemList' and $$et{Keys}) { + $keysIndex = unpack('N', $tag); + my $newIndex = $$et{Keys}{Remap}{$keysIndex}; + if (defined $newIndex) { + $tagInfo = $$et{Keys}{Info}{$keysIndex}; + unless ($newIndex) { + if ($tagInfo) { + $et->VPrint(1," - Keys:$$tagInfo{Name}"); + } else { + $delCount = ($delCount || 0) + 1; + } + ++$$et{CHANGED}; + next; + } + # use the new Keys index of this item if it changed + unless ($keysIndex == $newIndex) { + $tag = Set32u($newIndex); + substr($hdr, 4, 4) = $tag; + } + } else { + undef $keysIndex; } - $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$buff); } - if ($tagInfo) { - if ($$tagInfo{Unknown}) { - undef $tagInfo; - } elsif ($size > 100000000) { - # limit maximum size of atom that we load into memory - my $mb = $size / 0x100000; - $et->Warn("Not editing metadata in $tag atom. $mb MB is too big"); - undef $tagInfo; + # delete all ItemList tags when deleting group, but take care not to delete UserData Meta + if ($delGrp) { + if ($dirName eq 'ItemList') { + $delCount = ($delCount || 0) + 1; + ++$$et{CHANGED}; + next; + } elsif ($dirName eq 'UserData' and (not $tagInfo or not $$tagInfo{SubDirectory})) { + $delCount = ($delCount || 0) + 1; + ++$$et{CHANGED}; + next; } } + undef $tagInfo if $tagInfo and $$tagInfo{Unknown}; + if ($tagInfo and (not defined $$tagInfo{Writable} or $$tagInfo{Writable})) { - # read the atom data - $raf->Read($buff, $size) == $size or $et->Error("Error reading $tag data"), last; my $subdir = $$tagInfo{SubDirectory}; - my $newData; - if ($subdir) { + my ($newData, @chunkOffset); + + if ($subdir) { # process atoms in this container from a buffer in memory + + undef $$et{HandlerType} if $tag eq 'trak'; # init handler type for this track + my $subName = $$subdir{DirName} || $$tagInfo{Name}; my $start = $$subdir{Start} || 0; my $base = ($$dirInfo{Base} || 0) + $raf->Tell() - $size; @@ -168,16 +1023,23 @@ ($$$) my %subdirInfo = ( Parent => $dirName, DirName => $subName, + Name => $$tagInfo{Name}, + DirID => $tag, DataPt => \$buff, DataLen => $size, DataPos => $dPos, DirStart => $start, DirLen => $size - $start, Base => $base, - HasData => $$subdir{HasData}, # necessary? + HasData => $$subdir{HasData}, Multi => $$subdir{Multi}, # necessary? OutFile => $outfile, - InPlace => 2, # (to write fixed-length XMP if possible) + NoRefTest=> 1, # don't check directory references + WriteGroup => $$tagInfo{WriteGroup}, + # initialize array to hold details about chunk offset table + # (each entry has 3-5 items: 0=atom type, 1=table offset, 2=table size, + # 3=optional base offset, 4=optional item ID) + ChunkOffset => \@chunkOffset, ); # pass the header pointer if necessary (for EXIF IFD's # where the Base offset is at the end of the header) @@ -195,113 +1057,729 @@ ($$$) # demote non-QuickTime errors to warnings $$et{DemoteErrors} = 1 unless $$subTable{GROUPS}{0} eq 'QuickTime'; my $oldChanged = $$et{CHANGED}; - $newData = $et->WriteDirectory(\%subdirInfo, $subTable); + $newData = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc}); if ($$et{DemoteErrors}) { - # just copy existing subdirectory a non-quicktime error occurred + # just copy existing subdirectory if a non-quicktime error occurred $$et{CHANGED} = $oldChanged if $$et{DemoteErrors} > 1; delete $$et{DemoteErrors}; } - undef $newData if $$et{CHANGED} == $oldChanged; # don't change unless necessary + if (defined $newData and not length $newData and $$tagTablePtr{PERMANENT}) { + # do nothing if trying to delete tag from a PERMANENT table + $$et{CHANGED} = $oldChanged; + undef $newData; + } $$et{CUR_WRITE_GROUP} = $oldWriteGroup; SetByteOrder('MM'); # add back header if necessary if ($start and defined $newData and length $newData) { $newData = substr($buff,0,$start) . $newData; + $$_[1] += $start foreach @chunkOffset; } # the directory exists, so we don't need to add it - delete $$addDirs{$subName} if IsCurPath($et, $subName); - } else { - # --> this is where individual QuickTime tags would be edited, - # (this is such a can of worms, so don't implement this for now) - } - if (defined $newData) { - my $len = length $newData; - $len > 0x7ffffff7 and $et->Error("$tag to large to write"), last; - if ($len == $size or $dataPt or $foundMDAT) { - # write the updated directory now (unless length is zero, or it is needed as padding) - if ($len or (not $dataPt and not $foundMDAT) or - ($et->Options('FixCorruptedMOV') and $tag eq 'udta')) - { - Write($outfile, Set32u($len+8), $tag, $newData) or $rtnVal = 0, last; - $lengthChanged = 1 if $len != $size; + if ($curPath eq $writePath and $$addDirs{$subName} and $$addDirs{$subName} eq $dirName) { + delete $$addDirs{$subName}; + } + $didDir{$tag} = 1; # (note: keyed by tag ID) + + } else { # modify existing QuickTime tags in various formats + + my $nvHash = $et->GetNewValueHash($tagInfo); + if ($nvHash or $langTags{$tag} or $delGrp) { + my $nvHashNoLang = $nvHash; + my ($val, $len, $lang, $type, $flags, $ctry, $charsetQuickTime); + my $format = $$tagInfo{Format}; + my $hasData = ($$dirInfo{HasData} and $buff =~ /\0...data\0/s); + my $langInfo = $tagInfo; + if ($hasData) { + my $pos = 0; + for (;;$pos+=$len) { + if ($pos + 16 > $size) { + # add any new alternate language tags now + if ($langTags{$tag}) { + my $tg; + foreach $tg ('', sort keys %{$langTags{$tag}}) { + my $ti = $tg ? $langTags{$tag}{$tg} : $nvHashNoLang; + $nvHash = $et->GetNewValueHash($ti); + next unless $nvHash and not $$didTag{$nvHash}; + $$didTag{$nvHash} = 1; + next unless $$nvHash{IsCreating} and $et->IsOverwriting($nvHash); + my $newVal = $et->GetNewValue($nvHash); + next unless defined $newVal; + my $prVal = $newVal; + my $flags = FormatQTValue($et, \$newVal, $format); + next unless defined $newVal; + my ($ctry, $lang) = (0, $undLang); + if ($$ti{LangCode}) { + unless ($$ti{LangCode} =~ /^([A-Z]{3})?[-_]?([A-Z]{2})?$/i) { + $et->Warn("Invalid language code for $$ti{Name}"); + next; + } + # pack language and country codes + if ($1 and $1 ne 'und') { + $lang = ($lang << 5) | ($_ - 0x60) foreach unpack 'C*', lc($1); + } + $ctry = unpack('n', pack('a2',uc($2))) if $2 and $2 ne 'ZZ'; + } + $newData = substr($buff, 0, $pos) unless defined $newData; + $newData .= pack('Na4Nnn',16+length($newVal),'data',$flags,$ctry,$lang).$newVal; + my $grp = $et->GetGroup($ti, 1); + $et->VerboseValue("+ $grp:$$ti{Name}", $prVal); + ++$$et{CHANGED}; + } + } + last; + } + ($len, $type, $flags, $ctry, $lang) = unpack("x${pos}Na4Nnn", $buff); + $lang or $lang = $undLang; # treat both 0 and 'und' as 'und' + $langInfo = $tagInfo; + my $delTag = $delGrp; + my $newVal; + my $langCode = GetLangCode($lang, $ctry, 1); + for (;;) { + $langInfo = GetLangInfo($tagInfo, $langCode); + $nvHash = $et->GetNewValueHash($langInfo); + last if $nvHash or not $ctry or $lang ne $undLang or length($langCode)==2; + # check to see if tag was written with a 2-char country code only + $langCode = lc unpack('a2',pack('n',$ctry)); + } + # set flag to delete language tag when writing default + # (except for a default-language Keys entry) + if (not $nvHash and $nvHashNoLang) { + if ($lang eq $undLang and not $ctry and not $$didTag{$nvHashNoLang}) { + $nvHash = $nvHashNoLang; # write existing default + } else { + $delTag = 1; # delete tag + } + } + last if $pos + $len > $size; + if ($type eq 'data' and $len >= 16) { + $pos += 16; + $len -= 16; + $val = substr($buff, $pos, $len); + # decode value (see QuickTime.pm for an explanation) + if ($stringEncoding{$flags}) { + $val = $et->Decode($val, $stringEncoding{$flags}); + $val =~ s/\0$// unless $$tagInfo{Binary}; + $flags = 0x01; # write all strings as UTF-8 + } else { + if ($format) { + # update flags for the format we are writing + $flags = $qtFormat{$format} if $qtFormat{$format}; + } else { + $format = QuickTimeFormat($flags, $len); + } + $val = ReadValue(\$val, 0, $format, $$tagInfo{Count}, $len) if $format; + } + if (($nvHash and $et->IsOverwriting($nvHash, $val)) or $delTag) { + $newVal = $et->GetNewValue($nvHash) if defined $nvHash; + if ($delTag or not defined $newVal or $$didTag{$nvHash}) { + # delete the tag + my $grp = $et->GetGroup($langInfo, 1); + $et->VerboseValue("- $grp:$$langInfo{Name}", $val); + # copy data up to start of this tag to delete this value + $newData = substr($buff, 0, $pos-16) unless defined $newData; + ++$$et{CHANGED}; + next; + } + my $prVal = $newVal; + # format new value for writing (and get new flags) + $flags = FormatQTValue($et, \$newVal, $format); + my $grp = $et->GetGroup($langInfo, 1); + $et->VerboseValue("- $grp:$$langInfo{Name}", $val); + $et->VerboseValue("+ $grp:$$langInfo{Name}", $prVal); + $newData = substr($buff, 0, $pos-16) unless defined $newData; + $newData .= pack('Na4Nnn', length($newVal)+16, $type, $flags, $ctry, $lang); + $newData .= $newVal; + ++$$et{CHANGED}; + } elsif (defined $newData) { + $newData .= substr($buff, $pos-16, $len+16); + } + } elsif (defined $newData) { + $newData .= substr($buff, $pos, $len); + } + $$didTag{$nvHash} = 1 if $nvHash; + } + $newData .= substr($buff, $pos) if defined $newData and $pos < $size; + undef $val; # (already constructed $newData) + } elsif ($format) { + $val = ReadValue(\$buff, 0, $format, undef, $size); + } elsif (($tag =~ /^\xa9/ or $$tagInfo{IText}) and $size >= ($$tagInfo{IText} || 4)) { + if ($$tagInfo{IText} and $$tagInfo{IText} == 6) { + $lang = unpack('x4n', $buff); + $len = $size - 6; + $val = substr($buff, 6, $len); + } else { + ($len, $lang) = unpack('nn', $buff); + $len -= 4 if 4 + $len > $size; # (see QuickTime.pm for explanation) + $len = $size - 4 if $len > $size - 4 or $len < 0; + $val = substr($buff, 4, $len); + } + $lang or $lang = $undLang; # treat both 0 and 'und' as 'und' + if ($lang < 0x400 and $val !~ /^\xfe\xff/) { + $charsetQuickTime = $et->Options('CharsetQuickTime'); + $val = $et->Decode($val, $charsetQuickTime); + } else { + my $enc = $val=~s/^\xfe\xff// ? 'UTF16' : 'UTF8'; + $val = $et->Decode($val, $enc); + } + $val =~ s/\0+$//; # remove trailing nulls if they exist + my $langCode = UnpackLang($lang, 1); + $langInfo = GetLangInfo($tagInfo, $langCode); + $nvHash = $et->GetNewValueHash($langInfo); + if (not $nvHash and $nvHashNoLang) { + if ($lang eq $undLang and not $$didTag{$nvHashNoLang}) { + $nvHash = $nvHashNoLang; + } elsif ($canCreate) { + # delete other languages when writing default + my $grp = $et->GetGroup($langInfo, 1); + $et->VerboseValue("- $grp:$$langInfo{Name}", $val); + ++$$et{CHANGED}; + next; + } + } } else { - $lengthChanged = 1; # (we deleted this atom) + $val = $buff; } - next; - } else { - # bad things happen if 'mdat' atom is moved (eg. Adobe Bridge crashes -- - # there are absolute offsets that point into mdat), so hold this atom - # and write it out later - if ($len) { - push @hold, Set32u($len+8), $tag, $newData; - $et->VPrint(0," Moving '${tag}' atom to after 'mdat'"); - } else { - $et->VPrint(0," Freeing '${tag}' atom (and zeroing data)"); + if ($nvHash and defined $val) { + if ($et->IsOverwriting($nvHash, $val)) { + $newData = $et->GetNewValue($nvHash); + $newData = '' unless defined $newData or $canCreate; + ++$$et{CHANGED}; + my $grp = $et->GetGroup($langInfo, 1); + $et->VerboseValue("- $grp:$$langInfo{Name}", $val); + next unless defined $newData and not $$didTag{$nvHash}; + $et->VerboseValue("+ $grp:$$langInfo{Name}", $newData); + # add back necessary header and encode as necessary + if (defined $lang) { + $newData = $et->Encode($newData, $lang < 0x400 ? $charsetQuickTime : 'UTF8'); + if ($$tagInfo{IText} and $$tagInfo{IText} == 6) { + $newData = pack('Nn', 0, $lang) . $newData . "\0"; + } else { + $newData = pack('nn', length($newData), $lang) . $newData; + } + } elsif (not $format or $format =~ /^string/ and + not $$tagInfo{Binary} and not $$tagInfo{ValueConv}) + { + # write all strings as UTF-8 + $newData = $et->Encode($newData, 'UTF8'); + } elsif ($format and not $$tagInfo{Binary}) { + # format new value for writing + $newData = WriteValue($newData, $format); + } + } + $$didTag{$nvHash} = 1; # set flag so we don't add this tag again } - # write a 'free' atom here to keep 'mdat' at the same offset - substr($hdr, 4, 4) = 'free'; - $buff = "\0" x length($buff); # zero out old data } } - # write out the existing atom (or 'free' padding) - Write($outfile, $hdr, $buff) or $rtnVal = 0, last; + # write the new atom if it was modified + if (defined $newData) { + my $len = length($newData) + 8; + $len > 0x7fffffff and $et->Error("$$tagInfo{Name} to large to write"), last; + # update size in ChunkOffset list for modified 'uuid' atom + $$dirInfo{ChunkOffset}[-1][2] = $len if $tag eq 'uuid'; + next unless $len > 8; # don't write empty atom header + # maintain pointer to chunk offsets if necessary + if (@chunkOffset) { + $$_[1] += 8 + length $$outfile foreach @chunkOffset; + push @{$$dirInfo{ChunkOffset}}, @chunkOffset; + } + if ($$tagInfo{WriteLast}) { + $writeLast = ($writeLast || '') . Set32u($len) . $tag . $newData; + } else { + $boxPos{$tag} = [ length($$outfile), length($newData) + 8 ]; + # write the updated directory with its atom header + Write($outfile, Set32u($len), $tag, $newData) or $rtnVal=$rtnErr, $err=1, last; + } + next; + } + } + # keep track of data references in this track + if ($tag eq 'dinf') { + $$et{QtDataRef} = [ ]; # initialize list of data references + } elsif ($parent eq 'DataInfo' and length($buff) >= 4) { + # save data reference type and version/flags + push @{$$et{QtDataRef}}, [ $tag, Get32u(\$buff,0) ]; + } elsif ($tag eq 'stsd' and length($buff) >= 8) { + my $n = Get32u(\$buff, 4); # get number of sample descriptions in table + my ($pos, $flg) = (8, 0); + my ($i, $msg); + for ($i=0; $i<$n; ++$i) { # loop through sample descriptions + $pos + 16 <= length($buff) or $msg = 'Truncated sample table', last; + my $siz = Get32u(\$buff, $pos); + $pos + $siz <= length($buff) or $msg = 'Truncated sample table', last; + my $drefIdx = Get16u(\$buff, $pos + 14); + my $drefTbl = $$et{QtDataRef}; + if (not $drefIdx) { + $flg |= 0x01; # in this file if data reference index is 0 (if like iloc) + } elsif ($drefTbl and $$drefTbl[$drefIdx-1]) { + my $dref = $$drefTbl[$drefIdx-1]; + # $flg = 0x01-in this file, 0x02-in some other file + $flg |= ($$dref[1] == 1 and $$dref[0] ne 'rsrc') ? 0x01 : 0x02; + } else { + $msg = "No data reference for sample description $i"; + last; + } + $pos += $siz; + } + if ($msg) { + my $grp = $$et{CUR_WRITE_GROUP} || $parent; + $et->Error("$msg for $grp"); + return $rtnErr; + } + $$et{QtDataFlg} = $flg; + } + if ($tagInfo and $$tagInfo{WriteLast}) { + $writeLast = ($writeLast || '') . $hdr . $buff; } else { - # write the unknown/large atom header - Write($outfile, $hdr) or $rtnVal = 0, last; - next unless $size; - # copy the atom data - my $result = Image::ExifTool::CopyBlock($raf, $outfile, $size); - defined $result or $rtnVal = 0, last; - $result or $et->Error("Truncated $tag atom"), last; + # save position of this box in the output buffer + $boxPos{$tag} = [ length($$outfile), length($hdr) + length($buff) ]; + # copy the existing atom + Write($outfile, $hdr, $buff) or $rtnVal=$rtnErr, $err=1, last; } } - # add new directories at this level if necessary - if (exists $$et{EDIT_DIRS}{$dirName}) { + $et->VPrint(0, " [deleting $delCount $dirName tag".($delCount==1 ? '' : 's')."]\n") if $delCount; + + $createKeys &= ~0x01 unless $$addDirs{Keys}; # (Keys may have been written) + + # add new directories/tags at this level if necessary + if ($canCreate and (exists $$et{EDIT_DIRS}{$dirName} or $createKeys)) { # get a hash of tagInfo references to add to this directory my $dirs = $et->GetAddDirHash($tagTablePtr, $dirName); # make sorted list of new tags to be added - my @addTags = sort keys(%$dirs); - my $tag; + my @addTags = sort(keys(%$dirs), keys %$newTags); + my ($tag, $index); + # add Keys tags if necessary + if ($createKeys) { + if ($curPath eq 'MOV-Movie') { + # add Meta for Keys if necessary + unless ($didDir{meta}) { + $$dirs{meta} = $Image::ExifTool::QuickTime::Movie{meta}; + push @addTags, 'meta'; + } + } elsif ($curPath eq 'MOV-Movie-Meta') { + # special case for Keys Meta -- reset directories and start again + undef @addTags; + $dirs = { }; + foreach ('keys','ilst') { + next if $didDir{$_}; # don't add again + $$dirs{$_} = $Image::ExifTool::QuickTime::Meta{$_}; + push @addTags, $_; + } + } elsif ($curPath eq 'MOV-Movie-Meta-ItemList' and $$et{Keys}) { + foreach $index (sort { $a <=> $b } keys %{$$et{Keys}{Add}}) { + my $id = Set32u($index); + $$newTags{$id} = $$et{Keys}{Add}{$index}; + push @addTags, $id; + } + } else { + $dirs = $et->GetAddDirHash($tagTablePtr, $dirName); + push @addTags, sort keys %$dirs; + } + } + # (note that $tag may be a binary Keys index here) foreach $tag (@addTags) { - my $tagInfo = $$dirs{$tag}; - my $subdir = $$tagInfo{SubDirectory} or next; + my $tagInfo = $$dirs{$tag} || $$newTags{$tag}; + next if defined $$tagInfo{CanCreate} and not $$tagInfo{CanCreate}; + next if defined $$tagInfo{HandlerType} and + (not $$et{HandlerType} or $$et{HandlerType} ne $$tagInfo{HandlerType}); + my $subdir = $$tagInfo{SubDirectory}; + unless ($subdir) { + my $nvHash = $et->GetNewValueHash($tagInfo); + next unless $nvHash and not $$didTag{$nvHash}; + next unless $$nvHash{IsCreating} and $et->IsOverwriting($nvHash); + my $newVal = $et->GetNewValue($nvHash); + next unless defined $newVal; + my $prVal = $newVal; + my $flags = FormatQTValue($et, \$newVal, $$tagInfo{Format}); + next unless defined $newVal; + my ($ctry, $lang) = (0,0); + # handle alternate languages + if ($$tagInfo{LangCode}) { + $tag = substr($tag, 0, 4); # strip language code from tag ID + unless ($$tagInfo{LangCode} =~ /^([A-Z]{3})?[-_]?([A-Z]{2})?$/i) { + $et->Warn("Invalid language code for $$tagInfo{Name}"); + next; + } + # pack language and country codes + if ($1 and $1 ne 'und') { + $lang = ($lang << 5) | ($_ - 0x60) foreach unpack 'C*', lc($1); + } + $ctry = unpack('n', pack('a2',uc($2))) if $2 and $2 ne 'ZZ'; + } + if ($$dirInfo{HasData}) { + # add 'data' header + $lang or $lang = $undLang; + $newVal = pack('Na4Nnn',16+length($newVal),'data',$flags,$ctry,$lang).$newVal; + } elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) { + $lang or $lang = $undLang; + if ($ctry) { + my $grp = $et->GetGroup($tagInfo,1); + $et->Warn("Can't use country code for $grp:$$tagInfo{Name}"); + next; + } elsif ($$tagInfo{IText} and $$tagInfo{IText} == 6) { + # add 6-byte langText header and trailing null + $newVal = pack('Nn',0,$lang) . $newVal . "\0"; + } else { + # add IText header + $newVal = pack('nn',length($newVal),$lang) . $newVal; + } + } elsif ($ctry or $lang) { + my $grp = $et->GetGroup($tagInfo,1); + $et->Warn("Can't use language code for $grp:$$tagInfo{Name}"); + next; + } + if ($$tagInfo{WriteLast}) { + $writeLast = ($writeLast || '') . Set32u(8+length($newVal)) . $tag . $newVal; + } else { + $boxPos{$tag} = [ length($$outfile), 8 + length($newVal) ]; + Write($outfile, Set32u(8+length($newVal)), $tag, $newVal) or $rtnVal=$rtnErr, $err=1; + } + my $grp = $et->GetGroup($tagInfo, 1); + $et->VerboseValue("+ $grp:$$tagInfo{Name}", $prVal); + $$didTag{$nvHash} = 1; + ++$$et{CHANGED}; + next; + } my $subName = $$subdir{DirName} || $$tagInfo{Name}; # QuickTime hierarchy is complex, so check full directory path before adding - next unless IsCurPath($et, $subName); - my $buff = ''; # write from scratch + my $buff; + if ($createKeys and $curPath eq 'MOV-Movie' and $subName eq 'Meta') { + $et->VPrint(0, " Creating Meta with mdta Handler and Keys\n"); + # init Meta box for Keys tags with mdta Handler and empty Keys+ItemList + $buff = "\0\0\0\x20hdlr\0\0\0\0\0\0\0\0mdta\0\0\0\0\0\0\0\0\0\0\0\0" . + "\0\0\0\x10keys\0\0\0\0\0\0\0\0" . + "\0\0\0\x08ilst"; + } elsif ($createKeys and $curPath eq 'MOV-Movie-Meta') { + $buff = ($subName eq 'Keys' ? "\0\0\0\0\0\0\0\0" : ''); + } elsif ($subName eq 'Meta' and $$et{OPTIONS}{QuickTimeHandler}) { + $et->VPrint(0, " Creating Meta with mdir Handler\n"); + # init Meta box for ItemList tags with mdir Handler + $buff = "\0\0\0\x20hdlr\0\0\0\0\0\0\0\0mdir\0\0\0\0\0\0\0\0\0\0\0\0"; + } else { + next unless $curPath eq $writePath and $$addDirs{$subName} and $$addDirs{$subName} eq $dirName; + $buff = ''; # write from scratch + } my %subdirInfo = ( Parent => $dirName, DirName => $subName, DataPt => \$buff, DirStart => 0, + HasData => $$subdir{HasData}, OutFile => $outfile, + ChunkOffset => [ ], # (just to be safe) + WriteGroup => $$tagInfo{WriteGroup}, ); my $subTable = GetTagTable($$subdir{TagTable}); - my $newData = $et->WriteDirectory(\%subdirInfo, $subTable); + my $newData = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc}); if ($newData and length($newData) <= 0x7ffffff7) { - my $uuid = ''; - # add atom ID if necessary (obtain from Condition expression) + my $prefix = ''; + # add atom version or ID if necessary if ($$subdir{Start}) { - my $cond = $$tagInfo{Condition}; - $uuid = eval qq("$1") if $cond and $cond =~ m{=~\s*\/\^(.*)/}; - length($uuid) == $$subdir{Start} or $et->Error('Internal UUID error'); + if ($$subdir{Start} == 4) { + $prefix = "\0\0\0\0"; # a simple version number + } else { + # get UUID from Condition expression + my $cond = $$tagInfo{Condition}; + $prefix = eval qq("$1") if $cond and $cond =~ m{=~\s*\/\^(.*)/}; + length($prefix) == $$subdir{Start} or $et->Error('Internal UUID error'); + } + } + my $newHdr = Set32u(8+length($newData)+length($prefix)) . $tag . $prefix; + if ($$tagInfo{WriteLast}) { + $writeLast = ($writeLast || '') . $newHdr . $newData; + } else { + if ($tag eq 'uuid') { + # add offset for new uuid (needed for CR3 CTBO offsets) + my $off = $$dirInfo{ChunkOffset}; + push @$off, [ $tag, length($$outfile), length($newHdr) + length($newData) ]; + } + $boxPos{$tag} = [ length($$outfile), length($newHdr) + length($newData) ]; + Write($outfile, $newHdr, $newData) or $rtnVal=$rtnErr, $err=1; } - my $newHdr = Set32u(8+length($newData)+length($uuid)) . $tag . $uuid; - Write($outfile, $newHdr, $newData) or $rtnVal = 0; - $lengthChanged = 1; } - delete $$addDirs{$subName}; # add only once (must delete _after_ call to WriteDirectory()) + # add only once (must delete _after_ call to WriteDirectory()) + # (Keys is a special case, and will be removed after Meta is processed) + delete $$addDirs{$subName} unless $subName eq 'Keys'; + } + } + # write HEIC metadata after top-level 'meta' box has been processed if editing this information + if ($curPath eq 'MOV-Meta' and $$et{EDIT_DIRS}{ItemInformation}) { + $$dirInfo{BoxPos} = \%boxPos; + my $mdatEdit = WriteItemInfo($et, $dirInfo, $outfile); + if ($mdatEdit) { + $et->Error('Multiple top-level Meta containers') if $$et{mdatEdit}; + $$et{mdatEdit} = $mdatEdit; + } + } + # write out any necessary terminator + Write($outfile, $term) or $rtnVal=$rtnErr, $err=1 if $term and length $$outfile; + + # delete temporary Keys variables after Meta is processed + if ($dirName eq 'Meta') { + # delete any Meta box with no useful information (ie. only 'hdlr','keys','lang','ctry') + my $isEmpty = 1; + $emptyMeta{$_} or $isEmpty = 0, last foreach keys %boxPos; + if ($isEmpty) { + $et->VPrint(0,' Deleting ' . join('+', sort map { $emptyMeta{$_} } keys %boxPos)) if %boxPos; + $$outfile = ''; + ++$$et{CHANGED}; + } + if ($curPath eq 'MOV-Movie-Meta') { + delete $$addDirs{Keys}; # prevent creation of another Meta for Keys tags + delete $$et{Keys}; } } - # write out any atoms that we are holding until the end - Write($outfile, @hold) or $rtnVal = 0 if @hold; + + # return now if writing subdirectory + if ($dataPt) { + $et->Error("Internal error: WriteLast not on top-level atom!\n") if $writeLast; + return $err ? undef : $$outfile; + } # issue minor error if we didn't find an 'mdat' atom - # (we could duplicate atoms indefinitely through repeated editing if we - # held back some atoms here, so in this case it isn't a minor error) - $dataPt or $foundMDAT or $et->Error('No mdat atom found', @hold ? 0 : 1); + my $off = $$dirInfo{ChunkOffset}; + if (not @mdat) { + foreach $co (@$off) { + next if $$co[0] eq 'uuid'; + $et->Error('Media data referenced but not found'); + return $rtnVal; + } + $et->Warn('No media data', 1); + } + + # edit mdat blocks as required + # (0=old pos [0 if creating], 1=old end [0 if creating], 2=new data ref or undef to delete, + # 3=new data item id) + if ($$et{mdatEdit}) { + @mdatEdit = @{$$et{mdatEdit}}; + delete $$et{mdatEdit}; + } + foreach $edit (@mdatEdit) { + my (@thisMdat, @newMdat, $changed); + foreach $mdat (@mdat) { + # keep track of all chunks for the mdat with this header + if (length $$mdat[2]) { + push @newMdat, @thisMdat; + undef @thisMdat; + } + push @thisMdat, $mdat; + # is this edit inside this mdat chunk? + # - $$edit[0] and $$edit[1] will both be zero if we are creating a new chunk + # - $$mdat[1] is zero if mdat runs to end of file + # - $$edit[0] == $$edit[1] == $$mdat[0] if reviving a deleted chunk + # - $$mdat[5] is defined if this was a newly added/edited chunk + next if defined $$mdat[5] or $changed; # don't replace a newly added chunk + if (not $$edit[0] or # (newly created chunk) + # (edit is inside chunk) + ((($$edit[0] < $$mdat[1] or not $$mdat[1]) and $$edit[1] > $$mdat[0]) or + # (edit inserted at start or end of chunk) + ($$edit[0] == $$edit[1] and ($$edit[0] == $$mdat[0] or $$edit[0] == $$mdat[1])))) + { + if (not $$edit[0]) { + $$edit[0] = $$edit[1] = $$mdat[0]; # insert at start of this mdat + } elsif ($$edit[0] < $$mdat[0] or ($$edit[1] > $$mdat[1] and $$mdat[1])) { + $et->Error('ItemInfo runs across mdat boundary'); + return $rtnVal; + } + my $hdrChunk = $thisMdat[0]; + $hdrChunk or $et->Error('Internal error finding mdat header'), return $rtnVal; + # calculate difference in mdat size + my $diff = ($$edit[2] ? length(${$$edit[2]}) : 0) - ($$edit[1] - $$edit[0]); + # edit size of mdat in header if necessary + if ($diff) { + if (length($$hdrChunk[2]) == 8) { + my $size = Get32u(\$$hdrChunk[2], 0) + $diff; + $size > 0xffffffff and $et->Error("Can't yet grow mdat across 4GB boundary"), return $rtnVal; + Set32u($size, \$$hdrChunk[2], 0); + } elsif (length($$hdrChunk[2]) == 16) { + my $size = Get64u(\$$hdrChunk[2], 8) + $diff; + Set64u($size, \$$hdrChunk[2], 8); + } else { + $et->Error('Internal error. Invalid mdat header'); + return $rtnVal; + } + } + $changed = 1; + # remove the edited section of this chunk (if any) and replace with new data (if any) + if ($$edit[0] > $$mdat[0]) { + push @thisMdat, [ $$edit[0], $$edit[1], '', 0, $$edit[2], $$edit[3] ] if $$edit[2]; + # add remaining data after edit (or empty stub in case it is referenced by an offset) + push @thisMdat, [ $$edit[1], $$mdat[1], '' ]; + $$mdat[1] = $$edit[0]; # now ends at start of edit + } else { + if ($$edit[2]) { + # insert the new chunk before this chunk, moving the header to the new chunk + splice @thisMdat, -1, 0, [ $$edit[0],$$edit[1],$$mdat[2],0,$$edit[2],$$edit[3] ]; + $$mdat[2] = ''; # (header was moved to new chunk) + # initialize ChunkOffset pointer if necessary + if ($$edit[3]) { + my $n = 0; + foreach $co (@$off) { + next unless defined $$co[4] and $$co[4] == $$edit[3]; + ++$n; + if ($$co[0] eq 'stco_iloc') { + Set32u($$mdat[0], $outfile, $$co[1]); + } else { + Set64u($$mdat[0], $outfile, $$co[1]); + } + } + $n == 1 or $et->Error('Internal error updating chunk offsets'); + } + } + $$mdat[0] = $$edit[1]; # remove old data + } + } + } + if ($changed) { + @mdat = ( @newMdat, @thisMdat ); + ++$$et{CHANGED}; + } else { + $et->Error('Internal error modifying mdat'); + } + } + + # determine our new mdat positions + # (0=old pos, 1=old end, 2=mdat header, 3=new pos, 4=new data ref if changed, 5=new item ID) + my $pos = length $$outfile; + foreach $mdat (@mdat) { + $pos += length $$mdat[2]; + $$mdat[3] = $pos; + $pos += $$mdat[4] ? length(${$$mdat[4]}) : $$mdat[1] - $$mdat[0]; + } + + # fix up offsets for new mdat position(s) (and uuid positions in CR3 images) + foreach $co (@$off) { + my ($type, $ptr, $len, $base, $id) = @$co; + $base = 0 unless $base; + unless ($type =~ /^(stco|co64)_?(.*)$/) { + next if $type eq 'uuid'; + $type eq 'CTBO' or $et->Error('Internal error fixing offsets'), last; + # update 'CTBO' item offsets/sizes in Canon CR3 images + $$co[2] > 12 or $et->Error('Invalid CTBO atom'), last; + @mdat or $et->Error('Missing CR3 image data'), last; + my $n = Get32u($outfile, $$co[1] + 8); + $$co[2] < $n * 20 + 12 and $et->Error('Truncated CTBO atom'), last; + my (%ctboOff, $i); + # determine uuid types, and build an offset lookup based on CTBO ID number + foreach (@$off) { + next unless $$_[0] eq 'uuid' and $$_[2] >= 24; # (ignore undersized and deleted uuid boxes) + my $pos = $$_[1]; + next if $pos + 24 > length $$outfile; # (will happen for WriteLast uuid tags) + my $siz = Get32u($outfile, $pos); # get size of uuid atom + if ($siz == 1) { # check for extended (8-byte) size + next unless $$_[2] >= 32; + $pos += 8; + } + # get CTBO entry ID based on 16-byte UUID identifier + my $id = $ctboID{substr($$outfile, $pos+8, 16)}; + $ctboOff{$id} = $_ if defined $id; + } + # calculate new offset for the first mdat (size of -1 indicates it didn't change) + $ctboOff{3} = [ 'mdat', $mdat[0][3] - length $mdat[0][2], -1 ]; + for ($i=0; $i<$n; ++$i) { + my $pos = $$co[1] + 12 + $i * 20; + my $id = Get32u($outfile, $pos); + # ignore if size is zero unless we can add this entry + # (note: can't yet add/delete PreviewImage, but leave this possibility open) + next unless Get64u($outfile, $pos + 12) or $id == 1 or $id == 2; + if (not defined $ctboOff{$id}) { + $id==1 or $id==2 or $et->Error("Can't handle CR3 CTBO ID number $id"), last; + # XMP or PreviewImage was deleted -- set offset and size to zero + $ctboOff{$id} = [ 'uuid', 0, 0 ]; + } + # update the new offset and size of this entry + Set64u($ctboOff{$id}[1], $outfile, $pos + 4); + Set64u($ctboOff{$id}[2], $outfile, $pos + 12) unless $ctboOff{$id}[2] < 0; + } + next; + } + my $siz = $1 eq 'co64' ? 8 : 4; + my ($n, $tag); + if ($2) { # is this an offset in an iloc or 'gps ' atom? + $n = 1; + $type = $1; + $tag = $2; + } else { # this is an stco or co84 atom + next if $len < 8; + $n = Get32u($outfile, $ptr + 4); # get number of entries in table + $ptr += 8; + $len -= 8; + $tag = $1; + } + my $end = $ptr + $n * $siz; + $end > $ptr + $len and $et->Error("Invalid $tag table"), return $rtnVal; + for (; $ptr<$end; $ptr+=$siz) { + my ($ok, $i); + my $val = $type eq 'co64' ? Get64u($outfile, $ptr) : Get32u($outfile, $ptr); + for ($i=0; $i<@mdat; ++$i) { + $mdat = $mdat[$i]; + my $pos = $val + $base; + if (defined $$mdat[5]) { # is this chunk associated with an item we edited? + # set offset only for the corresponding new chunk + unless (defined $id and $id == $$mdat[5]) { + # could have pointed to empty chunk before inserted chunk + next unless $pos == $$mdat[0] and $$mdat[0] != $$mdat[1]; + } + } else { + # (have seen $pos == $$mdat[1], which is a real PITA) + next unless $pos >= $$mdat[0] and ($pos <= $$mdat[1] or not $$mdat[1]); + # step to next chunk if contiguous and at the end of this one + next if $pos == $$mdat[1] and $i+1 < @mdat and $pos == $mdat[$i+1][0]; + } + $val += $$mdat[3] - $$mdat[0]; + if ($val < 0) { + $et->Error("Error fixing up $tag offset"); + return $rtnVal; + } + if ($type eq 'co64') { + Set64u($val, $outfile, $ptr); + } elsif ($val <= 0xffffffff) { + Set32u($val, $outfile, $ptr); + } else { + $et->Error("Can't yet promote $tag offset to 64 bits"); + return $rtnVal; + } + $ok = 1; + last; + } + unless ($ok) { + $et->Error("Chunk offset in $tag atom is outside media data"); + return $rtnVal; + } + } + } + + # switch back to actual output file + $outfile = $$dirInfo{OutFile}; + + # write the metadata + Write($outfile, $outBuff) or $rtnVal = 0; + + # write the media data + foreach $mdat (@mdat) { + Write($outfile, $$mdat[2]) or $rtnVal = 0; # write mdat header + if ($$mdat[4]) { + Write($outfile, ${$$mdat[4]}) or $rtnVal = 0; + } else { + $raf->Seek($$mdat[0], 0) or $et->Error('Seek error'), last; + if ($$mdat[1]) { + my $result = Image::ExifTool::CopyBlock($raf, $outfile, $$mdat[1] - $$mdat[0]); + defined $result or $rtnVal = 0, last; + $result or $et->Error("Truncated mdat atom"), last; + } else { + # mdat continues to end of file + my $buff; + while ($raf->Read($buff, 65536)) { + Write($outfile, $buff) or $rtnVal = 0, last; + } + } + } + } + + # write the stuff that must come last + Write($outfile, $writeLast) or $rtnVal = 0 if $writeLast; - return $dataPt ? ($rtnVal ? $$outfile : undef) : $rtnVal; + return $rtnVal; } #------------------------------------------------------------------------------ @@ -312,7 +1790,7 @@ ($$$) sub WriteMOV($$) { my ($et, $dirInfo) = @_; - $et or return 1; + $et or return 1; # allow dummy access to autoload this package my $raf = $$dirInfo{RAF} or return 0; my ($buff, $ftype); @@ -325,15 +1803,16 @@ ($$) my $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main'); return 0 unless $$tagTablePtr{$tag}; - # determine the file type + # determine the file type (by default, assume MP4 if 'ftyp' exists + # without 'qt ' as a compatible brand, but HEIC is an exception) if ($tag eq 'ftyp' and $size >= 12 and $size < 100000 and $raf->Read($buff, $size-8) == $size-8 and $buff !~ /^(....)+(qt )/s) { - # file is MP4 format if 'ftyp' exists without 'qt ' as a compatible brand - if ($buff =~ /^(heic|mif1|msf1|heix|hevc|hevx)/) { + if ($buff =~ /^crx /) { + $ftype = 'CR3', + } elsif ($buff =~ /^(heic|mif1|msf1|heix|hevc|hevx|avif)/) { $ftype = 'HEIC'; - $et->Error("Can't currently write HEIC/HEIF files"); } else { $ftype = 'MP4'; } @@ -341,14 +1820,17 @@ ($$) $ftype = 'MOV'; } $et->SetFileType($ftype); # need to set "FileType" tag for a Condition - $et->InitWriteDirs($dirMap{$ftype}, 'XMP'); + $et->InitWriteDirs($dirMap{$ftype}, 'XMP', 'QuickTime'); $$et{DirMap} = $dirMap{$ftype}; # need access to directory map when writing + # track tags globally to avoid creating multiple tags in the case of duplicate directories + $$et{DidTag} = { }; SetByteOrder('MM'); $raf->Seek(0,0); # write the file $$dirInfo{Parent} = ''; $$dirInfo{DirName} = 'MOV'; + $$dirInfo{ChunkOffset} = [ ]; # (just to be safe) return WriteQuickTime($et, $dirInfo, $tagTablePtr) ? 1 : -1; } @@ -371,7 +1853,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/WriteXMP.pl b/src/Image-ExifTool/lib/Image/ExifTool/WriteXMP.pl index 9dec862e..927bcdf8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/WriteXMP.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/WriteXMP.pl @@ -45,7 +45,7 @@ package Image::ExifTool::XMP; my $xmpClose = "</x:xmpmeta>\n"; my $pktCloseW = "<?xpacket end='w'?>"; # writable by default my $pktCloseR = "<?xpacket end='r'?>"; -my $noPad; +my ($sp, $nl); #------------------------------------------------------------------------------ # Get XMP opening tag (and set x:xmptk appropriately) @@ -90,11 +90,11 @@ ($;$) #------------------------------------------------------------------------------ # Validate XMP property -# Inputs: 0) ExifTool ref, 1) validate hash ref +# Inputs: 0) ExifTool ref, 1) validate hash ref, 2) attribute hash ref # - issues warnings if problems detected -sub ValidateProperty($$) +sub ValidateProperty($$;$) { - my ($et, $propList) = @_; + my ($et, $propList, $attr) = @_; if ($$et{XmpValidate} and @$propList > 2) { if ($$propList[0] =~ /^x:x[ma]pmeta$/ and @@ -105,10 +105,23 @@ ($$) if ($$propList[-1] =~ /^rdf:(Bag|Seq|Alt)$/) { $et->Warn("Ignored empty $$propList[-1] list for $$propList[-2]", 1); } else { + if ($$propList[-2] eq 'rdf:Alt' and $attr) { + my $lang = $$attr{'xml:lang'}; + if ($lang and @$propList >= 5) { + my $langPath = join('/', @$propList[3..($#$propList-2)]); + my $valLang = $$et{XmpValidateLangAlt} || ($$et{XmpValidateLangAlt} = { }); + $$valLang{$langPath} or $$valLang{$langPath} = { }; + if ($$valLang{$langPath}{$lang}) { + $et->WarnOnce("Duplicate language ($lang) in lang-alt list: $langPath"); + } else { + $$valLang{$langPath}{$lang} = 1; + } + } + } my $xmpValidate = $$et{XmpValidate}; my $path = join('/', @$propList[3..$#$propList]); if (defined $$xmpValidate{$path}) { - $et->Warn("Duplicate XMP property: $path") if defined $$xmpValidate{$path}; + $et->Warn("Duplicate XMP property: $path"); } else { $$xmpValidate{$path} = 1; } @@ -124,7 +137,7 @@ ($$) #------------------------------------------------------------------------------ # Check XMP date values for validity and format accordingly -# Inputs: 1) date string +# Inputs: 1) EXIF-format date string # Returns: XMP date/time string (or undef on error) sub FormatXMPDate($) { @@ -324,9 +337,8 @@ ($$;$$$$) # add required properties if this is a list push @propList, "rdf:$listType", 'rdf:li 10' if $listType and $listType ne '1'; # set PropertyPath for all flattened tags of this structure if necessary - # (note: don't do this for variable-namespace structures (undef NAMESPACE)) my $strTable = $$tagInfo{Struct}; - if ($strTable and $$strTable{NAMESPACE} and not ($parentID and + if ($strTable and not ($parentID and # must test NoSubStruct flag to avoid infinite recursion (($$tagTablePtr{$parentID} and $$tagTablePtr{$parentID}{NoSubStruct}) or length $parentID > 500))) # avoid deep recursion @@ -494,7 +506,7 @@ ($$) next if $$nsUsed{$ns}; my $uri = $nsURI{$ns}; unless ($uri) { - warn "No URI for namepace prefix $ns!\n"; + warn "No URI for namespace prefix $ns!\n"; next; } my $ns2; @@ -543,6 +555,36 @@ ($$$$;$) } } +#------------------------------------------------------------------------------ +# Hack to use XMP writer for SphericalVideoXML +# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref +# Returns: SphericalVideoXML data +sub WriteGSpherical($$$) +{ + my ($et, $dirInfo, $tagTablePtr) = @_; + $$dirInfo{Compact} = 1, + my $dataPt = $$dirInfo{DataPt}; + if ($dataPt and $$dataPt) { + # make it look like XMP for writing + my $buff = $$dataPt; + $buff =~ s/<rdf:SphericalVideo/<?xpacket begin='.*?' id='W5M0MpCehiHzreSzNTczkc9d'?>\n<x:xmpmeta xmlns:x='adobe:ns:meta\/'><rdf:RDF/; + $buff =~ s/\s*xmlns:GSpherical/>\n<rdf:Description xmlns:GSpherical/s; + $buff =~ s/<\/rdf:SphericalVideo>/<\/rdf:Description>/; + $buff .= "</rdf:RDF></x:xmpmeta><?xpacket end='w'?>"; + $$dirInfo{DataPt} = \$buff; + $$dirInfo{DirLen} = length($buff) - ($$dirInfo{DirStart} || 0); + } + my $xmp = Image::ExifTool::XMP::WriteXMP($et, $dirInfo, $tagTablePtr); + if ($xmp) { + # change back to rdf:SphericalVideo structure + $xmp =~ s/^<\?xpacket begin.*?<rdf:RDF/<rdf:SphericalVideo\n/s; + $xmp =~ s/>\s*<rdf:Description rdf:about=''\s*/\n /; + $xmp =~ s/\s*<\/rdf:Description>\s*(<\/rdf:RDF>)/\n<\/rdf:SphericalVideo>$1/s; + $xmp =~ s/\s*<\/rdf:RDF>\s*<\/x:xmpmeta>.*//s; + } + return $xmp; +} + #------------------------------------------------------------------------------ # Utility routine to encode data in base64 # Inputs: 0) binary data string, 1) flag to avoid inserting newlines @@ -604,13 +646,12 @@ ($$$$$$) push @$startPt, length($$dataPt); # add end offset to list my $newData = substr($$dataPt, 0, $$startPt[0]); my $guid = '0' x 32; - my $sp = $noPad ? '' : ' '; # write the required xmpNote:HasExtendedXMP property - $newData .= "\n$sp<$rdfDesc rdf:about='${about}'\n$sp${sp}xmlns:xmpNote='$nsURI{xmpNote}'"; - if ($et->Options('XMPShorthand')) { + $newData .= "$nl$sp<$rdfDesc rdf:about='${about}'\n$sp${sp}xmlns:xmpNote='$nsURI{xmpNote}'"; + if ($$et{OPTIONS}{Compact}{Shorthand}) { $newData .= "\n$sp${sp}xmpNote:HasExtendedXMP='${guid}'/>\n"; } else { - $newData .= ">\n$sp$sp<xmpNote:HasExtendedXMP>$guid</xmpNote:HasExtendedXMP>\n$sp</$rdfDesc>\n"; + $newData .= ">$nl$sp$sp<xmpNote:HasExtendedXMP>$guid</xmpNote:HasExtendedXMP>$nl$sp</$rdfDesc>\n"; } my ($i, %descSize, $start); @@ -645,49 +686,49 @@ ($$$$$$) # Close out bottom-level property # Inputs: 0) current property path list ref, 1) longhand properties at each resource # level, 2) shorthand properties at each resource level, 3) resource flag for -# each property path level (set only if XMPShorthand is enabled) +# each property path level (set only if Shorthand is enabled) sub CloseProperty($$$$) { my ($curPropList, $long, $short, $resFlag) = @_; my $prop = pop @$curPropList; $prop =~ s/ .*//; # remove list index if it exists - my $pad = $noPad ? '' : ' ' x (scalar(@$curPropList) + 1); + my $pad = $sp x (scalar(@$curPropList) + 1); if ($$resFlag[@$curPropList]) { # close this XMP structure with possible shorthand properties if (length $$short[-1]) { if (length $$long[-1]) { # require a new Description if both longhand and shorthand properties - $$long[-2] .= ">\n$pad<$rdfDesc"; - $$short[-1] .= ">\n"; - $$long[-1] .= "$pad</$rdfDesc>\n"; + $$long[-2] .= ">$nl$pad<$rdfDesc"; + $$short[-1] .= ">$nl"; + $$long[-1] .= "$pad</$rdfDesc>$nl"; } else { # simply close empty property if all shorthand - $$short[-1] .= "/>\n"; + $$short[-1] .= "/>$nl"; } } else { # use "parseType" instead of opening a new Description $$long[-2] .= ' rdf:parseType="Resource"'; - $$short[-1] = length $$long[-1] ? ">\n" : "/>\n"; + $$short[-1] = length $$long[-1] ? ">$nl" : "/>$nl"; } - $$long[-1] .= "$pad</$prop>\n" if length $$long[-1]; + $$long[-1] .= "$pad</$prop>$nl" if length $$long[-1]; $$long[-2] .= $$short[-1] . $$long[-1]; pop @$short; pop @$long; } elsif (defined $$resFlag[@$curPropList]) { # close this top level Description with possible shorthand values if (length $$long[-1]) { - $$long[-2] .= $$short[-1] . ">\n" . $$long[-1] . "$pad</$prop>\n"; + $$long[-2] .= $$short[-1] . ">$nl" . $$long[-1] . "$pad</$prop>$nl"; } else { - $$long[-2] .= $$short[-1] . "/>\n"; # empty element (ie. all shorthand) + $$long[-2] .= $$short[-1] . "/>$nl"; # empty element (ie. all shorthand) } $$short[-1] = $$long[-1] = ''; } else { # close this property (no chance of shorthand) - $$long[-1] .= "$pad</$prop>\n"; + $$long[-1] .= "$pad</$prop>$nl"; unless (@$curPropList) { # add properties now that this top-level Description is complete - $$long[-2] .= ">\n" . $$long[-1]; + $$long[-2] .= ">$nl" . $$long[-1]; $$long[-1] = ''; } } @@ -696,8 +737,8 @@ ($$$$) #------------------------------------------------------------------------------ # Write XMP information -# Inputs: 0) ExifTool object reference, 1) source dirInfo reference, -# 2) [optional] tag table reference +# Inputs: 0) ExifTool ref, 1) source dirInfo ref (with optional WriteGroup), +# 2) [optional] tag table ref # Returns: with tag table: new XMP data (may be empty if no XMP data) or undef on error # without tag table: 1 on success, 0 if not valid XMP file, -1 on write error # Notes: May set dirInfo InPlace flag to rewrite with specified DirLen (=2 to allow larger) @@ -715,11 +756,10 @@ ($$;$) my $xmpFile = (not $tagTablePtr); # this is an XMP data file if no $tagTablePtr # prefer XMP over other metadata formats in some types of files my $preferred = $xmpFile || ($$et{PreferredGroup} and $$et{PreferredGroup} eq 'XMP'); - my $verbose = $et->Options('Verbose'); - my $compact = $et->Options('Compact') || 0; + my $verbose = $$et{OPTIONS}{Verbose}; + my %compact = ( %{$$et{OPTIONS}{Compact}} ); # (make a copy so we can change settings) my $dirLen = $$dirInfo{DirLen}; $dirLen = length($$dataPt) if not defined $dirLen and $dataPt; - $noPad = ($compact > 1); # # extract existing XMP information into %capture hash # @@ -736,6 +776,9 @@ ($$;$) delete $$et{XMP_IS_XML}; delete $$et{XMP_IS_SVG}; + # set current padding characters + ($sp, $nl) = ($compact{NoIndent} ? '' : ' ', $compact{NoNewline} ? '' : "\n"); + # get value for new rdf:about my $tagInfo = $Image::ExifTool::XMP::rdf{about}; if (defined $$et{NEW_VALUE}{$tagInfo}) { @@ -816,7 +859,7 @@ ($$;$) # if (%{$$et{DEL_GROUP}} and (grep /^XMP-.+$/, keys %{$$et{DEL_GROUP}} or # (logic is a bit more complex for group names in exiftool XML files) - grep m{^http://ns.exiftool.ca/}, values %nsUsed)) + grep m{^http://ns.exiftool.(?:ca|org)/}, values %nsUsed)) { my $del = $$et{DEL_GROUP}; my $path; @@ -827,7 +870,7 @@ ($$;$) $ns = $stdXlatNS{$ns} if $stdXlatNS{$ns}; my ($grp, @g); # no "XMP-" added to most groups in exiftool RDF/XML output file - if ($nsUsed{$ns} and (@g = ($nsUsed{$ns} =~ m{^http://ns.exiftool.ca/(.*?)/(.*?)/}))) { + if ($nsUsed{$ns} and (@g = ($nsUsed{$ns} =~ m{^http://ns.exiftool.(?:ca|org)/(.*?)/(.*?)/}))) { if ($g[1] =~ /^\d/) { $grp = "XML-$g[0]"; #(all XML-* groups stored as uppercase DEL_GROUP key) @@ -861,10 +904,12 @@ ($$;$) # get hash of all information we want to change # (sorted by tag name so alternate languages come last, but with structures # first so flattened tags may be used to override individual structure elements) - my @tagInfoList; + my (@tagInfoList, $delLangPath, %delLangPaths, %delAllLang, $firstNewPath); + my $writeGroup = $$dirInfo{WriteGroup}; foreach $tagInfo (sort ByTagName $et->GetNewTagInfoList()) { next unless $et->GetGroup($tagInfo, 0) eq 'XMP'; next if $$tagInfo{Name} eq 'XMP'; # (ignore full XMP block if we didn't write it already) + next if $writeGroup and $writeGroup ne $$et{NEW_VALUE}{$tagInfo}{WriteGroup}; if ($$tagInfo{Struct}) { unshift @tagInfoList, $tagInfo; } else { @@ -872,6 +917,7 @@ ($$;$) } } foreach $tagInfo (@tagInfoList) { + my @delPaths; # list of deleted paths my $tag = $$tagInfo{TagID}; my $path = GetPropertyPath($tagInfo); unless ($path) { @@ -987,9 +1033,33 @@ ($$;$) my $nvHash = $et->GetNewValueHash($tagInfo); my $overwrite = $et->IsOverwriting($nvHash); my $writable = $$tagInfo{Writable} || ''; - my (%attrs, $deleted, $added, $existed); + my (%attrs, $deleted, $added, $existed, $newLang); + # set up variables to save/restore paths of deleted lang-alt tags + if ($writable eq 'lang-alt') { + $newLang = lc($$tagInfo{LangCode} || 'x-default'); + if ($delLangPath and $delLangPath eq $path) { + # restore paths of deleted entries for this language + @delPaths = @{$delLangPaths{$newLang}} if $delLangPaths{$newLang}; + } else { + undef %delLangPaths; + $delLangPath = $path; # base path for deleted lang-alt tags + undef %delAllLang; + undef $firstNewPath; # reset first path for new lang-alt tag + } + if (%delAllLang) { + # add missing paths to delete list for entries where all languages were deleted + my ($prefix, $reSort); + foreach $prefix (keys %delAllLang) { + next if grep /^$prefix/, @delPaths; + push @delPaths, "${prefix}10"; + $reSort = 1; + } + @delPaths = sort @delPaths if $reSort; + } + } # delete existing entry if necessary if ($isStruct) { + # delete all structure (or pseudo-structure) elements require 'Image/ExifTool/XMPStruct.pl'; ($deleted, $added, $existed) = DeleteStruct($et, \%capture, \$path, $nvHash, \$changed); next unless $deleted or $added or $et->IsOverwriting($nvHash); @@ -999,7 +1069,7 @@ ($$;$) # take attributes from old values if they exist %attrs = %{$$cap[1]}; if ($overwrite) { - my ($delPath, $oldLang, $delLang, $addLang, @matchingPaths); + my ($oldLang, $delLang, $addLang, @matchingPaths, $langPathPat, %langsHere); # check to see if this is an indexed list item if ($path =~ / /) { my $pp; @@ -1008,17 +1078,24 @@ ($$;$) } else { push @matchingPaths, $path; } + my $oldOverwrite = $overwrite; foreach $path (@matchingPaths) { my ($val, $attrs) = @{$capture{$path}}; if ($writable eq 'lang-alt') { + # get original language code (lc for comparisons) + $oldLang = lc($$attrs{'xml:lang'} || 'x-default'); + # revert to original overwrite flag if this is in a different structure + if (not $langPathPat or $path !~ /^$langPathPat$/) { + $overwrite = $oldOverwrite; + ($langPathPat = $path) =~ s/\d+$/\\d+/; + } + # remember languages in this lang-alt list + $langsHere{$langPathPat}{$oldLang} = 1; unless (defined $addLang) { # add to lang-alt list by default if creating this tag from scratch $addLang = $$nvHash{IsCreating} ? 1 : 0; } - # get original language code (lc for comparisons) - $oldLang = lc($$attrs{'xml:lang'} || 'x-default'); if ($overwrite < 0) { - my $newLang = lc($$tagInfo{LangCode} || 'x-default'); next unless $oldLang eq $newLang; # only add new tag if we are overwriting this one # (note: this won't match if original XML contains CDATA!) @@ -1058,9 +1135,23 @@ ($$;$) } # save attributes and path from first deleted property # so we can replace it exactly - unless ($delPath) { - %attrs = %$attrs; - $delPath = $path; + %attrs = %$attrs unless @delPaths; + if ($writable eq 'lang-alt') { + $langsHere{$langPathPat}{$oldLang} = 0; # (lang was deleted) + } + # save deleted paths so we can replace the same elements + # (separately for each language of a lang-alt list) + if ($writable ne 'lang-alt' or $oldLang eq $newLang) { + push @delPaths, $path; + } else { + $delLangPaths{$oldLang} or $delLangPaths{$oldLang} = [ ]; + push @{$delLangPaths{$oldLang}}, $path; + } + # keep track of paths where we deleted all languages of a lang-alt tag + if ($delLang) { + my $p; + ($p = $path) =~ s/\d+$//; + $delAllLang{$p} = 1; } # delete this tag delete $capture{$path}; @@ -1072,14 +1163,28 @@ ($$;$) delete $capture{"$pp/rdf:type"} if @a == 1; } } - next unless $delPath or $$tagInfo{List} or $addLang; - if ($delPath) { - $path = $delPath; + next unless @delPaths or $$tagInfo{List} or $addLang; + if (@delPaths) { + $path = shift @delPaths; + # make sure new path is unique + while ($capture{$path}) { + last unless $path =~ s/ \d(\d+)$/' '.length($1+1).($1+1)/e; + } $deleted = 1; } else { # don't change tag if we couldn't delete old copy # unless this is a list or an lang-alt tag next unless $$tagInfo{List} or $oldLang; + # avoid adding duplicate entry to lang-alt in a list + if ($writable eq 'lang-alt' and %langsHere) { + foreach (sort keys %langsHere) { + next unless $path =~ /^$_$/; + last unless $langsHere{$_}{$newLang}; + $path =~ /(.* )\d(\d+)(.*? \d+)$/ or $et->Error('Internal error writing lang-alt list'), last; + my $nxt = $2 + 1; + $path = $1 . length($nxt) . ($nxt) . $3; # step to next index + } + } # (match last index to put in same lang-alt list for Bag of lang-alt items) $path =~ m/.* (\d+)/g or warn "Internal error: no list index!\n", next; $added = $1; @@ -1087,7 +1192,15 @@ ($$;$) } else { # we are never overwriting, so we must be adding to a list # match the last index unless this is a list of lang-alt lists - my $pat = $writable eq 'lang-alt' ? '.* (\d+)(.*? \d+)' : '.* (\d+)'; + my $pat = '.* (\d+)'; + if ($writable eq 'lang-alt') { + if ($firstNewPath) { + $path = $firstNewPath; + $overwrite = 1; # necessary to put x-default entry first below + } else { + $pat = '.* (\d+)(.*? \d+)'; + } + } if ($path =~ m/$pat/g) { $added = $1; # set position to end of matching index number @@ -1104,7 +1217,7 @@ ($$;$) $$tagInfo{LangCode} eq 'x-default')) { my $saveCap = $capture{$path}; - for (;;) { + while ($saveCap) { my $p = $path; substr($p, $pos, $len) = length($nxt) . $nxt; # increment index in the path of the existing item @@ -1116,10 +1229,9 @@ ($$;$) } } else { # add to end of list - for (;;) { + while ($capture{$path}) { my $try = length($nxt) . $nxt; substr($path, $pos, $len) = $try; - last unless $capture{$path}; $len = length $try; ++$nxt; } @@ -1142,8 +1254,10 @@ ($$;$) my @newValues = $et->GetNewValue($nvHash) or next; # set language attribute for lang-alt lists - $attrs{'xml:lang'} = $$tagInfo{LangCode} || 'x-default' if $writable eq 'lang-alt'; - + if ($writable eq 'lang-alt') { + $attrs{'xml:lang'} = $$tagInfo{LangCode} || 'x-default'; + $firstNewPath = $path if defined $added; # save path of first lang-alt tag added + } # add new value(s) to %capture hash my $subIdx; for (;;) { @@ -1164,7 +1278,9 @@ ($$;$) $et->Warn("$grp:$$tagInfo{Name} written as a literal because value is not a valid URI", 1); # fall through to write as a string literal } - delete $attrs{'rdf:resource'}; # (remove existing resource if necessary) + # remove existing value and/or resource attribute if they exist + delete $attrs{'rdf:value'}; + delete $attrs{'rdf:resource'}; $capture{$path} = [ $newValue, \%attrs ]; last; } @@ -1182,15 +1298,23 @@ ($$;$) # match last index except for lang-alt items where we want to put each # item in a different lang-alt list (so match the 2nd-last for these) my $pat = $writable eq 'lang-alt' ? '.* (\d+)(.*? \d+)' : '.* (\d+)'; - $path =~ m/$pat/g or warn("Internal error: no list index for $tag!\n"), next; + pos($path) = 0; + $path =~ m/$pat/g or warn("Internal error: no list index for $tag ($path) ($pat)!\n"), next; my $idx = $1; my $len = length $1; my $pos = pos($path) - $len - ($2 ? length $2 : 0); - # generate unique list sub-indices to store additional values in sequence + # use sub-indices if necessary to store additional values in sequence if ($subIdx) { $idx = substr($idx, 0, -length($subIdx)); # remove old sub-index $subIdx = substr($subIdx, 1) + 1; $subIdx = length($subIdx) . $subIdx; + } elsif (@delPaths) { + $path = shift @delPaths; + # make sure new path is unique + while ($capture{$path}) { + last unless $path =~ s/ \d(\d+)$/' '.length($1+1).($1+1)/e; + } + next; } else { $subIdx = '10'; } @@ -1228,7 +1352,6 @@ ($$;$) # write out the new XMP information (serialize it) # # start writing the XMP data - my $useShorthand = $et->Options('XMPShorthand'); my (@long, @short, @resFlag); $long[0] = $long[1] = $short[0] = ''; if ($$et{XMP_NO_XPACKET}) { @@ -1306,7 +1429,7 @@ ($$;$) my ($path2, $ns2); foreach $path2 (@pathList) { my @ns2s = ($path2 =~ m{(?:^|/)([^/]+?):}g); - my $opening = 0; + my $opening = $compact{OneDesc} ? 1 : 0; foreach $ns2 (@ns2s) { next if $ns2 eq 'rdf'; $nsNew{$ns2} and ++$opening, next; @@ -1335,18 +1458,17 @@ ($$;$) # open the new description $prop = $rdfDesc; %nsCur = %nsNew; # save current namespaces - my $sp = $noPad ? '' : ' '; my @ns = sort keys %nsCur; - $long[-2] .= "\n$sp<$prop rdf:about='${about}'"; + $long[-2] .= "$nl$sp<$prop rdf:about='${about}'"; # generate et:toolkit attribute if this is an exiftool RDF/XML output file - if (@ns and $nsCur{$ns[0]} =~ m{^http://ns.exiftool.ca/}) { + if (@ns and $nsCur{$ns[0]} =~ m{^http://ns.exiftool.(?:ca|org)/}) { $long[-2] .= "\n$sp${sp}xmlns:et='http://ns.exiftool.ca/1.0/'" . " et:toolkit='Image::ExifTool $Image::ExifTool::VERSION'"; } $long[-2] .= "\n$sp${sp}xmlns:$_='$nsCur{$_}'" foreach @ns; push @curPropList, $prop; - # set resFlag to 0 to indicate base description when XMPShorthand enabled - $resFlag[0] = 0 if $useShorthand; + # set resFlag to 0 to indicate base description when Shorthand enabled + $resFlag[0] = 0 if $compact{Shorthand}; } my ($val, $attrs) = @{$capture{$path}}; $debug and print "$path = $val\n"; @@ -1358,34 +1480,34 @@ ($$;$) $prop =~ s/ .*//; # remove list index if it exists # (we may add parseType and shorthand properties later, # so leave off the trailing ">" for now) - $long[-1] .= ($noPad ? '' : ' ' x scalar(@curPropList)) . "<$prop"; + $long[-1] .= ($compact{NoIndent} ? '' : ' ' x scalar(@curPropList)) . "<$prop"; if ($prop ne $rdfDesc and ($propList[$n+1] !~ /^rdf:/ or ($propList[$n+1] eq 'rdf:type' and $n+1 == $#propList))) { # check for empty structure if ($propList[$n+1] =~ /:~dummy~$/) { - $long[-1] .= " rdf:parseType='Resource'/>\n"; + $long[-1] .= " rdf:parseType='Resource'/>$nl"; pop @curPropList; $dummy = 1; last; } - if ($useShorthand) { + if ($compact{Shorthand}) { $resFlag[$#curPropList] = 1; push @long, ''; push @short, ''; } else { # use rdf:parseType='Resource' to avoid new 'rdf:Description' - $long[-1] .= " rdf:parseType='Resource'>\n"; + $long[-1] .= " rdf:parseType='Resource'>$nl"; } } else { - $long[-1] .= ">\n"; # (will be no shorthand properties) + $long[-1] .= ">$nl"; # (will be no shorthand properties) } } my $prop2 = pop @propList; # get new property name # add element unless it was a dummy structure field unless ($dummy or ($val eq '' and $prop2 =~ /:~dummy~$/)) { $prop2 =~ s/ .*//; # remove list index if it exists - my $pad = $noPad ? '' : ' ' x (scalar(@curPropList) + 1); + my $pad = $compact{NoIndent} ? '' : ' ' x (scalar(@curPropList) + 1); # (can't write as shortcut if it has attributes or CDATA) if (defined $resFlag[$#curPropList] and not %$attrs and $val !~ /<!\[CDATA\[/) { $short[-1] .= "\n$pad$prop2='${val}'"; @@ -1397,7 +1519,7 @@ ($$;$) my $quot = ($attrVal =~ /'/) ? '"' : "'"; $long[-1] .= " $attr=$quot$attrVal$quot"; } - $long[-1] .= length $val ? ">$val</$prop2>\n" : "/>\n"; + $long[-1] .= length $val ? ">$val</$prop2>$nl" : "/>$nl"; } } } @@ -1414,9 +1536,9 @@ ($$;$) $$dirInfo{ExtendedXMP} = $rtn[0]; $$dirInfo{ExtendedGUID} = $rtn[1]; # compact if necessary to fit - $compact = 1 if length($long[-2]) + 101 * $numPadLines > $maxDataLen; + $compact{NoPadding} = 1 if length($long[-2]) + 101 * $numPadLines > $maxDataLen; } - $compact = 1 if $$dirInfo{Compact}; + $compact{NoPadding} = 1 if $$dirInfo{Compact}; # # close out the XMP, clean up, and return our data # @@ -1438,7 +1560,7 @@ ($$;$) # pad to specified DirLen if ($len > $dirLen) { my $str = 'Not enough room to edit XMP in place'; - $str .= '. Try XMPShorthand option' unless $$et{OPTIONS}{XMPShorthand}; + $str .= '. Try Shorthand feature' unless $compact{Shorthand}; $et->Warn($str); return undef; } @@ -1448,7 +1570,7 @@ ($$;$) $len += length($pad) * $num; } $len < $dirLen and $long[-2] .= (' ' x ($dirLen - $len - 1)) . "\n"; - } elsif (not $compact and not $xmpFile and not $$dirInfo{ReadOnly}) { + } elsif (not $compact{NoPadding} and not $xmpFile and not $$dirInfo{ReadOnly}) { $long[-2] .= $pad x $numPadLines; } $long[-2] .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW); @@ -1491,7 +1613,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/Writer.pl b/src/Image-ExifTool/lib/Image/ExifTool/Writer.pl index 37627271..7e67e8c8 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/Writer.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/Writer.pl @@ -5,7 +5,7 @@ # # Notes: Also contains some less used ExifTool functions # -# URL: http://owl.phy.queensu.ca/~phil/exiftool/ +# URL: https://exiftool.org/ # # Revisions: 12/16/2004 - P. Harvey Created #------------------------------------------------------------------------------ @@ -28,7 +28,7 @@ package Image::ExifTool; sub ConvInv($$$$$;$$); my $loadedAllTables; # flag indicating we loaded all tables -my $advFmtSelf; # ExifTool during evaluation of advanced formatting expr +my $advFmtSelf; # ExifTool object during evaluation of advanced formatting expr # the following is a road map of where we write each directory # in the different types of files. @@ -48,6 +48,7 @@ package Image::ExifTool; MakerNotes => 'ExifIFD', CanonVRD => 'MakerNotes', # (so VRDOffset will get updated) NikonCapture => 'MakerNotes', # (to allow delete by group) + PhaseOne => 'MakerNotes', # (for editing PhaseOne SensorCalibration tags) ); my %exifMap = ( IFD1 => 'IFD0', @@ -118,22 +119,41 @@ package Image::ExifTool; XMP => [ undef, 'WriteXMP' ], ); +# RAW file types +my %rawType = ( + '3FR'=> 1, CR3 => 1, IIQ => 1, NEF => 1, RW2 => 1, + ARQ => 1, CRW => 1, K25 => 1, NRW => 1, RWL => 1, + ARW => 1, DCR => 1, KDC => 1, ORF => 1, SR2 => 1, + ARW => 1, ERF => 1, MEF => 1, PEF => 1, SRF => 1, + CR2 => 1, FFF => 1, MOS => 1, RAW => 1, SRW => 1, +); + # groups we are allowed to delete # Notes: # 1) these names must either exist in %dirMap, or be translated in InitWriteDirs()) # 2) any dependencies must be added to %excludeGroups my @delGroups = qw( - Adobe AFCP APP0 APP1 APP2 APP3 APP4 APP5 APP6 APP7 APP8 APP9 APP10 APP11 APP12 - APP13 APP14 APP15 CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix FotoStation - GlobParamIFD GPS ICC_Profile IFD0 IFD1 InteropIFD IPTC JFIF Jpeg2000 MakerNotes - Meta MetaIFD MIE MPF NikonCapture PDF PDF-update PhotoMechanic Photoshop PNG - PNG-pHYs PrintIM RMETA RSRC SubIFD Trailer XML XML-* XMP XMP-* + Adobe AFCP APP0 APP1 APP2 APP3 APP4 APP5 APP6 APP7 APP8 APP9 APP10 APP11 + APP12 APP13 APP14 APP15 CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix + FotoStation GlobParamIFD GPS ICC_Profile IFD0 IFD1 Insta360 InteropIFD IPTC + ItemList JFIF Jpeg2000 Keys MakerNotes Meta MetaIFD MIE MPF NikonCapture PDF + PDF-update PhotoMechanic Photoshop PNG PNG-pHYs PrintIM QuickTime RMETA RSRC + SubIFD Trailer UserData XML XML-* XMP XMP-* ); # family 2 group names that we can delete my @delGroup2 = qw( Audio Author Camera Document ExifTool Image Location Other Preview Printing Time Video ); +# Extra groups to delete when deleting another group +my %delMore = ( + QuickTime => [ qw(ItemList UserData Keys) ], + XMP => [ 'XMP-*' ], + XML => [ 'XML-*' ], +); + +# family 0 groups where directories should never be deleted +my %permanentDir = ( QuickTime => 1 ); # lookup for all valid family 2 groups (lower case) my %family2groups = map { lc $_ => 1 } @delGroup2, 'Unknown'; @@ -168,6 +188,7 @@ package Image::ExifTool; CanonVRD => [ 'Trailer' ], PhotoMechanic=> [ 'Trailer' ], MIE => [ 'Trailer' ], + QuickTime => [ qw(ItemList UserData Keys) ], ); # translate (lower case) wanted group when writing for tags where group name may change my %translateWantGroup = ( @@ -218,7 +239,7 @@ package Image::ExifTool; 'int64s' => [-9223372036854775808, 9223372036854775807], ); # lookup for file types with block-writable EXIF -my %blockExifTypes = map { $_ => 1 } qw(JPEG PNG JP2 MIE EXIF FLIF); +my %blockExifTypes = map { $_ => 1 } qw(JPEG PNG JP2 MIE EXIF FLIF MOV MP4); my $maxSegmentLen = 0xfffd; # maximum length of data in a JPEG segment my $maxXMPLen = $maxSegmentLen; # maximum length of XMP data in JPEG @@ -249,6 +270,7 @@ package Image::ExifTool; # NoFlat => treat flattened tags as 'unsafe' # NoShortcut => true to prevent looking up shortcut tags # ProtectSaved => protect existing new values with a save count greater than this +# IgnorePermanent => ignore attempts to delete a permanent tag # CreateGroups => [internal use] createGroups hash ref from related tags # ListOnly => [internal use] set only list or non-list tags # SetTags => [internal use] hash ref to return tagInfo refs of set tags @@ -258,12 +280,12 @@ package Image::ExifTool; # each value in the list. Internally, the new information is stored in # the following members of the $$self{NEW_VALUE}{$tagInfo} hash: # TagInfo - tag info ref -# DelValue - list ref for values to delete -# Value - list ref for values to add (not defined if deleting the tag) +# DelValue - list ref for raw values to delete +# Value - list ref for raw values to add (not defined if deleting the tag) # IsCreating - must be set for the tag to be added for the standard file types, # otherwise just changed if it already exists. This may be # overridden for file types with a PREFERRED metadata type. -# Set to 2 to create inidividual tags but not new groups +# Set to 2 to create individual tags but not new groups # EditOnly - flag set if tag should never be created (regardless of file type). # If this is set, then IsCreating must be false # CreateOnly - flag set if creating only (never edit existing tag) @@ -336,6 +358,9 @@ ($;$$%) $options{Type} = 'ValueConv' if $tag =~ s/#$//; my $convType = $options{Type} || ($$self{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv'); + # filter value if necessary + Filter($$self{OPTIONS}{FilterW}, \$value) if $convType eq 'PrintConv'; + my (@wantGroup, $family2); my $wantGroup = $options{Group}; if ($wantGroup) { @@ -423,10 +448,9 @@ ($;$$%) } } else { $$delGroup{$grp} = 1; - # add flag for XMP/XML family 1 groups if deleting all XMP - if ($grp =~ /^XM[LP]$/) { - $$delGroup{"$grp-*"} = 1; - push @donegrps, "$grp-*"; + # add extra groups to delete if necessary + if ($delMore{$grp}) { + $$delGroup{$_} = 1, push @donegrps, $_ foreach @{$delMore{$grp}}; } # remove all of this group from previous new values $self->RemoveNewValuesForGroup($grp); @@ -489,7 +513,10 @@ ($;$$%) # must load XMP table to set group1 names my $table = GetTagTable('Image::ExifTool::XMP::Main'); my $writeProc = $$table{WRITE_PROC}; - $writeProc and &$writeProc(); + if ($writeProc) { + no strict 'refs'; + &$writeProc(); + } } # fix case for known groups $wantGroup =~ s/$grpName/$grpName/i if $grpName and $grpName ne $_; @@ -503,7 +530,7 @@ ($;$$%) my $langCode; # allow language suffix of form "-en_CA" or "-<rfc3066>" on tag name if ($tag =~ /^([?*\w]+)-([a-z]{2})(_[a-z]{2})$/i or # MIE - $tag =~ /^([?*\w]+)-([a-z]{2,3}|[xi])(-[a-z\d]{2,8}(-[a-z\d]{1,8})*)?$/i) # XMP/PNG + $tag =~ /^([?*\w]+)-([a-z]{2,3}|[xi])(-[a-z\d]{2,8}(-[a-z\d]{1,8})*)?$/i) # XMP/PNG/QuickTime { $tag = $1; # normalize case of language codes @@ -567,7 +594,7 @@ ($;$$%) # the highest priority group # my (@tagInfoList, @writeAlsoList, %writeGroup, %preferred, %tagPriority); - my (%avoid, $wasProtected, $noCreate, %highestPriority); + my (%avoid, $wasProtected, $noCreate, %highestPriority, %highestQT); TAG: foreach $tagInfo (@matchingTags) { $tag = $$tagInfo{Name}; # get tag name for warnings @@ -575,17 +602,21 @@ ($;$$%) # initialize highest priority if we are starting a new tag $highestPriority{$lcTag} = -999 unless defined $highestPriority{$lcTag}; my ($priority, $writeGroup); + my $prfTag = defined $$tagInfo{Preferred} ? $$tagInfo{Preferred} : $$tagInfo{Table}{PREFERRED}; if ($wantGroup) { # a WriteGroup of All is special my $wgAll = ($$tagInfo{WriteGroup} and $$tagInfo{WriteGroup} eq 'All'); my @grp = $self->GetGroup($tagInfo); + my $hiPri = 1000; foreach $fg (@wantGroup) { my ($fam, $lcWant) = @$fg; $lcWant = $translateWantGroup{$lcWant} if $translateWantGroup{$lcWant}; # only set tag in specified group + # bump priority of preferred tag + $hiPri += $prfTag if $prfTag; if (not defined $fam) { if ($lcWant eq lc $grp[0]) { - # don't go to more generate write group of "All" + # don't go to more general write group of "All" # if something more specific was wanted $writeGroup = $grp[0] if $wgAll and not $writeGroup; next; @@ -610,9 +641,15 @@ ($;$$%) # can't yet write PreviewIFD tags (except for image) $lcWant eq 'PreviewIFD' and ++$foundMatch, next TAG; $writeGroup = $ifdName; # write to the specified IFD - } elsif ($grp[0] eq 'QuickTime' and $grp[1] eq 'Track#') { - next TAG unless $movGroup and $lcWant eq lc($movGroup); - $writeGroup = $movGroup; + } elsif ($grp[0] eq 'QuickTime') { + if ($grp[1] eq 'Track#') { + next TAG unless $movGroup and $lcWant eq lc($movGroup); + $writeGroup = $movGroup; + } else { + my $grp = $$tagInfo{Table}{WRITE_GROUP}; + next TAG unless $grp and $lcWant eq lc $grp; + $writeGroup = $grp; + } } elsif ($grp[0] eq 'MIE') { next TAG unless $mieGroup and $lcWant eq lc($mieGroup); $writeGroup = $mieGroup; # write to specific MIE group @@ -627,7 +664,7 @@ ($;$$%) } } $writeGroup or $writeGroup = ($$tagInfo{WriteGroup} || $grp[0]); - $priority = 1000; # highest priority since group was specified + $priority = $hiPri; # highest priority since group was specified } ++$foundMatch; # must do a dummy call to the write proc to autoload write package @@ -639,7 +676,10 @@ ($;$$%) my $src = GetTagTable($$table{SRC_TABLE}); $writeProc = $$src{WRITE_PROC} unless $writeProc; } - next unless $writeProc and &$writeProc(); + { + no strict 'refs'; + next unless $writeProc and &$writeProc(); + } # must still check writable flags in case of UserDefined tags my $writable = $$tagInfo{Writable}; next unless $writable or ($$table{WRITABLE} and @@ -660,6 +700,8 @@ ($;$$%) $priority = $$self{WRITE_PRIORITY}{lc($group0)} || 0; } } + # adjust priority based on Preferred level for this tag + $priority += $prfTag if $prfTag; } # don't write tag if protected my $prot = $$tagInfo{Protected}; @@ -678,6 +720,9 @@ ($;$$%) } # set priority for this tag $tagPriority{$tagInfo} = $priority; + # keep track of highest priority QuickTime tag + $highestQT{$lcTag} = $priority if $$table{GROUPS}{0} eq 'QuickTime' and + (not defined $highestQT{$lcTag} or $highestQT{$lcTag} < $priority); if ($priority > $highestPriority{$lcTag}) { $highestPriority{$lcTag} = $priority; $preferred{$lcTag} = { $tagInfo => 1 }; @@ -693,9 +738,14 @@ ($;$$%) } else { push @tagInfoList, $tagInfo; } + # special case to allow override of XMP WriteGroup + if ($writeGroup eq 'XMP') { + my $wg = $$tagInfo{WriteGroup} || $$table{WRITE_GROUP}; + $writeGroup = $wg if $wg; + } $writeGroup{$tagInfo} = $writeGroup; } - # sort tag info list in reverse order of priority (higest number last) + # sort tag info list in reverse order of priority (highest number last) # so we get the highest priority error message in the end @tagInfoList = sort { $tagPriority{$a} <=> $tagPriority{$b} } @tagInfoList; # must write any tags which also write other tags first @@ -727,7 +777,9 @@ ($;$$%) my $priority = $tagPriority{$tagInfo} or next; next if $priority == $highestPriority{$lcTag}; next if $priority < $nextHighest; - next if $$tagInfo{Avoid} or $$tagInfo{Permanent}; + my $permanent = $$tagInfo{Permanent}; + $permanent = $$tagInfo{Table}{PERMANENT} unless defined $permanent; + next if $$tagInfo{Avoid} or $permanent; next if $writeGroup{$tagInfo} eq 'MakerNotes'; if ($nextHighest < $priority) { $nextHighest = $priority; @@ -760,10 +812,12 @@ ($;$$%) my $noConv; my $writeGroup = $writeGroup{$tagInfo}; my $permanent = $$tagInfo{Permanent}; + $permanent = $$tagInfo{Table}{PERMANENT} unless defined $permanent; $writeGroup eq 'MakerNotes' and $permanent = 1 unless defined $permanent; my $wgrp1 = $self->GetWriteGroup1($tagInfo, $writeGroup); $tag = $$tagInfo{Name}; # get tag name for warnings - my $pref = $preferred{lc $tag} || { }; + my $lcTag = lc $tag; + my $pref = $preferred{$lcTag} || { }; my $shift = $options{Shift}; my $addValue = $options{AddValue}; if (defined $shift) { @@ -803,7 +857,7 @@ ($;$$%) # check to make sure this is a List or Shift tag if adding if ($addValue and not ($shift or $$tagInfo{List})) { if ($addValue eq '2') { - undef $addValue; # quitely reset this option + undef $addValue; # quietly reset this option } else { $err = "Can't add $wgrp1:$tag (not a List type)"; $verbose > 2 and print $out "$err\n"; @@ -838,6 +892,7 @@ ($;$$%) next; } } elsif ($permanent) { + return 0 if $options{IgnorePermanent}; # can't delete permanent tags, so set them to DelValue or empty string instead if (defined $$tagInfo{DelValue}) { $val = $$tagInfo{DelValue}; @@ -863,6 +918,20 @@ ($;$$%) next; } } + # set group delete flag if this tag represents an entire group + if ($$tagInfo{DelGroup} and not $options{DelValue}) { + my @del = ( $tag ); + $$self{DEL_GROUP}{$tag} = 1; + # delete extra groups if necessary + if ($delMore{$tag}) { + $$self{DEL_GROUP}{$_} = 1, push(@del,$_) foreach @{$delMore{$tag}}; + } + # remove all of this group from previous new values + $self->RemoveNewValuesForGroup($tag); + $verbose and print $out " Deleting tags in: @del\n"; + ++$numSet; + next; + } $noConv = 1; # value is not defined, so don't do conversion } # apply inverse PrintConv and ValueConv conversions @@ -949,7 +1018,12 @@ ($;$$%) # set priority flag to add only the high priority info # (will only create the priority tag if it doesn't exist, # others get changed only if they already exist) - if ($$pref{$tagInfo} or $$tagInfo{Table}{PREFERRED}) { + my $prf = defined $$tagInfo{Preferred} ? $$tagInfo{Preferred} : $$tagInfo{Table}{PREFERRED}; + # hack to prefer only a single tag in the QuickTime group + if ($$tagInfo{Table}{GROUPS}{0} eq 'QuickTime') { + $prf = 0 if $tagPriority{$tagInfo} < $highestQT{$lcTag}; + } + if ($$pref{$tagInfo} or $prf) { if ($permanent or $shift) { # don't create permanent or Shift-ed tag but define IsCreating # so we know that it is the preferred tag @@ -1053,6 +1127,9 @@ ($;$$%) undef $evalWarning; #### eval WriteAlso ($val) my $v = eval $$writeAlso{$wtag}; + # we wanted to do the eval in case there are side effect, but we + # don't want to write a value for a tag that is being deleted: + undef $v unless defined $val; $@ and $evalWarning = $@; unless ($evalWarning) { ($n,$evalWarning) = $self->SetNewValue($wgrp . $wtag, $v, %opts); @@ -1196,6 +1273,8 @@ ($$;@) QuickTimeUTC => $$options{QuickTimeUTC}, RequestAll => $$options{RequestAll} || 1, # (is this still necessary now that RequestTags are being set?) RequestTags => $$options{RequestTags}, + SaveFormat => $$options{SaveFormat}, + SavePath => $$options{SavePath}, ScanForXMP => $$options{ScanForXMP}, StrictDate => defined $$options{StrictDate} ? $$options{StrictDate} : 1, Struct => $structOpt, @@ -1259,13 +1338,13 @@ ($$;@) foreach $tag (@tags) { # don't try to set errors or warnings next if $tag =~ /^(Error|Warning)\b/; - # get approprite value type if necessary + # get appropriate value type if necessary if ($opts{SrcType} and $opts{SrcType} ne $srcType) { $$info{$tag} = $srcExifTool->GetValue($tag, $opts{SrcType}); } # set value for this tag my ($n, $e) = $self->SetNewValue($tag, $$info{$tag}, %opts); - # delete this tag if we could't set it + # delete this tag if we couldn't set it $n or delete $$info{$tag}; } return $info; @@ -1492,9 +1571,8 @@ ($$;@) #------------------------------------------------------------------------------ # Get new value(s) for tag -# Inputs: 0) ExifTool object reference, 1) tag name or tagInfo hash ref +# Inputs: 0) ExifTool object reference, 1) tag name (or tagInfo or nvHash ref, not public) # 2) optional pointer to return new value hash reference (not part of public API) -# or 0) ExifTool ref, 1) new value hash reference (not part of public API) # Returns: List of new Raw values (list may be empty if tag is being deleted) # Notes: 1) Preferentially returns new value from Extra table if writable Extra tag exists # 2) Must call AFTER IsOverwriting() returns 1 to get proper value for shifted times @@ -1662,6 +1740,8 @@ ($) # Notes: Restores saved new values, but currently doesn't restore them in the # original order, so there may be some minor side-effects when restoring tags # with overlapping groups. eg) XMP:Identifier, XMP-dc:Identifier +# Also, this doesn't do the right thing for list-type tags which accumulate +# values across a save point sub RestoreNewValues($) { my $self = shift; @@ -1761,7 +1841,7 @@ ($$;$$$) # Change file name and/or directory from FileName and Directory tags # Inputs: 0) ExifTool object reference, 1) current file name (including path) # 2) new name (or undef to build from FileName and Directory tags) -# 3) option: 'Link' to create link instead of renaming file +# 3) option: 'HardLink'/'SymLink' to create hard/symbolic link instead of renaming # 'Test' to only print new file name # 4) 0 to indicate that a file will no longer exist (used for 'Test' only) # Returns: 1=name changed OK, 0=nothing changed, -1=error changing name @@ -1776,8 +1856,10 @@ ($$;$$$) # determine the new file name unless (defined $newName) { if ($opt) { - if ($opt eq 'Link') { + if ($opt eq 'HardLink' or $opt eq 'Link') { $newName = $self->GetNewValue('HardLink'); + } elsif ($opt eq 'SymLink') { + $newName = $self->GetNewValue('SymLink'); } elsif ($opt eq 'Test') { $newName = $self->GetNewValue('TestName'); } @@ -1827,9 +1909,12 @@ ($$;$$$) length $newName or $self->Warn('New file name is empty'), return -1; # don't replace existing file if ($self->Exists($newName) and (not defined $usedFlag or $usedFlag)) { - if ($file ne $newName or $opt eq 'Link') { - $self->Warn("File '${newName}' already exists"); - return -1; + if ($file ne $newName or $opt =~ /Link$/) { + # allow for case-insensitive filesystem + if ($opt =~ /Link$/ or not $self->IsSameFile($file, $newName)) { + $self->Warn("File '${newName}' already exists"); + return -1; + } } else { $self->Warn('File name is unchanged'); return 0; @@ -1847,16 +1932,40 @@ ($$;$$$) $self->Warn("Error creating directory for '${newName}'"); return -1; } - $self->VPrint(0, "Created directory for '${newName}'"); + $self->VPrint(0, "Created directory for '${newName}'\n"); } - if ($opt eq 'Link') { + if ($opt eq 'HardLink' or $opt eq 'Link') { unless (link $file, $newName) { - $self->Warn("Error creating link '${newName}'"); + $self->Warn("Error creating hard link '${newName}'"); return -1; } ++$$self{CHANGED}; $self->VerboseValue('+ HardLink', $newName); return 1; + } elsif ($opt eq 'SymLink') { + $^O eq 'MSWin32' and $self->Warn('SymLink not supported in Windows'), return -1; + $newName =~ s(^\./)(); # remove leading "./" from link name if it exists + # path to linked file must be relative to the $newName directory, but $file + # is relative to the current directory, so convert it to an absolute path + # if using a relative directory and $newName isn't in the current directory + if ($file !~ m(^/) and $newName =~ m(/)) { + unless (eval { require Cwd }) { + $self->Warn('Install Cwd to make symlinks to other directories'); + return -1; + } + $file = eval { Cwd::abs_path($file) }; + unless (defined $file) { + $self->Warn('Error in Cwd::abs_path when creating symlink'); + return -1; + } + } + unless (eval { symlink $file, $newName } ) { + $self->Warn("Error creating symbolic link '${newName}'"); + return -1; + } + ++$$self{CHANGED}; + $self->VerboseValue('+ SymLink', $newName); + return 1; } # attempt to rename the file unless ($self->Rename($file, $newName)) { @@ -1961,13 +2070,15 @@ ($$;$$) { local ($_, *EXIFTOOL_FILE2, *EXIFTOOL_OUTFILE); my ($self, $infile, $outfile, $outType) = @_; - my (@fileTypeList, $fileType, $tiffType, $hdr, $seekErr, $type, $tmpfile, $hardLink, $testName); + my (@fileTypeList, $fileType, $tiffType, $hdr, $seekErr, $type, $tmpfile); my ($inRef, $outRef, $closeIn, $closeOut, $outPos, $outBuff, $eraseIn, $raf, $fileExt); + my ($hardLink, $symLink, $testName); my $oldRaf = $$self{RAF}; my $rtnVal = 0; # initialize member variables $self->Init(); + $$self{IsWriting} = 1; # first, save original file modify date if necessary # (do this now in case we are modifying file in place and shifting date) @@ -1993,8 +2104,10 @@ ($$;$$) my ($numNew, $numPseudo) = $self->CountNewValues(); if (not defined $outfile and defined $infile) { $hardLink = $self->GetNewValue('HardLink'); + $symLink = $self->GetNewValue('SymLink'); $testName = $self->GetNewValue('TestName'); undef $hardLink if defined $hardLink and not length $hardLink; + undef $symLink if defined $symLink and not length $symLink; undef $testName if defined $testName and not length $testName; my $newFileName = $self->GetNewValue('FileName', \$nvHash); my $newDir = $self->GetNewValue('Directory'); @@ -2013,10 +2126,11 @@ ($$;$$) if ((defined $newFileName or defined $newDir) and not ref $infile) { $self->SetFileName($infile) > 0 and $rtnVal = 1; } - if (defined $hardLink or defined $testName) { + if (defined $hardLink or defined $symLink or defined $testName) { my $src = $$self{NewName}; $src = $infile unless defined $src; - $hardLink and $self->SetFileName($src, $hardLink, 'Link') and $rtnVal = 1; + $hardLink and $self->SetFileName($src, $hardLink, 'HardLink') and $rtnVal = 1; + $symLink and $self->SetFileName($src, $symLink, 'SymLink') and $rtnVal = 1; $testName and $self->SetFileName($src, $testName, 'Test') and $rtnVal = 1; } return $rtnVal; @@ -2191,6 +2305,10 @@ ($$;$$) $fileType = $tiffType; undef $rtnVal; } else { + if ($tiffType eq 'FFF') { + # (see https://exiftool.org/forum/index.php?topic=10848.0) + $self->Error('Phocus may not properly update previews of edited FFF images', 1); + } $dirInfo{Parent} = $tiffType; $rtnVal = $self->ProcessTIFF(\%dirInfo); } @@ -2382,7 +2500,8 @@ ($$;$$) # set FileCreateDate if requested (and if possible!) ++$$self{CHANGED} if $setCreateDate and $self->SetFileModifyDate($target, $createTime, 'FileCreateDate', 1) > 0; # create hard link if requested and no output filename specified (and if possible!) - ++$$self{CHANGED} if defined $hardLink and $self->SetFileName($target, $hardLink, 'Link'); + ++$$self{CHANGED} if defined $hardLink and $self->SetFileName($target, $hardLink, 'HardLink'); + ++$$self{CHANGED} if defined $symLink and $self->SetFileName($target, $symLink, 'SymLink'); defined $testName and $self->SetFileName($target, $testName, 'Test'); } } @@ -2510,6 +2629,8 @@ ($) $family == 3 and return('Doc#', 'Main'); $family == 4 and return('Copy#'); + $family == 5 and return('[too many possibilities to list]'); + $family == 6 and return(@Image::ExifTool::Exif::formatName[1..$#Image::ExifTool::Exif::formatName]); LoadAllTables(); # first load all our tables @@ -2607,7 +2728,7 @@ ($$) if ($$self{OPTIONS}{Escape} eq 'XML') { $$valPt = Image::ExifTool::XMP::UnescapeXML($$valPt); } elsif ($$self{OPTIONS}{Escape} eq 'HTML') { - $$valPt = Image::ExifTool::HTML::UnescapeHTML($$valPt); + $$valPt = Image::ExifTool::HTML::UnescapeHTML($$valPt, $$self{OPTIONS}{Charset}); } } } @@ -2635,8 +2756,8 @@ ($$$$$;$$) ($wantGroup or not defined $wantGroup)) { $listSplit = ',?\s+' if $listSplit eq '1' and $$tagInfo{AutoSplit}; - my @splitVal = split /$listSplit/, $val; - $val = \@splitVal if @splitVal > 1; + my @splitVal = split /$listSplit/, $val, -1; + $val = @splitVal > 1 ? \@splitVal : @splitVal ? $splitVal[0] : ''; } } $type = $convType || $$self{ConvType} || 'PrintConv'; @@ -2733,7 +2854,7 @@ ($$$$$;$$) last Conv; } } elsif ($conv) { - if (ref $conv eq 'HASH') { + if (ref $conv eq 'HASH' and (not exists $$tagInfo{"${type}Inv"} or $convInvList)) { my ($multi, $lc); # insert alternate language print conversions if required if ($$self{CUR_LANG} and $type eq 'PrintConv' and @@ -2810,14 +2931,16 @@ ($$$$$;$$) } #------------------------------------------------------------------------------ -# convert tag names to values in a string (eg. '${EXIF:ISO}x $$' --> '100x $') +# Convert tag names to values or variables in a string +# (eg. '${EXIF:ISO}x $$' --> '100x $' without hash ref, or "$info{'EXIF:ISO'}x $" with) # Inputs: 0) ExifTool object ref, 1) reference to list of found tags # 2) string with embedded tag names, 3) Options: # undef - set missing tags to '' # 'Error' - issue minor error on missing tag (and return undef) # 'Warn' - issue minor warning on missing tag (and return undef) # 'Silent' - just return undef on missing tag (no errors/warnings) -# Hash ref - hash for return of tag/value pairs +# Hash ref - defined to interpolate as variables in string instead of values +# --> receives tag/value pairs for interpolation of the variables # 4) document group name if extracting from a specific document # 5) hash ref to cache tag keys for subsequent calls in document loop # Returns: string with embedded tag values (or '$info{TAGNAME}' entries with Hash ref option) @@ -2833,7 +2956,7 @@ ($$$;$$$) local $_; my ($self, $foundTags, $line, $opt, $docGrp, $cache) = @_; my $rtnStr = ''; - my $docNum; + my ($docNum, $tag); if ($docGrp) { $docNum = $docGrp =~ /(\d+)$/ ? $1 : 0; } else { @@ -2857,7 +2980,7 @@ ($$$;$$$) } # allow trailing '#' to indicate ValueConv value $type = 'ValueConv' if $line =~ s/^#//; - # (undocumented feature to allow '@' to evaluate list values separately, but only in braces) + # special advanced formatting '@' feature to evaluate list values separately if ($bra and $line =~ s/^\@(#)?//) { $asList = 1; $type = 'ValueConv' if $1; @@ -2886,8 +3009,9 @@ ($$$;$$$) for (;;) { # temporarily reset ListJoin option if evaluating list values separately - my $oldListJoin = $self->Options(ListJoin => undef) if $asList; - my $tag = shift @tags; + my $oldListJoin; + $oldListJoin = $self->Options(ListJoin => undef) if $asList; + $tag = shift @tags; my $lcTag = lc $tag; if ($cache and $lcTag !~ /(^|:)all$/) { # remove group from tag name (but not lower-case version) @@ -2914,7 +3038,10 @@ ($$$;$$$) } } my $doc = $lcTag =~ /\b(main|doc(\d+)):/ ? ($2 || 0) : $docNum; - $val = $self->GetValue($$cacheTag[$doc], $type) if $$cacheTag[$doc]; + if ($$cacheTag[$doc]) { + $tag = $$cacheTag[$doc]; + $val = $self->GetValue($tag, $type); + } } else { # add document number to tag if specified and it doesn't already exist if ($docGrp and $lcTag !~ /\b(main|doc\d+):/) { @@ -3098,13 +3225,52 @@ ($) return 1 if $$tagInfo{Table}{WRITABLE}; # must call WRITE_PROC to autoload writer because this may set the writable tag my $writeProc = $$tagInfo{Table}{WRITE_PROC}; - next unless $writeProc; - &$writeProc(); # dummy call to autoload writer - return 1 if $$tagInfo{Writable}; + if ($writeProc) { + no strict 'refs'; + &$writeProc(); # dummy call to autoload writer + return 1 if $$tagInfo{Writable}; + } } return 0; } +#------------------------------------------------------------------------------ +# Check to see if these are the same file +# Inputs: 0) ExifTool ref, 1) first file name, 2) second file name +# Returns: true if file names reference the same file +sub IsSameFile($$$) +{ + my ($self, $file, $file2) = @_; + return 0 unless lc $file eq lc $file2; # (only looking for differences in case) + my ($isSame, $interrupted); + my $tmp1 = "${file}_ExifTool_tmp_$$"; + my $tmp2 = "${file2}_ExifTool_tmp_$$"; + { + local *TMP1; + local $SIG{INT} = sub { $interrupted = 1 }; + if ($self->Open(\*TMP1, $tmp1, '>')) { + close TMP1; + $isSame = 1 if $self->Exists($tmp2); + $self->Unlink($tmp1); + } + } + if ($interrupted and $SIG{INT}) { + no strict 'refs'; + &{$SIG{INT}}(); + } + return $isSame; +} + +#------------------------------------------------------------------------------ +# Is this a raw file type? +# Inputs: 0) Exiftool ref +# Returns: true if FileType is a type of RAW image +sub IsRawType($) +{ + my $self = shift; + return $rawType{$$self{FileType}}; +} + #------------------------------------------------------------------------------ # Create directory for specified file # Inputs: 0) ExifTool ref, 1) complete file name including path @@ -3220,6 +3386,8 @@ ($$) if ($val =~ /^Unknown\s*\((.*)\)$/i) { $val = $1; # was unknown if ($val =~ /^0x([\da-fA-F]+)$/) { + # disable "Hexadecimal number > 0xffffffff non-portable" warning + local $SIG{'__WARN__'} = sub { }; $val = hex($val); # convert hex value } } else { @@ -3372,7 +3540,7 @@ ($) sub GetWriteGroup1($$) { my ($self, $tagInfo, $writeGroup) = @_; - return $writeGroup unless $writeGroup =~ /^(MakerNotes|XMP|Composite)$/; + return $writeGroup unless $writeGroup =~ /^(MakerNotes|XMP|Composite|QuickTime)$/; return $self->GetGroup($tagInfo, 1); } @@ -3387,6 +3555,7 @@ ($$) sub GetNewValueHash($$;$$$$) { my ($self, $tagInfo, $writeGroup, $opts) = @_; + return undef unless $tagInfo; my $nvHash = $$self{NEW_VALUE}{$tagInfo}; my %opts; # quick lookup for options @@ -3395,10 +3564,11 @@ ($$;$$$$) if ($writeGroup) { # find the new value in the list with the specified write group - # (QuickTime and All are special cases because all group1 tags may be updated at once) - while ($nvHash and $$nvHash{WriteGroup} ne $writeGroup and - $$nvHash{WriteGroup} !~ /^(QuickTime|All)$/) - { + while ($nvHash and $$nvHash{WriteGroup} ne $writeGroup) { + # QuickTime and All are special cases because all group1 tags may be updated at once + last if $$nvHash{WriteGroup} =~ /^(QuickTime|All)$/; + # replace existing entry if WriteGroup is 'All' (avoids confusion of forum10349) + last if $$tagInfo{WriteGroup} and $$tagInfo{WriteGroup} eq 'All'; $nvHash = $$nvHash{Next}; } } @@ -3475,7 +3645,10 @@ () $table = GetTagTable(shift @tableNames); # call write proc if it exists in case it adds tags to the table my $writeProc = $$table{WRITE_PROC}; - $writeProc and &$writeProc(); + if ($writeProc) { + no strict 'refs'; + &$writeProc(); + } # recursively scan through tables in subdirectories foreach (TagTableKeys($table)) { my @infoArray = GetTagInfoList($table,$_); @@ -3672,14 +3845,14 @@ ($$) # initialize ADD_DIRS and EDIT_DIRS hashes for all directories that need # to be created or will have tags changed in them # Inputs: 0) ExifTool object reference, 1) file type string (or map hash ref) -# 2) preferred family 0 group name for creating tags +# 2) preferred family 0 group for creating tags, 3) alternate preferred group # Notes: # - the ADD_DIRS and EDIT_DIRS keys are the directory names, and the values # are the names of the parent directories (undefined for a top-level directory) # - also initializes FORCE_WRITE lookup -sub InitWriteDirs($$;$) +sub InitWriteDirs($$;$$) { - my ($self, $fileType, $preferredGroup) = @_; + my ($self, $fileType, $preferredGroup, $altGroup) = @_; my $editDirs = $$self{EDIT_DIRS} = { }; my $addDirs = $$self{ADD_DIRS} = { }; my $fileDirs = $dirMap{$fileType}; @@ -3698,18 +3871,21 @@ ($$;$) for ($nvHash=$self->GetNewValueHash($tagInfo); $nvHash; $nvHash=$$nvHash{Next}) { # are we creating this tag? (otherwise just deleting or editing it) my $isCreating = $$nvHash{IsCreating}; - if ($isCreating) { - # if another group is taking priority, only create - # directory if specifically adding tags to this group - # or if this tag isn't being added to the priority group - $isCreating = 0 if $preferredGroup and - $preferredGroup ne $self->GetGroup($tagInfo, 0) and - $$nvHash{CreateGroups}{$preferredGroup}; - } else { - # creating this directory if any tag is preferred and has a value - $isCreating = 1 if ($preferredGroup and $$nvHash{Value} and - $preferredGroup eq $self->GetGroup($tagInfo, 0)) and - not $$nvHash{EditOnly}; + if ($preferredGroup) { + my $g0 = $self->GetGroup($tagInfo, 0); + if ($isCreating) { + # if another group is taking priority, only create + # directory if specifically adding tags to this group + # or if this tag isn't being added to the priority group + $isCreating = 0 if $preferredGroup ne $g0 and + $$nvHash{CreateGroups}{$preferredGroup} and + (not $altGroup or $altGroup ne $g0); + } else { + # create this directory if any tag is preferred and has a value + # (unless group creation is disabled via the WriteMode option) + $isCreating = 1 if $$nvHash{Value} and $preferredGroup eq $g0 and + not $$nvHash{EditOnly} and $$self{OPTIONS}{WriteMode} =~ /g/; + } } # tag belongs to directory specified by WriteGroup, or by # the Group0 name if WriteGroup not defined @@ -3719,11 +3895,11 @@ ($$;$) $dirName = 'MIE' . ($1 || ''); } my @dirNames; - # allow a group name of '*' to force writing EXIF/IPTC/XMP (ForceWrite tag) + # allow a group name of '*' to force writing EXIF/IPTC/XMP/PNG (ForceWrite tag) if ($dirName eq '*' and $$nvHash{Value}) { my $val = $$nvHash{Value}[0]; if ($val) { - foreach (qw(EXIF IPTC XMP FixBase)) { + foreach (qw(EXIF IPTC XMP PNG FixBase)) { next unless $val =~ /\b($_|All)\b/i; push @dirNames, $_; push @dirNames, 'EXIF' if $_ eq 'FixBase'; @@ -3731,6 +3907,9 @@ ($$;$) } } $dirName = shift @dirNames; + } elsif ($dirName eq 'QuickTime') { + # write to specific QuickTime group + $dirName = $self->GetGroup($tagInfo, 1); } while ($dirName) { my $parent = $$fileDirs{$dirName}; @@ -3791,7 +3970,7 @@ ($$;$) sub WriteDirectory($$$;$) { my ($self, $dirInfo, $tagTablePtr, $writeProc) = @_; - my ($out, $nvHash); + my ($out, $nvHash, $delFlag); $tagTablePtr or return undef; $out = $$self{OPTIONS}{TextOut} if $$self{OPTIONS}{Verbose}; @@ -3804,9 +3983,18 @@ ($$$;$) my $delGroup = $$self{DEL_GROUP}; # delete entire directory if specified my $grp1 = $dirName; - my $delFlag = ($$delGroup{$grp0} or $$delGroup{$grp1}); + $delFlag = ($$delGroup{$grp0} or $$delGroup{$grp1}) unless $permanentDir{$grp0}; + # (never delete an entire QuickTime group) if ($delFlag) { - unless ($blockExifTypes{$$self{FILE_TYPE}}) { + if (($grp0 =~ /^(MakerNotes)$/ or $grp1 =~ /^(IFD0|ExifIFD|MakerNotes)$/) and + $self->IsRawType() and + # allow non-permanent MakerNote directories to be deleted (ie. NikonCapture) + (not $$dirInfo{TagInfo} or not defined $$dirInfo{TagInfo}{Permanent} or + $$dirInfo{TagInfo}{Permanent})) + { + $self->WarnOnce("Can't delete $1 from $$self{FileType}",1); + undef $grp1; + } elsif (not $blockExifTypes{$$self{FILE_TYPE}}) { # restrict delete logic to prevent entire tiff image from being killed # (don't allow IFD0 to be deleted, and delete only ExifIFD if EXIF specified) if ($$self{FILE_TYPE} eq 'PSD') { @@ -3886,7 +4074,7 @@ ($$$;$) $self->Warn("Can't write EXIF as a block to $$self{FILE_TYPE} file"); last; } - # this can happen if we call WriteDirectory for an EXIF directory without going + # this can happen if we call WriteDirectory for an EXIF directory without going # through WriteTIFF as the WriteProc (which happens if conditionally replacing # the EXIF block and the condition fails), but we never want to do a block write # in this case because the EXIF block would end up with two TIFF headers @@ -3897,6 +4085,11 @@ ($$$;$) my $newVal = $self->GetNewValue($nvHash); unless (defined $newVal and length $newVal) { return '' unless $dataPt or $$dirInfo{RAF}; # nothing to do if block never existed + # don't allow MakerNotes to be removed from RAW files + if ($blockName eq 'MakerNotes' and $rawType{$$self{FileType}}) { + $self->Warn("Can't delete MakerNotes from $$self{VALUE}{FileType}",1); + return undef; + } $verb = 'Deleting'; $newVal = ''; } @@ -3906,7 +4099,9 @@ ($$$;$) return $newVal; } # guard against writing the same directory twice - if (defined $dataPt and defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos}) { + if (defined $dataPt and defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos} and + not $$dirInfo{NoRefTest}) + { my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0) + $$self{BASE}; # (Phase One P25 IIQ files have ICC_Profile duplicated in IFD0 and IFD1) if ($$self{PROCESSED}{$addr} and ($dirName ne 'ICC_Profile' or $$self{TIFF_TYPE} ne 'IIQ')) { @@ -3943,7 +4138,11 @@ ($$$;$) $$self{DIR_NAME} = $dirName; push @{$$self{PATH}}, $dirName; $$dirInfo{IsWriting} = 1; - my $newData = &$writeProc($self, $dirInfo, $tagTablePtr); + my $newData; + { + no strict 'refs'; + $newData = &$writeProc($self, $dirInfo, $tagTablePtr); + } pop @{$$self{PATH}}; # nothing changed if error occurred or nothing was created $$self{CHANGED} = $oldChanged unless defined $newData and (length($newData) or $isRewriting); @@ -4487,7 +4686,7 @@ ($$;$$) my ($self, $val, $tzFlag, $dateOnly) = @_; my ($rtnVal, $tz); # strip off timezone first if it exists - if ($val =~ s/([+-])(\d{1,2}):?(\d{2})\s*$//i) { + if ($val =~ s/([+-])(\d{1,2}):?(\d{2})\s*(DST)?$//i) { $tz = sprintf("$1%.2d:$3", $2); } elsif ($val =~ s/Z$//i) { $tz = 'Z'; @@ -4520,6 +4719,11 @@ ($$;$$) } elsif ($lib eq 'POSIX::strptime') { @a = eval { POSIX::strptime($val, $fmt) }; } else { + # protect against a negative epoch time, it can cause a hard crash in Windows + if ($^O eq 'MSWin32' and $fmt =~ /%s/ and $val =~ /-\d/) { + warn "Can't convert negative epoch time\n"; + return undef; + } @a = eval { my $t = Time::Piece->strptime($val, $fmt); return ($t->sec, $t->min, $t->hour, $t->mday, $t->_mon, $t->_year); @@ -4563,7 +4767,7 @@ ($$;$$) if (not $tz) { if (eval { require Time::Local }) { # determine timezone offset for this time - my @args = ($a[4],$a[3],$a[2],$a[1],$a[0]-1,$yr-1900); + my @args = ($a[4],$a[3],$a[2],$a[1],$a[0]-1,$yr); my $diff = Time::Local::timegm(@args) - TimeLocal(@args); $tz = TimeZoneString($diff / 60); } else { @@ -4573,7 +4777,7 @@ ($$;$$) } elsif (defined $tzFlag) { $tz = $fs = ''; # remove timezone and sub-seconds } - if (defined $ss) { + if (defined $ss and $ss < 60) { $ss = ":$ss"; } elsif ($dateOnly) { $ss = ''; @@ -4581,7 +4785,9 @@ ($$;$$) $ss = ':00'; } # construct properly formatted date/time string - $rtnVal = "$yr:$a[0]:$a[1] $a[2]:$a[3]$ss$fs$tz"; + if ($a[0]<=12 and $a[1]<=31 and $a[2]<=24 and $a[3]<=59) { + $rtnVal = "$yr:$a[0]:$a[1] $a[2]:$a[3]$ss$fs$tz"; + } } elsif ($dateOnly) { $rtnVal = join ':', $yr, @a; } @@ -4592,19 +4798,20 @@ ($$;$$) #------------------------------------------------------------------------------ # Set byte order according to our current preferences -# Inputs: 0) ExifTool object ref +# Inputs: 0) ExifTool object ref, 1) default byte order # Returns: new byte order ('II' or 'MM') and sets current byte order # Notes: takes the first of the following that is valid: # 1) ByteOrder option # 2) new value for ExifByteOrder -# 3) makenote byte order from last file read -# 4) big endian -sub SetPreferredByteOrder($) +# 3) default byte order passed to this routine +# 4) makenote byte order from last file read +# 5) big endian +sub SetPreferredByteOrder($;$) { - my $self = shift; + my ($self, $default) = @_; my $byteOrder = $self->Options('ByteOrder') || $self->GetNewValue('ExifByteOrder') || - $$self{MAKER_NOTE_BYTE_ORDER} || 'MM'; + $default || $$self{MAKER_NOTE_BYTE_ORDER} || 'MM'; unless (SetByteOrder($byteOrder)) { warn "Invalid byte order '${byteOrder}'\n" if $self->Options('Verbose'); $byteOrder = $$self{MAKER_NOTE_BYTE_ORDER} || 'MM'; @@ -4684,7 +4891,7 @@ (@) } sub Set64u(@) { - my $val = shift; + my $val = $_[0]; my $hi = int($val / 4294967296); my $lo = Set32u($val - $hi * 4294967296); $hi = Set32u($hi); @@ -5201,7 +5408,7 @@ ($$) } unless ($marker and $marker == 0xda) { $isEXV or $self->Error('Corrupted JPEG image'), return 1; - $marker and $marker ne 0xd9 and $self->Error('Corrupted EXV file'), return 1; + $marker and $marker != 0xd9 and $self->Error('Corrupted EXV file'), return 1; } $raf->Seek($pos, 0) or $self->Error('Seek error'), return 1; # @@ -5466,7 +5673,8 @@ ($$) my ($buff, $endPos, $trailInfo); my $delPreview = $$self{DEL_PREVIEW}; $trailInfo = IdentifyTrailer($raf) unless $$delGroup{Trailer}; - unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer}) { + my $nvTrail = $self->GetNewValueHash($Image::ExifTool::Extra{Trailer}); + unless ($oldOutfile or $delPreview or $trailInfo or $$delGroup{Trailer} or $nvTrail) { # blindly copy the rest of the file while ($raf->Read($buff, 65536)) { Write($outfile, $buff) or $err = 1, last; @@ -5497,7 +5705,20 @@ ($$) } # remember position of last data copied $endPos = $raf->Tell() - length($buff); - # rewrite trailers if they exist + # write new trailer if specified + if ($nvTrail) { + # access new value directly to avoid copying a potentially very large data block + if ($$nvTrail{Value} and $$nvTrail{Value}[0]) { # (note: "0" will also delete the trailer) + $self->VPrint(0, ' Writing new trailer'); + Write($outfile, $$nvTrail{Value}[0]) or $err = 1; + ++$$self{CHANGED}; + } elsif ($raf->Seek(0, 2) and $raf->Tell() != $endPos) { + $self->VPrint(0, ' Deleting trailer (', $raf->Tell() - $endPos, ' bytes)'); + ++$$self{CHANGED}; # changed if there was previously a trailer + } + last; # all done + } + # rewrite existing trailers if ($trailInfo) { my $tbuf = ''; $raf->Seek(-length($buff), 1); # seek back to just after EOI @@ -5661,7 +5882,7 @@ ($$) HexDump($segDataPt, undef, %dumpParms); } } - # group delete of APP segements + # group delete of APP segments if ($$delGroup{$dirName}) { $verbose and print $out " Deleting $dirName segment\n"; ++$$self{CHANGED}; @@ -6454,7 +6675,7 @@ ($$$) } #------------------------------------------------------------------------------ -# copy image data from one file to another +# Copy image data from one file to another # Inputs: 0) ExifTool object reference # 1) reference to list of image data [ position, size, pad bytes ] # 2) output file ref @@ -6483,7 +6704,7 @@ ($$$) } #------------------------------------------------------------------------------ -# write to binary data block +# Write to binary data block # Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref # Returns: Binary data block or undefined on error sub WriteBinaryData($$$) @@ -6524,7 +6745,6 @@ ($$$) next unless $writeInfo and $writeInfo eq $tagInfo; } # add offsets for variable-sized tags if necessary - my $varFmt; while (@varInfo and $varInfo[0][0] < $tagID) { $varSize = $varInfo[0][1]; # get accumulated variable size shift @varInfo; @@ -6556,6 +6776,8 @@ ($$$) next unless $self->IsOverwriting($nvHash, $val); my $newVal = $self->GetNewValue($nvHash); next unless defined $newVal; # can't delete from a binary table + # update DataMember with new value if necessary + $$self{$$tagInfo{DataMember}} = $newVal if $$tagInfo{DataMember}; # only write masked bits if specified my $mask = $$tagInfo{Mask}; $newVal = (($newVal << $$tagInfo{BitShift}) & $mask) | ($val & ~$mask) if $mask; @@ -6612,7 +6834,7 @@ ($$$) $$previewInfo{IsShort} = 1 unless $format eq 'int32u'; $$previewInfo{Absolute} = 1 if $$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '3'; # get the value of the Composite::PreviewImage tag - $$previewInfo{Data} = $self->GetNewValue($Image::ExifTool::Composite{PreviewImage}); + $$previewInfo{Data} = $self->GetNewValue(GetCompositeTagInfo('PreviewImage')); unless (defined $$previewInfo{Data}) { if ($offset >= 0 and $offset + $size <= $$dirInfo{DataLen}) { $$previewInfo{Data} = substr(${$$dirInfo{DataPt}},$offset,$size); @@ -6661,6 +6883,7 @@ ($$$) sub WriteTIFF($$$) { my ($self, $dirInfo, $tagTablePtr) = @_; + $self or return 1; # allow dummy access my $buff = ''; $$dirInfo{OutFile} = \$buff; return $buff if $self->ProcessTIFF($dirInfo, $tagTablePtr) > 0; @@ -6686,7 +6909,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/XMP.pm b/src/Image-ExifTool/lib/Image/ExifTool/XMP.pm index 7bf252b0..47a00d64 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/XMP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/XMP.pm @@ -49,7 +49,7 @@ use Image::ExifTool::Exif; use Image::ExifTool::GPS; require Exporter; -$VERSION = '3.17'; +$VERSION = '3.32'; @ISA = qw(Exporter); @EXPORT_OK = qw(EscapeXML UnescapeXML); @@ -62,12 +62,13 @@ sub EncodeBase64($;$); sub SaveBlankInfo($$$;$); sub ProcessBlankInfo($$$;$); sub ValidateXMP($;$); -sub ValidateProperty($$); -sub UnescapeChar($$); +sub ValidateProperty($$;$); +sub UnescapeChar($$;$); sub AddFlattenedTags($;$$); sub FormatXMPDate($); sub ConvertRational($); sub ConvertRationalList($); +sub WriteGSpherical($$$); # lookup for translating to ExifTool namespaces (and family 1 group names) %stdXlatNS = ( @@ -100,6 +101,7 @@ my %xmpNS = ( aux => 'http://ns.adobe.com/exif/1.0/aux/', album => 'http://ns.adobe.com/album/1.0/', cc => 'http://creativecommons.org/ns#', # changed 2007/12/21 - PH + crd => 'http://ns.adobe.com/camera-raw-defaults/1.0/', crs => 'http://ns.adobe.com/camera-raw-settings/1.0/', crss => 'http://ns.adobe.com/camera-raw-saved-settings/1.0/', dc => 'http://purl.org/dc/elements/1.1/', @@ -176,13 +178,16 @@ my %xmpNS = ( GSpherical=> 'http://ns.google.com/videos/1.0/spherical/', GDepth => 'http://ns.google.com/photos/1.0/depthmap/', GFocus => 'http://ns.google.com/photos/1.0/focus/', + GCamera => 'http://ns.google.com/photos/1.0/camera/', + GCreations=> 'http://ns.google.com/photos/1.0/creations/', dwc => 'http://rs.tdwg.org/dwc/index.htm', GettyImagesGIFT => 'http://xmp.gettyimages.com/gift/1.0/', LImage => 'http://ns.leiainc.com/photos/1.0/image/', + Profile => 'http://ns.google.com/photos/dd/1.0/profile/', ); # build reverse namespace lookup -my %uri2ns; +my %uri2ns = ( 'http://ns.exiftool.org/1.0/' => 'et' ); # (allow exiftool.org as well as exiftool.ca) { my $ns; foreach $ns (keys %nsURI) { @@ -558,6 +563,10 @@ my %sRetouchArea = ( Name => 'photoshop', SubDirectory => { TagTable => 'Image::ExifTool::XMP::photoshop' }, }, + crd => { + Name => 'crd', + SubDirectory => { TagTable => 'Image::ExifTool::XMP::crd' }, + }, crs => { Name => 'crs', SubDirectory => { TagTable => 'Image::ExifTool::XMP::crs' }, @@ -746,6 +755,14 @@ my %sRetouchArea = ( Name => 'GFocus', SubDirectory => { TagTable => 'Image::ExifTool::XMP::GFocus' }, }, + GCamera => { + Name => 'GCamera', + SubDirectory => { TagTable => 'Image::ExifTool::XMP::GCamera' }, + }, + GCreations => { + Name => 'GCreations', + SubDirectory => { TagTable => 'Image::ExifTool::XMP::GCreations' }, + }, dwc => { Name => 'dwc', SubDirectory => { TagTable => 'Image::ExifTool::DarwinCore::Main' }, @@ -762,6 +779,10 @@ my %sRetouchArea = ( Name => 'LImage', SubDirectory => { TagTable => 'Image::ExifTool::XMP::LImage' }, }, + Device => { + Name => 'Device', + SubDirectory => { TagTable => 'Image::ExifTool::XMP::Device' }, + }, ); # hack to allow XML containing Dublin Core metadata to be handled like XMP (eg. EPUB - see ZIP.pm) @@ -935,7 +956,7 @@ my %sPantryItem = ( This structure must have an InstanceID field, but may also contain any other XMP properties. }, - InstanceID => { Namespace => 'xmpMM' }, + InstanceID => { Namespace => 'xmpMM', List => 0 }, ); # XMP Media Management namespace properties (xmpMM, xapMM) @@ -1358,6 +1379,7 @@ my %sPantryItem = ( Exposure2012 => { Writable => 'real' }, Contrast2012 => { Writable => 'integer' }, Highlights2012 => { Writable => 'integer' }, + Highlight2012 => { Writable => 'integer' }, # (written by Nikon software) Shadows2012 => { Writable => 'integer' }, Whites2012 => { Writable => 'integer' }, Blacks2012 => { Writable => 'integer' }, @@ -1452,6 +1474,17 @@ my %sPantryItem = ( PerspectiveX => { Writable => 'real' }, PerspectiveY => { Writable => 'real' }, UprightFourSegmentsCount => { Writable => 'integer' }, + AutoTone => { Writable => 'boolean' }, + Texture => { Writable => 'integer' }, + # more stuff (ref forum10721) + OverrideLookVignette => { Writable => 'boolean' }, + Look => { + Struct => { + STRUCT_NAME => 'Look', + NAMESPACE => 'crs', + Name => { }, + } + }, ); # Tiff namespace properties (tiff) @@ -1463,8 +1496,8 @@ my %sPantryItem = ( TABLE_DESC => 'XMP TIFF', NOTES => q{ EXIF namespace for TIFF tags. See - L<http://www.cipa.jp/std/documents/e/DC-010-2017_E.pdf> for the - specification. + L<https://web.archive.org/web/20180921145139if_/http://www.cipa.jp:80/std/documents/e/DC-010-2017_E.pdf> + for the specification. }, ImageWidth => { Writable => 'integer' }, ImageLength => { Writable => 'integer', Name => 'ImageHeight' }, @@ -1554,8 +1587,8 @@ my %sPantryItem = ( PRIORITY => 0, # not as reliable as actual EXIF tags NOTES => q{ EXIF namespace for EXIF tags. See - L<http://www.cipa.jp/std/documents/e/DC-010-2017_E.pdf> for the - specification. + L<https://web.archive.org/web/20180921145139if_/http://www.cipa.jp:80/std/documents/e/DC-010-2017_E.pdf> + for the specification. }, ExifVersion => { }, FlashpixVersion => { }, @@ -1998,6 +2031,7 @@ my %sPantryItem = ( PrintConvInv => '$val=~s/\s*m$//; $val', }, NativeDigest => { }, #PH + # new Exif ); # Exif extended properties (exifEX, ref 12) @@ -2037,10 +2071,11 @@ my %sPantryItem = ( Writable => 'integer', }, CameraOwnerName => { Name => 'OwnerName' }, - BodySerialNumber => { Name => 'SerialNumber' }, + BodySerialNumber => { Name => 'SerialNumber', Groups => { 2 => 'Camera' } }, LensSpecification => { Name => 'LensInfo', Writable => 'rational', + Groups => { 2 => 'Camera' }, List => 'Seq', RawJoin => 1, # join list into a string before ValueConv ValueConv => \&ConvertRationalList, @@ -2064,9 +2099,9 @@ my %sPantryItem = ( instead of using the existing XMP-aux:LensInfo }, }, - LensMake => { }, - LensModel => { }, - LensSerialNumber => { }, + LensMake => { Groups => { 2 => 'Camera' } }, + LensModel => { Groups => { 2 => 'Camera' } }, + LensSerialNumber => { Groups => { 2 => 'Camera' } }, InteroperabilityIndex => { Name => 'InteropIndex', Description => 'Interoperability Index', @@ -2083,6 +2118,35 @@ my %sPantryItem = ( WaterDepth => { Writable => 'rational' }, Acceleration => { Writable => 'rational' }, CameraElevationAngle=> { Writable => 'rational' }, + # new in Exif 2.32 (according to the spec, these should use a different namespace + # URI, but the same namespace prefix... Exactly how is that supposed to work?!! + # -- I'll just stick with the same URI) + CompositeImage => { Writable => 'integer', + PrintConv => { + 0 => 'Unknown', + 1 => 'Not a Composite Image', + 2 => 'General Composite Image', + 3 => 'Composite Image Captured While Shooting', + }, + }, + CompositeImageCount => { List => 'Seq', Writable => 'integer' }, + CompositeImageExposureTimes => { + FlatName => 'CompImage', + Struct => { + STRUCT_NAME => 'CompImageExp', + NAMESPACE => 'exifEX', + TotalExposurePeriod => { Writable => 'rational' }, + SumOfExposureTimesOfAll => { Writable => 'rational', FlatName => 'SumExposureAll' }, + SumOfExposureTimesOfUsed=> { Writable => 'rational', FlatName => 'SumExposureUsed' }, + MaxExposureTimesOfAll => { Writable => 'rational', FlatName => 'MaxExposureAll' }, + MaxExposureTimesOfUsed => { Writable => 'rational', FlatName => 'MaxExposureUsed' }, + MinExposureTimesOfAll => { Writable => 'rational', FlatName => 'MinExposureAll' }, + MinExposureTimesOfUsed => { Writable => 'rational', FlatName => 'MinExposureUsed' }, + NumberOfSequences => { Writable => 'integer', FlatName => 'NumSequences' }, + NumberOfImagesInSequences=>{ Writable => 'integer', FlatName => 'ImagesPerSequence' }, + Values => { List => 'Seq', Writable => 'rational' }, + }, + }, ); # Auxiliary namespace properties (aux) - not fully documented (ref PH) @@ -2214,10 +2278,12 @@ my %sPantryItem = ( # Composite XMP tags %Image::ExifTool::XMP::Composite = ( - # get latitude/logitude reference from XMP lat/long tags + # get latitude/longitude reference from XMP lat/long tags # (used to set EXIF GPS position from XMP tags) GPSLatitudeRef => { - Require => 'XMP:GPSLatitude', + Require => 'XMP-exif:GPSLatitude', + Groups => { 2 => 'Location' }, + # Note: Do not Inihibit based on EXIF:GPSLatitudeRef (see forum10192) ValueConv => q{ IsFloat($val[0]) and return $val[0] < 0 ? "S" : "N"; $val[0] =~ /^.*([NS])/; @@ -2226,7 +2292,8 @@ my %sPantryItem = ( PrintConv => { N => 'North', S => 'South' }, }, GPSLongitudeRef => { - Require => 'XMP:GPSLongitude', + Require => 'XMP-exif:GPSLongitude', + Groups => { 2 => 'Location' }, ValueConv => q{ IsFloat($val[0]) and return $val[0] < 0 ? "W" : "E"; $val[0] =~ /^.*([EW])/; @@ -2235,7 +2302,8 @@ my %sPantryItem = ( PrintConv => { E => 'East', W => 'West' }, }, GPSDestLatitudeRef => { - Require => 'XMP:GPSDestLatitude', + Require => 'XMP-exif:GPSDestLatitude', + Groups => { 2 => 'Location' }, ValueConv => q{ IsFloat($val[0]) and return $val[0] < 0 ? "S" : "N"; $val[0] =~ /^.*([NS])/; @@ -2244,7 +2312,8 @@ my %sPantryItem = ( PrintConv => { N => 'North', S => 'South' }, }, GPSDestLongitudeRef => { - Require => 'XMP:GPSDestLongitude', + Require => 'XMP-exif:GPSDestLongitude', + Groups => { 2 => 'Location' }, ValueConv => q{ IsFloat($val[0]) and return $val[0] < 0 ? "W" : "E"; $val[0] =~ /^.*([EW])/; @@ -2267,6 +2336,7 @@ my %sPantryItem = ( Inhibit => { 6 => 'Composite:LensID', # don't override existing Composite:LensID }, + Groups => { 2 => 'Camera' }, ValueConv => '$val', PrintConv => 'Image::ExifTool::XMP::PrintLensID($self, @val)', }, @@ -2280,6 +2350,7 @@ my %sPantryItem = ( 4 => 'XMP:FlashRedEyeMode', 5 => 'XMP:Flash', # handle structured flash information too }, + Groups => { 2 => 'Camera' }, Writable => 1, PrintHex => 1, SeparateTable => 'EXIF Flash', @@ -2289,11 +2360,11 @@ my %sPantryItem = ( my $i = 0; $val[$i++] = $val[5]{$_} foreach qw(Fired Return Mode Function RedEyeMode); } - return (($val[0] and lc($val[0]) eq 'true') ? 0x01 : 0) | + return((($val[0] and lc($val[0]) eq 'true') ? 0x01 : 0) | (($val[1] || 0) << 1) | (($val[2] || 0) << 3) | (($val[3] and lc($val[3]) eq 'true') ? 0x20 : 0) | - (($val[4] and lc($val[4]) eq 'true') ? 0x40 : 0); + (($val[4] and lc($val[4]) eq 'true') ? 0x40 : 0)); }, PrintConv => \%Image::ExifTool::Exif::flash, WriteAlso => { @@ -2333,13 +2404,14 @@ sub EscapeXML($) # Unescape XML character references (entities and numerical) # Inputs: 0) string to be unescaped # 1) optional hash reference to convert entity names to numbers +# 2) optional character encoding # Returns: unescaped string my %charNum = ('quot'=>34, 'amp'=>38, 'apos'=>39, 'lt'=>60, 'gt'=>62); -sub UnescapeXML($;$) +sub UnescapeXML($;$$) { - my ($str, $conv) = @_; + my ($str, $conv, $enc) = @_; $conv = \%charNum unless $conv; - $str =~ s/&(#?\w+);/UnescapeChar($1,$conv)/sge; + $str =~ s/&(#?\w+);/UnescapeChar($1,$conv,$enc)/sge; return $str; } @@ -2377,10 +2449,11 @@ sub FullUnescapeXML($) # Convert XML character reference to UTF-8 # Inputs: 0) XML character reference stripped of the '&' and ';' (eg. 'quot', '#34', '#x22') # 1) hash reference for looking up character numbers by name +# 2) optional character encoding (default 'UTF8') # Returns: UTF-8 equivalent (or original character on conversion error) -sub UnescapeChar($$) +sub UnescapeChar($$;$) { - my ($ch, $conv) = @_; + my ($ch, $conv, $enc) = @_; my $val = $$conv{$ch}; unless (defined $val) { if ($ch =~ /^#x([0-9a-fA-F]+)$/) { @@ -2392,20 +2465,21 @@ sub UnescapeChar($$) } } return chr($val) if $val < 0x80; # simple ASCII - return pack('C0U', $val) if $] >= 5.006001; - return Image::ExifTool::PackUTF8($val); + $val = $] >= 5.006001 ? pack('C0U', $val) : Image::ExifTool::PackUTF8($val); + $val = Image::ExifTool::Decode(undef, $val, 'UTF8', undef, $enc) if $enc and $enc ne 'UTF8'; + return $val; } #------------------------------------------------------------------------------ # Does a string contain valid UTF-8 characters? -# Inputs: 0) string reference +# Inputs: 0) string reference, 1) true to allow last character to be truncated # Returns: 0=regular ASCII, -1=invalid UTF-8, 1=valid UTF-8 with maximum 16-bit # wide characters, 2=valid UTF-8 requiring 32-bit wide characters # Notes: Changes current string position # (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this) -sub IsUTF8($) +sub IsUTF8($;$) { - my $strPt = shift; + my ($strPt, $trunc) = @_; pos($$strPt) = 0; # start at beginning of string return 0 unless $$strPt =~ /([\x80-\xff])/g; my $rtnVal = 1; @@ -2427,7 +2501,11 @@ sub IsUTF8($) # were required in the UTF-8 character $rtnVal = 2; } - return -1 unless $$strPt =~ /\G([\x80-\xbf]{$n})/g; + my $pos = pos $$strPt; + unless ($$strPt =~ /\G([\x80-\xbf]{$n})/g) { + return $rtnVal if $trunc and $pos + $n > length $$strPt; + return -1; + } # the following is ref https://www.cl.cam.ac.uk/%7Emgk25/ucs/utf8_check.c if ($n == 2) { return -1 if ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or @@ -2647,8 +2725,6 @@ sub AddFlattenedTags($;$$) $$tagInfo{Struct} = $strTable; # replace old-style name with HASH ref delete $$tagInfo{SubDirectory}; # deprecated use of SubDirectory in Struct tags } - # do not add flattened tags to variable-namespace structures - next if exists $$strTable{NAMESPACE} and not defined $$strTable{NAMESPACE}; # get prefix for flattened tag names my $flat = (defined $$tagInfo{FlatName} ? $$tagInfo{FlatName} : $$tagInfo{Name}); @@ -2690,6 +2766,7 @@ sub AddFlattenedTags($;$$) # generate new flattened tag information based on structure field my $flatName = $flat . $flatField; $flatInfo = { %$fieldInfo, Name => $flatName, Flat => 0 }; + $$flatInfo{FlatName} = $flatName if $$fieldInfo{FlatName}; # make a copy of the Groups hash if necessary $$flatInfo{Groups} = { %{$$fieldInfo{Groups}} } if $$fieldInfo{Groups}; # add new flattened tag to table @@ -2970,8 +3047,20 @@ sub FoundXMP($$$$;$) if ($$tagTablePtr{NAMESPACE}) { $tagID = $tag; } else { + $xns = $xmpNS{$ns}; + unless (defined $xns) { + $xns = $ns; + # validate namespace prefix + unless ($ns =~ /^[A-Z_a-z\x80-\xff][-.0-9A-Z_a-z\x80-\xff]*$/ or $ns eq '') { + $et->Warn("Invalid XMP namespace prefix '${ns}'"); + # clean up prefix for use as an ExifTool group name + $ns =~ tr/-.0-9A-Z_a-z\x80-\xff//dc; + $ns =~ /^[A-Z_a-z\x80-\xff]/ or $ns = "ns_$ns"; + $stdXlatNS{$xns} = $ns; + $xmpNS{$ns} = $xns; + } + } # add XMP namespace prefix to avoid collisions in variable-namespace tables - $xns = $xmpNS{$ns} || $ns; $tagID = "$xns:$tag"; # add namespace to top-level structure property $structProps[0][0] = "$xns:" . $structProps[0][0] if @structProps; @@ -2997,14 +3086,6 @@ NoLoop: $ti = $$tagTablePtr{$t} or next; next unless ref $ti eq 'HASH' and $$ti{Struct}; $addedFlat = AddFlattenedTags($tagTablePtr, $t); - if ($tagInfo) { - # all done if we just wanted to initialize the flattened tag - if ($$tagInfo{Flat}) { - warn "Orphan tagInfo with Flat flag set: $$tagInfo{Name}\n"; - delete $$tagInfo{Flat}; - } - last NoLoop; - } # all done if we generated the tag we are looking for $tagInfo = $$tagTablePtr{$tagID} and last NoLoop if $addedFlat; } @@ -3062,11 +3143,8 @@ NoLoop: } last unless $sti; } - $tagInfo = { - %$sti, - Name => $flat . $$sti{Name}, - WasAdded => 1, - }; + # generate new tagInfo hash based on existing top-level tag + $tagInfo = { %$sti, Name => $flat . $$sti{Name} }; # be careful not to copy elements we shouldn't... delete $$tagInfo{Description}; # Description will be different # can't copy group hash because group 1 will be different and @@ -3076,11 +3154,12 @@ NoLoop: last; } } - $tagInfo or $tagInfo = { Name => $name, WasAdded => 1, Priority => 0 }; + # generate a default tagInfo hash if necessary + $tagInfo or $tagInfo = { Name => $name, IsDefault => 1, Priority => 0 }; # add tag Namespace entry for tags in variable-namespace tables $$tagInfo{Namespace} = $xns if $xns; - if ($$et{curURI}{$ns} and $$et{curURI}{$ns} =~ m{^http://ns.exiftool.ca/(.*?)/(.*?)/}) { + if ($$et{curURI}{$ns} and $$et{curURI}{$ns} =~ m{^http://ns.exiftool.(?:ca|org)/(.*?)/(.*?)/}) { my %grps = ( 0 => $1, 1 => $2 ); # apply a little magic to recover original group names # from this exiftool-written RDF/XML file @@ -3145,7 +3224,7 @@ NoLoop: $val = $et->Decode($val, 'UTF8'); # convert rational and date values to a more sensible format my $fmt = $$tagInfo{Writable}; - my $new = $$tagInfo{WasAdded} && $$et{OPTIONS}{XMPAutoConv}; + my $new = $$tagInfo{IsDefault} && $$et{OPTIONS}{XMPAutoConv}; if ($fmt or $new) { $rawVal = $val; # save raw value for verbose output if (($new or $fmt eq 'rational') and ConvertRational($val)) { @@ -3160,6 +3239,26 @@ NoLoop: my $key = $et->FoundTag($tagInfo, $val) or return 0; # save original components of rational numbers (used when copying) $$et{RATIONAL}{$key} = $rational if defined $rational; + # allow read-only subdirectories (eg. embedded base64 XMP/IPTC in NKSC files) + if ($$tagInfo{SubDirectory} and not $$et{IsWriting}) { + my $subdir = $$tagInfo{SubDirectory}; + my $dataPt = ref $$et{VALUE}{$key} ? $$et{VALUE}{$key} : \$$et{VALUE}{$key}; + # process subdirectory information + my %dirInfo = ( + DirName => $$subdir{DirName} || $$tagInfo{Name}, + DataPt => $dataPt, + DirLen => length $$dataPt, + IsExtended => 1, # (hack to avoid Duplicate warning for embedded XMP) + ); + my $oldOrder = GetByteOrder(); + SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder}; + my $oldNS = $$et{definedNS}; + delete $$et{definedNS}; + my $subTablePtr = GetTagTable($$subdir{TagTable}) || $tagTablePtr; + $et->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc}); + SetByteOrder($oldOrder); + $$et{definedNS} = $oldNS; + } # save structure/list information if necessary if (@structProps and (@structProps > 1 or defined $structProps[0][1]) and not $$et{NO_STRUCT}) @@ -3244,7 +3343,6 @@ sub ParseXMPElement($$$;$$$$) # (empty elements end with '/', eg. <a:b/>) if ($attrs !~ s/\/$//) { my $nesting = 1; - my $tok; for (;;) { # this match fails with perl 5.6.2 (perl bug!), but it works without # the '(.*?)', so we must do it differently... @@ -3544,10 +3642,10 @@ sub ParseXMPElement($$$;$$$$) if ($prop eq 'rdf:Description' and $val) { $val =~ s/<!--.*?-->//g; $val =~ s/^\s+//; $val =~ s/\s+$//; } - # if element value is empty, take value from 'resource' attribute - # (preferentially) or 'about' attribute (if no 'resource') - if ($val eq '' and ($attrs =~ /\bresource=(['"])(.*?)\1/ or - $attrs =~ /\babout=(['"])(.*?)\1/)) + # if element value is empty, take value from RDF 'value' or 'resource' attribute + # (preferentially) or 'about' attribute (if no 'value' or 'resource') + if ($val eq '' and ($attrs =~ /\brdf:(?:value|resource)=(['"])(.*?)\1/ or + $attrs =~ /\brdf:about=(['"])(.*?)\1/)) { $val = $2; $wasEmpty = 1; @@ -3565,7 +3663,7 @@ sub ParseXMPElement($$$;$$$$) # ignore et:desc, and et:val if preceded by et:prt --$count; } else { - ValidateProperty($et, $propList) if $$et{XmpValidate}; + ValidateProperty($et, $propList, \%attrs) if $$et{XmpValidate}; &$foundProc($et, $tagTablePtr, $propList, $val, \%attrs); } } @@ -3639,6 +3737,7 @@ sub ProcessXMP($$;$) $$et{definedNS} = { }; delete $$et{XmpAbout}; delete $$et{XmpValidate}; # don't validate by default + delete $$et{XmpValidateLangAlt}; # ignore non-standard XMP while in strict MWG compatibility mode if (($Image::ExifTool::MWG::strict or $$et{OPTIONS}{Validate}) and @@ -3700,7 +3799,7 @@ sub ProcessXMP($$;$) $fmt = 'n'; # UTF-16 or 32 MM with BOM } elsif ($buf2 =~ /^(\xff\xfe)(<\?xml|<rdf:RDF|<x(mp)?:x[ma]pmeta)/g) { $fmt = 'v'; # UTF-16 or 32 II with BOM - } elsif ($buf2 =~ /^(\xef\xbb\xbf)?(<\?xml|<rdf:RDF|<x(mp)?:x[ma]pmeta)/g) { + } elsif ($buf2 =~ /^(\xef\xbb\xbf)?(<\?xml|<rdf:RDF|<x(mp)?:x[ma]pmeta|<svg\b)/g) { $fmt = 0; # UTF-8 with BOM or unknown encoding without BOM } elsif ($buf2 =~ /^(\xfe\xff|\xff\xfe|\xef\xbb\xbf)(<\?xpacket begin=)/g) { $double = $1; # double-encoded UTF @@ -3849,8 +3948,8 @@ sub ProcessXMP($$;$) # extract XMP as a block if specified my $blockName = $$dirInfo{BlockInfo} ? $$dirInfo{BlockInfo}{Name} : 'XMP'; if (($$et{REQ_TAG_LOOKUP}{lc $blockName} or ($$et{TAGS_FROM_FILE} and - not $$et{EXCL_TAG_LOOKUP}{lc $blockName})) and - ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'XMP')) + not $$et{EXCL_TAG_LOOKUP}{lc $blockName})) and ($$et{FileType} eq 'XMP' or + ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'XMP'))) { $et->FoundTag($$dirInfo{BlockInfo} || 'XMP', substr($$dataPt, $dirStart, $dirLen)); } @@ -4012,7 +4111,7 @@ information. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/XMP2.pl b/src/Image-ExifTool/lib/Image/ExifTool/XMP2.pl index bd6f847a..588ee21a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/XMP2.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/XMP2.pl @@ -15,6 +15,7 @@ # 9) http://www.w3.org/TR/SVG11/ # 11) http://www.extensis.com/en/support/kb_article.jsp?articleNumber=6102211 # 12) XMPSpecificationPart3_May2013, page 58 +# 13) https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf #------------------------------------------------------------------------------ package Image::ExifTool::XMP; @@ -23,6 +24,8 @@ package Image::ExifTool::XMP; use Image::ExifTool qw(:Utils); use Image::ExifTool::XMP; +sub Init_crd($); + #------------------------------------------------------------------------------ # xmpDM structure definitions @@ -74,6 +77,77 @@ package Image::ExifTool::XMP; timeValue => { }, value => { Writable => 'integer', Notes => 'only in XMP 2008 spec; an error?' }, ); +my %sPose = ( + STRUCT_NAME => 'Pose', + NAMESPACE => { Pose => 'http://ns.google.com/photos/dd/1.0/pose/' }, + PositionX => { Writable => 'real', Groups => { 2 => 'Location' } }, + PositionY => { Writable => 'real', Groups => { 2 => 'Location' } }, + PositionZ => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationX => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationY => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationZ => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationW => { Writable => 'real', Groups => { 2 => 'Location' } }, + Timestamp => { + Writable => 'integer', + Shift => 'Time', + Groups => { 2 => 'Time' }, + ValueConv => 'ConvertUnixTime($val / 1000, 1, 3)', + ValueConvInv => 'int(GetUnixTime($val, 1) * 1000)', + PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val,undef,1)', + }, +); +my %sEarthPose = ( + STRUCT_NAME => 'EarthPose', + NAMESPACE => { EarthPose => 'http://ns.google.com/photos/dd/1.0/earthpose/' }, + Latitude => { Writable => 'real', Groups => { 2 => 'Location' }, %latConv }, + Longitude => { Writable => 'real', Groups => { 2 => 'Location' }, %longConv }, + Altitude => { + Writable => 'real', + Groups => { 2 => 'Location' }, + PrintConv => '"$val m"', + PrintConvInv => '$val=~s/\s*m$//;$val', + }, + RotationX => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationY => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationZ => { Writable => 'real', Groups => { 2 => 'Location' } }, + RotationW => { Writable => 'real', Groups => { 2 => 'Location' } }, + Timestamp => { + Writable => 'integer', + Shift => 'Time', + Groups => { 2 => 'Time' }, + ValueConv => 'ConvertUnixTime($val / 1000, 1, 3)', + ValueConvInv => 'int(GetUnixTime($val, 1) * 1000)', + PrintConv => '$self->ConvertDateTime($val)', + PrintConvInv => '$self->InverseDateTime($val,undef,1)', + }, +); +my %sVendorInfo = ( + STRUCT_NAME => 'VendorInfo', + NAMESPACE => { VendorInfo => 'http://ns.google.com/photos/dd/1.0/vendorinfo/' }, + Model => { }, + Manufacturer => { }, + Notes => { }, +); +my %sAppInfo = ( + STRUCT_NAME => 'AppInfo', + NAMESPACE => { AppInfo => 'http://ns.google.com/photos/dd/1.0/appinfo/' }, + Application => { }, + Version => { }, + ItemURI => { }, +); + +# camera-raw defaults +%Image::ExifTool::XMP::crd = ( + %xmpTableDefaults, + INIT_TABLE => \&Init_crd, + GROUPS => { 1 => 'XMP-crd', 2 => 'Image' }, + NAMESPACE => 'crd', + AVOID => 1, + TABLE_DESC => 'Photoshop Camera Defaults namespace', + NOTES => 'Adobe Camera Raw Defaults tags.', + # (tags added dynamically when WRITE_PROC is called) +); # XMP Dynamic Media namespace properties (xmpDM) %Image::ExifTool::XMP::xmpDM = ( @@ -375,7 +449,7 @@ package Image::ExifTool::XMP; RatingScaleMaxValue => { FlatName => 'ScaleMaxValue' }, RatingValueLogoLink => { FlatName => 'ValueLogoLink' }, RatingRegion => { - FlatName => 'RatingRegion', + FlatName => 'Region', Struct => \%sLocationDetails, List => 'Bag', }, @@ -422,6 +496,39 @@ package Image::ExifTool::XMP; HeightPixels=> { Writable => 'integer' }, UsedVideoFrame => { Struct => \%sTimecode }, ); +my %sBoundaryPoint = ( # new in 1.5 + STRUCT_NAME => 'BoundaryPoint', + NAMESPACE => 'Iptc4xmpExt', + rbX => { FlatName => 'X', Writable => 'real' }, + rbY => { FlatName => 'Y', Writable => 'real' }, +); +my %sRegionBoundary = ( # new in 1.5 + STRUCT_NAME => 'RegionBoundary', + NAMESPACE => 'Iptc4xmpExt', + rbShape => { FlatName => 'Shape', PrintConv => { rectangle => 'Rectangle', circle => 'Circle', polygon => 'Polygon' } }, + rbUnit => { FlatName => 'Unit', PrintConv => { pixel => 'Pixel', relative => 'Relative' } }, + rbX => { FlatName => 'X', Writable => 'real' }, + rbY => { FlatName => 'Y', Writable => 'real' }, + rbW => { FlatName => 'W', Writable => 'real' }, + rbH => { FlatName => 'H', Writable => 'real' }, + rbRx => { FlatName => 'Rx', Writable => 'real' }, + rbVertices => { FlatName => 'Vertices', List => 'Seq', Struct => \%sBoundaryPoint }, +); +my %sImageRegion = ( # new in 1.5 + STRUCT_NAME => 'ImageRegion', + NAMESPACE => undef, # undefined to allow variable-namespace extensions + NOTES => q{ + This structure is new in the IPTC Extension version 1.5 specification. As + well as the fields defined below, this structure may contain any top-level + XMP tags, but since they aren't pre-defined the only way to add these tags + is to write ImageRegion as a structure with these tags as new fields. + }, + RegionBoundary => { Namespace => 'Iptc4xmpExt', FlatName => 'Boundary', Struct => \%sRegionBoundary }, + rId => { Namespace => 'Iptc4xmpExt', FlatName => 'ID' }, + Name => { Namespace => 'Iptc4xmpExt', Writable => 'lang-alt' }, + rCtype => { Namespace => 'Iptc4xmpExt', FlatName => 'Ctype', List => 'Bag', Struct => \%sEntity }, + rRole => { Namespace => 'Iptc4xmpExt', FlatName => 'Role', List => 'Bag', Struct => \%sEntity }, +); # IPTC Extension namespace properties (Iptc4xmpExt) (ref 4) %Image::ExifTool::XMP::iptcExt = ( @@ -430,9 +537,9 @@ package Image::ExifTool::XMP; NAMESPACE => 'Iptc4xmpExt', TABLE_DESC => 'XMP IPTC Extension', NOTES => q{ - IPTC Extension namespace tags. The actual namespace prefix is - "Iptc4xmpExt", but ExifTool shortens this for the family 1 group name. (see - L<http://www.iptc.org/IPTC4XMP/>) + This table contains tags defined by the IPTC Extension schema version 1.5. + The actual namespace prefix is "Iptc4xmpExt", but ExifTool shortens this for + the family 1 group name. (see L<http://www.iptc.org/IPTC4XMP/>) }, AboutCvTerm => { Struct => \%sCVTermDetails, @@ -489,12 +596,13 @@ package Image::ExifTool::XMP; List => 'Bag', Notes => 'deprecated by version 1.2', }, - DigImageGUID => { Name => 'DigitalImageGUID' }, + DigImageGUID => { Groups => { 2 => 'Image' }, Name => 'DigitalImageGUID' }, DigitalSourcefileType => { Name => 'DigitalSourceFileType', Notes => 'now deprecated -- replaced by DigitalSourceType', + Groups => { 2 => 'Image' }, }, - DigitalSourceType => { Name => 'DigitalSourceType' }, + DigitalSourceType => { Name => 'DigitalSourceType', Groups => { 2 => 'Image' } }, EmbdEncRightsExpr => { Struct => { STRUCT_NAME => 'EEREDetails', @@ -537,8 +645,8 @@ package Image::ExifTool::XMP; Groups => { 2 => 'Location' }, List => 'Bag', }, - MaxAvailHeight => { Writable => 'integer' }, - MaxAvailWidth => { Writable => 'integer' }, + MaxAvailHeight => { Groups => { 2 => 'Image' }, Writable => 'integer' }, + MaxAvailWidth => { Groups => { 2 => 'Image' }, Writable => 'integer' }, ModelAge => { List => 'Bag', Writable => 'integer' }, OrganisationInImageCode => { List => 'Bag' }, OrganisationInImageName => { List => 'Bag' }, @@ -673,6 +781,7 @@ package Image::ExifTool::XMP; # new IPTC video metadata 1.2 properties # (ref http://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.2.html) RecDevice => { + Groups => { 2 => 'Device' }, Struct => { STRUCT_NAME => 'Device', NAMESPACE => 'Iptc4xmpExt', @@ -684,7 +793,9 @@ package Image::ExifTool::XMP; }, }, PlanningRef => { List => 'Bag', Struct => \%sEntityWithRole }, - audioBitsPerSample => { Writable => 'integer' }, + audioBitsPerSample => { Groups => { 2 => 'Audio' }, Writable => 'integer' }, + # new IPTC Extension schema 1.5 property + ImageRegion => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sImageRegion }, ); #------------------------------------------------------------------------------ @@ -1116,7 +1227,7 @@ package Image::ExifTool::XMP; NAMESPACE => 'PixelLive', AVOID => 1, NOTES => q{ - PixelLive namespace tags. These tags are not writable becase they are very + PixelLive namespace tags. These tags are not writable because they are very uncommon and I haven't been able to locate a reference which gives the namespace URI. }, @@ -1174,15 +1285,15 @@ package Image::ExifTool::XMP; TagStructure => { Struct => \%sTagStruct, List => 'Bag' }, TagStructureLabelName => { Name => 'LabelName1', Flat => 1 }, TagStructureReference => { Name => 'Reference1', Flat => 1 }, - TagStructureSubLabels => { Name => 'SubLables1', Flat => 1 }, + TagStructureSubLabels => { Name => 'SubLabels1', Flat => 1 }, TagStructureParentReference => { Name => 'ParentReference1', Flat => 1 }, TagStructureSubLabelsLabelName => { Name => 'LabelName2', Flat => 1 }, TagStructureSubLabelsReference => { Name => 'Reference2', Flat => 1 }, - TagStructureSubLabelsSubLabels => { Name => 'SubLables2', Flat => 1 }, + TagStructureSubLabelsSubLabels => { Name => 'SubLabels2', Flat => 1 }, TagStructureSubLabelsParentReference => { Name => 'ParentReference2', Flat => 1 }, TagStructureSubLabelsSubLabelsLabelName => { Name => 'LabelName3', Flat => 1 }, TagStructureSubLabelsSubLabelsReference => { Name => 'Reference3', Flat => 1 }, - TagStructureSubLabelsSubLabelsSubLabels => { Name => 'SubLables3', Flat => 1 }, + TagStructureSubLabelsSubLabelsSubLabels => { Name => 'SubLabels3', Flat => 1 }, TagStructureSubLabelsSubLabelsParentReference => { Name => 'ParentReference3', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName4', Flat => 1 }, TagStructureSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference4', Flat => 1 }, @@ -1373,7 +1484,7 @@ package Image::ExifTool::XMP; ); # Microsoft ExpressionMedia namespace properties (expressionmedia) -# (ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4235.0.html) +# (ref https://exiftool.org/forum/index.php/topic,4235.0.html) %Image::ExifTool::XMP::ExpressionMedia = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-expressionmedia', 2 => 'Image' }, @@ -1566,7 +1677,7 @@ package Image::ExifTool::XMP; ); # Google panorama namespace properties -# (ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,4569.0.html) +# (ref https://exiftool.org/forum/index.php/topic,4569.0.html) %Image::ExifTool::XMP::GPano = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-GPano', 2 => 'Image' }, @@ -1608,11 +1719,13 @@ package Image::ExifTool::XMP; %Image::ExifTool::XMP::GSpherical = ( %xmpTableDefaults, GROUPS => { 1 => 'XMP-GSpherical', 2 => 'Image' }, + WRITE_GROUP => 'GSpherical', # write in special location for video files NAMESPACE => 'GSpherical', AVOID => 1, NOTES => q{ Not actually XMP. These RDF/XML tags are used in Google spherical MP4 - videos. See + videos. These tags are written into the video track of MOV/MP4 files, and + not at the top level like other XMP tags. See L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md> for the specification. }, @@ -1647,8 +1760,8 @@ package Image::ExifTool::XMP; # Google depthmap information (ref https://developers.google.com/depthmap-metadata/reference) %Image::ExifTool::XMP::GDepth = ( GROUPS => { 0 => 'XMP', 1 => 'XMP-GDepth', 2 => 'Image' }, - NAMESPACE => { 'GDepth' => 'http://ns.google.com/photos/1.0/depthmap/' }, - AVOID => 1, # (too potential tag name conflicts) + NAMESPACE => 'GDepth', + AVOID => 1, # (too many potential tag name conflicts) NOTES => q{ Google depthmap information. See L<https://developers.google.com/depthmap-metadata/> for the specification. @@ -1665,6 +1778,7 @@ package Image::ExifTool::XMP; Far => { Writable => 'real' }, Mime => { }, Data => { + Name => 'DepthImage', ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)', ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)', }, @@ -1699,6 +1813,194 @@ package Image::ExifTool::XMP; FocalPointY => { Writable => 'real' }, ); +# Google camera namespace (ref PH) +%Image::ExifTool::XMP::GCamera = ( + %xmpTableDefaults, + GROUPS => { 1 => 'XMP-GCamera', 2 => 'Camera' }, + NAMESPACE => 'GCamera', + NOTES => 'Camera information found in Google panorama images.', + BurstID => { }, + BurstPrimary => { }, + PortraitNote => { }, + PortraitRequest => { + Notes => 'High Definition Render Pipeline (HDRP) data', #PH (guess) + ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)', + ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)', + }, + PortraitVersion => { }, + SpecialTypeID => { List => 'Bag' }, + PortraitNote => { }, + DisableAutoCreation => { List => 'Bag' }, + hdrp_makernote => { + Name => 'HDRPMakerNote', + # decoded data starts with the following bytes, but nothing yet is known about its contents: + # 48 44 52 50 02 ef 64 35 6d 5e 70 1e 2c ea e3 4c [HDRP..d5m^p.,..L] + ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)', + ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)', + }, +); + +# Google creations namespace (ref PH) +%Image::ExifTool::XMP::GCreations = ( + %xmpTableDefaults, + GROUPS => { 1 => 'XMP-GCreations', 2 => 'Camera' }, + NAMESPACE => 'GCreations', + NOTES => 'Google creations tags.', + CameraBurstID => { }, +); + +# Google depth-map Device namespace (ref 13) +%Image::ExifTool::XMP::Device = ( + %xmpTableDefaults, + GROUPS => { 1 => 'XMP-Device', 2 => 'Camera' }, + NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' }, + NOTES => q{ + Google depth-map Device tags. See + L<https://developer.android.com/training/camera2/Dynamic-depth-v1.0.pdf> for + the specification. + }, + Container => { + Struct => { + STRUCT_NAME => 'DeviceContainer', + NAMESPACE => { Container => 'http://ns.google.com/photos/dd/1.0/container/' }, + Directory => { + List => 'Seq', + Struct => { + STRUCT_NAME => 'DeviceDirectory', + NAMESPACE => { Container => 'http://ns.google.com/photos/dd/1.0/container/' }, + Item => { + Struct => { + STRUCT_NAME => 'DeviceItem', + NAMESPACE => { Item => 'http://ns.google.com/photos/dd/1.0/item/' }, + Mime => { }, + Length => { Writable => 'integer' }, + Padding => { Writable => 'integer' }, + DataURI => { }, + }, + }, + }, + } + }, + }, + Profiles => { + List => 'Seq', + FlatName => '', + Struct => { + STRUCT_NAME => 'DeviceProfiles', + NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' }, + Profile => { + Struct => { + STRUCT_NAME => 'DeviceProfile', + NAMESPACE => { Profile => 'http://ns.google.com/photos/dd/1.0/profile/' }, + CameraIndices => { List => 'Seq', Writable => 'integer' }, + Type => { }, + }, + }, + }, + }, + Cameras => { + List => 'Seq', + FlatName => '', + Struct => { + STRUCT_NAME => 'DeviceCameras', + NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' }, + Camera => { + Struct => { + STRUCT_NAME => 'DeviceCamera', + NAMESPACE => { Camera => 'http://ns.google.com/photos/dd/1.0/camera/' }, + DepthMap => { + Struct => { + STRUCT_NAME => 'DeviceDepthMap', + NAMESPACE => { DepthMap => 'http://ns.google.com/photos/dd/1.0/depthmap/' }, + ConfidenceURI => { }, + DepthURI => { }, + Far => { Writable => 'real' }, + Format => { }, + ItemSemantic=> { }, + MeasureType => { }, + Near => { Writable => 'real' }, + Units => { }, + Software => { }, + FocalTableEntryCount => { Writable => 'integer' }, + FocalTable => { }, # (base64) + }, + }, + Image => { + Struct => { + STRUCT_NAME => 'DeviceImage', + NAMESPACE => { Image => 'http://ns.google.com/photos/dd/1.0/image/' }, + ItemSemantic=> { }, + ItemURI => { }, + }, + }, + ImagingModel => { + Struct => { + STRUCT_NAME => 'DeviceImagingModel', + NAMESPACE => { ImagingModel => 'http://ns.google.com/photos/dd/1.0/imagingmodel/' }, + Distortion => { }, # (base64) + DistortionCount => { Writable => 'integer' }, + FocalLengthX => { Writable => 'real' }, + FocalLengthY => { Writable => 'real' }, + ImageHeight => { Writable => 'integer' }, + ImageWidth => { Writable => 'integer' }, + PixelAspectRatio=> { Writable => 'real' }, + PrincipalPointX => { Writable => 'real' }, + PrincipalPointY => { Writable => 'real' }, + Skew => { Writable => 'real' }, + }, + }, + PointCloud => { + Struct => { + STRUCT_NAME => 'DevicePointCloud', + NAMESPACE => { PointCloud => 'http://ns.google.com/photos/dd/1.0/pointcloud/' }, + PointCloud => { Writable => 'integer' }, + Points => { }, + Metric => { Writable => 'boolean' }, + }, + }, + Pose => { Struct => \%sPose }, + LightEstimate => { + Struct => { + STRUCT_NAME => 'DeviceLightEstimate', + NAMESPACE => { LightEstimate => 'http://ns.google.com/photos/dd/1.0/lightestimate/' }, + ColorCorrectionR => { Writable => 'real' }, + ColorCorrectionG => { Writable => 'real' }, + ColorCorrectionB => { Writable => 'real' }, + PixelIntensity => { Writable => 'real' }, + }, + }, + VendorInfo => { Struct => \%sVendorInfo }, + AppInfo => { Struct => \%sAppInfo }, + Trait => { }, + }, + }, + }, + }, + VendorInfo => { Struct => \%sVendorInfo }, + AppInfo => { Struct => \%sAppInfo }, + EarthPos => { Struct => \%sEarthPose }, + Pose => { Struct => \%sPose }, + Planes => { + List => 'Seq', + FlatName => '', + Struct => { + STRUCT_NAME => 'DevicePlanes', + NAMESPACE => { Device => 'http://ns.google.com/photos/dd/1.0/device/' }, + Plane => { + Struct => { + STRUCT_NAME => 'DevicePlane', + NAMESPACE => { Plane => 'http://ns.google.com/photos/dd/1.0/plane/' }, + Pose => { Struct => \%sPose }, + ExtentX => { Writable => 'real' }, + ExtentZ => { Writable => 'real' }, + BoundaryVertexCount => { Writable => 'integer' }, + Boundary => { }, + }, + }, + }, + }, +); + # Getty Images namespace (ref PH) %Image::ExifTool::XMP::GettyImages = ( %xmpTableDefaults, @@ -1709,7 +2011,7 @@ package Image::ExifTool::XMP; prefix recorded in the file, but ExifTool shortens this for the family 1 group name. }, - Personality => { }, + Personality => { List => 'Bag' }, OriginalFilename => { Name => 'OriginalFileName' }, ParentMEID => { }, # the following from StarGeek @@ -1742,6 +2044,7 @@ package Image::ExifTool::XMP; MinorVersion => { }, RightAlbedo => { Notes => 'Right stereoscopic image', + Groups => { 2 => 'Preview' }, ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)', ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)', }, @@ -1779,6 +2082,23 @@ package Image::ExifTool::XMP; NAMESPACE => undef, # variable namespace ); +#------------------------------------------------------------------------------ +# Generate crd tags +# Inputs: 0) tag table ref +sub Init_crd($) +{ + my $tagTablePtr = shift; + # import tags from CRS namespace + my $crsTable = GetTagTable('Image::ExifTool::XMP::crs'); + my $tag; + foreach $tag (Image::ExifTool::TagTableKeys($crsTable)) { + my $crsInfo = $$crsTable{$tag}; + my $tagInfo = $$tagTablePtr{$tag} = { %$crsInfo }; + $$tagInfo{Groups} = { 0 => 'XMP', 1 => 'XMP-crd' , 2 => $$crsInfo{Groups}{2} } if $$crsInfo{Groups}; + } +} + + 1; #end __END__ @@ -1797,7 +2117,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/XMPStruct.pl b/src/Image-ExifTool/lib/Image/ExifTool/XMPStruct.pl index 570e98f0..f0023942 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/XMPStruct.pl +++ b/src/Image-ExifTool/lib/Image/ExifTool/XMPStruct.pl @@ -107,7 +107,8 @@ ($;$) $val = ''; $delim = $delim ? "\\$delim|,|\\||\$" : ',|\\||$'; for (;;) { - $$obj =~ s/^(.*?)($delim)//s and $val .= $1; + $$obj =~ s/^(.*?)($delim)//s or last; + $val .= $1; last unless $2; $2 eq '|' or $$obj = $2 . $$obj, last; $$obj =~ s/^(.)//s and $val .= $1; # add escaped character @@ -232,7 +233,7 @@ ($$$) # create new structure field if necessary $fieldInfo or $fieldInfo = $$strTable{$tag} = { %$tagInfo, # (also copies the necessary TagID and PropertyPath) - Namespace => $$tagInfo{Table}{NAMESPACE}, + Namespace => $$tagInfo{Namespace} || $$tagInfo{Table}{NAMESPACE}, LangCode => $langCode, }; # delete stuff we don't need (shouldn't cause harm, but better safe than sorry) @@ -397,7 +398,11 @@ ($$$$$) my $verbose = $et->Options('Verbose'); @delPaths = sort @delPaths if $verbose > 1; foreach $p (@delPaths) { - $et->VerboseValue("- XMP-$p", $$capture{$p}[0]) if $verbose > 1; + if ($verbose > 1) { + my $p2 = $p; + $p2 =~ s/^(\w+)/$stdXlatNS{$1} || $1/e; + $et->VerboseValue("- XMP-$p2", $$capture{$p}[0]); + } delete $$capture{$p}; $deleted = 1; ++$$changed; @@ -461,7 +466,9 @@ ($$$$$$) $$capture{$path} = [ $val, \%attrs ]; # print verbose message if ($et and $et->Options('Verbose') > 1) { - $et->VerboseValue("+ XMP-$path", $val); + my $p = $path; + $p =~ s/^(\w+)/$stdXlatNS{$1} || $1/e; + $et->VerboseValue("+ XMP-$p", $val); } } @@ -550,7 +557,11 @@ ($$$$$$) my $path = $basePath . '/' . ConformPathToNamespace($et, "rdf:type"); unless ($$capture{$path}) { $$capture{$path} = [ '', { 'rdf:resource' => $$strTable{TYPE} } ]; - $et->VerboseValue("+ XMP-$path", $$strTable{TYPE}) if $verbose > 1; + if ($verbose > 1) { + my $p = $path; + $p =~ s/^(\w+)/$stdXlatNS{$1} || $1/e; + $et->VerboseValue("+ XMP-$p", $$strTable{TYPE}); + } } } return $changed; @@ -621,6 +632,7 @@ ($;$) my ($key, %structs, %var, %lists, $si, %listKeys, @siList); my $ex = $$et{TAG_EXTRA}; my $valueHash = $$et{VALUE}; + my $fileOrder = $$et{FILE_ORDER}; my $tagExtra = $$et{TAG_EXTRA}; foreach $key (keys %{$$et{TAG_INFO}}) { $$ex{$key} or next; @@ -764,7 +776,13 @@ ($;$) # everything else, and this is really what we care about) my $k = $listKeys{$oldStruct}; if ($k) { # ($k will be undef for an empty structure) - $k lt $key and $et->DeleteTag($key), next; + if ($k lt $key) { + # keep lowest file order + $$fileOrder{$k} = $$fileOrder{$key} if $$fileOrder{$k} > $$fileOrder{$key}; + $et->DeleteTag($key); + next; + } + $$fileOrder{$key} = $$fileOrder{$k} if $$fileOrder{$key} > $$fileOrder{$k}; $et->DeleteTag($k); # remove tag with greater copy number } } @@ -775,11 +793,11 @@ ($;$) # save strInfo ref and file order if ($var{$strInfo}) { # set file order to just before the first associated flattened tag - if ($var{$strInfo}[1] > $$et{FILE_ORDER}{$key}) { - $var{$strInfo}[1] = $$et{FILE_ORDER}{$key} - 0.5; + if ($var{$strInfo}[1] > $$fileOrder{$key}) { + $var{$strInfo}[1] = $$fileOrder{$key} - 0.5; } } else { - $var{$strInfo} = [ $strInfo, $$et{FILE_ORDER}{$key} - 0.5 ]; + $var{$strInfo} = [ $strInfo, $$fileOrder{$key} - 0.5 ]; } # preserve original flattened tags if requested if ($keepFlat) { @@ -809,7 +827,7 @@ ($;$) foreach $si (sort { $var{$a}[1] <=> $var{$b}[1] } @siList) { $key = $et->FoundTag($var{$si}[0], ''); $$valueHash{$key} = $structs{$si}; - $$et{FILE_ORDER}{$key} = $var{$si}[1]; + $$fileOrder{$key} = $var{$si}[1]; } } @@ -833,7 +851,7 @@ =head1 DESCRIPTION =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/ZIP.pm b/src/Image-ExifTool/lib/Image/ExifTool/ZIP.pm index a822d277..b8284c2d 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/ZIP.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/ZIP.pm @@ -19,7 +19,7 @@ use strict; use vars qw($VERSION $warnString); use Image::ExifTool qw(:DataAccess :Utils); -$VERSION = '1.23'; +$VERSION = '1.26'; sub WarnProc($) { $warnString = $_[0]; } @@ -43,6 +43,14 @@ my %iWorkFile = ( 'Index/Tables/DataList.iwa' => 'NUMBERS', ); +my %iWorkType = ( + NUMBERS => 'NUMBERS', + PAGES => 'PAGES', + KEY => 'KEY', + KTH => 'KTH', + NMBTEMPLATE => 'NMBTEMPLATE', +); + # ZIP metadata blocks %Image::ExifTool::ZIP::Main = ( PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData, @@ -274,7 +282,7 @@ sub ProcessRAR($$) last if $size < 0; next unless $size; # ignore blocks with no data # don't try to read very large blocks unless LargeFileSupport is enabled - if ($size > 0x80000000 and not $et->Options('LargeFileSupport')) { + if ($size >= 0x80000000 and not $et->Options('LargeFileSupport')) { $et->Warn('Large block encountered. Aborting.'); last; } @@ -300,6 +308,9 @@ sub ProcessRAR($$) $raf->Seek($size, 1) or last if $size; } $$et{DOC_NUM} = 0; + if ($docNum > 1 and not $et->Options('Duplicates')) { + $et->Warn("Use the Duplicates option to extract tags for all $docNum files", 1); + } return 1; } @@ -379,13 +390,14 @@ sub ProcessZIP($$) { my ($et, $dirInfo) = @_; my $raf = $$dirInfo{RAF}; - my ($buff, $buf2, $zip, $docNum); + my ($buff, $buf2, $zip); return 0 unless $raf->Read($buff, 30) == 30 and $buff =~ /^PK\x03\x04/; my $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::Main'); + my $docNum = 0; - # use Archive::Zip if avilable + # use Archive::Zip if available for (;;) { unless (eval { require Archive::Zip } and eval { require IO::File }) { if ($$et{FILE_EXT} and $$et{FILE_EXT} ne 'ZIP') { @@ -440,11 +452,18 @@ sub ProcessZIP($$) # check for an Office Open file (DOCX, etc) # --> read '[Content_Types].xml' to determine the file type - my ($mime, @members, $epub); + my ($mime, @members); my $cType = $zip->memberNamed('[Content_Types].xml'); if ($cType) { ($buff, $status) = $zip->contents($cType); - if (not $status and $buff =~ /ContentType\s*=\s*(['"])([^"']+)\.main(\+xml)?\1/) { + if (not $status and ( + # first look for the main document with the expected name + $buff =~ m{\sPartName\s*=\s*['"](?:/ppt/presentation.xml|/word/document.xml|/xl/workbook.xml)['"][^>]*\sContentType\s*=\s*(['"])([^"']+)\.main(\+xml)?\1} or + # then look for the main part + $buff =~ /<Override[^>]*\sPartName[^<]+\sContentType\s*=\s*(['"])([^"']+)\.main(\+xml)?\1/ or + # and if all else fails, use the default main + $buff =~ /ContentType\s*=\s*(['"])([^"']+)\.main(\+xml)?\1/)) + { $mime = $2; } } @@ -558,7 +577,6 @@ sub ProcessZIP($$) # otherwise just extract general ZIP information $et->SetFileType(); @members = $zip->members(); - $docNum = 0; my ($member, $iWorkType); # special files to extract my %extract = ( @@ -587,7 +605,8 @@ sub ProcessZIP($$) $et->FoundTag($extract{$file} => $buff); } } elsif ($file eq 'Index/Document.iwa' and not $iWorkType) { - $iWorkType = 'PAGES'; + my $type = $iWorkType{$$et{FILE_EXT} || ''}; + $iWorkType = $type || 'PAGES'; } elsif ($iWorkFile{$file}) { $iWorkType = $iWorkFile{$file}; } @@ -599,12 +618,14 @@ sub ProcessZIP($$) if ($zip) { delete $$dirInfo{ZIP}; delete $$et{DOC_NUM}; + if ($docNum > 1 and not $et->Options('Duplicates')) { + $et->Warn("Use the Duplicates option to extract tags for all $docNum files", 1); + } return 1; } # # process the ZIP file by hand (funny, but this seems easier than using Archive::Zip) # - $docNum = 0; $et->VPrint(1, " -- processing as binary data --\n"); $raf->Seek(30, 0); $et->SetFileType(); @@ -650,6 +671,9 @@ sub ProcessZIP($$) $raf->Read($buff, 30) == 30 and $buff =~ /^PK\x03\x04/ or last; } delete $$et{DOC_NUM}; + if ($docNum > 1 and not $et->Options('Duplicates')) { + $et->Warn("Use the Duplicates option to extract tags for all $docNum files", 1); + } return 1; } @@ -676,7 +700,7 @@ Electronic Publication (EPUB), and Sketch design files (SKETCH). =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/src/Image-ExifTool/lib/Image/ExifTool/iWork.pm b/src/Image-ExifTool/lib/Image/ExifTool/iWork.pm index be5310d8..aa381b6a 100644 --- a/src/Image-ExifTool/lib/Image/ExifTool/iWork.pm +++ b/src/Image-ExifTool/lib/Image/ExifTool/iWork.pm @@ -14,7 +14,7 @@ use Image::ExifTool qw(:DataAccess :Utils); use Image::ExifTool::XMP; use Image::ExifTool::ZIP; -$VERSION = '1.05'; +$VERSION = '1.06'; # test for recognized iWork document extensions and outer XML elements my %iWorkType = ( @@ -70,7 +70,7 @@ sub GetTagID($) { my $props = shift; return 0 if $$props[-1] =~ /^\w+:ID$/; # ignore ID tags - return ($$props[0] =~ /^.*?:(.*)/) ? $1 : $$props[0]; + return $$props[0] =~ /^.*?:(.*)/ ? $1 : $$props[0]; } #------------------------------------------------------------------------------ @@ -155,7 +155,7 @@ sub Process_iWork($$) Image::ExifTool::ZIP::HandleMember($et, $member); # process only the index XML and JPEG thumbnail/preview files - next unless $file =~ m{^(index\.(xml|apxl)|QuickLook/Thumbnail\.jpg|[^/]+/preview.jpg)$}i; + next unless $file =~ m{^(index\.(xml|apxl)|QuickLook/Thumbnail\.jpg|[^/]+/preview(-micro|-web)?.jpg)$}i; # get the file contents if necessary # (CAREFUL! $buff MUST be local since we hand off a value ref to PreviewImage) my ($buff, $buffPt); @@ -169,7 +169,8 @@ sub Process_iWork($$) } # extract JPEG as PreviewImage (should only be QuickLook/Thumbnail.jpg) if ($file =~ /\.jpg$/) { - $et->FoundTag('PreviewImage', $buffPt); + my $type = ($file =~ /preview-(\w+)/) ? ($1 eq 'web' ? 'Other' : 'Thumbnail') : 'Preview'; + $et->FoundTag($type . 'Image', $buffPt); next; } # process "metadata" section of XML index file @@ -214,7 +215,7 @@ information from Apple iWork '09 XML+ZIP files. =head1 AUTHOR -Copyright 2003-2018, Phil Harvey (phil at owl.phy.queensu.ca) +Copyright 2003-2020, Phil Harvey (philharvey66 at gmail.com) This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.